• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
CCVideoLayerImpl(LayerChromium * owner)62 CCVideoLayerImpl::CCVideoLayerImpl(LayerChromium* owner)
63     : CCLayerImpl(owner)
64 {
65 }
66 
~CCVideoLayerImpl()67 CCVideoLayerImpl::~CCVideoLayerImpl()
68 {
69     cleanupResources();
70 }
71 
setTexture(size_t i,VideoLayerChromium::Texture texture)72 void CCVideoLayerImpl::setTexture(size_t i, VideoLayerChromium::Texture texture)
73 {
74     ASSERT(i < 3);
75     m_textures[i] = texture;
76 }
77 
draw(const IntRect &)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 
drawYUV(const CCVideoLayerImpl::YUVProgram * program) const104 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 
drawRGBA(const CCVideoLayerImpl::RGBAProgram * program) const142 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 
dumpLayerProperties(TextStream & ts,int indent) const163 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