2 * Copyright (C) 2011 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
28 #if USE(ACCELERATED_COMPOSITING)
30 #include "cc/CCVideoLayerImpl.h"
32 #include "GraphicsContext3D.h"
33 #include "LayerRendererChromium.h"
34 #include "NotImplemented.h"
35 #include "cc/CCProxy.h"
36 #include <wtf/text/WTFString.h>
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,
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] = {
62 CCVideoLayerImpl::CCVideoLayerImpl(int id)
67 CCVideoLayerImpl::~CCVideoLayerImpl()
72 void CCVideoLayerImpl::setTexture(size_t index, Platform3DObject textureId, const IntSize& size, const IntSize& visibleSize)
75 m_textures[index].id = textureId;
76 m_textures[index].size = size;
77 m_textures[index].visibleSize = visibleSize;
80 void CCVideoLayerImpl::setNativeTexture(Platform3DObject textureId, const IntSize& size, const IntSize& visibleSize)
82 m_nativeTextureId = textureId;
83 m_nativeTextureSize = size;
84 m_nativeTextureVisibleSize = visibleSize;
87 void CCVideoLayerImpl::draw(LayerRendererChromium* layerRenderer)
89 ASSERT(CCProxy::isImplThread());
94 switch (m_frameFormat) {
95 case VideoFrameChromium::YV12:
96 case VideoFrameChromium::YV16:
97 drawYUV(layerRenderer);
99 case VideoFrameChromium::RGBA:
100 drawRGBA(layerRenderer);
102 case VideoFrameChromium::NativeTexture:
103 drawNativeTexture(layerRenderer);
106 // FIXME: Implement other paths.
112 void CCVideoLayerImpl::drawYUV(LayerRendererChromium* layerRenderer) const
114 const YUVProgram* program = layerRenderer->videoLayerYUVProgram();
115 ASSERT(program && program->initialized());
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];
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));
129 GLC(context, context->useProgram(program->program()));
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));
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));
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));
144 layerRenderer->drawTexturedQuad(drawTransform(), bounds().width(), bounds().height(), drawOpacity(), FloatQuad(),
145 program->vertexShader().matrixLocation(),
146 program->fragmentShader().alphaLocation(),
149 // Reset active texture back to texture 0.
150 GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
153 void CCVideoLayerImpl::drawRGBA(LayerRendererChromium* layerRenderer) const
155 const RGBAProgram* program = layerRenderer->videoLayerRGBAProgram();
156 ASSERT(program && program->initialized());
158 GraphicsContext3D* context = layerRenderer->context();
159 CCVideoLayerImpl::Texture texture = m_textures[VideoFrameChromium::rgbPlane];
161 GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
162 GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, texture.id));
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));
168 GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0));
170 layerRenderer->drawTexturedQuad(drawTransform(), bounds().width(), bounds().height(), drawOpacity(), layerRenderer->sharedGeometryQuad(),
171 program->vertexShader().matrixLocation(),
172 program->fragmentShader().alphaLocation(),
176 void CCVideoLayerImpl::drawNativeTexture(LayerRendererChromium* layerRenderer) const
178 const NativeTextureProgram* program = layerRenderer->videoLayerNativeTextureProgram();
179 ASSERT(program && program->initialized());
181 GraphicsContext3D* context = layerRenderer->context();
183 GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
184 GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_nativeTextureId));
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));
190 GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0));
192 layerRenderer->drawTexturedQuad(drawTransform(), bounds().width(), bounds().height(), drawOpacity(), layerRenderer->sharedGeometryQuad(),
193 program->vertexShader().matrixLocation(),
194 program->fragmentShader().alphaLocation(),
198 void CCVideoLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const
200 writeIndent(ts, indent);
201 ts << "video layer\n";
202 CCLayerImpl::dumpLayerProperties(ts, indent);
207 #endif // USE(ACCELERATED_COMPOSITING)