tizen beta release
[profile/ivi/webkit-efl.git] / Source / WebCore / platform / graphics / chromium / cc / CCVideoLayerImpl.cpp
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 "cc/CCProxy.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(int id)
63     : CCLayerImpl(id)
64 {
65 }
66
67 CCVideoLayerImpl::~CCVideoLayerImpl()
68 {
69     cleanupResources();
70 }
71
72 void CCVideoLayerImpl::setTexture(size_t index, Platform3DObject textureId, const IntSize& size, const IntSize& visibleSize)
73 {
74     ASSERT(index < 3);
75     m_textures[index].id = textureId;
76     m_textures[index].size = size;
77     m_textures[index].visibleSize = visibleSize;
78 }
79
80 void CCVideoLayerImpl::setNativeTexture(Platform3DObject textureId, const IntSize& size, const IntSize& visibleSize)
81 {
82     m_nativeTextureId = textureId;
83     m_nativeTextureSize = size;
84     m_nativeTextureVisibleSize = visibleSize;
85 }
86
87 void CCVideoLayerImpl::draw(LayerRendererChromium* layerRenderer)
88 {
89     ASSERT(CCProxy::isImplThread());
90
91     if (m_skipsDraw)
92         return;
93
94     switch (m_frameFormat) {
95     case VideoFrameChromium::YV12:
96     case VideoFrameChromium::YV16:
97         drawYUV(layerRenderer);
98         break;
99     case VideoFrameChromium::RGBA:
100         drawRGBA(layerRenderer);
101         break;
102     case VideoFrameChromium::NativeTexture:
103         drawNativeTexture(layerRenderer);
104         break;
105     default:
106         // FIXME: Implement other paths.
107         notImplemented();
108         break;
109     }
110 }
111
112 void CCVideoLayerImpl::drawYUV(LayerRendererChromium* layerRenderer) const
113 {
114     const YUVProgram* program = layerRenderer->videoLayerYUVProgram();
115     ASSERT(program && program->initialized());
116
117     GraphicsContext3D* context = layerRenderer->context();
118     CCVideoLayerImpl::Texture yTexture = m_textures[VideoFrameChromium::yPlane];
119     CCVideoLayerImpl::Texture uTexture = m_textures[VideoFrameChromium::uPlane];
120     CCVideoLayerImpl::Texture vTexture = m_textures[VideoFrameChromium::vPlane];
121
122     GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE1));
123     GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, yTexture.id));
124     GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE2));
125     GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, uTexture.id));
126     GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE3));
127     GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, vTexture.id));
128
129     GLC(context, context->useProgram(program->program()));
130
131     float yWidthScaleFactor = static_cast<float>(yTexture.visibleSize.width()) / yTexture.size.width();
132     // Arbitrarily take the u sizes because u and v dimensions are identical.
133     float uvWidthScaleFactor = static_cast<float>(uTexture.visibleSize.width()) / uTexture.size.width();
134     GLC(context, context->uniform1f(program->vertexShader().yWidthScaleFactorLocation(), yWidthScaleFactor));
135     GLC(context, context->uniform1f(program->vertexShader().uvWidthScaleFactorLocation(), uvWidthScaleFactor));
136
137     GLC(context, context->uniform1i(program->fragmentShader().yTextureLocation(), 1));
138     GLC(context, context->uniform1i(program->fragmentShader().uTextureLocation(), 2));
139     GLC(context, context->uniform1i(program->fragmentShader().vTextureLocation(), 3));
140
141     GLC(context, context->uniformMatrix3fv(program->fragmentShader().ccMatrixLocation(), 0, const_cast<float*>(yuv2RGB), 1));
142     GLC(context, context->uniform3fv(program->fragmentShader().yuvAdjLocation(), const_cast<float*>(yuvAdjust), 1));
143
144     layerRenderer->drawTexturedQuad(drawTransform(), bounds().width(), bounds().height(), drawOpacity(), FloatQuad(),
145                                     program->vertexShader().matrixLocation(),
146                                     program->fragmentShader().alphaLocation(),
147                                     -1);
148
149     // Reset active texture back to texture 0.
150     GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
151 }
152
153 void CCVideoLayerImpl::drawRGBA(LayerRendererChromium* layerRenderer) const
154 {
155     const RGBAProgram* program = layerRenderer->videoLayerRGBAProgram();
156     ASSERT(program && program->initialized());
157
158     GraphicsContext3D* context = layerRenderer->context();
159     CCVideoLayerImpl::Texture texture = m_textures[VideoFrameChromium::rgbPlane];
160
161     GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
162     GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, texture.id));
163
164     GLC(context, context->useProgram(program->program()));
165     float widthScaleFactor = static_cast<float>(texture.visibleSize.width()) / texture.size.width();
166     GLC(context, context->uniform4f(program->vertexShader().texTransformLocation(), 0, 0, widthScaleFactor, 1));
167
168     GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0));
169
170     layerRenderer->drawTexturedQuad(drawTransform(), bounds().width(), bounds().height(), drawOpacity(), layerRenderer->sharedGeometryQuad(),
171                                     program->vertexShader().matrixLocation(),
172                                     program->fragmentShader().alphaLocation(),
173                                     -1);
174 }
175
176 void CCVideoLayerImpl::drawNativeTexture(LayerRendererChromium* layerRenderer) const
177 {
178     const NativeTextureProgram* program = layerRenderer->videoLayerNativeTextureProgram();
179     ASSERT(program && program->initialized());
180
181     GraphicsContext3D* context = layerRenderer->context();
182
183     GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
184     GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_nativeTextureId));
185
186     GLC(context, context->useProgram(program->program()));
187     float widthScaleFactor = static_cast<float>(m_nativeTextureVisibleSize.width()) / m_nativeTextureSize.width();
188     GLC(context, context->uniform4f(program->vertexShader().texTransformLocation(), 0, 0, widthScaleFactor, 1));
189
190     GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0));
191
192     layerRenderer->drawTexturedQuad(drawTransform(), bounds().width(), bounds().height(), drawOpacity(), layerRenderer->sharedGeometryQuad(),
193                                     program->vertexShader().matrixLocation(),
194                                     program->fragmentShader().alphaLocation(),
195                                     -1);
196 }
197
198 void CCVideoLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const
199 {
200     writeIndent(ts, indent);
201     ts << "video layer\n";
202     CCLayerImpl::dumpLayerProperties(ts, indent);
203 }
204
205 }
206
207 #endif // USE(ACCELERATED_COMPOSITING)