Home | History | Annotate | Download | only in cc
      1 /*
      2  * Copyright (C) 2011 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  * 1.  Redistributions of source code must retain the above copyright
      9  *     notice, this list of conditions and the following disclaimer.
     10  * 2.  Redistributions in binary form must reproduce the above copyright
     11  *     notice, this list of conditions and the following disclaimer in the
     12  *     documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     17  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 
     28 #if USE(ACCELERATED_COMPOSITING)
     29 
     30 #include "cc/CCVideoLayerImpl.h"
     31 
     32 #include "GraphicsContext3D.h"
     33 #include "LayerRendererChromium.h"
     34 #include "NotImplemented.h"
     35 #include "VideoLayerChromium.h"
     36 #include <wtf/text/WTFString.h>
     37 
     38 namespace WebCore {
     39 
     40 // These values are magic numbers that are used in the transformation
     41 // from YUV to RGB color values.
     42 // They are taken from the following webpage:
     43 // http://www.fourcc.org/fccyvrgb.php
     44 const float CCVideoLayerImpl::yuv2RGB[9] = {
     45     1.164f, 1.164f, 1.164f,
     46     0.f, -.391f, 2.018f,
     47     1.596f, -.813f, 0.f,
     48 };
     49 
     50 // These values map to 16, 128, and 128 respectively, and are computed
     51 // as a fraction over 256 (e.g. 16 / 256 = 0.0625).
     52 // They are used in the YUV to RGBA conversion formula:
     53 //   Y - 16   : Gives 16 values of head and footroom for overshooting
     54 //   U - 128  : Turns unsigned U into signed U [-128,127]
     55 //   V - 128  : Turns unsigned V into signed V [-128,127]
     56 const float CCVideoLayerImpl::yuvAdjust[3] = {
     57     -0.0625f,
     58     -0.5f,
     59     -0.5f,
     60 };
     61 
     62 CCVideoLayerImpl::CCVideoLayerImpl(LayerChromium* owner)
     63     : CCLayerImpl(owner)
     64 {
     65 }
     66 
     67 CCVideoLayerImpl::~CCVideoLayerImpl()
     68 {
     69     cleanupResources();
     70 }
     71 
     72 void CCVideoLayerImpl::setTexture(size_t i, VideoLayerChromium::Texture texture)
     73 {
     74     ASSERT(i < 3);
     75     m_textures[i] = texture;
     76 }
     77 
     78 void CCVideoLayerImpl::draw(const IntRect&)
     79 {
     80     if (m_skipsDraw)
     81         return;
     82 
     83     ASSERT(layerRenderer());
     84     const RGBAProgram* rgbaProgram = layerRenderer()->videoLayerRGBAProgram();
     85     ASSERT(rgbaProgram && rgbaProgram->initialized());
     86     const YUVProgram* yuvProgram = layerRenderer()->videoLayerYUVProgram();
     87     ASSERT(yuvProgram && yuvProgram->initialized());
     88 
     89     switch (m_frameFormat) {
     90     case VideoFrameChromium::YV12:
     91     case VideoFrameChromium::YV16:
     92         drawYUV(yuvProgram);
     93         break;
     94     case VideoFrameChromium::RGBA:
     95         drawRGBA(rgbaProgram);
     96         break;
     97     default:
     98         // FIXME: Implement other paths.
     99         notImplemented();
    100         break;
    101     }
    102 }
    103 
    104 void CCVideoLayerImpl::drawYUV(const CCVideoLayerImpl::YUVProgram* program) const
    105 {
    106     GraphicsContext3D* context = layerRenderer()->context();
    107     VideoLayerChromium::Texture yTexture = m_textures[VideoFrameChromium::yPlane];
    108     VideoLayerChromium::Texture uTexture = m_textures[VideoFrameChromium::uPlane];
    109     VideoLayerChromium::Texture vTexture = m_textures[VideoFrameChromium::vPlane];
    110 
    111     GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE1));
    112     GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, yTexture.id));
    113     GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE2));
    114     GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, uTexture.id));
    115     GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE3));
    116     GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, vTexture.id));
    117 
    118     layerRenderer()->useShader(program->program());
    119 
    120     float yWidthScaleFactor = static_cast<float>(yTexture.visibleSize.width()) / yTexture.size.width();
    121     // Arbitrarily take the u sizes because u and v dimensions are identical.
    122     float uvWidthScaleFactor = static_cast<float>(uTexture.visibleSize.width()) / uTexture.size.width();
    123     GLC(context, context->uniform1f(program->vertexShader().yWidthScaleFactorLocation(), yWidthScaleFactor));
    124     GLC(context, context->uniform1f(program->vertexShader().uvWidthScaleFactorLocation(), uvWidthScaleFactor));
    125 
    126     GLC(context, context->uniform1i(program->fragmentShader().yTextureLocation(), 1));
    127     GLC(context, context->uniform1i(program->fragmentShader().uTextureLocation(), 2));
    128     GLC(context, context->uniform1i(program->fragmentShader().vTextureLocation(), 3));
    129 
    130     GLC(context, context->uniformMatrix3fv(program->fragmentShader().ccMatrixLocation(), 0, const_cast<float*>(yuv2RGB), 1));
    131     GLC(context, context->uniform3fv(program->fragmentShader().yuvAdjLocation(), const_cast<float*>(yuvAdjust), 1));
    132 
    133     LayerChromium::drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(),
    134                                     bounds().width(), bounds().height(), drawOpacity(),
    135                                     program->vertexShader().matrixLocation(),
    136                                     program->fragmentShader().alphaLocation());
    137 
    138     // Reset active texture back to texture 0.
    139     GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
    140 }
    141 
    142 void CCVideoLayerImpl::drawRGBA(const CCVideoLayerImpl::RGBAProgram* program) const
    143 {
    144     GraphicsContext3D* context = layerRenderer()->context();
    145     VideoLayerChromium::Texture texture = m_textures[VideoFrameChromium::rgbPlane];
    146 
    147     GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
    148     GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, texture.id));
    149 
    150     layerRenderer()->useShader(program->program());
    151     float widthScaleFactor = static_cast<float>(texture.visibleSize.width()) / texture.size.width();
    152     GLC(context, context->uniform4f(program->vertexShader().texTransformLocation(), 0, 0, widthScaleFactor, 1));
    153 
    154     GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0));
    155 
    156     LayerChromium::drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(),
    157                                     bounds().width(), bounds().height(), drawOpacity(),
    158                                     program->vertexShader().matrixLocation(),
    159                                     program->fragmentShader().alphaLocation());
    160 }
    161 
    162 
    163 void CCVideoLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const
    164 {
    165     writeIndent(ts, indent);
    166     ts << "video layer\n";
    167     CCLayerImpl::dumpLayerProperties(ts, indent);
    168 }
    169 
    170 }
    171 
    172 #endif // USE(ACCELERATED_COMPOSITING)
    173