[chromium] Separate CCVideoDrawQuad and from the layer tree and video provider by...
authordanakj@chromium.org <danakj@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 11 Jun 2012 22:58:16 +0000 (22:58 +0000)
committerdanakj@chromium.org <danakj@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 11 Jun 2012 22:58:16 +0000 (22:58 +0000)
https://bugs.webkit.org/show_bug.cgi?id=88363

Reviewed by Adrienne Walker.

Source/Platform:

* Platform.gypi:
* chromium/public/WebVideoFrame.h:
* chromium/src/WebVideoFrame.cpp: Removed.

Source/WebCore:

CCVideoDrawQuad should not contain any pointers to data in the layer
tree so we are able to serialize it across process boundaries. This
patch removes the ManagedTexture pointers from the quad class,
replacing them with texture ids. It removes the WebVideoFrame* from
the quad, replacing it with the frame provider's texture id included
in the WebVideoFrame structure. And it uses a WebTransformationMatrix
instead of a pointer to an array of floats.

Texture allocation is done in CCVideoLayerImpl via the
contentsTextureAllocator, so that the memory usage can be tracked.

We move the copyPlaneToTextures() method back from LayerRendererChromium
to CCVideoLayerImpl, as this method uses the texture data pointer in the
WebVideoFrame, and we do not want to give this pointer to the quad
class. Instead, this method makes use of the LayerTextureSubImage class
to copy the pixel data into the texture.

LayerTextureSubImage is updated to allow non-4byte texture formats.

* platform/graphics/chromium/LayerRendererChromium.cpp:
(WebCore::LayerRendererChromium::drawYUV):
(WebCore::LayerRendererChromium::drawRGBA):
(WebCore::LayerRendererChromium::drawNativeTexture2D):
(WebCore::LayerRendererChromium::drawStreamTexture):
(WebCore::LayerRendererChromium::drawVideoQuad):
* platform/graphics/chromium/LayerTextureSubImage.cpp:
(WebCore::LayerTextureSubImage::uploadWithTexSubImage):
(WebCore::LayerTextureSubImage::uploadWithMapTexSubImage):
* platform/graphics/chromium/TextureCopier.cpp:
* platform/graphics/chromium/cc/CCVideoDrawQuad.cpp:
(WebCore::CCVideoDrawQuad::create):
(WebCore::CCVideoDrawQuad::CCVideoDrawQuad):
* platform/graphics/chromium/cc/CCVideoDrawQuad.h:
(CCVideoDrawQuad):
(WebCore::CCVideoDrawQuad::planes):
(WebCore::CCVideoDrawQuad::frameProviderTextureId):
* platform/graphics/chromium/cc/CCVideoLayerImpl.cpp:
(WebCore::CCVideoLayerImpl::~CCVideoLayerImpl):
(WebCore::CCVideoLayerImpl::willDraw):
(WebCore::CCVideoLayerImpl::willDrawInternal):
(WebCore::CCVideoLayerImpl::appendQuads):
(WebCore::CCVideoLayerImpl::didDraw):
(WebCore::CCVideoLayerImpl::FramePlane::allocateData):
(WebCore):
(WebCore::CCVideoLayerImpl::FramePlane::freeData):
(WebCore::CCVideoLayerImpl::allocatePlaneData):
(WebCore::CCVideoLayerImpl::copyPlaneData):
(WebCore::CCVideoLayerImpl::freePlaneData):
(WebCore::CCVideoLayerImpl::freeUnusedPlaneData):
(WebCore::CCVideoLayerImpl::didLoseContext):
* platform/graphics/chromium/cc/CCVideoLayerImpl.h:
(FramePlane):
(WebCore::CCVideoLayerImpl::FramePlane::FramePlane):

Source/WebKit/chromium:

* tests/CCLayerTreeHostImplTest.cpp:
* tests/CCTiledLayerTestCommon.h:
(WebKitTests::FakeTextureCopier::copyToTexture):
* tests/Canvas2DLayerChromiumTest.cpp:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@120015 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
Source/Platform/ChangeLog
Source/Platform/Platform.gypi
Source/Platform/chromium/public/WebVideoFrame.h
Source/Platform/chromium/src/WebVideoFrame.cpp [deleted file]
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
Source/WebCore/platform/graphics/chromium/LayerTextureSubImage.cpp
Source/WebCore/platform/graphics/chromium/cc/CCVideoDrawQuad.cpp
Source/WebCore/platform/graphics/chromium/cc/CCVideoDrawQuad.h
Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp
Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp
Source/WebKit/chromium/tests/CCTiledLayerTestCommon.h

index 8b84ce2..aab0ebb 100644 (file)
@@ -1,3 +1,14 @@
+2012-06-11  Dana Jansens  <danakj@chromium.org>
+
+        [chromium] Separate CCVideoDrawQuad and from the layer tree and video provider by removing ManagedTexture and WebVideoFrame pointers from the quad
+        https://bugs.webkit.org/show_bug.cgi?id=88363
+
+        Reviewed by Adrienne Walker.
+
+        * Platform.gypi:
+        * chromium/public/WebVideoFrame.h:
+        * chromium/src/WebVideoFrame.cpp: Removed.
+
 2012-06-08  David Reveman  <reveman@chromium.org>
 
         [Chromium] Compositor doesn't support translucent root layers.
index aaf2ee8..aedee26 100644 (file)
             'chromium/src/WebFloatQuad.cpp',
             'chromium/src/WebPrerenderingSupport.cpp',
             'chromium/src/WebString.cpp',
-            'chromium/src/WebVideoFrame.cpp',
         ]
     }
 }
index db0aa7d..74799bb 100644 (file)
@@ -38,13 +38,17 @@ namespace WebKit {
 // Keep in sync with chromium's media::VideoFrame::Format.
 class WebVideoFrame {
 public:
-    static const unsigned maxPlanes;
-    static const unsigned numRGBPlanes;
-    static const unsigned rgbPlane;
-    static const unsigned numYUVPlanes;
-    static const unsigned yPlane;
-    static const unsigned uPlane;
-    static const unsigned vPlane;
+    enum {
+        rgbPlane = 0,
+        numRGBPlanes = 1
+    };
+    enum {
+        yPlane = 0,
+        uPlane = 1,
+        vPlane = 2,
+        numYUVPlanes = 3
+    };
+    enum { maxPlanes = 3 };
 
     enum Format {
         FormatInvalid = 0,
diff --git a/Source/Platform/chromium/src/WebVideoFrame.cpp b/Source/Platform/chromium/src/WebVideoFrame.cpp
deleted file mode 100644 (file)
index 8c86659..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include <public/WebVideoFrame.h>
-
-namespace WebKit {
-
-const unsigned WebVideoFrame::maxPlanes = 3;
-const unsigned WebVideoFrame::numRGBPlanes = 1;
-const unsigned WebVideoFrame::rgbPlane = 0;
-const unsigned WebVideoFrame::numYUVPlanes = 3;
-const unsigned WebVideoFrame::yPlane = 0;
-const unsigned WebVideoFrame::uPlane = 1;
-const unsigned WebVideoFrame::vPlane = 2;
-
-} // namespace WebKit
-
index 8fccfa1..3cb8c49 100644 (file)
@@ -1,3 +1,64 @@
+2012-06-11  Dana Jansens  <danakj@chromium.org>
+
+        [chromium] Separate CCVideoDrawQuad and from the layer tree and video provider by removing ManagedTexture and WebVideoFrame pointers from the quad
+        https://bugs.webkit.org/show_bug.cgi?id=88363
+
+        Reviewed by Adrienne Walker.
+
+        CCVideoDrawQuad should not contain any pointers to data in the layer
+        tree so we are able to serialize it across process boundaries. This
+        patch removes the ManagedTexture pointers from the quad class,
+        replacing them with texture ids. It removes the WebVideoFrame* from
+        the quad, replacing it with the frame provider's texture id included
+        in the WebVideoFrame structure. And it uses a WebTransformationMatrix
+        instead of a pointer to an array of floats.
+
+        Texture allocation is done in CCVideoLayerImpl via the
+        contentsTextureAllocator, so that the memory usage can be tracked.
+
+        We move the copyPlaneToTextures() method back from LayerRendererChromium
+        to CCVideoLayerImpl, as this method uses the texture data pointer in the
+        WebVideoFrame, and we do not want to give this pointer to the quad
+        class. Instead, this method makes use of the LayerTextureSubImage class
+        to copy the pixel data into the texture.
+
+        LayerTextureSubImage is updated to allow non-4byte texture formats.
+
+        * platform/graphics/chromium/LayerRendererChromium.cpp:
+        (WebCore::LayerRendererChromium::drawYUV):
+        (WebCore::LayerRendererChromium::drawRGBA):
+        (WebCore::LayerRendererChromium::drawNativeTexture2D):
+        (WebCore::LayerRendererChromium::drawStreamTexture):
+        (WebCore::LayerRendererChromium::drawVideoQuad):
+        * platform/graphics/chromium/LayerTextureSubImage.cpp:
+        (WebCore::LayerTextureSubImage::uploadWithTexSubImage):
+        (WebCore::LayerTextureSubImage::uploadWithMapTexSubImage):
+        * platform/graphics/chromium/TextureCopier.cpp:
+        * platform/graphics/chromium/cc/CCVideoDrawQuad.cpp:
+        (WebCore::CCVideoDrawQuad::create):
+        (WebCore::CCVideoDrawQuad::CCVideoDrawQuad):
+        * platform/graphics/chromium/cc/CCVideoDrawQuad.h:
+        (CCVideoDrawQuad):
+        (WebCore::CCVideoDrawQuad::planes):
+        (WebCore::CCVideoDrawQuad::frameProviderTextureId):
+        * platform/graphics/chromium/cc/CCVideoLayerImpl.cpp:
+        (WebCore::CCVideoLayerImpl::~CCVideoLayerImpl):
+        (WebCore::CCVideoLayerImpl::willDraw):
+        (WebCore::CCVideoLayerImpl::willDrawInternal):
+        (WebCore::CCVideoLayerImpl::appendQuads):
+        (WebCore::CCVideoLayerImpl::didDraw):
+        (WebCore::CCVideoLayerImpl::FramePlane::allocateData):
+        (WebCore):
+        (WebCore::CCVideoLayerImpl::FramePlane::freeData):
+        (WebCore::CCVideoLayerImpl::allocatePlaneData):
+        (WebCore::CCVideoLayerImpl::copyPlaneData):
+        (WebCore::CCVideoLayerImpl::freePlaneData):
+        (WebCore::CCVideoLayerImpl::freeUnusedPlaneData):
+        (WebCore::CCVideoLayerImpl::didLoseContext):
+        * platform/graphics/chromium/cc/CCVideoLayerImpl.h:
+        (FramePlane):
+        (WebCore::CCVideoLayerImpl::FramePlane::FramePlane):
+
 2012-06-11  Joshua Bell  <jsbell@chromium.org>
 
         IndexedDB: Object stores are not successfully deleted
index 780fc32..120cbbe 100644 (file)
@@ -983,22 +983,22 @@ void LayerRendererChromium::drawYUV(const CCVideoDrawQuad* quad)
     const VideoYUVProgram* program = videoYUVProgram();
     ASSERT(program && program->initialized());
 
-    const CCVideoLayerImpl::Texture& yTexture = quad->textures()[WebKit::WebVideoFrame::yPlane];
-    const CCVideoLayerImpl::Texture& uTexture = quad->textures()[WebKit::WebVideoFrame::uPlane];
-    const CCVideoLayerImpl::Texture& vTexture = quad->textures()[WebKit::WebVideoFrame::vPlane];
+    const CCVideoLayerImpl::FramePlane& yPlane = quad->planes()[WebKit::WebVideoFrame::yPlane];
+    const CCVideoLayerImpl::FramePlane& uPlane = quad->planes()[WebKit::WebVideoFrame::uPlane];
+    const CCVideoLayerImpl::FramePlane& vPlane = quad->planes()[WebKit::WebVideoFrame::vPlane];
 
     GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE1));
-    GLC(context(), context()->bindTexture(GraphicsContext3D::TEXTURE_2D, yTexture.m_texture->textureId()));
+    GLC(context(), context()->bindTexture(GraphicsContext3D::TEXTURE_2D, yPlane.textureId));
     GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE2));
-    GLC(context(), context()->bindTexture(GraphicsContext3D::TEXTURE_2D, uTexture.m_texture->textureId()));
+    GLC(context(), context()->bindTexture(GraphicsContext3D::TEXTURE_2D, uPlane.textureId));
     GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE3));
-    GLC(context(), context()->bindTexture(GraphicsContext3D::TEXTURE_2D, vTexture.m_texture->textureId()));
+    GLC(context(), context()->bindTexture(GraphicsContext3D::TEXTURE_2D, vPlane.textureId));
 
     GLC(context(), context()->useProgram(program->program()));
 
-    float yWidthScaleFactor = static_cast<float>(yTexture.m_visibleSize.width()) / yTexture.m_texture->size().width();
+    float yWidthScaleFactor = static_cast<float>(yPlane.visibleSize.width()) / yPlane.size.width();
     // Arbitrarily take the u sizes because u and v dimensions are identical.
-    float uvWidthScaleFactor = static_cast<float>(uTexture.m_visibleSize.width()) / uTexture.m_texture->size().width();
+    float uvWidthScaleFactor = static_cast<float>(uPlane.visibleSize.width()) / uPlane.size.width();
     GLC(context(), context()->uniform1f(program->vertexShader().yWidthScaleFactorLocation(), yWidthScaleFactor));
     GLC(context(), context()->uniform1f(program->vertexShader().uvWidthScaleFactorLocation(), uvWidthScaleFactor));
 
@@ -1006,8 +1006,27 @@ void LayerRendererChromium::drawYUV(const CCVideoDrawQuad* quad)
     GLC(context(), context()->uniform1i(program->fragmentShader().uTextureLocation(), 2));
     GLC(context(), context()->uniform1i(program->fragmentShader().vTextureLocation(), 3));
 
-    GLC(context(), context()->uniformMatrix3fv(program->fragmentShader().ccMatrixLocation(), 1, 0, const_cast<float*>(CCVideoLayerImpl::yuv2RGB)));
-    GLC(context(), context()->uniform3fv(program->fragmentShader().yuvAdjLocation(), 1, const_cast<float*>(CCVideoLayerImpl::yuvAdjust)));
+    // These values are magic numbers that are used in the transformation from YUV to RGB color values.
+    // They are taken from the following webpage: http://www.fourcc.org/fccyvrgb.php
+    float yuv2RGB[9] = {
+        1.164f, 1.164f, 1.164f,
+        0.f, -.391f, 2.018f,
+        1.596f, -.813f, 0.f,
+    };
+    GLC(context(), context()->uniformMatrix3fv(program->fragmentShader().ccMatrixLocation(), 1, 0, yuv2RGB));
+
+    // These values map to 16, 128, and 128 respectively, and are computed
+    // as a fraction over 256 (e.g. 16 / 256 = 0.0625).
+    // They are used in the YUV to RGBA conversion formula:
+    //   Y - 16   : Gives 16 values of head and footroom for overshooting
+    //   U - 128  : Turns unsigned U into signed U [-128,127]
+    //   V - 128  : Turns unsigned V into signed V [-128,127]
+    float yuvAdjust[3] = {
+        -0.0625f,
+        -0.5f,
+        -0.5f,
+    };
+    GLC(context(), context()->uniform3fv(program->fragmentShader().yuvAdjLocation(), 1, yuvAdjust));
 
     const IntSize& bounds = quad->quadRect().size();
     drawTexturedQuad(quad->layerTransform(), bounds.width(), bounds.height(), quad->opacity(), FloatQuad(),
@@ -1041,73 +1060,35 @@ void LayerRendererChromium::drawSingleTextureVideoQuad(const CCVideoDrawQuad* qu
 void LayerRendererChromium::drawRGBA(const CCVideoDrawQuad* quad)
 {
     const TextureProgram* program = textureProgram();
-    const CCVideoLayerImpl::Texture& texture = quad->textures()[WebKit::WebVideoFrame::rgbPlane];
-    float widthScaleFactor = static_cast<float>(texture.m_visibleSize.width()) / texture.m_texture->size().width();
-    drawSingleTextureVideoQuad(quad, program, widthScaleFactor, texture.m_texture->textureId(), GraphicsContext3D::TEXTURE_2D);
+    const CCVideoLayerImpl::FramePlane& plane = quad->planes()[WebKit::WebVideoFrame::rgbPlane];
+    float widthScaleFactor = static_cast<float>(plane.visibleSize.width()) / plane.size.width();
+    drawSingleTextureVideoQuad(quad, program, widthScaleFactor, plane.textureId, GraphicsContext3D::TEXTURE_2D);
 }
 
 void LayerRendererChromium::drawNativeTexture2D(const CCVideoDrawQuad* quad)
 {
-    drawSingleTextureVideoQuad(quad, textureProgram(), 1, quad->frame()->textureId(), GraphicsContext3D::TEXTURE_2D);
+    drawSingleTextureVideoQuad(quad, textureProgram(), 1, quad->frameProviderTextureId(), GraphicsContext3D::TEXTURE_2D);
 }
 
 void LayerRendererChromium::drawStreamTexture(const CCVideoDrawQuad* quad)
 {
+    static float glMatrix[16];
+
     ASSERT(context()->getExtensions()->supports("GL_OES_EGL_image_external") && context()->getExtensions()->isEnabled("GL_OES_EGL_image_external"));
 
     const VideoStreamTextureProgram* program = videoStreamTextureProgram();
     GLC(context(), context()->useProgram(program->program()));
-    ASSERT(quad->matrix());
-    GLC(context(), context()->uniformMatrix4fv(program->vertexShader().texMatrixLocation(), 1, false, const_cast<float*>(quad->matrix())));
 
-    drawSingleTextureVideoQuad(quad, program, 1, quad->frame()->textureId(), Extensions3DChromium::GL_TEXTURE_EXTERNAL_OES);
-}
-
-bool LayerRendererChromium::copyFrameToTextures(const CCVideoDrawQuad* quad)
-{
-    const WebKit::WebVideoFrame* frame = quad->frame();
-
-    for (unsigned plane = 0; plane < frame->planes(); ++plane)
-        copyPlaneToTexture(quad, frame->data(plane), plane);
-
-    for (unsigned plane = frame->planes(); plane < CCVideoLayerImpl::MaxPlanes; ++plane) {
-        CCVideoLayerImpl::Texture* texture = &quad->textures()[plane];
-        texture->m_texture.clear();
-        texture->m_visibleSize = IntSize();
-    }
-    return true;
-}
+    toGLMatrix(&glMatrix[0], quad->matrix());
+    GLC(context(), context()->uniformMatrix4fv(program->vertexShader().texMatrixLocation(), 1, false, glMatrix));
 
-void LayerRendererChromium::copyPlaneToTexture(const CCVideoDrawQuad* quad, const void* plane, int index)
-{
-    CCVideoLayerImpl::Texture& texture = quad->textures()[index];
-    RefPtr<CCGraphicsContext> ccContext = CCGraphicsContext::create3D(m_context);
-    texture.m_texture->bindTexture(ccContext.get(), m_implTextureAllocator.get());
-    GC3Denum format = texture.m_texture->format();
-    IntSize dimensions = texture.m_texture->size();
-
-    void* mem = static_cast<Extensions3DChromium*>(context()->getExtensions())->mapTexSubImage2DCHROMIUM(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, dimensions.width(), dimensions.height(), format, GraphicsContext3D::UNSIGNED_BYTE, Extensions3DChromium::WRITE_ONLY);
-    if (mem) {
-        memcpy(mem, plane, dimensions.width() * dimensions.height());
-        GLC(context(), static_cast<Extensions3DChromium*>(context()->getExtensions())->unmapTexSubImage2DCHROMIUM(mem));
-    } else {
-        // If mapTexSubImage2DCHROMIUM fails, then do the slower texSubImage2D
-        // upload. This does twice the copies as mapTexSubImage2DCHROMIUM, one
-        // in the command buffer and another to the texture.
-        GLC(context(), context()->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, dimensions.width(), dimensions.height(), format, GraphicsContext3D::UNSIGNED_BYTE, plane));
-    }
+    drawSingleTextureVideoQuad(quad, program, 1, quad->frameProviderTextureId(), Extensions3DChromium::GL_TEXTURE_EXTERNAL_OES);
 }
 
 void LayerRendererChromium::drawVideoQuad(const CCVideoDrawQuad* quad)
 {
     ASSERT(CCProxy::isImplThread());
 
-    if (!quad->frame())
-        return;
-
-    if (!copyFrameToTextures(quad))
-        return;
-
     switch (quad->format()) {
     case GraphicsContext3D::LUMINANCE:
         drawYUV(quad);
index 5d912ea..4bea904 100644 (file)
@@ -30,6 +30,7 @@
 #include "LayerTextureSubImage.h"
 
 #include "Extensions3DChromium.h"
+#include "LayerRendererChromium.h" // For GLC() macro
 #include "TraceEvent.h"
 #include "cc/CCGraphicsContext.h"
 
@@ -93,7 +94,7 @@ void LayerTextureSubImage::uploadWithTexSubImage(const uint8_t* image, const Int
         // FIXME: Implement this path for software compositing.
         return;
     }
-    context3d->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, destRect.x(), destRect.y(), destRect.width(), destRect.height(), format, GraphicsContext3D::UNSIGNED_BYTE, pixelSource);
+    GLC(context3d, context3d->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, destRect.x(), destRect.y(), destRect.width(), destRect.height(), format, GraphicsContext3D::UNSIGNED_BYTE, pixelSource));
 }
 
 void LayerTextureSubImage::uploadWithMapTexSubImage(const uint8_t* image, const IntRect& imageRect,
@@ -119,17 +120,24 @@ void LayerTextureSubImage::uploadWithMapTexSubImage(const uint8_t* image, const
         return;
     }
 
+    unsigned int componentsPerPixel;
+    unsigned int bytesPerComponent;
+    if (!GraphicsContext3D::computeFormatAndTypeParameters(format, GraphicsContext3D::UNSIGNED_BYTE, &componentsPerPixel, &bytesPerComponent)) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+
     if (imageRect.width() == sourceRect.width() && !offset.x())
-        memcpy(pixelDest, &image[4 * offset.y() * imageRect.width()], imageRect.width() * destRect.height() * 4);
+        memcpy(pixelDest, &image[offset.y() * imageRect.width() * componentsPerPixel * bytesPerComponent], imageRect.width() * destRect.height() * componentsPerPixel * bytesPerComponent);
     else {
         // Strides not equal, so do a row-by-row memcpy from the
         // paint results into the pixelDest
         for (int row = 0; row < destRect.height(); ++row)
-            memcpy(&pixelDest[destRect.width() * 4 * row],
+            memcpy(&pixelDest[destRect.width() * row * componentsPerPixel * bytesPerComponent],
                    &image[4 * (offset.x() + (offset.y() + row) * imageRect.width())],
-                   destRect.width() * 4);
+                   destRect.width() * componentsPerPixel * bytesPerComponent);
     }
-    extensions->unmapTexSubImage2DCHROMIUM(pixelDest);
+    GLC(context3d, extensions->unmapTexSubImage2DCHROMIUM(pixelDest));
 }
 
 } // namespace WebCore
index 9cca714..c905c02 100644 (file)
 
 namespace WebCore {
 
-PassOwnPtr<CCVideoDrawQuad> CCVideoDrawQuad::create(const CCSharedQuadState* sharedQuadState, const IntRect& quadRect, CCVideoLayerImpl::Texture* textures, WebKit::WebVideoFrame* frame, GC3Denum format)
+PassOwnPtr<CCVideoDrawQuad> CCVideoDrawQuad::create(const CCSharedQuadState* sharedQuadState, const IntRect& quadRect, CCVideoLayerImpl::FramePlane planes[WebKit::WebVideoFrame::maxPlanes], unsigned frameProviderTextureId, GC3Denum format, const WebKit::WebTransformationMatrix& matrix)
 {
-    return adoptPtr(new CCVideoDrawQuad(sharedQuadState, quadRect, textures, frame, format));
+    return adoptPtr(new CCVideoDrawQuad(sharedQuadState, quadRect, planes, frameProviderTextureId, format, matrix));
 }
 
-CCVideoDrawQuad::CCVideoDrawQuad(const CCSharedQuadState* sharedQuadState, const IntRect& quadRect, CCVideoLayerImpl::Texture* textures, WebKit::WebVideoFrame* frame, GC3Denum format)
+CCVideoDrawQuad::CCVideoDrawQuad(const CCSharedQuadState* sharedQuadState, const IntRect& quadRect, CCVideoLayerImpl::FramePlane planes[WebKit::WebVideoFrame::maxPlanes], unsigned frameProviderTextureId, GC3Denum format, const WebKit::WebTransformationMatrix& matrix)
     : CCDrawQuad(sharedQuadState, CCDrawQuad::VideoContent, quadRect)
-    , m_textures(textures)
-    , m_frame(frame)
+    , m_frameProviderTextureId(frameProviderTextureId)
     , m_format(format)
-    , m_matrix(0)
+    , m_matrix(matrix)
 {
+    for (size_t i = 0; i < WebKit::WebVideoFrame::maxPlanes; ++i)
+      m_planes[i] = planes[i];
+
 }
 
 }
index 9eb357f..985b544 100644 (file)
 #include "GraphicsTypes3D.h"
 #include "cc/CCDrawQuad.h"
 #include "cc/CCVideoLayerImpl.h"
+#include <public/WebTransformationMatrix.h>
 #include <wtf/PassOwnPtr.h>
 
-namespace WebKit {
-class WebVideoFrame;
-}
-
 namespace WebCore {
 
 class CCVideoDrawQuad : public CCDrawQuad {
     WTF_MAKE_NONCOPYABLE(CCVideoDrawQuad);
 public:
-    static PassOwnPtr<CCVideoDrawQuad> create(const CCSharedQuadState*, const IntRect&, CCVideoLayerImpl::Texture* textures, WebKit::WebVideoFrame*, GC3Denum format);
+    static PassOwnPtr<CCVideoDrawQuad> create(const CCSharedQuadState*, const IntRect&, CCVideoLayerImpl::FramePlane planes[WebKit::WebVideoFrame::maxPlanes], unsigned frameProviderTextureId, GC3Denum format, const WebKit::WebTransformationMatrix&);
 
-    CCVideoLayerImpl::Texture* textures() const { return m_textures; }
-    WebKit::WebVideoFrame* frame() const { return m_frame; }
+    // Each index in this array corresponds to a plane in WebKit::WebVideoFrame.
+    const CCVideoLayerImpl::FramePlane* planes() const { return m_planes; }
+    unsigned frameProviderTextureId() const { return m_frameProviderTextureId; }
     GC3Denum format() const { return m_format; }
-    const float* matrix() const { return m_matrix; }
-
-    void setMatrix(const float* matrix) { m_matrix = matrix; }
+    const WebKit::WebTransformationMatrix& matrix() const { return m_matrix; }
 
 private:
-    CCVideoDrawQuad(const CCSharedQuadState*, const IntRect&, CCVideoLayerImpl::Texture* textures, WebKit::WebVideoFrame*, GC3Denum format);
+    CCVideoDrawQuad(const CCSharedQuadState*, const IntRect&, CCVideoLayerImpl::FramePlane planes[WebKit::WebVideoFrame::maxPlanes], unsigned frameProviderTextureId, GC3Denum format, const WebKit::WebTransformationMatrix&);
 
-    CCVideoLayerImpl::Texture* m_textures;
-    WebKit::WebVideoFrame* m_frame;
+    CCVideoLayerImpl::FramePlane m_planes[WebKit::WebVideoFrame::maxPlanes];
+    unsigned m_frameProviderTextureId;
     GC3Denum m_format;
-    const float* m_matrix;
+    WebKit::WebTransformationMatrix m_matrix;
 };
 
 }
index 105c119..a60413c 100644 (file)
 #include "Extensions3DChromium.h"
 #include "GraphicsContext3D.h"
 #include "LayerRendererChromium.h"
+#include "LayerTextureSubImage.h"
 #include "NotImplemented.h"
 #include "ProgramBinding.h"
+#include "TextureManager.h" // For TextureAllocator
 #include "cc/CCLayerTreeHostImpl.h"
 #include "cc/CCProxy.h"
 #include "cc/CCQuadCuller.h"
 
 namespace WebCore {
 
-// These values are magic numbers that are used in the transformation
-// from YUV to RGB color values.
-// They are taken from the following webpage:
-// http://www.fourcc.org/fccyvrgb.php
-const float CCVideoLayerImpl::yuv2RGB[9] = {
-    1.164f, 1.164f, 1.164f,
-    0.f, -.391f, 2.018f,
-    1.596f, -.813f, 0.f,
-};
-
-// These values map to 16, 128, and 128 respectively, and are computed
-// as a fraction over 256 (e.g. 16 / 256 = 0.0625).
-// They are used in the YUV to RGBA conversion formula:
-//   Y - 16   : Gives 16 values of head and footroom for overshooting
-//   U - 128  : Turns unsigned U into signed U [-128,127]
-//   V - 128  : Turns unsigned V into signed V [-128,127]
-const float CCVideoLayerImpl::yuvAdjust[3] = {
-    -0.0625f,
-    -0.5f,
-    -0.5f,
-};
-
-// This matrix is the default transformation for stream textures.
-const float CCVideoLayerImpl::flipTransform[16] = {
-    1, 0, 0, 0,
-    0, -1, 0, 0,
-    0, 0, 1, 0,
-    0, 1, 0, 1,
-};
-
 CCVideoLayerImpl::CCVideoLayerImpl(int id, WebKit::WebVideoFrameProvider* provider)
     : CCLayerImpl(id)
     , m_provider(provider)
     , m_frame(0)
 {
-    memcpy(m_streamTextureMatrix, flipTransform, sizeof(m_streamTextureMatrix));
+    // This matrix is the default transformation for stream textures, and flips on the Y axis.
+    m_streamTextureMatrix = WebKit::WebTransformationMatrix(
+        1, 0, 0, 0,
+        0, -1, 0, 0,
+        0, 0, 1, 0,
+        0, 1, 0, 1);
 
     // This only happens during a commit on the compositor thread while the main
     // thread is blocked. That makes this a thread-safe call to set the video
@@ -96,8 +73,12 @@ CCVideoLayerImpl::~CCVideoLayerImpl()
         m_provider->setVideoFrameProviderClient(0);
         m_provider = 0;
     }
-    for (unsigned i = 0; i < MaxPlanes; ++i)
-        m_textures[i].m_texture.clear();
+    freePlaneData(layerTreeHostImpl()->layerRenderer());
+
+#if !ASSERT_DISABLED
+    for (unsigned i = 0; i < WebKit::WebVideoFrame::maxPlanes; ++i)
+        ASSERT(!m_framePlanes[i].textureId);
+#endif
 }
 
 void CCVideoLayerImpl::stopUsingProvider()
@@ -141,13 +122,14 @@ void CCVideoLayerImpl::willDraw(CCRenderer* layerRenderer, CCGraphicsContext* co
     // lock should not cause a deadlock.
     m_providerMutex.lock();
 
-    willDrawInternal(layerRenderer);
+    willDrawInternal(layerRenderer, context);
+    freeUnusedPlaneData(layerRenderer);
 
     if (!m_frame)
         m_providerMutex.unlock();
 }
 
-void CCVideoLayerImpl::willDrawInternal(CCRenderer* layerRenderer)
+void CCVideoLayerImpl::willDrawInternal(CCRenderer* layerRenderer, CCGraphicsContext* context)
 {
     ASSERT(CCProxy::isImplThread());
 
@@ -169,9 +151,22 @@ void CCVideoLayerImpl::willDrawInternal(CCRenderer* layerRenderer)
         return;
     }
 
-    if (!reserveTextures(*m_frame, m_format, layerRenderer)) {
+    if (m_frame->planes() > WebKit::WebVideoFrame::maxPlanes) {
+        m_provider->putCurrentFrame(m_frame);
+        m_frame = 0;
+        return;
+    }
+
+    if (!allocatePlaneData(layerRenderer)) {
         m_provider->putCurrentFrame(m_frame);
         m_frame = 0;
+        return;
+    }
+
+    if (!copyPlaneData(layerRenderer, context)) {
+        m_provider->putCurrentFrame(m_frame);
+        m_frame = 0;
+        return;
     }
 }
 
@@ -182,11 +177,16 @@ void CCVideoLayerImpl::appendQuads(CCQuadCuller& quadList, const CCSharedQuadSta
     if (!m_frame)
         return;
 
+    // FIXME: When we pass quads out of process, we need to double-buffer, or
+    // otherwise synchonize use of all textures in the quad.
+
     IntRect quadRect(IntPoint(), bounds());
-    OwnPtr<CCVideoDrawQuad> videoQuad = CCVideoDrawQuad::create(sharedQuadState, quadRect, m_textures, m_frame, m_format);
+    WebKit::WebTransformationMatrix matrix;
 
     if (m_format == Extensions3DChromium::GL_TEXTURE_EXTERNAL_OES)
-        videoQuad->setMatrix(m_streamTextureMatrix);
+        matrix = m_streamTextureMatrix;
+
+    OwnPtr<CCVideoDrawQuad> videoQuad = CCVideoDrawQuad::create(sharedQuadState, quadRect, m_framePlanes, m_frame->textureId(), m_format, matrix);
 
     quadList.append(videoQuad.release());
 }
@@ -199,8 +199,6 @@ void CCVideoLayerImpl::didDraw()
     if (!m_frame)
         return;
 
-    for (unsigned plane = 0; plane < m_frame->planes(); ++plane)
-        m_textures[plane].m_texture->unreserve();
     m_provider->putCurrentFrame(m_frame);
     m_frame = 0;
 
@@ -243,35 +241,88 @@ IntSize CCVideoLayerImpl::computeVisibleSize(const WebKit::WebVideoFrame& frame,
     return IntSize(visibleWidth, visibleHeight);
 }
 
-bool CCVideoLayerImpl::reserveTextures(const WebKit::WebVideoFrame& frame, GC3Denum format, CCRenderer* layerRenderer)
+bool CCVideoLayerImpl::FramePlane::allocateData(CCRenderer* layerRenderer)
+{
+    if (textureId)
+        return true;
+
+    textureId = layerRenderer->contentsTextureAllocator()->createTexture(size, format);
+    return textureId;
+}
+
+void CCVideoLayerImpl::FramePlane::freeData(CCRenderer* layerRenderer)
+{
+    if (!textureId)
+        return;
+
+    layerRenderer->contentsTextureAllocator()->deleteTexture(textureId, size, format);
+    textureId = 0;
+}
+
+bool CCVideoLayerImpl::allocatePlaneData(CCRenderer* layerRenderer)
 {
-    if (frame.planes() > MaxPlanes)
-        return false;
     int maxTextureSize = layerRenderer->capabilities().maxTextureSize;
-    for (unsigned plane = 0; plane < frame.planes(); ++plane) {
-        IntSize requiredTextureSize(frame.stride(plane), videoFrameDimension(frame.height(), plane, frame.format()));
-        // If the renderer cannot handle this large of a texture, return false.
-        // FIXME: Remove this test when tiled layers are implemented.
+    for (unsigned planeIndex = 0; planeIndex < m_frame->planes(); ++planeIndex) {
+        CCVideoLayerImpl::FramePlane& plane = m_framePlanes[planeIndex];
+
+        IntSize requiredTextureSize(m_frame->stride(planeIndex), videoFrameDimension(m_frame->height(), planeIndex, m_frame->format()));
+        // FIXME: Remove the test against maxTextureSize when tiled layers are implemented.
         if (requiredTextureSize.isZero() || requiredTextureSize.width() > maxTextureSize || requiredTextureSize.height() > maxTextureSize)
             return false;
-        if (!m_textures[plane].m_texture) {
-            m_textures[plane].m_texture = ManagedTexture::create(layerRenderer->implTextureManager());
-            if (!m_textures[plane].m_texture)
+
+        if (plane.size != requiredTextureSize || plane.format != m_format) {
+            plane.freeData(layerRenderer);
+            plane.size = requiredTextureSize;
+            plane.format = m_format;
+        }
+
+        if (!plane.textureId) {
+            if (!plane.allocateData(layerRenderer))
                 return false;
-            m_textures[plane].m_visibleSize = IntSize();
-        } else {
-            // The implTextureManager may have been destroyed and recreated since the last frame, so pass the new one.
-            // This is a no-op if the TextureManager is still around.
-            m_textures[plane].m_texture->setTextureManager(layerRenderer->implTextureManager());
+            plane.visibleSize = computeVisibleSize(*m_frame, planeIndex);
         }
-        if (m_textures[plane].m_texture->size() != requiredTextureSize)
-            m_textures[plane].m_visibleSize = computeVisibleSize(frame, plane);
-        if (!m_textures[plane].m_texture->reserve(requiredTextureSize, format))
-            return false;
     }
     return true;
 }
 
+bool CCVideoLayerImpl::copyPlaneData(CCRenderer* layerRenderer, CCGraphicsContext* context)
+{
+    size_t softwarePlaneCount = m_frame->planes();
+    if (!softwarePlaneCount)
+        return true;
+
+    GraphicsContext3D* context3d = context->context3D();
+    if (!context3d) {
+        // FIXME: Implement this path for software compositing.
+        return false;
+    }
+
+    LayerTextureSubImage uploader(true);
+    for (size_t softwarePlaneIndex = 0; softwarePlaneIndex < softwarePlaneCount; ++softwarePlaneIndex) {
+        CCVideoLayerImpl::FramePlane& plane = m_framePlanes[softwarePlaneIndex];
+        const uint8_t* softwarePlanePixels = static_cast<const uint8_t*>(m_frame->data(softwarePlaneIndex));
+        IntRect planeRect(IntPoint(), plane.size);
+
+        context3d->bindTexture(GraphicsContext3D::TEXTURE_2D, plane.textureId);
+        uploader.setSubImageSize(plane.size);
+        uploader.upload(softwarePlanePixels, planeRect, planeRect, planeRect, plane.format, context);
+    }
+    return true;
+}
+
+void CCVideoLayerImpl::freePlaneData(CCRenderer* layerRenderer)
+{
+    for (unsigned i = 0; i < WebKit::WebVideoFrame::maxPlanes; ++i)
+        m_framePlanes[i].freeData(layerRenderer);
+}
+
+void CCVideoLayerImpl::freeUnusedPlaneData(CCRenderer* layerRenderer)
+{
+    unsigned firstUnusedPlane = m_frame ? m_frame->planes() : 0;
+    for (unsigned i = firstUnusedPlane; i < WebKit::WebVideoFrame::maxPlanes; ++i)
+        m_framePlanes[i].freeData(layerRenderer);
+}
+
 void CCVideoLayerImpl::didReceiveFrame()
 {
     setNeedsRedraw();
@@ -279,14 +330,17 @@ void CCVideoLayerImpl::didReceiveFrame()
 
 void CCVideoLayerImpl::didUpdateMatrix(const float matrix[16])
 {
-    memcpy(m_streamTextureMatrix, matrix, sizeof(m_streamTextureMatrix));
+    m_streamTextureMatrix = WebKit::WebTransformationMatrix(
+        matrix[0], matrix[1], matrix[2], matrix[3],
+        matrix[4], matrix[5], matrix[6], matrix[7],
+        matrix[8], matrix[9], matrix[10], matrix[11],
+        matrix[12], matrix[13], matrix[14], matrix[15]);
     setNeedsRedraw();
 }
 
 void CCVideoLayerImpl::didLoseContext()
 {
-    for (unsigned i = 0; i < MaxPlanes; ++i)
-        m_textures[i].m_texture.clear();
+    freePlaneData(layerTreeHostImpl()->layerRenderer());
 }
 
 void CCVideoLayerImpl::setNeedsRedraw()
index 221f600..bef1d5f 100644 (file)
 #ifndef CCVideoLayerImpl_h
 #define CCVideoLayerImpl_h
 
-#include "ManagedTexture.h"
+#include "GraphicsContext3D.h"
+#include "IntSize.h"
 #include "cc/CCLayerImpl.h"
+#include <public/WebTransformationMatrix.h>
 #include <public/WebVideoFrameProvider.h>
 
 namespace WebKit {
@@ -65,15 +67,17 @@ public:
 
     void setNeedsRedraw();
 
-    static const float yuv2RGB[9];
-    static const float yuvAdjust[3];
-    static const float flipTransform[16];
+    struct FramePlane {
+        unsigned textureId;
+        IntSize size;
+        GC3Denum format;
+        IntSize visibleSize;
 
-    struct Texture {
-        OwnPtr<ManagedTexture> m_texture;
-        IntSize m_visibleSize;
+        FramePlane() : textureId(0) { }
+
+        bool allocateData(CCRenderer*);
+        void freeData(CCRenderer*);
     };
-    enum { MaxPlanes = 3 };
 
 private:
     CCVideoLayerImpl(int, WebKit::WebVideoFrameProvider*);
@@ -81,19 +85,23 @@ private:
     static IntSize computeVisibleSize(const WebKit::WebVideoFrame&, unsigned plane);
     virtual const char* layerTypeAsString() const OVERRIDE { return "VideoLayer"; }
 
-    void willDrawInternal(CCRenderer*);
-    bool reserveTextures(const WebKit::WebVideoFrame&, GC3Denum format, CCRenderer*);
+    void willDrawInternal(CCRenderer*, CCGraphicsContext*);
+    bool allocatePlaneData(CCRenderer*);
+    bool copyPlaneData(CCRenderer*, CCGraphicsContext*);
+    void freePlaneData(CCRenderer*);
+    void freeUnusedPlaneData(CCRenderer*);
 
     // Guards the destruction of m_provider and the frame that it provides
     Mutex m_providerMutex;
     WebKit::WebVideoFrameProvider* m_provider;
 
-    Texture m_textures[MaxPlanes];
-
-    float m_streamTextureMatrix[16];
+    WebKit::WebTransformationMatrix m_streamTextureMatrix;
 
     WebKit::WebVideoFrame* m_frame;
     GC3Denum m_format;
+
+    // Each index in this array corresponds to a plane in WebKit::WebVideoFrame.
+    FramePlane m_framePlanes[WebKit::WebVideoFrame::maxPlanes];
 };
 
 }
index 24c78ab..37e22fa 100644 (file)
@@ -1,3 +1,15 @@
+2012-06-11  Dana Jansens  <danakj@chromium.org>
+
+        [chromium] Separate CCVideoDrawQuad and from the layer tree and video provider by removing ManagedTexture and WebVideoFrame pointers from the quad
+        https://bugs.webkit.org/show_bug.cgi?id=88363
+
+        Reviewed by Adrienne Walker.
+
+        * tests/CCLayerTreeHostImplTest.cpp:
+        * tests/CCTiledLayerTestCommon.h:
+        (WebKitTests::FakeTextureCopier::copyToTexture):
+        * tests/Canvas2DLayerChromiumTest.cpp:
+
 2012-06-11  Joshua Bell  <jsbell@chromium.org>
 
         IndexedDB: Object stores are not successfully deleted
index 5c8f02b..ab9a088 100644 (file)
@@ -1789,6 +1789,7 @@ TEST_F(CCLayerTreeHostImplTest, dontUseOldResourcesAfterLostContext)
     videoLayer->setAnchorPoint(FloatPoint(0, 0));
     videoLayer->setContentBounds(IntSize(10, 10));
     videoLayer->setDrawsContent(true);
+    videoLayer->setLayerTreeHostImpl(m_hostImpl.get());
     rootLayer->addChild(videoLayer.release());
 
     OwnPtr<CCIOSurfaceLayerImpl> ioSurfaceLayer = CCIOSurfaceLayerImpl::create(4);
index 9824d8c..f15201a 100644 (file)
@@ -157,6 +157,7 @@ public:
 class FakeTextureCopier : public WebCore::TextureCopier {
 public:
     virtual void copyTexture(WebCore::CCGraphicsContext*, unsigned, unsigned, const WebCore::IntSize&) { }
+    virtual void copyToTexture(WebCore::CCGraphicsContext*, const void*, unsigned, const WebCore::IntSize&, GC3Denum) { }
 };
 
 class FakeTextureUploader : public WebCore::TextureUploader {