12bde8e466a4451c7319e3a072d118917957d6554Steve Block/* 22bde8e466a4451c7319e3a072d118917957d6554Steve Block * Copyright (C) 2011 Google Inc. All rights reserved. 32bde8e466a4451c7319e3a072d118917957d6554Steve Block * 42bde8e466a4451c7319e3a072d118917957d6554Steve Block * Redistribution and use in source and binary forms, with or without 52bde8e466a4451c7319e3a072d118917957d6554Steve Block * modification, are permitted provided that the following conditions 62bde8e466a4451c7319e3a072d118917957d6554Steve Block * are met: 72bde8e466a4451c7319e3a072d118917957d6554Steve Block * 82bde8e466a4451c7319e3a072d118917957d6554Steve Block * 1. Redistributions of source code must retain the above copyright 92bde8e466a4451c7319e3a072d118917957d6554Steve Block * notice, this list of conditions and the following disclaimer. 102bde8e466a4451c7319e3a072d118917957d6554Steve Block * 2. Redistributions in binary form must reproduce the above copyright 112bde8e466a4451c7319e3a072d118917957d6554Steve Block * notice, this list of conditions and the following disclaimer in the 122bde8e466a4451c7319e3a072d118917957d6554Steve Block * documentation and/or other materials provided with the distribution. 132bde8e466a4451c7319e3a072d118917957d6554Steve Block * 142bde8e466a4451c7319e3a072d118917957d6554Steve Block * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 152bde8e466a4451c7319e3a072d118917957d6554Steve Block * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 162bde8e466a4451c7319e3a072d118917957d6554Steve Block * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 172bde8e466a4451c7319e3a072d118917957d6554Steve Block * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 182bde8e466a4451c7319e3a072d118917957d6554Steve Block * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 192bde8e466a4451c7319e3a072d118917957d6554Steve Block * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 202bde8e466a4451c7319e3a072d118917957d6554Steve Block * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 212bde8e466a4451c7319e3a072d118917957d6554Steve Block * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 222bde8e466a4451c7319e3a072d118917957d6554Steve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 232bde8e466a4451c7319e3a072d118917957d6554Steve Block * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 242bde8e466a4451c7319e3a072d118917957d6554Steve Block */ 252bde8e466a4451c7319e3a072d118917957d6554Steve Block 262bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "config.h" 272bde8e466a4451c7319e3a072d118917957d6554Steve Block 282bde8e466a4451c7319e3a072d118917957d6554Steve Block#if USE(ACCELERATED_COMPOSITING) 292bde8e466a4451c7319e3a072d118917957d6554Steve Block 302bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "cc/CCVideoLayerImpl.h" 312bde8e466a4451c7319e3a072d118917957d6554Steve Block 322bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "GraphicsContext3D.h" 332bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "LayerRendererChromium.h" 342bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "NotImplemented.h" 352bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "VideoLayerChromium.h" 362bde8e466a4451c7319e3a072d118917957d6554Steve Block#include <wtf/text/WTFString.h> 372bde8e466a4451c7319e3a072d118917957d6554Steve Block 382bde8e466a4451c7319e3a072d118917957d6554Steve Blocknamespace WebCore { 392bde8e466a4451c7319e3a072d118917957d6554Steve Block 402bde8e466a4451c7319e3a072d118917957d6554Steve Block// These values are magic numbers that are used in the transformation 412bde8e466a4451c7319e3a072d118917957d6554Steve Block// from YUV to RGB color values. 422bde8e466a4451c7319e3a072d118917957d6554Steve Block// They are taken from the following webpage: 432bde8e466a4451c7319e3a072d118917957d6554Steve Block// http://www.fourcc.org/fccyvrgb.php 442bde8e466a4451c7319e3a072d118917957d6554Steve Blockconst float CCVideoLayerImpl::yuv2RGB[9] = { 452bde8e466a4451c7319e3a072d118917957d6554Steve Block 1.164f, 1.164f, 1.164f, 462bde8e466a4451c7319e3a072d118917957d6554Steve Block 0.f, -.391f, 2.018f, 472bde8e466a4451c7319e3a072d118917957d6554Steve Block 1.596f, -.813f, 0.f, 482bde8e466a4451c7319e3a072d118917957d6554Steve Block}; 492bde8e466a4451c7319e3a072d118917957d6554Steve Block 502bde8e466a4451c7319e3a072d118917957d6554Steve Block// These values map to 16, 128, and 128 respectively, and are computed 512bde8e466a4451c7319e3a072d118917957d6554Steve Block// as a fraction over 256 (e.g. 16 / 256 = 0.0625). 522bde8e466a4451c7319e3a072d118917957d6554Steve Block// They are used in the YUV to RGBA conversion formula: 532bde8e466a4451c7319e3a072d118917957d6554Steve Block// Y - 16 : Gives 16 values of head and footroom for overshooting 542bde8e466a4451c7319e3a072d118917957d6554Steve Block// U - 128 : Turns unsigned U into signed U [-128,127] 552bde8e466a4451c7319e3a072d118917957d6554Steve Block// V - 128 : Turns unsigned V into signed V [-128,127] 562bde8e466a4451c7319e3a072d118917957d6554Steve Blockconst float CCVideoLayerImpl::yuvAdjust[3] = { 572bde8e466a4451c7319e3a072d118917957d6554Steve Block -0.0625f, 582bde8e466a4451c7319e3a072d118917957d6554Steve Block -0.5f, 592bde8e466a4451c7319e3a072d118917957d6554Steve Block -0.5f, 602bde8e466a4451c7319e3a072d118917957d6554Steve Block}; 612bde8e466a4451c7319e3a072d118917957d6554Steve Block 622bde8e466a4451c7319e3a072d118917957d6554Steve BlockCCVideoLayerImpl::CCVideoLayerImpl(LayerChromium* owner) 632bde8e466a4451c7319e3a072d118917957d6554Steve Block : CCLayerImpl(owner) 642bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 652bde8e466a4451c7319e3a072d118917957d6554Steve Block} 662bde8e466a4451c7319e3a072d118917957d6554Steve Block 672bde8e466a4451c7319e3a072d118917957d6554Steve BlockCCVideoLayerImpl::~CCVideoLayerImpl() 682bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 692bde8e466a4451c7319e3a072d118917957d6554Steve Block cleanupResources(); 702bde8e466a4451c7319e3a072d118917957d6554Steve Block} 712bde8e466a4451c7319e3a072d118917957d6554Steve Block 722bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid CCVideoLayerImpl::setTexture(size_t i, VideoLayerChromium::Texture texture) 732bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 742bde8e466a4451c7319e3a072d118917957d6554Steve Block ASSERT(i < 3); 752bde8e466a4451c7319e3a072d118917957d6554Steve Block m_textures[i] = texture; 762bde8e466a4451c7319e3a072d118917957d6554Steve Block} 772bde8e466a4451c7319e3a072d118917957d6554Steve Block 782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid CCVideoLayerImpl::draw(const IntRect&) 792bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 802bde8e466a4451c7319e3a072d118917957d6554Steve Block if (m_skipsDraw) 812bde8e466a4451c7319e3a072d118917957d6554Steve Block return; 822bde8e466a4451c7319e3a072d118917957d6554Steve Block 832bde8e466a4451c7319e3a072d118917957d6554Steve Block ASSERT(layerRenderer()); 842bde8e466a4451c7319e3a072d118917957d6554Steve Block const RGBAProgram* rgbaProgram = layerRenderer()->videoLayerRGBAProgram(); 852bde8e466a4451c7319e3a072d118917957d6554Steve Block ASSERT(rgbaProgram && rgbaProgram->initialized()); 862bde8e466a4451c7319e3a072d118917957d6554Steve Block const YUVProgram* yuvProgram = layerRenderer()->videoLayerYUVProgram(); 872bde8e466a4451c7319e3a072d118917957d6554Steve Block ASSERT(yuvProgram && yuvProgram->initialized()); 882bde8e466a4451c7319e3a072d118917957d6554Steve Block 892bde8e466a4451c7319e3a072d118917957d6554Steve Block switch (m_frameFormat) { 902bde8e466a4451c7319e3a072d118917957d6554Steve Block case VideoFrameChromium::YV12: 912bde8e466a4451c7319e3a072d118917957d6554Steve Block case VideoFrameChromium::YV16: 922bde8e466a4451c7319e3a072d118917957d6554Steve Block drawYUV(yuvProgram); 932bde8e466a4451c7319e3a072d118917957d6554Steve Block break; 942bde8e466a4451c7319e3a072d118917957d6554Steve Block case VideoFrameChromium::RGBA: 952bde8e466a4451c7319e3a072d118917957d6554Steve Block drawRGBA(rgbaProgram); 962bde8e466a4451c7319e3a072d118917957d6554Steve Block break; 972bde8e466a4451c7319e3a072d118917957d6554Steve Block default: 982bde8e466a4451c7319e3a072d118917957d6554Steve Block // FIXME: Implement other paths. 992bde8e466a4451c7319e3a072d118917957d6554Steve Block notImplemented(); 1002bde8e466a4451c7319e3a072d118917957d6554Steve Block break; 1012bde8e466a4451c7319e3a072d118917957d6554Steve Block } 1022bde8e466a4451c7319e3a072d118917957d6554Steve Block} 1032bde8e466a4451c7319e3a072d118917957d6554Steve Block 1042bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid CCVideoLayerImpl::drawYUV(const CCVideoLayerImpl::YUVProgram* program) const 1052bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 1062bde8e466a4451c7319e3a072d118917957d6554Steve Block GraphicsContext3D* context = layerRenderer()->context(); 1072bde8e466a4451c7319e3a072d118917957d6554Steve Block VideoLayerChromium::Texture yTexture = m_textures[VideoFrameChromium::yPlane]; 1082bde8e466a4451c7319e3a072d118917957d6554Steve Block VideoLayerChromium::Texture uTexture = m_textures[VideoFrameChromium::uPlane]; 1092bde8e466a4451c7319e3a072d118917957d6554Steve Block VideoLayerChromium::Texture vTexture = m_textures[VideoFrameChromium::vPlane]; 1102bde8e466a4451c7319e3a072d118917957d6554Steve Block 1112bde8e466a4451c7319e3a072d118917957d6554Steve Block GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE1)); 1122bde8e466a4451c7319e3a072d118917957d6554Steve Block GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, yTexture.id)); 1132bde8e466a4451c7319e3a072d118917957d6554Steve Block GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE2)); 1142bde8e466a4451c7319e3a072d118917957d6554Steve Block GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, uTexture.id)); 1152bde8e466a4451c7319e3a072d118917957d6554Steve Block GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE3)); 1162bde8e466a4451c7319e3a072d118917957d6554Steve Block GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, vTexture.id)); 1172bde8e466a4451c7319e3a072d118917957d6554Steve Block 1182bde8e466a4451c7319e3a072d118917957d6554Steve Block layerRenderer()->useShader(program->program()); 1192bde8e466a4451c7319e3a072d118917957d6554Steve Block 1202bde8e466a4451c7319e3a072d118917957d6554Steve Block float yWidthScaleFactor = static_cast<float>(yTexture.visibleSize.width()) / yTexture.size.width(); 1212bde8e466a4451c7319e3a072d118917957d6554Steve Block // Arbitrarily take the u sizes because u and v dimensions are identical. 1222bde8e466a4451c7319e3a072d118917957d6554Steve Block float uvWidthScaleFactor = static_cast<float>(uTexture.visibleSize.width()) / uTexture.size.width(); 1232bde8e466a4451c7319e3a072d118917957d6554Steve Block GLC(context, context->uniform1f(program->vertexShader().yWidthScaleFactorLocation(), yWidthScaleFactor)); 1242bde8e466a4451c7319e3a072d118917957d6554Steve Block GLC(context, context->uniform1f(program->vertexShader().uvWidthScaleFactorLocation(), uvWidthScaleFactor)); 1252bde8e466a4451c7319e3a072d118917957d6554Steve Block 1262bde8e466a4451c7319e3a072d118917957d6554Steve Block GLC(context, context->uniform1i(program->fragmentShader().yTextureLocation(), 1)); 1272bde8e466a4451c7319e3a072d118917957d6554Steve Block GLC(context, context->uniform1i(program->fragmentShader().uTextureLocation(), 2)); 1282bde8e466a4451c7319e3a072d118917957d6554Steve Block GLC(context, context->uniform1i(program->fragmentShader().vTextureLocation(), 3)); 1292bde8e466a4451c7319e3a072d118917957d6554Steve Block 1302bde8e466a4451c7319e3a072d118917957d6554Steve Block GLC(context, context->uniformMatrix3fv(program->fragmentShader().ccMatrixLocation(), 0, const_cast<float*>(yuv2RGB), 1)); 1312bde8e466a4451c7319e3a072d118917957d6554Steve Block GLC(context, context->uniform3fv(program->fragmentShader().yuvAdjLocation(), const_cast<float*>(yuvAdjust), 1)); 1322bde8e466a4451c7319e3a072d118917957d6554Steve Block 1332bde8e466a4451c7319e3a072d118917957d6554Steve Block LayerChromium::drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(), 1342bde8e466a4451c7319e3a072d118917957d6554Steve Block bounds().width(), bounds().height(), drawOpacity(), 1352bde8e466a4451c7319e3a072d118917957d6554Steve Block program->vertexShader().matrixLocation(), 1362bde8e466a4451c7319e3a072d118917957d6554Steve Block program->fragmentShader().alphaLocation()); 1372bde8e466a4451c7319e3a072d118917957d6554Steve Block 1382bde8e466a4451c7319e3a072d118917957d6554Steve Block // Reset active texture back to texture 0. 1392bde8e466a4451c7319e3a072d118917957d6554Steve Block GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); 1402bde8e466a4451c7319e3a072d118917957d6554Steve Block} 1412bde8e466a4451c7319e3a072d118917957d6554Steve Block 1422bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid CCVideoLayerImpl::drawRGBA(const CCVideoLayerImpl::RGBAProgram* program) const 1432bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 1442bde8e466a4451c7319e3a072d118917957d6554Steve Block GraphicsContext3D* context = layerRenderer()->context(); 1452bde8e466a4451c7319e3a072d118917957d6554Steve Block VideoLayerChromium::Texture texture = m_textures[VideoFrameChromium::rgbPlane]; 1462bde8e466a4451c7319e3a072d118917957d6554Steve Block 1472bde8e466a4451c7319e3a072d118917957d6554Steve Block GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); 1482bde8e466a4451c7319e3a072d118917957d6554Steve Block GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, texture.id)); 1492bde8e466a4451c7319e3a072d118917957d6554Steve Block 1502bde8e466a4451c7319e3a072d118917957d6554Steve Block layerRenderer()->useShader(program->program()); 1512bde8e466a4451c7319e3a072d118917957d6554Steve Block float widthScaleFactor = static_cast<float>(texture.visibleSize.width()) / texture.size.width(); 1522bde8e466a4451c7319e3a072d118917957d6554Steve Block GLC(context, context->uniform4f(program->vertexShader().texTransformLocation(), 0, 0, widthScaleFactor, 1)); 1532bde8e466a4451c7319e3a072d118917957d6554Steve Block 1542bde8e466a4451c7319e3a072d118917957d6554Steve Block GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0)); 1552bde8e466a4451c7319e3a072d118917957d6554Steve Block 1562bde8e466a4451c7319e3a072d118917957d6554Steve Block LayerChromium::drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(), 1572bde8e466a4451c7319e3a072d118917957d6554Steve Block bounds().width(), bounds().height(), drawOpacity(), 1582bde8e466a4451c7319e3a072d118917957d6554Steve Block program->vertexShader().matrixLocation(), 1592bde8e466a4451c7319e3a072d118917957d6554Steve Block program->fragmentShader().alphaLocation()); 1602bde8e466a4451c7319e3a072d118917957d6554Steve Block} 1612bde8e466a4451c7319e3a072d118917957d6554Steve Block 1622bde8e466a4451c7319e3a072d118917957d6554Steve Block 1632bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid CCVideoLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const 1642bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 1652bde8e466a4451c7319e3a072d118917957d6554Steve Block writeIndent(ts, indent); 1662bde8e466a4451c7319e3a072d118917957d6554Steve Block ts << "video layer\n"; 1672bde8e466a4451c7319e3a072d118917957d6554Steve Block CCLayerImpl::dumpLayerProperties(ts, indent); 1682bde8e466a4451c7319e3a072d118917957d6554Steve Block} 1692bde8e466a4451c7319e3a072d118917957d6554Steve Block 1702bde8e466a4451c7319e3a072d118917957d6554Steve Block} 1712bde8e466a4451c7319e3a072d118917957d6554Steve Block 1722bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif // USE(ACCELERATED_COMPOSITING) 173