diff options
Diffstat (limited to 'WebCore/platform/graphics/chromium/VideoLayerChromium.cpp')
-rw-r--r-- | WebCore/platform/graphics/chromium/VideoLayerChromium.cpp | 426 |
1 files changed, 0 insertions, 426 deletions
diff --git a/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp b/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp deleted file mode 100644 index 24fd732..0000000 --- a/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp +++ /dev/null @@ -1,426 +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" - -#if USE(ACCELERATED_COMPOSITING) -#include "VideoLayerChromium.h" - -#include "Extensions3DChromium.h" -#include "GraphicsContext3D.h" -#include "LayerRendererChromium.h" -#include "RenderLayerBacking.h" -#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) -{ - return adoptRef(new VideoLayerChromium(owner, provider)); -} - -VideoLayerChromium::VideoLayerChromium(GraphicsLayerChromium* owner, VideoFrameProvider* provider) - : LayerChromium(owner) - , m_skipsDraw(true) - , m_frameFormat(VideoFrameChromium::Invalid) - , m_provider(provider) - , m_currentFrame(0) -{ - resetFrameParameters(); -} - -VideoLayerChromium::~VideoLayerChromium() -{ - cleanupResources(); -} - -void VideoLayerChromium::cleanupResources() -{ - LayerChromium::cleanupResources(); - releaseCurrentFrame(); - if (!layerRenderer()) - return; - - GraphicsContext3D* context = layerRendererContext(); - for (unsigned plane = 0; plane < VideoFrameChromium::maxPlanes; plane++) { - if (m_textures[plane]) - GLC(context, context->deleteTexture(m_textures[plane])); - } -} - -void VideoLayerChromium::updateContentsIfDirty() -{ - if (!m_contentsDirty) - return; - - RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_owner->client()); - if (!backing || backing->paintingGoesToWindow()) - return; - - ASSERT(drawsContent()); - - m_skipsDraw = false; - VideoFrameChromium* frame = m_provider->getCurrentFrame(); - if (!frame) { - m_skipsDraw = true; - m_provider->putCurrentFrame(frame); - return; - } - - 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; - } - - if (frame->surfaceType() == VideoFrameChromium::TypeTexture) { - releaseCurrentFrame(); - saveCurrentFrame(frame); - m_dirtyRect.setSize(FloatSize()); - m_contentsDirty = false; - return; - } - - // 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; - } - - // Update texture planes. - for (unsigned 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); -} - -unsigned VideoLayerChromium::determineTextureFormat(VideoFrameChromium* frame) -{ - switch (frame->format()) { - case VideoFrameChromium::YV12: - return GraphicsContext3D::LUMINANCE; - case VideoFrameChromium::RGBA: - return GraphicsContext3D::RGBA; - default: - break; - } - return GraphicsContext3D::INVALID_VALUE; -} - -bool VideoLayerChromium::allocateTexturesIfNeeded(GraphicsContext3D* context, VideoFrameChromium* frame, unsigned textureFormat) -{ - ASSERT(context); - ASSERT(frame); - - for (unsigned plane = 0; plane < frame->planes(); plane++) { - IntSize planeTextureSize = frame->requiredTextureSize(plane); - - // 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; - - 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->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D, 0, textureFormat, dimensions.width(), dimensions.height(), 0, textureFormat, GraphicsContext3D::UNSIGNED_BYTE)); -} - -void VideoLayerChromium::updateTexture(GraphicsContext3D* context, unsigned textureId, const IntSize& dimensions, unsigned format, const void* data) -{ - ASSERT(context); - GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId)); - 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, data, dimensions.width() * dimensions.height()); - GLC(context, static_cast<Extensions3DChromium*>(context->getExtensions())->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()); - - switch (m_frameFormat) { - case VideoFrameChromium::YV12: - drawYUV(sv); - break; - case VideoFrameChromium::RGBA: - drawRGBA(sv); - break; - default: - // FIXME: Implement other paths. - notImplemented(); - break; - } - releaseCurrentFrame(); -} - -void VideoLayerChromium::releaseCurrentFrame() -{ - if (!m_currentFrame) - return; - - m_provider->putCurrentFrame(m_currentFrame); - m_currentFrame = 0; - resetFrameParameters(); -} - -void VideoLayerChromium::drawYUV(const SharedValues* sv) -{ - 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()); -} - -void VideoLayerChromium::resetFrameParameters() -{ - for (unsigned plane = 0; plane < VideoFrameChromium::maxPlanes; plane++) { - m_textures[plane] = 0; - m_textureSizes[plane] = IntSize(); - m_frameSizes[plane] = IntSize(); - } -} - -void VideoLayerChromium::saveCurrentFrame(VideoFrameChromium* frame) -{ - ASSERT(!m_currentFrame); - m_currentFrame = frame; - for (unsigned plane = 0; plane < frame->planes(); plane++) { - m_textures[plane] = frame->texture(plane); - m_textureSizes[plane] = frame->requiredTextureSize(plane); - m_frameSizes[plane] = m_textureSizes[plane]; - } -} - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) |