[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

kbr at google.com kbr at google.com
Wed Dec 22 12:23:37 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 3bbba84a12cb68815ed4157ae515e6beb6151c5e
Author: kbr at google.com <kbr at google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Aug 20 22:12:01 2010 +0000

    2010-08-20  Adrienne Walker  <enne at google.com>
    
            Reviewed by Kenneth Russell.
    
            Implement HTMLVideoElement support for texImage2D and texSubImage2D
            https://bugs.webkit.org/show_bug.cgi?id=33852
    
            Test: fast/canvas/webgl/tex-image-and-sub-image-2d-with-video.html
    
            * html/canvas/WebGLRenderingContext.cpp:
            (WebCore::WebGLRenderingContext::WebGLRenderingContext):
            (WebCore::WebGLRenderingContext::videoFrameToImage):
            (WebCore::WebGLRenderingContext::texImage2D):
            (WebCore::WebGLRenderingContext::texSubImage2D):
            (WebCore::WebGLRenderingContext::LRUImageBufferCache::LRUImageBufferCache):
            (WebCore::WebGLRenderingContext::LRUImageBufferCache::imageBuffer):
            (WebCore::WebGLRenderingContext::LRUImageBufferCache::bubbleToFront):
            * html/canvas/WebGLRenderingContext.h:
    2010-08-20  Adrienne Walker  <enne at google.com>
    
            Reviewed by Kenneth Russell.
    
            Implement HTMLVideoElement support for texImage2D and texSubImage2D
            https://bugs.webkit.org/show_bug.cgi?id=33852
    
            * fast/canvas/webgl/resources/quadrants.mp4: Added.
            * fast/canvas/webgl/resources/quadrants.ogv: Added.
            * fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-expected.txt: Added.
            * fast/canvas/webgl/tex-image-and-sub-image-2d-with-video.html: Added.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@65756 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index b853a37..1442a08 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,15 @@
+2010-08-20  Adrienne Walker  <enne at google.com>
+
+        Reviewed by Kenneth Russell.
+
+        Implement HTMLVideoElement support for texImage2D and texSubImage2D
+        https://bugs.webkit.org/show_bug.cgi?id=33852
+
+        * fast/canvas/webgl/resources/quadrants.mp4: Added.
+        * fast/canvas/webgl/resources/quadrants.ogv: Added.
+        * fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-expected.txt: Added.
+        * fast/canvas/webgl/tex-image-and-sub-image-2d-with-video.html: Added.
+
 2010-08-20  Dumitru Daniliuc  <dumi at chromium.org>
 
         Reviewed by Adam Barth.
diff --git a/LayoutTests/fast/canvas/webgl/resources/quadrants.mp4 b/LayoutTests/fast/canvas/webgl/resources/quadrants.mp4
new file mode 100644
index 0000000..bab4f8d
Binary files /dev/null and b/LayoutTests/fast/canvas/webgl/resources/quadrants.mp4 differ
diff --git a/LayoutTests/fast/canvas/webgl/resources/quadrants.ogv b/LayoutTests/fast/canvas/webgl/resources/quadrants.ogv
new file mode 100644
index 0000000..13f5568
Binary files /dev/null and b/LayoutTests/fast/canvas/webgl/resources/quadrants.ogv differ
diff --git a/LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-expected.txt b/LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-expected.txt
new file mode 100644
index 0000000..9bc08ac
--- /dev/null
+++ b/LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-expected.txt
@@ -0,0 +1,39 @@
+ 
+Verify texImage2D and texSubImage2D code paths taking Videos
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+Testing texImage2D with flipY=false
+PASS pixelAt(0, 0) is red
+PASS pixelAt(bufWidth-1, 0) is green
+PASS pixelAt(0, bufHeight-1) is yellow
+PASS pixelAt(bufWidth-1, bufHeight-1) is blue
+Testing texImage2D with flipY=true
+PASS pixelAt(0, 0) is yellow
+PASS pixelAt(bufWidth-1, 0) is blue
+PASS pixelAt(0, bufHeight-1) is red
+PASS pixelAt(bufWidth-1, bufHeight-1) is green
+Testing TexSubImage2D with flipY=false, scale=2, ox=0, oy=0
+PASS pixelAt(0, 0) is red
+PASS pixelAt(bufWidth-1, 0) is black
+PASS pixelAt(0, bufHeight-1) is black
+PASS pixelAt(bufWidth-1, bufHeight-1) is black
+Testing TexSubImage2D with flipY=true, scale=2, ox=0, oy=0
+PASS pixelAt(0, 0) is yellow
+PASS pixelAt(bufWidth-1, 0) is black
+PASS pixelAt(0, bufHeight-1) is black
+PASS pixelAt(bufWidth-1, bufHeight-1) is black
+Testing TexSubImage2D with flipY=false, scale=2, ox=0.5, oy=0.5
+PASS pixelAt(0, 0) is black
+PASS pixelAt(bufWidth-1, 0) is black
+PASS pixelAt(0, bufHeight-1) is black
+PASS pixelAt(bufWidth-1, bufHeight-1) is blue
+Testing TexSubImage2D with flipY=true, scale=2, ox=0.5, oy=0.5
+PASS pixelAt(0, 0) is black
+PASS pixelAt(bufWidth-1, 0) is black
+PASS pixelAt(0, bufHeight-1) is black
+PASS pixelAt(bufWidth-1, bufHeight-1) is green
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video.html b/LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video.html
new file mode 100644
index 0000000..1eae5d4
--- /dev/null
+++ b/LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video.html
@@ -0,0 +1,154 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../js/resources/js-test-style.css"/>
+<script src="../../js/resources/js-test-pre.js"></script>
+<script src="resources/webgl-test.js"></script>
+<script src="resources/webgl-test-utils.js"></script>
+<script src="../../../media/media-file.js"></script>
+<script>
+var wtu = WebGLTestUtils;
+var gl = null;
+var textureLoc = null;
+var successfullyParsed = false;
+
+function init()
+{
+    if (window.initNonKhronosFramework) {
+        window.initNonKhronosFramework(true);
+    }
+
+    description('Verify texImage2D and texSubImage2D code paths taking Videos');
+
+    var canvas = document.getElementById("example");
+    gl = wtu.create3DContext(canvas);
+    var program = wtu.setupTexturedQuad(gl);
+
+    gl.clearColor(0,0,0,1);
+    gl.clearDepth(1);
+
+    textureLoc = gl.getUniformLocation(gl.program, "tex");
+
+    var mediaFile = findMediaFile("video", "resources/quadrants");
+    loadVideo(mediaFile);
+}
+
+function loadVideo(src) {
+    var video = document.getElementsByTagName('video')[0];
+
+    function startVideo() {
+        // Resize canvas to fit video.
+        var canvas = document.getElementsByTagName('canvas')[0];
+        canvas.width = video.videoWidth;
+        canvas.height = video.videoHeight;
+
+        runTest(video);
+    };
+    video.addEventListener("canplay", startVideo);
+    video.src = src;
+}
+
+// These declarations need to be global for "shouldBe" to see them
+var buf = null;
+var bufWidth;
+var bufHeight;
+var red = [255, 0, 0, 255];
+var green = [0, 255, 0, 255];
+var blue = [0, 0, 255, 255];
+var yellow = [255, 255, 0, 255];
+var black = [0, 0, 0, 255];
+var clear = [127, 127, 127, 255];
+function pixelAt(x, y) {
+    var index = y * bufWidth * 4 + x * 4;
+    return [buf[index], buf[index+1], buf[index+2], buf[index+3]];
+}
+
+function runOneIteration(video, flipY, useTexSubImage2D, ulColor, urColor, blColor, brColor, ox, oy, scale) {
+    var canvas = document.getElementsByTagName('canvas')[0];
+    gl.viewport(0, 0, canvas.width, canvas.height);
+
+    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+    // Disable any writes to the alpha channel
+    gl.colorMask(1, 1, 1, 0);
+
+    var texture = gl.createTexture();
+    // Bind the texture to texture unit 0
+    gl.bindTexture(gl.TEXTURE_2D, texture);
+    // Set up texture parameters
+    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+    // Set up pixel store parameters
+    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY);
+    gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
+    // Upload the image into the texture
+    if (useTexSubImage2D) {
+        // Fill initial texture with black.
+        var texWidth = scale * canvas.width;
+        var texHeight = scale * canvas.height;
+        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texWidth, texHeight, 0,
+                      gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+        gl.texSubImage2D(gl.TEXTURE_2D, 0, ox * texWidth, oy * texHeight, gl.RGBA, gl.UNSIGNED_BYTE, video);
+        debug('Testing TexSubImage2D with flipY=' + flipY +', scale=' + scale + ', ox=' + ox + ', oy=' + oy);
+    } else {
+        debug('Testing texImage2D with flipY=' + flipY);
+        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, video);
+    }
+
+    // Point the uniform sampler to texture unit 0
+    gl.uniform1i(textureLoc, 0);
+    // Draw the triangles
+    wtu.drawQuad(gl, clear);
+    // Read back the rendering results
+    bufWidth = canvas.width;
+    bufHeight = canvas.height;
+    buf = new Uint8Array(bufWidth * bufHeight * 4);
+    gl.readPixels(0, 0, bufWidth, bufHeight, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+
+    shouldBe("pixelAt(0, 0)", ulColor);
+    shouldBe("pixelAt(bufWidth-1, 0)", urColor);
+    shouldBe("pixelAt(0, bufHeight-1)", blColor);
+    shouldBe("pixelAt(bufWidth-1, bufHeight-1)", brColor);
+}
+
+function runTest(video)
+{
+    // Original square should have red, green, yellow, blue quadrants,
+    // with a cross in the middle:
+    //
+    // R|G
+    // -+-
+    // Y|B
+
+    // texImage2D the whole texture
+    runOneIteration(video, false, false, "red", "green", "yellow", "blue");
+    runOneIteration(video, true, false, "yellow", "blue", "red", "green");
+
+    // texSubImage2D upper left
+    runOneIteration(video, false, true, "red", "black", "black", "black", 0, 0, 2);
+    runOneIteration(video, true, true, "yellow", "black", "black", "black", 0, 0, 2);
+
+    // texSubImage2D lower right
+    runOneIteration(video, false, true, "black", "black", "black", "blue", 0.5, 0.5, 2);
+    runOneIteration(video, true, true, "black", "black", "black", "green", 0.5, 0.5, 2);
+
+    successfullyParsed = true;
+    var epilogue = document.createElement("script");
+    epilogue.onload = finish;
+    epilogue.src = "../../js/resources/js-test-post.js";
+    document.body.appendChild(epilogue);
+}
+
+function finish() {
+    if (window.nonKhronosFrameworkNotifyDone) {
+        window.nonKhronosFrameworkNotifyDone();
+    }
+}
+</script>
+</head>
+<body onload="init()">
+<video id="sourcevideo"></video>
+<canvas id="example"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+</body>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 5d3d5c4..e2f9b25 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,22 @@
+2010-08-20  Adrienne Walker  <enne at google.com>
+
+        Reviewed by Kenneth Russell.
+
+        Implement HTMLVideoElement support for texImage2D and texSubImage2D
+        https://bugs.webkit.org/show_bug.cgi?id=33852
+
+        Test: fast/canvas/webgl/tex-image-and-sub-image-2d-with-video.html
+
+        * html/canvas/WebGLRenderingContext.cpp:
+        (WebCore::WebGLRenderingContext::WebGLRenderingContext):
+        (WebCore::WebGLRenderingContext::videoFrameToImage):
+        (WebCore::WebGLRenderingContext::texImage2D):
+        (WebCore::WebGLRenderingContext::texSubImage2D):
+        (WebCore::WebGLRenderingContext::LRUImageBufferCache::LRUImageBufferCache):
+        (WebCore::WebGLRenderingContext::LRUImageBufferCache::imageBuffer):
+        (WebCore::WebGLRenderingContext::LRUImageBufferCache::bubbleToFront):
+        * html/canvas/WebGLRenderingContext.h:
+
 2010-08-20  Dumitru Daniliuc  <dumi at chromium.org>
 
         Reviewed by Adam Barth.
diff --git a/WebCore/html/canvas/WebGLRenderingContext.cpp b/WebCore/html/canvas/WebGLRenderingContext.cpp
index 4465833..2733953 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.cpp
+++ b/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -36,6 +36,7 @@
 #include "FrameView.h"
 #include "HTMLCanvasElement.h"
 #include "HTMLImageElement.h"
+#include "HTMLVideoElement.h"
 #include "ImageBuffer.h"
 #include "ImageData.h"
 #include "NotImplemented.h"
@@ -98,6 +99,7 @@ WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, Pa
     , m_needsUpdate(true)
     , m_markedCanvasDirty(false)
     , m_activeTextureUnit(0)
+    , m_videoCache(4)
     , m_packAlignment(4)
     , m_unpackAlignment(4)
     , m_unpackFlipY(false)
@@ -2188,19 +2190,32 @@ void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned
                    m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
 }
 
+PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* video)
+{
+    if (!video || !video->videoWidth() || !video->videoHeight()) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+        return 0;
+    }
+    IntSize size(video->videoWidth(), video->videoHeight());
+    ImageBuffer* buf = m_videoCache.imageBuffer(size);
+    if (!buf) {
+        m_context->synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY);
+        return 0;
+    }
+    IntRect destRect(0, 0, size.width(), size.height());
+    // FIXME: Turn this into a GPU-GPU texture copy instead of CPU readback.
+    video->paintCurrentFrameInContext(buf->context(), destRect);
+    return buf->copyImage();
+}
+
 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
                                        unsigned format, unsigned type, HTMLVideoElement* video, ExceptionCode& ec)
 {
-    // FIXME: Need to implement this call
-    UNUSED_PARAM(target);
-    UNUSED_PARAM(level);
-    UNUSED_PARAM(internalformat);
-    UNUSED_PARAM(format);
-    UNUSED_PARAM(type);
-    UNUSED_PARAM(video);
-
     ec = 0;
-    cleanupAfterGraphicsCall(false);
+    RefPtr<Image> image = videoFrameToImage(video);
+    if (!video)
+        return;
+    texImage2DImpl(target, level, internalformat, format, type, image.get(), m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
 }
 
 void WebGLRenderingContext::texParameter(unsigned long target, unsigned long pname, float paramf, int parami, bool isFloat)
@@ -2342,16 +2357,11 @@ void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsig
 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
                                           unsigned format, unsigned type, HTMLVideoElement* video, ExceptionCode& ec)
 {
-    // FIXME: Need to implement this call
-    UNUSED_PARAM(target);
-    UNUSED_PARAM(level);
-    UNUSED_PARAM(xoffset);
-    UNUSED_PARAM(yoffset);
-    UNUSED_PARAM(format);
-    UNUSED_PARAM(type);
-    UNUSED_PARAM(video);
     ec = 0;
-    cleanupAfterGraphicsCall(false);
+    RefPtr<Image> image = videoFrameToImage(video);
+    if (!video)
+        return;
+    texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
 }
 
 void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, float x, ExceptionCode& ec)
@@ -3564,6 +3574,42 @@ void WebGLRenderingContext::restoreStatesAfterVertexAttrib0Simulation()
     m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, objectOrZero(m_boundArrayBuffer.get()));
 }
 
+WebGLRenderingContext::LRUImageBufferCache::LRUImageBufferCache(int capacity)
+    : m_buffers(new OwnPtr<ImageBuffer>[capacity])
+    , m_capacity(capacity)
+{
+}
+
+ImageBuffer* WebGLRenderingContext::LRUImageBufferCache::imageBuffer(const IntSize& size)
+{
+    int i;
+    for (i = 0; i < m_capacity; ++i) {
+        ImageBuffer* buf = m_buffers[i].get();
+        if (!buf)
+            break;
+        if (buf->size() != size)
+            continue;
+        bubbleToFront(i);
+        return buf;
+    }
+
+    OwnPtr<ImageBuffer> temp = ImageBuffer::create(size);
+    if (!temp)
+        return 0;
+    i = std::min(m_capacity - 1, i);
+    m_buffers[i] = temp.release();
+
+    ImageBuffer* buf = m_buffers[i].get();
+    bubbleToFront(i);
+    return buf;
+}
+
+void WebGLRenderingContext::LRUImageBufferCache::bubbleToFront(int idx)
+{
+    for (int i = idx; i > 0; --i)
+        m_buffers[i].swap(m_buffers[i-1]);
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(3D_CANVAS)
diff --git a/WebCore/html/canvas/WebGLRenderingContext.h b/WebCore/html/canvas/WebGLRenderingContext.h
index 48fa7c8..f39b373 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.h
+++ b/WebCore/html/canvas/WebGLRenderingContext.h
@@ -35,6 +35,8 @@
 #include "Uint8Array.h"
 #include "WebGLGetInfo.h"
 
+#include <wtf/OwnArrayPtr.h>
+
 namespace WebCore {
 
 class WebGLActiveInfo;
@@ -49,6 +51,7 @@ class WebGLTexture;
 class WebGLUniformLocation;
 class HTMLImageElement;
 class HTMLVideoElement;
+class ImageBuffer;
 class ImageData;
 class WebKitCSSMatrix;
 
@@ -320,6 +323,8 @@ public:
 
     bool validateWebGLObject(WebGLObject* object);
 
+    PassRefPtr<Image> videoFrameToImage(HTMLVideoElement* video);
+
     OwnPtr<GraphicsContext3D> m_context;
     bool m_needsUpdate;
     bool m_markedCanvasDirty;
@@ -387,6 +392,19 @@ public:
     RefPtr<WebGLTexture> m_blackTexture2D;
     RefPtr<WebGLTexture> m_blackTextureCubeMap;
 
+    // Fixed-size cache of reusable image buffers for video texImage2D calls.
+    class LRUImageBufferCache {
+    public:
+        LRUImageBufferCache(int capacity);
+        // The pointer returned is owned by the image buffer map.
+        ImageBuffer* imageBuffer(const IntSize& size);
+    private:
+        void bubbleToFront(int idx);
+        OwnArrayPtr<OwnPtr<ImageBuffer> > m_buffers;
+        int m_capacity;
+    };
+    LRUImageBufferCache m_videoCache;
+
     int m_maxTextureSize;
     int m_maxCubeMapTextureSize;
     int m_maxTextureLevel;

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list