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

commit-queue at webkit.org commit-queue at webkit.org
Wed Dec 22 13:49:44 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 3dc048773945637986376ebaa3e23efdcddebadf
Author: commit-queue at webkit.org <commit-queue at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Sep 27 23:47:54 2010 +0000

    2010-09-27  Victoria Kirst  <vrk at google.com>
    
            Reviewed by James Robinson.
    
            Modifies VideoLayerChromium to do YUV to RGB color conversion in the
            GPU. Also adds support for RGBA video frame formats, though this code
            path is currently never run because the video frames are in YV12
            format.
            https://bugs.webkit.org/show_bug.cgi?id=45069
    
            * platform/graphics/chromium/LayerRendererChromium.cpp:
            (WebCore::LayerRendererChromium::initializeSharedObjects):
            (WebCore::LayerRendererChromium::cleanupSharedObjects):
            * platform/graphics/chromium/LayerRendererChromium.h:
            (WebCore::LayerRendererChromium::videoLayerSharedValues):
            * platform/graphics/chromium/VideoLayerChromium.cpp:
            (WebCore::VideoLayerChromium::SharedValues::SharedValues):
            (WebCore::VideoLayerChromium::SharedValues::~SharedValues):
            (WebCore::VideoLayerChromium::VideoLayerChromium):
            (WebCore::VideoLayerChromium::~VideoLayerChromium):
            (WebCore::VideoLayerChromium::updateContents):
            (WebCore::VideoLayerChromium::updateYUVContents):
            (WebCore::VideoLayerChromium::allocateYUVTextures):
            (WebCore::VideoLayerChromium::updateYUVTextures):
            (WebCore::VideoLayerChromium::updateRGBAContents):
            (WebCore::VideoLayerChromium::allocateTexture):
            (WebCore::VideoLayerChromium::updateTexture):
            (WebCore::VideoLayerChromium::updateContentsCompleted):
            (WebCore::VideoLayerChromium::draw):
            (WebCore::VideoLayerChromium::drawYUV):
            (WebCore::VideoLayerChromium::drawRGBA):
            * platform/graphics/chromium/VideoLayerChromium.h:
            (WebCore::VideoLayerChromium::drawsContent):
            (WebCore::VideoLayerChromium::SharedValues::yuvShaderProgram):
            (WebCore::VideoLayerChromium::SharedValues::rgbaShaderProgram):
            (WebCore::VideoLayerChromium::SharedValues::yuvShaderMatrixLocation):
            (WebCore::VideoLayerChromium::SharedValues::rgbaShaderMatrixLocation):
            (WebCore::VideoLayerChromium::SharedValues::yuvWidthScaleFactorLocation):
            (WebCore::VideoLayerChromium::SharedValues::rgbaWidthScaleFactorLocation):
            (WebCore::VideoLayerChromium::SharedValues::yTextureLocation):
            (WebCore::VideoLayerChromium::SharedValues::uTextureLocation):
            (WebCore::VideoLayerChromium::SharedValues::vTextureLocation):
            (WebCore::VideoLayerChromium::SharedValues::yuvAlphaLocation):
            (WebCore::VideoLayerChromium::SharedValues::rgbaTextureLocation):
            (WebCore::VideoLayerChromium::SharedValues::ccMatrixLocation):
            (WebCore::VideoLayerChromium::SharedValues::initialized):
    2010-09-27  Victoria Kirst  <vrk at google.com>
    
            Reviewed by James Robinson.
    
            Fixing constants in VideoFrameChromiumImpl so that it overloads the
            VideoFrameChromium const declarations. Also adding logic such that a
            VideoFrameChromium understands what size its texture should be based
            on frame format.
            https://bugs.webkit.org/show_bug.cgi?id=45069
    
            * src/VideoFrameChromiumImpl.cpp:
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@68447 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index e41a6f4..b9d811f 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,50 @@
+2010-09-27  Victoria Kirst  <vrk at google.com>
+
+        Reviewed by James Robinson.
+
+        Modifies VideoLayerChromium to do YUV to RGB color conversion in the
+        GPU. Also adds support for RGBA video frame formats, though this code
+        path is currently never run because the video frames are in YV12
+        format.
+        https://bugs.webkit.org/show_bug.cgi?id=45069
+
+        * platform/graphics/chromium/LayerRendererChromium.cpp:
+        (WebCore::LayerRendererChromium::initializeSharedObjects):
+        (WebCore::LayerRendererChromium::cleanupSharedObjects):
+        * platform/graphics/chromium/LayerRendererChromium.h:
+        (WebCore::LayerRendererChromium::videoLayerSharedValues):
+        * platform/graphics/chromium/VideoLayerChromium.cpp:
+        (WebCore::VideoLayerChromium::SharedValues::SharedValues):
+        (WebCore::VideoLayerChromium::SharedValues::~SharedValues):
+        (WebCore::VideoLayerChromium::VideoLayerChromium):
+        (WebCore::VideoLayerChromium::~VideoLayerChromium):
+        (WebCore::VideoLayerChromium::updateContents):
+        (WebCore::VideoLayerChromium::updateYUVContents):
+        (WebCore::VideoLayerChromium::allocateYUVTextures):
+        (WebCore::VideoLayerChromium::updateYUVTextures):
+        (WebCore::VideoLayerChromium::updateRGBAContents):
+        (WebCore::VideoLayerChromium::allocateTexture):
+        (WebCore::VideoLayerChromium::updateTexture):
+        (WebCore::VideoLayerChromium::updateContentsCompleted):
+        (WebCore::VideoLayerChromium::draw):
+        (WebCore::VideoLayerChromium::drawYUV):
+        (WebCore::VideoLayerChromium::drawRGBA):
+        * platform/graphics/chromium/VideoLayerChromium.h:
+        (WebCore::VideoLayerChromium::drawsContent):
+        (WebCore::VideoLayerChromium::SharedValues::yuvShaderProgram):
+        (WebCore::VideoLayerChromium::SharedValues::rgbaShaderProgram):
+        (WebCore::VideoLayerChromium::SharedValues::yuvShaderMatrixLocation):
+        (WebCore::VideoLayerChromium::SharedValues::rgbaShaderMatrixLocation):
+        (WebCore::VideoLayerChromium::SharedValues::yuvWidthScaleFactorLocation):
+        (WebCore::VideoLayerChromium::SharedValues::rgbaWidthScaleFactorLocation):
+        (WebCore::VideoLayerChromium::SharedValues::yTextureLocation):
+        (WebCore::VideoLayerChromium::SharedValues::uTextureLocation):
+        (WebCore::VideoLayerChromium::SharedValues::vTextureLocation):
+        (WebCore::VideoLayerChromium::SharedValues::yuvAlphaLocation):
+        (WebCore::VideoLayerChromium::SharedValues::rgbaTextureLocation):
+        (WebCore::VideoLayerChromium::SharedValues::ccMatrixLocation):
+        (WebCore::VideoLayerChromium::SharedValues::initialized):
+
 2010-09-27  Peter Kasting  <pkasting at google.com>
 
         Reviewed by James Robinson.
diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
index ce9533d..03c8d7b 100644
--- a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
+++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
@@ -724,7 +724,8 @@ bool LayerRendererChromium::initializeSharedObjects()
     m_layerSharedValues = adoptPtr(new LayerChromium::SharedValues(m_context.get()));
     m_contentLayerSharedValues = adoptPtr(new ContentLayerChromium::SharedValues(m_context.get()));
     m_canvasLayerSharedValues = adoptPtr(new CanvasLayerChromium::SharedValues(m_context.get()));
-    if (!m_layerSharedValues->initialized() || !m_contentLayerSharedValues->initialized() || !m_canvasLayerSharedValues->initialized()) {
+    m_videoLayerSharedValues = adoptPtr(new VideoLayerChromium::SharedValues(m_context.get()));
+    if (!m_layerSharedValues->initialized() || !m_contentLayerSharedValues->initialized() || !m_canvasLayerSharedValues->initialized() || !m_videoLayerSharedValues->initialized()) {
         cleanupSharedObjects();
         return false;
     }
@@ -739,6 +740,7 @@ void LayerRendererChromium::cleanupSharedObjects()
     m_layerSharedValues.clear();
     m_contentLayerSharedValues.clear();
     m_canvasLayerSharedValues.clear();
+    m_videoLayerSharedValues.clear();
 
     if (m_scrollShaderProgram) {
         GLC(m_context, m_context->deleteProgram(m_scrollShaderProgram));
diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.h b/WebCore/platform/graphics/chromium/LayerRendererChromium.h
index a051c2e..9179d5e 100644
--- a/WebCore/platform/graphics/chromium/LayerRendererChromium.h
+++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.h
@@ -39,6 +39,7 @@
 #include "IntRect.h"
 #include "LayerChromium.h"
 #include "SkBitmap.h"
+#include "VideoLayerChromium.h"
 #include <wtf/HashMap.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/PassOwnPtr.h>
@@ -105,6 +106,7 @@ public:
     const LayerChromium::SharedValues* layerSharedValues() const { return m_layerSharedValues.get(); }
     const ContentLayerChromium::SharedValues* contentLayerSharedValues() const { return m_contentLayerSharedValues.get(); }
     const CanvasLayerChromium::SharedValues* canvasLayerSharedValues() const { return m_canvasLayerSharedValues.get(); }
+    const VideoLayerChromium::SharedValues* videoLayerSharedValues() const { return m_videoLayerSharedValues.get(); }
 
     void resizeOnscreenContent(const IntSize&);
 
@@ -173,6 +175,7 @@ private:
     OwnPtr<LayerChromium::SharedValues> m_layerSharedValues;
     OwnPtr<ContentLayerChromium::SharedValues> m_contentLayerSharedValues;
     OwnPtr<CanvasLayerChromium::SharedValues> m_canvasLayerSharedValues;
+    OwnPtr<VideoLayerChromium::SharedValues> m_videoLayerSharedValues;
 
     OwnPtr<GraphicsContext3D> m_context;
 };
diff --git a/WebCore/platform/graphics/chromium/VideoFrameChromium.h b/WebCore/platform/graphics/chromium/VideoFrameChromium.h
index bbd677e..34e922b 100644
--- a/WebCore/platform/graphics/chromium/VideoFrameChromium.h
+++ b/WebCore/platform/graphics/chromium/VideoFrameChromium.h
@@ -31,18 +31,20 @@
 #ifndef VideoFrameChromium_h
 #define VideoFrameChromium_h
 
+#include "IntSize.h"
+
 namespace WebCore {
 
 // A class that represents a video frame in chromium.
 class VideoFrameChromium {
 public:
-    static const unsigned cMaxPlanes;
-    static const unsigned cNumRGBPlanes;
-    static const unsigned cRGBPlane;
-    static const unsigned cNumYUVPlanes;
-    static const unsigned cYPlane;
-    static const unsigned cUPlane;
-    static const unsigned cVPlane;
+    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;
 
     // These enums must be kept in sync with WebKit::WebVideoFrame.
     enum Format {
@@ -74,6 +76,7 @@ public:
     virtual unsigned planes() const = 0;
     virtual int stride(unsigned plane) const = 0;
     virtual const void* data(unsigned plane) const = 0;
+    virtual const IntSize requiredTextureSize(unsigned plane) const = 0;
 };
 
 } // namespace WebCore
diff --git a/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp b/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
index 0fb1bb4..71761b7 100644
--- a/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
@@ -36,15 +36,134 @@
 #include "GraphicsContext3D.h"
 #include "LayerRendererChromium.h"
 #include "RenderLayerBacking.h"
-#include "skia/ext/platform_canvas.h"
-
-#if PLATFORM(SKIA)
-#include "NativeImageSkia.h"
-#include "PlatformContextSkia.h"
-#endif
+#include "VideoFrameChromium.h"
+#include "VideoFrameProvider.h"
 
 namespace WebCore {
 
+// These values are magic numbers that are used in the transformation
+// from YUV to RGB color values.
+const float VideoLayerChromium::yuv2RGB[9] = {
+    1.f, 1.f, 1.f,
+    0.f, -.344f, 1.772f,
+    1.403f, -.714f, 0.f,
+};
+
+VideoLayerChromium::SharedValues::SharedValues(GraphicsContext3D* context)
+    : m_context(context)
+    , m_yuvShaderProgram(0)
+    , m_rgbaShaderProgram(0)
+    , m_yuvShaderMatrixLocation(0)
+    , m_yuvWidthScaleFactorLocation(0)
+    , m_rgbaShaderMatrixLocation(0)
+    , m_rgbaWidthScaleFactorLocation(0)
+    , m_ccMatrixLocation(0)
+    , m_yTextureLocation(0)
+    , m_uTextureLocation(0)
+    , m_vTextureLocation(0)
+    , m_rgbaTextureLocation(0)
+    , m_yuvAlphaLocation(0)
+    , m_rgbaAlphaLocation(0)
+    , m_initialized(false)
+{
+    // Frame textures are allocated based on stride width, not visible frame
+    // width, such that there is a guarantee that the frame rows line up
+    // properly and are not shifted by (stride - width) pixels. To hide the
+    // "padding" pixels between the edge of the visible frame width and the end
+    // of the stride, we give the shader a widthScaleFactor (<=1.0) of how much
+    // of the width of the texture should be shown when drawing the texture onto
+    // the vertices.
+    char vertexShaderString[] =
+        "precision mediump float;     \n"
+        "attribute vec4 a_position;   \n"
+        "attribute vec2 a_texCoord;   \n"
+        "uniform mat4 matrix;         \n"
+        "varying vec2 v_texCoord;     \n"
+        "uniform float widthScaleFactor;  \n"
+        "void main()                  \n"
+        "{                            \n"
+        "  gl_Position = matrix * a_position; \n"
+        "  v_texCoord = vec2(widthScaleFactor * a_texCoord.x, a_texCoord.y); \n"
+        "}                            \n";
+
+    char yuvFragmentShaderString[] =
+        "precision mediump float;                             \n"
+        "precision mediump int;                               \n"
+        "varying vec2 v_texCoord;                             \n"
+        "uniform sampler2D y_texture;                         \n"
+        "uniform sampler2D u_texture;                         \n"
+        "uniform sampler2D v_texture;                         \n"
+        "uniform float alpha;                                 \n"
+        "uniform mat3 cc_matrix;                              \n"
+        "void main()                                          \n"
+        "{                                                    \n"
+        "  float y = texture2D(y_texture, v_texCoord).x;      \n"
+        "  float u = texture2D(u_texture, v_texCoord).r - .5; \n"
+        "  float v = texture2D(v_texture, v_texCoord).r - .5; \n"
+        "  vec3 rgb = cc_matrix * vec3(y, u, v);              \n"
+        "  gl_FragColor = vec4(rgb.x, rgb.y, rgb.z, 1.0) * alpha; \n"
+        "}                                                    \n";
+
+    char rgbaFragmentShaderString[] =
+        "precision mediump float;                             \n"
+        "varying vec2 v_texCoord;                             \n"
+        "uniform sampler2D rgba_texture;                      \n"
+        "uniform float alpha;                                 \n"
+        "void main()                                          \n"
+        "{                                                    \n"
+        "  vec4 texColor = texture2D(rgba_texture, vec2(v_texCoord.x, 1.0 - v_texCoord.y)); \n"
+        "  gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n"
+        "}                                                    \n";
+
+    m_rgbaShaderProgram = createShaderProgram(m_context, vertexShaderString, rgbaFragmentShaderString);
+    if (!m_rgbaShaderProgram) {
+        LOG_ERROR("VideoLayerChromium: Failed to create rgba shader program");
+        return;
+    }
+
+    m_yuvShaderProgram = createShaderProgram(m_context, vertexShaderString, yuvFragmentShaderString);
+    if (!m_yuvShaderProgram) {
+        LOG_ERROR("VideoLayerChromium: Failed to create yuv shader program");
+        return;
+    }
+
+    m_yuvShaderMatrixLocation = m_context->getUniformLocation(m_yuvShaderProgram, "matrix");
+    m_yuvWidthScaleFactorLocation = m_context->getUniformLocation(m_yuvShaderProgram, "widthScaleFactor");
+    m_yTextureLocation = m_context->getUniformLocation(m_yuvShaderProgram, "y_texture");
+    m_uTextureLocation = m_context->getUniformLocation(m_yuvShaderProgram, "u_texture");
+    m_vTextureLocation = m_context->getUniformLocation(m_yuvShaderProgram, "v_texture");
+    m_ccMatrixLocation = m_context->getUniformLocation(m_yuvShaderProgram, "cc_matrix");
+    m_yuvAlphaLocation = m_context->getUniformLocation(m_yuvShaderProgram, "alpha");
+
+    ASSERT(m_yuvShaderMatrixLocation != -1);
+    ASSERT(m_yuvWidthScaleFactorLocation != -1);
+    ASSERT(m_yTextureLocation != -1);
+    ASSERT(m_uTextureLocation != -1);
+    ASSERT(m_vTextureLocation != -1);
+    ASSERT(m_ccMatrixLocation != -1);
+    ASSERT(m_yuvAlphaLocation != -1);
+
+    m_rgbaShaderMatrixLocation = m_context->getUniformLocation(m_rgbaShaderProgram, "matrix");
+    m_rgbaTextureLocation = m_context->getUniformLocation(m_rgbaShaderProgram, "rgba_texture");
+    m_rgbaWidthScaleFactorLocation = m_context->getUniformLocation(m_rgbaShaderProgram, "widthScaleFactor");
+    m_rgbaAlphaLocation = m_context->getUniformLocation(m_rgbaShaderProgram, "alpha");
+
+    ASSERT(m_rgbaShaderMatrixLocation != -1);
+    ASSERT(m_rgbaTextureLocation != -1);
+    ASSERT(m_rgbaWidthScaleFactorLocation != -1);
+    ASSERT(m_rgbaAlphaLocation != -1);
+
+    m_initialized = true;
+}
+
+VideoLayerChromium::SharedValues::~SharedValues()
+{
+    if (m_yuvShaderProgram)
+        GLC(m_context, m_context->deleteProgram(m_yuvShaderProgram));
+    if (m_rgbaShaderProgram)
+        GLC(m_context, m_context->deleteProgram(m_rgbaShaderProgram));
+}
+
 PassRefPtr<VideoLayerChromium> VideoLayerChromium::create(GraphicsLayerChromium* owner,
                                                           VideoFrameProvider* provider)
 {
@@ -52,14 +171,25 @@ PassRefPtr<VideoLayerChromium> VideoLayerChromium::create(GraphicsLayerChromium*
 }
 
 VideoLayerChromium::VideoLayerChromium(GraphicsLayerChromium* owner, VideoFrameProvider* provider)
-    : ContentLayerChromium(owner)
-#if PLATFORM(SKIA)
-    , m_canvas(0)
-    , m_skiaContext(0)
-#endif
-    , m_graphicsContext(0)
+    : LayerChromium(owner)
+    , m_skipsDraw(true)
+    , m_frameFormat(VideoFrameChromium::Invalid)
     , m_provider(provider)
 {
+    for (int plane = 0; plane < VideoFrameChromium::maxPlanes; plane++) {
+        m_textures[plane] = 0;
+        m_textureSizes[plane] = IntSize();
+        m_frameSizes[plane] = IntSize();
+    }
+}
+
+VideoLayerChromium::~VideoLayerChromium()
+{
+    GraphicsContext3D* context = layerRendererContext();
+    for (int plane = 0; plane < VideoFrameChromium::maxPlanes; plane++) {
+        if (m_textures[plane])
+            GLC(context, context->deleteTexture(m_textures[plane]));
+    }
 }
 
 void VideoLayerChromium::updateContents()
@@ -70,129 +200,174 @@ void VideoLayerChromium::updateContents()
 
     ASSERT(drawsContent());
 
-    IntRect dirtyRect(m_dirtyRect);
-    IntSize requiredTextureSize;
-
-#if PLATFORM(SKIA)
-    requiredTextureSize = m_bounds;
-    IntRect boundsRect(IntPoint(0, 0), m_bounds);
-
-    // If the texture needs to be reallocated, then we must redraw the entire
-    // contents of the layer.
-    if (requiredTextureSize != m_allocatedTextureSize)
-        dirtyRect = boundsRect;
-    else {
-        // Clip the dirtyRect to the size of the layer to avoid drawing outside
-        // the bounds of the backing texture.
-        dirtyRect.intersect(boundsRect);
+    m_skipsDraw = false;
+    VideoFrameChromium* frame = m_provider->getCurrentFrame();
+    if (!frame) {
+        m_skipsDraw = true;
+        m_provider->putCurrentFrame(frame);
+        return;
     }
 
-    if (!m_canvas.get()
-        || dirtyRect.width() != m_canvas->getDevice()->width()
-        || dirtyRect.height() != m_canvas->getDevice()->height()) {
-        m_canvas = new skia::PlatformCanvas(dirtyRect.width(), dirtyRect.height(), true);
-        m_skiaContext = new PlatformContextSkia(m_canvas.get());
-
-        // This is needed to get text to show up correctly.
-        // FIXME: Does this take us down a very slow text rendering path?
-        m_skiaContext->setDrawingToImageBuffer(true);
-        m_graphicsContext = new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(m_skiaContext.get()));
+    m_frameFormat = frame->format();
+    unsigned textureFormat = determineTextureFormat(frame);
+    if (textureFormat == GraphicsContext3D::INVALID_VALUE) {
+        // FIXME: Implement other paths.
+        notImplemented();
+        m_skipsDraw = true;
+        m_provider->putCurrentFrame(frame);
+        return;
     }
 
-    // Bring the canvas into the coordinate system of the paint rect.
-    m_canvas->translate(static_cast<SkScalar>(-dirtyRect.x()), static_cast<SkScalar>(-dirtyRect.y()));
-
-    // FIXME: Remove this test when tiled layers are implemented.
-    m_skipsDraw = false;
-    if (!layerRenderer()->checkTextureSize(requiredTextureSize)) {
+    // Allocate textures for planes if they are not allocated already, or
+    // reallocate textures that are the wrong size for the frame.
+    GraphicsContext3D* context = layerRendererContext();
+    bool texturesAllocated = allocateTexturesIfNeeded(context, frame, textureFormat);
+    if (!texturesAllocated) {
         m_skipsDraw = true;
+        m_provider->putCurrentFrame(frame);
         return;
     }
 
-    unsigned textureId = m_contentsTexture;
-    if (!textureId)
-        textureId = layerRenderer()->createLayerTexture();
-
-    // If the texture id or size changed since last time, then we need to tell GL
-    // to re-allocate a texture.
-    if (m_contentsTexture != textureId || requiredTextureSize != m_allocatedTextureSize)
-        createTextureRect(requiredTextureSize, dirtyRect, textureId);
-    else
-        updateTextureRect(dirtyRect, textureId);
-#else
-    // FIXME: Implement non-skia path
-    notImplemented();
-#endif
+    // Update texture planes.
+    for (int plane = 0; plane < frame->planes(); plane++) {
+        ASSERT(frame->requiredTextureSize(plane) == m_textureSizes[plane]);
+        updateTexture(context, m_textures[plane], frame->requiredTextureSize(plane), textureFormat, frame->data(plane));
+    }
+
+    m_dirtyRect.setSize(FloatSize());
+    m_contentsDirty = false;
+    m_provider->putCurrentFrame(frame);
 }
 
-void VideoLayerChromium::createTextureRect(const IntSize& requiredTextureSize, const IntRect& updateRect, unsigned textureId)
+unsigned VideoLayerChromium::determineTextureFormat(VideoFrameChromium* frame)
 {
-    // Paint into graphics context and get bitmap.
-    m_owner->paintGraphicsLayerContents(*m_graphicsContext, updateRect);
-    void* pixels = 0;
-    IntSize bitmapSize = IntSize();
-#if PLATFORM(SKIA)
-    const SkBitmap& bitmap = m_canvas->getDevice()->accessBitmap(false);
-    const SkBitmap* skiaBitmap = &bitmap;
-    ASSERT(skiaBitmap);
-
-    SkAutoLockPixels lock(*skiaBitmap);
-    SkBitmap::Config skiaConfig = skiaBitmap->config();
-    // FIXME: Do we need to support more image configurations?
-    if (skiaConfig == SkBitmap::kARGB_8888_Config) {
-        pixels = skiaBitmap->getPixels();
-        bitmapSize = IntSize(skiaBitmap->width(), skiaBitmap->height());
+    switch (frame->format()) {
+    case VideoFrameChromium::YV12:
+        return GraphicsContext3D::LUMINANCE;
+    case VideoFrameChromium::RGBA:
+        return GraphicsContext3D::RGBA;
     }
-#else
-    // FIXME: Implement non-skia path
-    notImplemented();
-#endif
-    if (!pixels)
-        return;
+    return GraphicsContext3D::INVALID_VALUE;
+}
 
-    GraphicsContext3D* context = layerRendererContext();
-    context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId);
-    ASSERT(bitmapSize == requiredTextureSize);
-    context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, requiredTextureSize.width(), requiredTextureSize.height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels);
+bool VideoLayerChromium::allocateTexturesIfNeeded(GraphicsContext3D* context, VideoFrameChromium* frame, unsigned textureFormat)
+{
+    ASSERT(context);
+    ASSERT(frame);
+
+    for (int plane = 0; plane < frame->planes(); plane++) {
+        IntSize planeTextureSize = frame->requiredTextureSize(plane);
 
-    m_contentsTexture = textureId;
-    m_allocatedTextureSize = requiredTextureSize;
+        // If the renderer cannot handle this large of a texture, return false.
+        // FIXME: Remove this test when tiled layers are implemented.
+        if (!layerRenderer()->checkTextureSize(planeTextureSize))
+            return false;
 
-    updateCompleted();
+        if (!m_textures[plane])
+            m_textures[plane] = layerRenderer()->createLayerTexture();
+
+        if (!planeTextureSize.isZero() && planeTextureSize != m_textureSizes[plane]) {
+            allocateTexture(context, m_textures[plane], planeTextureSize, textureFormat);
+            m_textureSizes[plane] = planeTextureSize;
+            m_frameSizes[plane] = IntSize(frame->width(), frame->height());
+        }
+    }
+    return true;
+}
+
+void VideoLayerChromium::allocateTexture(GraphicsContext3D* context, unsigned textureId, const IntSize& dimensions, unsigned textureFormat)
+{
+    GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId));
+    GLC(context, context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, textureFormat, dimensions.width(), dimensions.height(), 0, textureFormat, GraphicsContext3D::UNSIGNED_BYTE, 0));
 }
 
-void VideoLayerChromium::updateTextureRect(const IntRect& updateRect, unsigned textureId)
+void VideoLayerChromium::updateTexture(GraphicsContext3D* context, unsigned textureId, const IntSize& dimensions, unsigned format, const void* data)
 {
-#if PLATFORM(SKIA)
-    const SkBitmap& bitmap = m_canvas->getDevice()->accessBitmap(true);
-    SkBitmap* skiaBitmap = const_cast<SkBitmap*>(&bitmap);
-    ASSERT(skiaBitmap);
-
-    SkAutoLockPixels lock(*skiaBitmap);
-    SkBitmap::Config skiaConfig = skiaBitmap->config();
-
-    if (skiaConfig == SkBitmap::kARGB_8888_Config) {
-        GraphicsContext3D* context = layerRendererContext();
-        context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId);
-        ASSERT(context->supportsMapSubCHROMIUM());
-        void* mem = context->mapTexSubImage2DCHROMIUM(GraphicsContext3D::TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, GraphicsContext3D::WRITE_ONLY);
-        skiaBitmap->setPixels(mem);
-        m_owner->paintGraphicsLayerContents(*m_graphicsContext, updateRect);
-        context->unmapTexSubImage2DCHROMIUM(mem);
+    ASSERT(context);
+    GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId));
+    void* mem = context->mapTexSubImage2DCHROMIUM(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, dimensions.width(), dimensions.height(), format, GraphicsContext3D::UNSIGNED_BYTE, GraphicsContext3D::WRITE_ONLY);
+    if (mem) {
+        memcpy(mem, data, dimensions.width() * dimensions.height());
+        GLC(context, context->unmapTexSubImage2DCHROMIUM(mem));
+    } else {
+        // FIXME: We should have some sort of code to handle the case when
+        // mapTexSubImage2D fails.
+        m_skipsDraw = true;
     }
+}
+
+void VideoLayerChromium::draw()
+{
+    if (m_skipsDraw)
+        return;
+
+    ASSERT(layerRenderer());
+    const VideoLayerChromium::SharedValues* sv = layerRenderer()->videoLayerSharedValues();
+    ASSERT(sv && sv->initialized());
 
-    updateCompleted();
-#else
-    // FIXME: Implement non-skia path
-    notImplemented();
-#endif
+    switch (m_frameFormat) {
+    case VideoFrameChromium::YV12:
+        drawYUV(sv);
+        break;
+    case VideoFrameChromium::RGBA:
+        drawRGBA(sv);
+        break;
+    default:
+        // FIXME: Implement other paths.
+        notImplemented();
+        break;
+    }
 }
 
-void VideoLayerChromium::updateCompleted()
+void VideoLayerChromium::drawYUV(const SharedValues* sv)
 {
-    m_dirtyRect.setSize(FloatSize());
-    m_contentsDirty = false;
+    GraphicsContext3D* context = layerRendererContext();
+    GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE1));
+    GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::yPlane]));
+    GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE2));
+    GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::uPlane]));
+    GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE3));
+    GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::vPlane]));
+
+    layerRenderer()->useShader(sv->yuvShaderProgram());
+    unsigned frameWidth = m_frameSizes[VideoFrameChromium::yPlane].width();
+    unsigned textureWidth = m_textureSizes[VideoFrameChromium::yPlane].width();
+    float widthScaleFactor = static_cast<float>(frameWidth) / textureWidth;
+    GLC(context, context->uniform1f(sv->yuvWidthScaleFactorLocation(), widthScaleFactor));
+
+    GLC(context, context->uniform1i(sv->yTextureLocation(), 1));
+    GLC(context, context->uniform1i(sv->uTextureLocation(), 2));
+    GLC(context, context->uniform1i(sv->vTextureLocation(), 3));
+
+    GLC(context, context->uniformMatrix3fv(sv->ccMatrixLocation(), 0, const_cast<float*>(yuv2RGB), 1));
+
+    drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(),
+                     bounds().width(), bounds().height(), drawOpacity(),
+                     sv->yuvShaderMatrixLocation(), sv->yuvAlphaLocation());
+
+    // Reset active texture back to texture 0.
+    GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
 }
 
+void VideoLayerChromium::drawRGBA(const SharedValues* sv)
+{
+    GraphicsContext3D* context = layerRendererContext();
+    GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
+    GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::rgbPlane]));
+
+    layerRenderer()->useShader(sv->rgbaShaderProgram());
+    unsigned frameWidth = m_frameSizes[VideoFrameChromium::rgbPlane].width();
+    unsigned textureWidth = m_textureSizes[VideoFrameChromium::rgbPlane].width();
+    float widthScaleFactor = static_cast<float>(frameWidth) / textureWidth;
+    GLC(context, context->uniform1f(sv->rgbaWidthScaleFactorLocation(), widthScaleFactor));
+
+    GLC(context, context->uniform1i(sv->rgbaTextureLocation(), 0));
+
+    drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(),
+                     bounds().width(), bounds().height(), drawOpacity(),
+                     sv->rgbaShaderMatrixLocation(), sv->rgbaAlphaLocation());
 }
+
+} // namespace WebCore
+
 #endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/chromium/VideoLayerChromium.h b/WebCore/platform/graphics/chromium/VideoLayerChromium.h
index 3507cb2..0c7bf73 100644
--- a/WebCore/platform/graphics/chromium/VideoLayerChromium.h
+++ b/WebCore/platform/graphics/chromium/VideoLayerChromium.h
@@ -34,31 +34,76 @@
 
 #if USE(ACCELERATED_COMPOSITING)
 
-#include "ContentLayerChromium.h"
+#include "LayerChromium.h"
 #include "VideoFrameProvider.h"
 
 namespace WebCore {
 
 // A Layer that contains a Video element.
-class VideoLayerChromium : public ContentLayerChromium {
+class VideoLayerChromium : public LayerChromium {
 public:
     static PassRefPtr<VideoLayerChromium> create(GraphicsLayerChromium* owner = 0,
                                                  VideoFrameProvider* = 0);
-    virtual bool drawsContent() { return true; }
+    virtual ~VideoLayerChromium();
     virtual void updateContents();
+    virtual bool drawsContent() { return true; }
+    virtual void draw();
+
+    class SharedValues {
+    public:
+        explicit SharedValues(GraphicsContext3D*);
+        ~SharedValues();
+        unsigned yuvShaderProgram() const { return m_yuvShaderProgram; }
+        unsigned rgbaShaderProgram() const { return m_rgbaShaderProgram; }
+        int yuvShaderMatrixLocation() const { return m_yuvShaderMatrixLocation; }
+        int rgbaShaderMatrixLocation() const { return m_rgbaShaderMatrixLocation; }
+        int yuvWidthScaleFactorLocation() const { return m_yuvWidthScaleFactorLocation; }
+        int rgbaWidthScaleFactorLocation() const { return m_rgbaWidthScaleFactorLocation; }
+        int yTextureLocation() const { return m_yTextureLocation; }
+        int uTextureLocation() const { return m_uTextureLocation; }
+        int vTextureLocation() const { return m_vTextureLocation; }
+        int yuvAlphaLocation() const { return m_yuvAlphaLocation; }
+        int rgbaAlphaLocation() const { return m_rgbaAlphaLocation; }
+        int rgbaTextureLocation() const { return m_rgbaTextureLocation; }
+        int ccMatrixLocation() const { return m_ccMatrixLocation; }
+        bool initialized() const { return m_initialized; };
+    private:
+        GraphicsContext3D* m_context;
+        unsigned m_yuvShaderProgram;
+        unsigned m_rgbaShaderProgram;
+        int m_yuvShaderMatrixLocation;
+        int m_rgbaShaderMatrixLocation;
+        int m_yuvWidthScaleFactorLocation;
+        int m_rgbaWidthScaleFactorLocation;
+        int m_yTextureLocation;
+        int m_uTextureLocation;
+        int m_vTextureLocation;
+        int m_rgbaTextureLocation;
+        int m_ccMatrixLocation;
+        int m_yuvAlphaLocation;
+        int m_rgbaAlphaLocation;
+        bool m_initialized;
+    };
 
 private:
     VideoLayerChromium(GraphicsLayerChromium* owner, VideoFrameProvider*);
-    void createTextureRect(const IntSize& requiredTextureSize, const IntRect& updateRect, unsigned textureId);
-    void updateTextureRect(const IntRect& updateRect, unsigned textureId);
-    void updateCompleted();
+    static unsigned determineTextureFormat(VideoFrameChromium*);
+    bool allocateTexturesIfNeeded(GraphicsContext3D*, VideoFrameChromium*, unsigned textureFormat);
+    void updateYUVContents(GraphicsContext3D*, const VideoFrameChromium*);
+    void updateRGBAContents(GraphicsContext3D*, const VideoFrameChromium*);
+    void allocateTexture(GraphicsContext3D*, unsigned textureId, const IntSize& dimensions, unsigned textureFormat);
+    void updateTexture(GraphicsContext3D*, unsigned textureId, const IntSize& dimensions, unsigned textureFormat, const void* data);
+    void drawYUV(const SharedValues*);
+    void drawRGBA(const SharedValues*);
 
-#if PLATFORM(SKIA)
-    OwnPtr<skia::PlatformCanvas> m_canvas;
-    OwnPtr<PlatformContextSkia> m_skiaContext;
-#endif
-    OwnPtr<GraphicsContext> m_graphicsContext;
+    static const float yuv2RGB[9];
+
+    VideoFrameChromium::Format m_frameFormat;
     OwnPtr<VideoFrameProvider> m_provider;
+    bool m_skipsDraw;
+    unsigned m_textures[3];
+    IntSize m_textureSizes[3];
+    IntSize m_frameSizes[3];
 };
 
 }
diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog
index 5636de1..91c6732 100644
--- a/WebKit/chromium/ChangeLog
+++ b/WebKit/chromium/ChangeLog
@@ -1,3 +1,15 @@
+2010-09-27  Victoria Kirst  <vrk at google.com>
+
+        Reviewed by James Robinson.
+
+        Fixing constants in VideoFrameChromiumImpl so that it overloads the
+        VideoFrameChromium const declarations. Also adding logic such that a
+        VideoFrameChromium understands what size its texture should be based
+        on frame format.
+        https://bugs.webkit.org/show_bug.cgi?id=45069
+
+        * src/VideoFrameChromiumImpl.cpp:
+
 2010-09-27  Vangelis Kokkevis  <vangelis at chromium.org>
 
         Reviewed by James Robinson.
diff --git a/WebKit/chromium/src/VideoFrameChromiumImpl.cpp b/WebKit/chromium/src/VideoFrameChromiumImpl.cpp
index 2b98320..60e75b8 100644
--- a/WebKit/chromium/src/VideoFrameChromiumImpl.cpp
+++ b/WebKit/chromium/src/VideoFrameChromiumImpl.cpp
@@ -36,15 +36,15 @@
 
 using namespace WebCore;
 
-namespace WebKit {
+const unsigned VideoFrameChromium::maxPlanes = 3;
+const unsigned VideoFrameChromium::numRGBPlanes = 1;
+const unsigned VideoFrameChromium::rgbPlane = 0;
+const unsigned VideoFrameChromium::numYUVPlanes = 3;
+const unsigned VideoFrameChromium::yPlane = 0;
+const unsigned VideoFrameChromium::uPlane = 1;
+const unsigned VideoFrameChromium::vPlane = 2;
 
-const unsigned cMaxPlanes = 3;
-const unsigned cNumRGBPlanes = 1;
-const unsigned cRGBPlane = 0;
-const unsigned cNumYUVPlanes = 3;
-const unsigned cYPlane = 0;
-const unsigned cUPlane = 1;
-const unsigned cVPlane = 2;
+namespace WebKit {
 
 WebVideoFrame* VideoFrameChromiumImpl::toWebVideoFrame(VideoFrameChromium* videoFrame)
 {
@@ -108,4 +108,22 @@ const void* VideoFrameChromiumImpl::data(unsigned plane) const
     return 0;
 }
 
+const IntSize VideoFrameChromiumImpl::requiredTextureSize(unsigned plane) const
+{
+    switch (format()) {
+    case RGBA:
+        return IntSize(stride(plane), height());
+    case YV12:
+        switch (plane) {
+        case yPlane:
+            return IntSize(stride(plane), height());
+        case uPlane:
+            return IntSize(stride(plane), height() / 2);
+        case vPlane:
+            return IntSize(stride(plane), height() / 2);
+        }
+    }
+    return IntSize();
+}
+
 } // namespace WebKit
diff --git a/WebKit/chromium/src/VideoFrameChromiumImpl.h b/WebKit/chromium/src/VideoFrameChromiumImpl.h
index 3ad424c..042cd7e 100644
--- a/WebKit/chromium/src/VideoFrameChromiumImpl.h
+++ b/WebKit/chromium/src/VideoFrameChromiumImpl.h
@@ -56,6 +56,7 @@ public:
     virtual unsigned planes() const;
     virtual int stride(unsigned plane) const;
     virtual const void* data(unsigned plane) const;
+    virtual const IntSize requiredTextureSize(unsigned plane) const;
 
 private:
     WebVideoFrame* m_webVideoFrame;

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list