16b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner/* 26b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * Copyright (C) 2010 Google Inc. All rights reserved. 36b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * 46b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * Redistribution and use in source and binary forms, with or without 56b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * modification, are permitted provided that the following conditions 66b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * are met: 76b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * 86b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * 1. Redistributions of source code must retain the above copyright 96b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * notice, this list of conditions and the following disclaimer. 106b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * 2. Redistributions in binary form must reproduce the above copyright 116b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * notice, this list of conditions and the following disclaimer in the 126b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * documentation and/or other materials provided with the distribution. 136b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * 146b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 156b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 166b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 176b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 186b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 196b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 206b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 216b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 226b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 236b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 246b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner */ 256b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 266b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "config.h" 276b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 286b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#if USE(ACCELERATED_COMPOSITING) 296b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 306b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "RenderSurfaceChromium.h" 316b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 3281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "cc/CCLayerImpl.h" 336b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "GraphicsContext3D.h" 3481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "LayerChromium.h" 356b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "LayerRendererChromium.h" 36f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include "LayerTexture.h" 3781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "TextStream.h" 3881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include <wtf/text/CString.h> 396b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 406b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennernamespace WebCore { 416b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 4281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochRenderSurfaceChromium::RenderSurfaceChromium(CCLayerImpl* owningLayer) 436b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner : m_owningLayer(owningLayer) 442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block , m_maskLayer(0) 45f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch , m_skipsDraw(false) 466b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 476b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 486b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 496b70adc33054f8aee8c54d0f460458a9df11b8a5Russell BrennerRenderSurfaceChromium::~RenderSurfaceChromium() 506b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 516b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner cleanupResources(); 526b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 536b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 546b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennervoid RenderSurfaceChromium::cleanupResources() 556b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 56f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!m_contentsTexture) 576b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return; 586b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 596b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner ASSERT(layerRenderer()); 606b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 61f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_contentsTexture.clear(); 626b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 636b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 646b70adc33054f8aee8c54d0f460458a9df11b8a5Russell BrennerLayerRendererChromium* RenderSurfaceChromium::layerRenderer() 656b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 666b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner ASSERT(m_owningLayer); 676b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return m_owningLayer->layerRenderer(); 686b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 696b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 702fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockFloatRect RenderSurfaceChromium::drawableContentRect() const 712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block FloatRect localContentRect(-0.5 * m_contentRect.width(), -0.5 * m_contentRect.height(), 732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_contentRect.width(), m_contentRect.height()); 742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block FloatRect drawableContentRect = m_drawTransform.mapRect(localContentRect); 752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (m_owningLayer->replicaLayer()) 762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block drawableContentRect.unite(m_replicaDrawTransform.mapRect(localContentRect)); 772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return drawableContentRect; 792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 81f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochbool RenderSurfaceChromium::prepareContentsTexture() 826b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 83f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch IntSize requiredSize(m_contentRect.size()); 84f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch TextureManager* textureManager = layerRenderer()->textureManager(); 856b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 86f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!m_contentsTexture) 87f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_contentsTexture = LayerTexture::create(layerRenderer()->context(), textureManager); 886b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 8965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (m_contentsTexture->isReserved()) 9065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return true; 9165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 92f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!m_contentsTexture->reserve(requiredSize, GraphicsContext3D::RGBA)) { 93f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_skipsDraw = true; 94f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return false; 956b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner } 96f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 97f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_skipsDraw = false; 98f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return true; 99f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 100f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 10181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid RenderSurfaceChromium::drawSurface(CCLayerImpl* maskLayer, const TransformationMatrix& drawTransform) 102f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 1032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block GraphicsContext3D* context3D = layerRenderer()->context(); 104f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 1052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int shaderMatrixLocation = -1; 1062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int shaderAlphaLocation = -1; 10781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch const RenderSurfaceChromium::Program* program = layerRenderer()->renderSurfaceProgram(); 10881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch const RenderSurfaceChromium::MaskProgram* maskProgram = layerRenderer()->renderSurfaceMaskProgram(); 10981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ASSERT(program && program->initialized()); 1102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block bool useMask = false; 1112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (maskLayer && maskLayer->drawsContent()) { 1122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!maskLayer->bounds().isEmpty()) { 1132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block context3D->makeContextCurrent(); 11481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch layerRenderer()->useShader(maskProgram->program()); 1152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block GLC(context3D, context3D->activeTexture(GraphicsContext3D::TEXTURE0)); 11681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch GLC(context3D, context3D->uniform1i(maskProgram->fragmentShader().samplerLocation(), 0)); 1172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_contentsTexture->bindTexture(); 1182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block GLC(context3D, context3D->activeTexture(GraphicsContext3D::TEXTURE1)); 11981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch GLC(context3D, context3D->uniform1i(maskProgram->fragmentShader().maskSamplerLocation(), 1)); 1202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block maskLayer->bindContentsTexture(); 1212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block GLC(context3D, context3D->activeTexture(GraphicsContext3D::TEXTURE0)); 12281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch shaderMatrixLocation = maskProgram->vertexShader().matrixLocation(); 12381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch shaderAlphaLocation = maskProgram->fragmentShader().alphaLocation(); 1242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block useMask = true; 1252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 1262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 1272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!useMask) { 12981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch layerRenderer()->useShader(program->program()); 1302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_contentsTexture->bindTexture(); 13181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch GLC(context3D, context3D->uniform1i(program->fragmentShader().samplerLocation(), 0)); 13281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch shaderMatrixLocation = program->vertexShader().matrixLocation(); 13381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch shaderAlphaLocation = program->fragmentShader().alphaLocation(); 1342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 1352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block LayerChromium::drawTexturedQuad(layerRenderer()->context(), layerRenderer()->projectionMatrix(), drawTransform, 1372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_contentRect.width(), m_contentRect.height(), m_drawOpacity, 1382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block shaderMatrixLocation, shaderAlphaLocation); 1392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 1402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid RenderSurfaceChromium::draw(const IntRect&) 1422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 1432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (m_skipsDraw || !m_contentsTexture) 1442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return; 1452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // FIXME: By using the same RenderSurface for both the content and its reflection, 1462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // it's currently not possible to apply a separate mask to the reflection layer 1472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // or correctly handle opacity in reflections (opacity must be applied after drawing 1482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // both the layer and its reflection). The solution is to introduce yet another RenderSurface 1492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // to draw the layer and its reflection in. For now we only apply a separate reflection 1502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // mask if the contents don't have a mask of their own. 15181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch CCLayerImpl* replicaMaskLayer = m_maskLayer; 1522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!m_maskLayer && m_owningLayer->replicaLayer()) 1532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block replicaMaskLayer = m_owningLayer->replicaLayer()->maskLayer(); 154f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 155f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch layerRenderer()->setScissorToRect(m_scissorRect); 156f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 1572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Reflection draws before the layer. 1582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (m_owningLayer->replicaLayer()) 1592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block drawSurface(replicaMaskLayer, m_replicaDrawTransform); 160f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 1612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block drawSurface(m_maskLayer, m_drawTransform); 1626b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 1636b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 16481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochString RenderSurfaceChromium::name() const 16581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{ 16681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#ifndef NDEBUG 16781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return String::format("RenderSurface(id=%i,owner=%s)", m_owningLayer->debugID(), m_owningLayer->name().utf8().data()); 16881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#else 16981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return String::format("RenderSurface(owner=%s)", m_owningLayer->name().utf8().data()); 17081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#endif 17181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch} 17281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 17381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic void writeIndent(TextStream& ts, int indent) 17481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{ 17581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch for (int i = 0; i != indent; ++i) 17681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ts << " "; 17781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch} 17881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 17981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid RenderSurfaceChromium::dumpSurface(TextStream& ts, int indent) const 18081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{ 18181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch writeIndent(ts, indent); 18281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ts << name() << "\n"; 18381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 18481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch writeIndent(ts, indent+1); 18581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ts << "contentRect: (" << m_contentRect.x() << ", " << m_contentRect.y() << ", " << m_contentRect.width() << ", " << m_contentRect.height() << "\n"; 18681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch} 18781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 1886b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 1896b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#endif // USE(ACCELERATED_COMPOSITING) 190