Home | History | Annotate | Download | only in chromium
      1 /*
      2  * Copyright (C) 2010 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 are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 
     32 #include "config.h"
     33 
     34 #if USE(ACCELERATED_COMPOSITING)
     35 #include "LayerRendererChromium.h"
     36 
     37 #include "Canvas2DLayerChromium.h"
     38 #include "Extensions3DChromium.h"
     39 #include "FloatQuad.h"
     40 #include "GeometryBinding.h"
     41 #include "GraphicsContext3D.h"
     42 #include "LayerChromium.h"
     43 #include "LayerTexture.h"
     44 #include "NotImplemented.h"
     45 #include "TextStream.h"
     46 #include "TextureManager.h"
     47 #include "TraceEvent.h"
     48 #include "WebGLLayerChromium.h"
     49 #include "cc/CCLayerImpl.h"
     50 #if USE(SKIA)
     51 #include "NativeImageSkia.h"
     52 #include "PlatformContextSkia.h"
     53 #elif USE(CG)
     54 #include <CoreGraphics/CGBitmapContext.h>
     55 #endif
     56 
     57 namespace WebCore {
     58 
     59 // FIXME: Make this limit adjustable and give it a useful value.
     60 static size_t textureMemoryLimitBytes = 64 * 1024 * 1024;
     61 
     62 static TransformationMatrix orthoMatrix(float left, float right, float bottom, float top)
     63 {
     64     float deltaX = right - left;
     65     float deltaY = top - bottom;
     66     TransformationMatrix ortho;
     67     if (!deltaX || !deltaY)
     68         return ortho;
     69     ortho.setM11(2.0f / deltaX);
     70     ortho.setM41(-(right + left) / deltaX);
     71     ortho.setM22(2.0f / deltaY);
     72     ortho.setM42(-(top + bottom) / deltaY);
     73 
     74     // Z component of vertices is always set to zero as we don't use the depth buffer
     75     // while drawing.
     76     ortho.setM33(0);
     77 
     78     return ortho;
     79 }
     80 
     81 // Returns true if the matrix has no rotation, skew or perspective components to it.
     82 static bool isScaleOrTranslation(const TransformationMatrix& m)
     83 {
     84     return !m.m12() && !m.m13() && !m.m14()
     85            && !m.m21() && !m.m23() && !m.m24()
     86            && !m.m31() && !m.m32() && !m.m43()
     87            && m.m44();
     88 
     89 }
     90 
     91 bool LayerRendererChromium::compareLayerZ(const RefPtr<CCLayerImpl>& a, const RefPtr<CCLayerImpl>& b)
     92 {
     93     return a->drawDepth() < b->drawDepth();
     94 }
     95 
     96 PassRefPtr<LayerRendererChromium> LayerRendererChromium::create(PassRefPtr<GraphicsContext3D> context, PassOwnPtr<TilePaintInterface> contentPaint)
     97 {
     98     if (!context)
     99         return 0;
    100 
    101     RefPtr<LayerRendererChromium> layerRenderer(adoptRef(new LayerRendererChromium(context, contentPaint)));
    102     if (!layerRenderer->hardwareCompositing())
    103         return 0;
    104 
    105     return layerRenderer.release();
    106 }
    107 
    108 LayerRendererChromium::LayerRendererChromium(PassRefPtr<GraphicsContext3D> context,
    109                                              PassOwnPtr<TilePaintInterface> contentPaint)
    110     : m_viewportScrollPosition(IntPoint(-1, -1))
    111     , m_rootLayer(0)
    112     , m_rootLayerContentPaint(contentPaint)
    113     , m_currentShader(0)
    114     , m_currentRenderSurface(0)
    115     , m_offscreenFramebufferId(0)
    116     , m_compositeOffscreen(false)
    117     , m_context(context)
    118     , m_childContextsWereCopied(false)
    119     , m_contextSupportsLatch(false)
    120     , m_defaultRenderSurface(0)
    121 {
    122     m_contextSupportsLatch = m_context->getExtensions()->supports("GL_CHROMIUM_latch");
    123     m_hardwareCompositing = initializeSharedObjects();
    124     m_rootLayerContentTiler = LayerTilerChromium::create(this, IntSize(256, 256), LayerTilerChromium::NoBorderTexels);
    125     ASSERT(m_rootLayerContentTiler);
    126 
    127     m_headsUpDisplay = CCHeadsUpDisplay::create(this);
    128 }
    129 
    130 LayerRendererChromium::~LayerRendererChromium()
    131 {
    132     m_headsUpDisplay.clear(); // Explicitly destroy the HUD before the TextureManager dies.
    133     cleanupSharedObjects();
    134 }
    135 
    136 GraphicsContext3D* LayerRendererChromium::context()
    137 {
    138     return m_context.get();
    139 }
    140 
    141 void LayerRendererChromium::debugGLCall(GraphicsContext3D* context, const char* command, const char* file, int line)
    142 {
    143     unsigned long error = context->getError();
    144     if (error != GraphicsContext3D::NO_ERROR)
    145         LOG_ERROR("GL command failed: File: %s\n\tLine %d\n\tcommand: %s, error %x\n", file, line, command, static_cast<int>(error));
    146 }
    147 
    148 void LayerRendererChromium::useShader(unsigned programId)
    149 {
    150     if (programId != m_currentShader) {
    151         GLC(m_context.get(), m_context->useProgram(programId));
    152         m_currentShader = programId;
    153     }
    154 }
    155 
    156 void LayerRendererChromium::invalidateRootLayerRect(const IntRect& dirtyRect)
    157 {
    158     m_rootLayerContentTiler->invalidateRect(dirtyRect);
    159 }
    160 
    161 void LayerRendererChromium::updateRootLayerContents()
    162 {
    163     TRACE_EVENT("LayerRendererChromium::updateRootLayerContents", this, 0);
    164     m_rootLayerContentTiler->update(*m_rootLayerContentPaint, m_viewportVisibleRect);
    165 }
    166 
    167 void LayerRendererChromium::drawRootLayer()
    168 {
    169     TransformationMatrix scroll;
    170     scroll.translate(-m_viewportVisibleRect.x(), -m_viewportVisibleRect.y());
    171 
    172     m_rootLayerContentTiler->uploadCanvas();
    173     m_rootLayerContentTiler->draw(m_viewportVisibleRect, scroll, 1.0f);
    174 }
    175 
    176 void LayerRendererChromium::setViewport(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition)
    177 {
    178     bool visibleRectChanged = m_viewportVisibleRect.size() != visibleRect.size();
    179 
    180     m_viewportVisibleRect = visibleRect;
    181     m_viewportContentRect = contentRect;
    182     m_viewportScrollPosition = scrollPosition;
    183 
    184     if (visibleRectChanged) {
    185         // Reset the current render surface to force an update of the viewport and
    186         // projection matrix next time useRenderSurface is called.
    187         m_currentRenderSurface = 0;
    188         m_rootLayerContentTiler->invalidateEntireLayer();
    189     }
    190 }
    191 
    192 void LayerRendererChromium::updateAndDrawLayers()
    193 {
    194     ASSERT(m_hardwareCompositing);
    195 
    196     if (!m_rootLayer)
    197         return;
    198 
    199     updateRootLayerContents();
    200 
    201     // Recheck that we still have a root layer. This may become null if
    202     // compositing gets turned off during a paint operation.
    203     if (!m_rootLayer)
    204         return;
    205 
    206     LayerList renderSurfaceLayerList;
    207 
    208     updateLayers(renderSurfaceLayerList);
    209 
    210     // Before drawLayers:
    211     if (hardwareCompositing() && m_contextSupportsLatch) {
    212         // FIXME: The multithreaded compositor case will not work as long as
    213         // copyTexImage2D resolves to the parent texture, because the main
    214         // thread can execute WebGL calls on the child context at any time,
    215         // potentially clobbering the parent texture that is being renderered
    216         // by the compositor thread.
    217         if (m_childContextsWereCopied) {
    218             Extensions3DChromium* parentExt = static_cast<Extensions3DChromium*>(m_context->getExtensions());
    219             // For each child context:
    220             //   glWaitLatch(Offscreen->Compositor);
    221             ChildContextMap::iterator i = m_childContexts.begin();
    222             for (; i != m_childContexts.end(); ++i) {
    223                 Extensions3DChromium* childExt = static_cast<Extensions3DChromium*>(i->first->getExtensions());
    224                 GC3Duint latchId;
    225                 childExt->getChildToParentLatchCHROMIUM(&latchId);
    226                 parentExt->waitLatchCHROMIUM(latchId);
    227             }
    228         }
    229         // Reset to false to indicate that we have consumed the dirty child
    230         // contexts' parent textures. (This is only useful when the compositor
    231         // is multithreaded.)
    232         m_childContextsWereCopied = false;
    233     }
    234 
    235     drawLayers(renderSurfaceLayerList);
    236 
    237     m_textureManager->unprotectAllTextures();
    238 
    239     // After drawLayers:
    240     if (hardwareCompositing() && m_contextSupportsLatch) {
    241         Extensions3DChromium* parentExt = static_cast<Extensions3DChromium*>(m_context->getExtensions());
    242         // For each child context:
    243         //   glSetLatch(Compositor->Offscreen);
    244         ChildContextMap::iterator i = m_childContexts.begin();
    245         for (; i != m_childContexts.end(); ++i) {
    246             Extensions3DChromium* childExt = static_cast<Extensions3DChromium*>(i->first->getExtensions());
    247             GC3Duint latchId;
    248             childExt->getParentToChildLatchCHROMIUM(&latchId);
    249             parentExt->setLatchCHROMIUM(latchId);
    250         }
    251     }
    252 
    253     if (isCompositingOffscreen())
    254         copyOffscreenTextureToDisplay();
    255 }
    256 
    257 void LayerRendererChromium::updateLayers(LayerList& renderSurfaceLayerList)
    258 {
    259     TRACE_EVENT("LayerRendererChromium::updateLayers", this, 0);
    260     m_rootLayer->createCCLayerImplIfNeeded();
    261     CCLayerImpl* rootDrawLayer = m_rootLayer->ccLayerImpl();
    262 
    263     if (!rootDrawLayer->renderSurface())
    264         rootDrawLayer->createRenderSurface();
    265     ASSERT(rootDrawLayer->renderSurface());
    266 
    267     rootDrawLayer->renderSurface()->m_contentRect = IntRect(IntPoint(0, 0), m_viewportVisibleRect.size());
    268 
    269     IntRect rootScissorRect(m_viewportVisibleRect);
    270     // The scissorRect should not include the scroll offset.
    271     rootScissorRect.move(-m_viewportScrollPosition.x(), -m_viewportScrollPosition.y());
    272     rootDrawLayer->setScissorRect(rootScissorRect);
    273 
    274     m_defaultRenderSurface = rootDrawLayer->renderSurface();
    275 
    276     renderSurfaceLayerList.append(rootDrawLayer);
    277 
    278     TransformationMatrix identityMatrix;
    279     m_defaultRenderSurface->m_layerList.clear();
    280     // Unfortunately, updatePropertiesAndRenderSurfaces() currently both updates the layers and updates the draw state
    281     // (transforms, etc). It'd be nicer if operations on the presentation layers happened later, but the draw
    282     // transforms are needed by large layers to determine visibility. Tiling will fix this by eliminating the
    283     // concept of a large content layer.
    284     updatePropertiesAndRenderSurfaces(m_rootLayer.get(), identityMatrix, renderSurfaceLayerList, m_defaultRenderSurface->m_layerList);
    285 
    286     paintLayerContents(renderSurfaceLayerList);
    287 
    288     // FIXME: Before updateCompositorResourcesRecursive, when the compositor runs in
    289     // its own thread, and when the copyTexImage2D bug is fixed, insert
    290     // a glWaitLatch(Compositor->Offscreen) on all child contexts here instead
    291     // of after updateCompositorResourcesRecursive.
    292     // Also uncomment the glSetLatch(Compositor->Offscreen) code in addChildContext.
    293 //  if (hardwareCompositing() && m_contextSupportsLatch) {
    294 //      // For each child context:
    295 //      //   glWaitLatch(Compositor->Offscreen);
    296 //      ChildContextMap::iterator i = m_childContexts.begin();
    297 //      for (; i != m_childContexts.end(); ++i) {
    298 //          Extensions3DChromium* ext = static_cast<Extensions3DChromium*>(i->first->getExtensions());
    299 //          GC3Duint childToParentLatchId, parentToChildLatchId;
    300 //          ext->getParentToChildLatchCHROMIUM(&parentToChildLatchId);
    301 //          ext->waitLatchCHROMIUM(parentToChildLatchId);
    302 //      }
    303 //  }
    304 
    305     updateCompositorResourcesRecursive(m_rootLayer.get());
    306 
    307     // After updateCompositorResourcesRecursive, set/wait latches for all child
    308     // contexts. This will prevent the compositor from using any of the child
    309     // parent textures while WebGL commands are executing from javascript *and*
    310     // while the final parent texture is being blit'd. copyTexImage2D
    311     // uses the parent texture as a temporary resolve buffer, so that's why the
    312     // waitLatch is below, to block the compositor from using the parent texture
    313     // until the next WebGL SwapBuffers (or copyTextureToParentTexture for
    314     // Canvas2D).
    315     if (hardwareCompositing() && m_contextSupportsLatch) {
    316         m_childContextsWereCopied = true;
    317         // For each child context:
    318         //   glSetLatch(Offscreen->Compositor);
    319         //   glWaitLatch(Compositor->Offscreen);
    320         ChildContextMap::iterator i = m_childContexts.begin();
    321         for (; i != m_childContexts.end(); ++i) {
    322             Extensions3DChromium* ext = static_cast<Extensions3DChromium*>(i->first->getExtensions());
    323             GC3Duint childToParentLatchId, parentToChildLatchId;
    324             ext->getParentToChildLatchCHROMIUM(&parentToChildLatchId);
    325             ext->getChildToParentLatchCHROMIUM(&childToParentLatchId);
    326             ext->setLatchCHROMIUM(childToParentLatchId);
    327             ext->waitLatchCHROMIUM(parentToChildLatchId);
    328         }
    329     }
    330 }
    331 
    332 void LayerRendererChromium::paintLayerContents(const LayerList& renderSurfaceLayerList)
    333 {
    334     for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) {
    335         CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex].get();
    336         RenderSurfaceChromium* renderSurface = renderSurfaceLayer->renderSurface();
    337         ASSERT(renderSurface);
    338 
    339         // Render surfaces whose drawable area has zero width or height
    340         // will have no layers associated with them and should be skipped.
    341         if (!renderSurface->m_layerList.size())
    342             continue;
    343 
    344         LayerList& layerList = renderSurface->m_layerList;
    345         ASSERT(layerList.size());
    346         for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex) {
    347             CCLayerImpl* ccLayerImpl = layerList[layerIndex].get();
    348 
    349             // Layers that start a new render surface will be painted when the render
    350             // surface's list is processed.
    351             if (ccLayerImpl->renderSurface() && ccLayerImpl->renderSurface() != renderSurface)
    352                 continue;
    353 
    354             LayerChromium* layer = ccLayerImpl->owner();
    355             if (layer->bounds().isEmpty())
    356                 continue;
    357 
    358             const IntRect targetSurfaceRect = layer->ccLayerImpl()->scissorRect();
    359 
    360             if (layer->drawsContent())
    361                 layer->paintContentsIfDirty(targetSurfaceRect);
    362             if (layer->maskLayer() && layer->maskLayer()->drawsContent())
    363                 layer->maskLayer()->paintContentsIfDirty(targetSurfaceRect);
    364             if (layer->replicaLayer() && layer->replicaLayer()->drawsContent())
    365                 layer->replicaLayer()->paintContentsIfDirty(targetSurfaceRect);
    366             if (layer->replicaLayer() && layer->replicaLayer()->maskLayer() && layer->replicaLayer()->maskLayer()->drawsContent())
    367                 layer->replicaLayer()->maskLayer()->paintContentsIfDirty(targetSurfaceRect);
    368         }
    369     }
    370 }
    371 
    372 void LayerRendererChromium::drawLayers(const LayerList& renderSurfaceLayerList)
    373 {
    374     TRACE_EVENT("LayerRendererChromium::drawLayers", this, 0);
    375     CCLayerImpl* rootDrawLayer = m_rootLayer->ccLayerImpl();
    376     makeContextCurrent();
    377 
    378     // The GL viewport covers the entire visible area, including the scrollbars.
    379     GLC(m_context.get(), m_context->viewport(0, 0, m_viewportVisibleRect.width(), m_viewportVisibleRect.height()));
    380 
    381     // Bind the common vertex attributes used for drawing all the layers.
    382     m_sharedGeometry->prepareForDraw();
    383 
    384     // FIXME: These calls can be made once, when the compositor context is initialized.
    385     GLC(m_context.get(), m_context->disable(GraphicsContext3D::DEPTH_TEST));
    386     GLC(m_context.get(), m_context->disable(GraphicsContext3D::CULL_FACE));
    387 
    388     // Blending disabled by default. Root layer alpha channel on Windows is incorrect when Skia uses ClearType.
    389     GLC(m_context.get(), m_context->disable(GraphicsContext3D::BLEND));
    390 
    391     useRenderSurface(m_defaultRenderSurface);
    392 
    393     // Clear to blue to make it easier to spot unrendered regions.
    394     m_context->clearColor(0, 0, 1, 1);
    395     m_context->colorMask(true, true, true, true);
    396     m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
    397     // Mask out writes to alpha channel: subpixel antialiasing via Skia results in invalid
    398     // zero alpha values on text glyphs. The root layer is always opaque.
    399     m_context->colorMask(true, true, true, false);
    400 
    401     drawRootLayer();
    402 
    403     // Re-enable color writes to layers, which may be partially transparent.
    404     m_context->colorMask(true, true, true, true);
    405 
    406     GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND));
    407     GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
    408     GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST));
    409 
    410     // Update the contents of the render surfaces. We traverse the array from
    411     // back to front to guarantee that nested render surfaces get rendered in the
    412     // correct order.
    413     for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) {
    414         CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex].get();
    415         ASSERT(renderSurfaceLayer->renderSurface());
    416 
    417         // Render surfaces whose drawable area has zero width or height
    418         // will have no layers associated with them and should be skipped.
    419         if (!renderSurfaceLayer->renderSurface()->m_layerList.size())
    420             continue;
    421 
    422         if (useRenderSurface(renderSurfaceLayer->renderSurface())) {
    423             if (renderSurfaceLayer != rootDrawLayer) {
    424                 GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
    425                 GLC(m_context.get(), m_context->clearColor(0, 0, 0, 0));
    426                 GLC(m_context.get(), m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT));
    427                 GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST));
    428             }
    429 
    430             LayerList& layerList = renderSurfaceLayer->renderSurface()->m_layerList;
    431             ASSERT(layerList.size());
    432             for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex)
    433                 drawLayer(layerList[layerIndex].get(), renderSurfaceLayer->renderSurface());
    434         }
    435     }
    436 
    437     if (m_headsUpDisplay->enabled()) {
    438         GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND));
    439         GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
    440         GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
    441         useRenderSurface(m_defaultRenderSurface);
    442         m_headsUpDisplay->draw();
    443     }
    444 
    445     GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
    446     GLC(m_context.get(), m_context->disable(GraphicsContext3D::BLEND));
    447 }
    448 
    449 void LayerRendererChromium::finish()
    450 {
    451     TRACE_EVENT("LayerRendererChromium::finish", this, 0);
    452     m_context->finish();
    453 }
    454 
    455 void LayerRendererChromium::present()
    456 {
    457     TRACE_EVENT("LayerRendererChromium::present", this, 0);
    458     // We're done! Time to swapbuffers!
    459 
    460     // Note that currently this has the same effect as swapBuffers; we should
    461     // consider exposing a different entry point on GraphicsContext3D.
    462     m_context->prepareTexture();
    463 
    464     m_headsUpDisplay->onPresent();
    465 }
    466 
    467 void LayerRendererChromium::setRootLayer(PassRefPtr<LayerChromium> layer)
    468 {
    469     m_rootLayer = layer;
    470     if (m_rootLayer)
    471         m_rootLayer->setLayerRenderer(this);
    472     m_rootLayerContentTiler->invalidateEntireLayer();
    473 }
    474 
    475 void LayerRendererChromium::getFramebufferPixels(void *pixels, const IntRect& rect)
    476 {
    477     ASSERT(rect.maxX() <= m_viewportVisibleRect.width() && rect.maxY() <= m_viewportVisibleRect.height());
    478 
    479     if (!pixels)
    480         return;
    481 
    482     makeContextCurrent();
    483 
    484     GLC(m_context.get(), m_context->readPixels(rect.x(), rect.y(), rect.width(), rect.height(),
    485                                          GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels));
    486 }
    487 
    488 // FIXME: This method should eventually be replaced by a proper texture manager.
    489 unsigned LayerRendererChromium::createLayerTexture()
    490 {
    491     unsigned textureId = 0;
    492     GLC(m_context.get(), textureId = m_context->createTexture());
    493     GLC(m_context.get(), m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId));
    494     // Do basic linear filtering on resize.
    495     GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR));
    496     GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR));
    497     // NPOT textures in GL ES only work when the wrap mode is set to GraphicsContext3D::CLAMP_TO_EDGE.
    498     GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE));
    499     GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE));
    500     return textureId;
    501 }
    502 
    503 void LayerRendererChromium::deleteLayerTexture(unsigned textureId)
    504 {
    505     if (!textureId)
    506         return;
    507 
    508     GLC(m_context.get(), m_context->deleteTexture(textureId));
    509 }
    510 
    511 // Returns true if any part of the layer falls within the visibleRect
    512 bool LayerRendererChromium::isLayerVisible(LayerChromium* layer, const TransformationMatrix& matrix, const IntRect& visibleRect)
    513 {
    514     // Form the matrix used by the shader to map the corners of the layer's
    515     // bounds into clip space.
    516     TransformationMatrix renderMatrix = matrix;
    517     renderMatrix.scale3d(layer->bounds().width(), layer->bounds().height(), 1);
    518     renderMatrix = m_projectionMatrix * renderMatrix;
    519 
    520     FloatRect layerRect(-0.5, -0.5, 1, 1);
    521     FloatRect mappedRect = renderMatrix.mapRect(layerRect);
    522 
    523     // The layer is visible if it intersects any part of a rectangle whose origin
    524     // is at (-1, -1) and size is 2x2.
    525     return mappedRect.intersects(FloatRect(-1, -1, 2, 2));
    526 }
    527 
    528 // Recursively walks the layer tree starting at the given node and computes all the
    529 // necessary transformations, scissor rectangles, render surfaces, etc.
    530 void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* layer, const TransformationMatrix& parentMatrix, LayerList& renderSurfaceLayerList, LayerList& layerList)
    531 {
    532     // Make sure we have CCLayerImpls for this subtree.
    533     layer->createCCLayerImplIfNeeded();
    534     layer->setLayerRenderer(this);
    535     if (layer->maskLayer()) {
    536         layer->maskLayer()->createCCLayerImplIfNeeded();
    537         layer->maskLayer()->setLayerRenderer(this);
    538     }
    539     if (layer->replicaLayer()) {
    540         layer->replicaLayer()->createCCLayerImplIfNeeded();
    541         layer->replicaLayer()->setLayerRenderer(this);
    542     }
    543     if (layer->replicaLayer() && layer->replicaLayer()->maskLayer()) {
    544         layer->replicaLayer()->maskLayer()->createCCLayerImplIfNeeded();
    545         layer->replicaLayer()->maskLayer()->setLayerRenderer(this);
    546     }
    547 
    548     CCLayerImpl* drawLayer = layer->ccLayerImpl();
    549     // Currently we're calling pushPropertiesTo() twice - once here and once in updateCompositorResourcesRecursive().
    550     // We should only call pushPropertiesTo() in commit, but because we rely on the draw layer state to update
    551     // RenderSurfaces and we rely on RenderSurfaces being up to date in order to paint contents we have
    552     // to update the draw layers twice.
    553     // FIXME: Remove this call once layer updates no longer depend on render surfaces.
    554     layer->pushPropertiesTo(drawLayer);
    555 
    556     // Compute the new matrix transformation that will be applied to this layer and
    557     // all its sublayers. It's important to remember that the layer's position
    558     // is the position of the layer's anchor point. Also, the coordinate system used
    559     // assumes that the origin is at the lower left even though the coordinates the browser
    560     // gives us for the layers are for the upper left corner. The Y flip happens via
    561     // the orthographic projection applied at render time.
    562     // The transformation chain for the layer is (using the Matrix x Vector order):
    563     // M = M[p] * Tr[l] * M[l] * Tr[c]
    564     // Where M[p] is the parent matrix passed down to the function
    565     //       Tr[l] is the translation matrix locating the layer's anchor point
    566     //       Tr[c] is the translation offset between the anchor point and the center of the layer
    567     //       M[l] is the layer's matrix (applied at the anchor point)
    568     // This transform creates a coordinate system whose origin is the center of the layer.
    569     // Note that the final matrix used by the shader for the layer is P * M * S . This final product
    570     // is computed in drawTexturedQuad().
    571     // Where: P is the projection matrix
    572     //        M is the layer's matrix computed above
    573     //        S is the scale adjustment (to scale up to the layer size)
    574     IntSize bounds = drawLayer->bounds();
    575     FloatPoint anchorPoint = drawLayer->anchorPoint();
    576     FloatPoint position = drawLayer->position();
    577 
    578     // Offset between anchor point and the center of the quad.
    579     float centerOffsetX = (0.5 - anchorPoint.x()) * bounds.width();
    580     float centerOffsetY = (0.5 - anchorPoint.y()) * bounds.height();
    581 
    582     TransformationMatrix layerLocalTransform;
    583     // LT = Tr[l]
    584     layerLocalTransform.translate3d(position.x(), position.y(), drawLayer->anchorPointZ());
    585     // LT = Tr[l] * M[l]
    586     layerLocalTransform.multiply(drawLayer->transform());
    587     // LT = Tr[l] * M[l] * Tr[c]
    588     layerLocalTransform.translate3d(centerOffsetX, centerOffsetY, -drawLayer->anchorPointZ());
    589 
    590     TransformationMatrix combinedTransform = parentMatrix;
    591     combinedTransform = combinedTransform.multiply(layerLocalTransform);
    592 
    593     FloatRect layerRect(-0.5 * drawLayer->bounds().width(), -0.5 * drawLayer->bounds().height(), drawLayer->bounds().width(), drawLayer->bounds().height());
    594     IntRect transformedLayerRect;
    595 
    596     // The layer and its descendants render on a new RenderSurface if any of
    597     // these conditions hold:
    598     // 1. The layer clips its descendants and its transform is not a simple translation.
    599     // 2. If the layer has opacity != 1 and does not have a preserves-3d transform style.
    600     // 3. The layer uses a mask
    601     // 4. The layer has a replica (used for reflections)
    602     // If a layer preserves-3d then we don't create a RenderSurface for it to avoid flattening
    603     // out its children. The opacity value of the children layers is multiplied by the opacity
    604     // of their parent.
    605     bool useSurfaceForClipping = drawLayer->masksToBounds() && !isScaleOrTranslation(combinedTransform);
    606     bool useSurfaceForOpacity = drawLayer->opacity() != 1 && !drawLayer->preserves3D();
    607     bool useSurfaceForMasking = drawLayer->maskLayer();
    608     bool useSurfaceForReflection = drawLayer->replicaLayer();
    609     if (useSurfaceForMasking || useSurfaceForReflection || ((useSurfaceForClipping || useSurfaceForOpacity) && drawLayer->descendantsDrawsContent())) {
    610         RenderSurfaceChromium* renderSurface = drawLayer->renderSurface();
    611         if (!renderSurface)
    612             renderSurface = drawLayer->createRenderSurface();
    613 
    614         // The origin of the new surface is the upper left corner of the layer.
    615         TransformationMatrix drawTransform;
    616         drawTransform.translate3d(0.5 * bounds.width(), 0.5 * bounds.height(), 0);
    617         drawLayer->setDrawTransform(drawTransform);
    618 
    619         transformedLayerRect = IntRect(0, 0, bounds.width(), bounds.height());
    620 
    621         // Layer's opacity will be applied when drawing the render surface.
    622         renderSurface->m_drawOpacity = drawLayer->opacity();
    623         if (drawLayer->superlayer() && drawLayer->superlayer()->preserves3D())
    624             renderSurface->m_drawOpacity *= drawLayer->superlayer()->drawOpacity();
    625         drawLayer->setDrawOpacity(1);
    626 
    627         TransformationMatrix layerOriginTransform = combinedTransform;
    628         layerOriginTransform.translate3d(-0.5 * bounds.width(), -0.5 * bounds.height(), 0);
    629         renderSurface->m_originTransform = layerOriginTransform;
    630         if (layerOriginTransform.isInvertible() && drawLayer->superlayer()) {
    631             TransformationMatrix parentToLayer = layerOriginTransform.inverse();
    632 
    633             drawLayer->setScissorRect(parentToLayer.mapRect(drawLayer->superlayer()->scissorRect()));
    634         } else
    635             drawLayer->setScissorRect(IntRect());
    636 
    637         // The render surface scissor rect is the scissor rect that needs to
    638         // be applied before drawing the render surface onto its containing
    639         // surface and is therefore expressed in the superlayer's coordinate system.
    640         renderSurface->m_scissorRect = drawLayer->superlayer() ? drawLayer->superlayer()->scissorRect() : drawLayer->scissorRect();
    641 
    642         renderSurface->m_layerList.clear();
    643 
    644         if (drawLayer->maskLayer()) {
    645             renderSurface->m_maskLayer = drawLayer->maskLayer();
    646             drawLayer->maskLayer()->setTargetRenderSurface(renderSurface);
    647         } else
    648             renderSurface->m_maskLayer = 0;
    649 
    650         if (drawLayer->replicaLayer() && drawLayer->replicaLayer()->maskLayer())
    651             drawLayer->replicaLayer()->maskLayer()->setTargetRenderSurface(renderSurface);
    652 
    653         renderSurfaceLayerList.append(drawLayer);
    654     } else {
    655         // DT = M[p] * LT
    656         drawLayer->setDrawTransform(combinedTransform);
    657         transformedLayerRect = enclosingIntRect(drawLayer->drawTransform().mapRect(layerRect));
    658 
    659         drawLayer->setDrawOpacity(drawLayer->opacity());
    660 
    661         if (drawLayer->superlayer()) {
    662             if (drawLayer->superlayer()->preserves3D())
    663                drawLayer->setDrawOpacity(drawLayer->drawOpacity() * drawLayer->superlayer()->drawOpacity());
    664 
    665             // Layers inherit the scissor rect from their superlayer.
    666             drawLayer->setScissorRect(drawLayer->superlayer()->scissorRect());
    667 
    668             drawLayer->setTargetRenderSurface(drawLayer->superlayer()->targetRenderSurface());
    669         }
    670 
    671         if (layer != m_rootLayer)
    672             drawLayer->clearRenderSurface();
    673 
    674         if (drawLayer->masksToBounds()) {
    675             IntRect scissor = drawLayer->scissorRect();
    676             scissor.intersect(transformedLayerRect);
    677             drawLayer->setScissorRect(scissor);
    678         }
    679     }
    680 
    681     if (drawLayer->renderSurface())
    682         drawLayer->setTargetRenderSurface(drawLayer->renderSurface());
    683     else {
    684         ASSERT(drawLayer->superlayer());
    685         drawLayer->setTargetRenderSurface(drawLayer->superlayer()->targetRenderSurface());
    686     }
    687 
    688     // drawableContentRect() is always stored in the coordinate system of the
    689     // RenderSurface the layer draws into.
    690     if (drawLayer->drawsContent())
    691         drawLayer->setDrawableContentRect(transformedLayerRect);
    692     else
    693         drawLayer->setDrawableContentRect(IntRect());
    694 
    695     TransformationMatrix sublayerMatrix = drawLayer->drawTransform();
    696 
    697     // Flatten to 2D if the layer doesn't preserve 3D.
    698     if (!drawLayer->preserves3D()) {
    699         sublayerMatrix.setM13(0);
    700         sublayerMatrix.setM23(0);
    701         sublayerMatrix.setM31(0);
    702         sublayerMatrix.setM32(0);
    703         sublayerMatrix.setM33(1);
    704         sublayerMatrix.setM34(0);
    705         sublayerMatrix.setM43(0);
    706     }
    707 
    708     // Apply the sublayer transform at the center of the layer.
    709     sublayerMatrix.multiply(drawLayer->sublayerTransform());
    710 
    711     // The origin of the sublayers is the top left corner of the layer, not the
    712     // center. The matrix passed down to the sublayers is therefore:
    713     // M[s] = M * Tr[-center]
    714     sublayerMatrix.translate3d(-bounds.width() * 0.5, -bounds.height() * 0.5, 0);
    715 
    716     // Compute the depth value of the center of the layer which will be used when
    717     // sorting the layers for the preserves-3d property.
    718     const TransformationMatrix& layerDrawMatrix = drawLayer->renderSurface() ? drawLayer->renderSurface()->m_drawTransform : drawLayer->drawTransform();
    719     if (drawLayer->superlayer()) {
    720         if (!drawLayer->superlayer()->preserves3D())
    721             drawLayer->setDrawDepth(drawLayer->superlayer()->drawDepth());
    722         else
    723             drawLayer->setDrawDepth(layerDrawMatrix.m43());
    724     } else
    725         drawLayer->setDrawDepth(0);
    726 
    727     LayerList& descendants = (drawLayer->renderSurface() ? drawLayer->renderSurface()->m_layerList : layerList);
    728     descendants.append(drawLayer);
    729     unsigned thisLayerIndex = descendants.size() - 1;
    730 
    731     const Vector<RefPtr<LayerChromium> >& sublayers = layer->getSublayers();
    732     for (size_t i = 0; i < sublayers.size(); ++i) {
    733         sublayers[i]->createCCLayerImplIfNeeded();
    734         CCLayerImpl* sublayer = sublayers[i]->ccLayerImpl();
    735         updatePropertiesAndRenderSurfaces(sublayers[i].get(), sublayerMatrix, renderSurfaceLayerList, descendants);
    736 
    737         if (sublayer->renderSurface()) {
    738             RenderSurfaceChromium* sublayerRenderSurface = sublayer->renderSurface();
    739             IntRect drawableContentRect = drawLayer->drawableContentRect();
    740             drawableContentRect.unite(enclosingIntRect(sublayerRenderSurface->drawableContentRect()));
    741             drawLayer->setDrawableContentRect(drawableContentRect);
    742             descendants.append(sublayer);
    743         } else {
    744             IntRect drawableContentRect = drawLayer->drawableContentRect();
    745             drawableContentRect.unite(sublayer->drawableContentRect());
    746             drawLayer->setDrawableContentRect(drawableContentRect);
    747         }
    748     }
    749 
    750     if (drawLayer->masksToBounds() || useSurfaceForMasking) {
    751         IntRect drawableContentRect = drawLayer->drawableContentRect();
    752         drawableContentRect.intersect(transformedLayerRect);
    753         drawLayer->setDrawableContentRect(drawableContentRect);
    754     }
    755 
    756     if (drawLayer->renderSurface() && layer != m_rootLayer) {
    757         RenderSurfaceChromium* renderSurface = drawLayer->renderSurface();
    758         renderSurface->m_contentRect = drawLayer->drawableContentRect();
    759         FloatPoint surfaceCenter = renderSurface->contentRectCenter();
    760 
    761         // Restrict the RenderSurface size to the portion that's visible.
    762         FloatSize centerOffsetDueToClipping;
    763 
    764         // Don't clip if the layer is reflected as the reflection shouldn't be
    765         // clipped.
    766         if (!drawLayer->replicaLayer()) {
    767             renderSurface->m_contentRect.intersect(drawLayer->scissorRect());
    768             FloatPoint clippedSurfaceCenter = renderSurface->contentRectCenter();
    769             centerOffsetDueToClipping = clippedSurfaceCenter - surfaceCenter;
    770         }
    771 
    772         // The RenderSurface backing texture cannot exceed the maximum supported
    773         // texture size.
    774         renderSurface->m_contentRect.setWidth(std::min(renderSurface->m_contentRect.width(), m_maxTextureSize));
    775         renderSurface->m_contentRect.setHeight(std::min(renderSurface->m_contentRect.height(), m_maxTextureSize));
    776 
    777         if (renderSurface->m_contentRect.isEmpty())
    778             renderSurface->m_layerList.clear();
    779 
    780         // Since the layer starts a new render surface we need to adjust its
    781         // scissor rect to be expressed in the new surface's coordinate system.
    782         drawLayer->setScissorRect(drawLayer->drawableContentRect());
    783 
    784         // Adjust the origin of the transform to be the center of the render surface.
    785         renderSurface->m_drawTransform = renderSurface->m_originTransform;
    786         renderSurface->m_drawTransform.translate3d(surfaceCenter.x() + centerOffsetDueToClipping.width(), surfaceCenter.y() + centerOffsetDueToClipping.height(), 0);
    787 
    788         // Compute the transformation matrix used to draw the replica of the render
    789         // surface.
    790         if (drawLayer->replicaLayer()) {
    791             renderSurface->m_replicaDrawTransform = renderSurface->m_originTransform;
    792             renderSurface->m_replicaDrawTransform.translate3d(drawLayer->replicaLayer()->position().x(), drawLayer->replicaLayer()->position().y(), 0);
    793             renderSurface->m_replicaDrawTransform.multiply(drawLayer->replicaLayer()->transform());
    794             renderSurface->m_replicaDrawTransform.translate3d(surfaceCenter.x() - anchorPoint.x() * bounds.width(), surfaceCenter.y() - anchorPoint.y() * bounds.height(), 0);
    795         }
    796     }
    797 
    798     // If preserves-3d then sort all the descendants by the Z coordinate of their
    799     // center. If the preserves-3d property is also set on the superlayer then
    800     // skip the sorting as the superlayer will sort all the descendants anyway.
    801     if (drawLayer->preserves3D() && (!drawLayer->superlayer() || !drawLayer->superlayer()->preserves3D()))
    802         std::stable_sort(&descendants.at(thisLayerIndex), descendants.end(), compareLayerZ);
    803 }
    804 
    805 void LayerRendererChromium::updateCompositorResourcesRecursive(LayerChromium* layer)
    806 {
    807     const Vector<RefPtr<LayerChromium> >& sublayers = layer->getSublayers();
    808     for (size_t i = 0; i < sublayers.size(); ++i)
    809         updateCompositorResourcesRecursive(sublayers[i].get());
    810 
    811     if (layer->bounds().isEmpty())
    812         return;
    813 
    814     CCLayerImpl* drawLayer = layer->ccLayerImpl();
    815 
    816     if (drawLayer->drawsContent())
    817         drawLayer->updateCompositorResources();
    818     if (drawLayer->maskLayer() && drawLayer->maskLayer()->drawsContent())
    819         drawLayer->maskLayer()->updateCompositorResources();
    820     if (drawLayer->replicaLayer() && drawLayer->replicaLayer()->drawsContent())
    821         drawLayer->replicaLayer()->updateCompositorResources();
    822     if (drawLayer->replicaLayer() && drawLayer->replicaLayer()->maskLayer() && drawLayer->replicaLayer()->maskLayer()->drawsContent())
    823         drawLayer->replicaLayer()->maskLayer()->updateCompositorResources();
    824 
    825     layer->pushPropertiesTo(drawLayer);
    826 }
    827 
    828 void LayerRendererChromium::setCompositeOffscreen(bool compositeOffscreen)
    829 {
    830     if (m_compositeOffscreen == compositeOffscreen)
    831        return;
    832 
    833     m_compositeOffscreen = compositeOffscreen;
    834 
    835     if (!m_compositeOffscreen && m_rootLayer)
    836         m_rootLayer->ccLayerImpl()->clearRenderSurface();
    837 }
    838 
    839 LayerTexture* LayerRendererChromium::getOffscreenLayerTexture()
    840 {
    841     return m_compositeOffscreen ? m_rootLayer->ccLayerImpl()->renderSurface()->m_contentsTexture.get() : 0;
    842 }
    843 
    844 void LayerRendererChromium::copyOffscreenTextureToDisplay()
    845 {
    846     if (m_compositeOffscreen) {
    847         makeContextCurrent();
    848 
    849         useRenderSurface(0);
    850         m_defaultRenderSurface->m_drawTransform.makeIdentity();
    851         m_defaultRenderSurface->m_drawTransform.translate3d(0.5 * m_defaultRenderSurface->m_contentRect.width(),
    852                                                             0.5 * m_defaultRenderSurface->m_contentRect.height(), 0);
    853         m_defaultRenderSurface->m_drawOpacity = 1;
    854         m_defaultRenderSurface->draw(m_defaultRenderSurface->m_contentRect);
    855     }
    856 }
    857 
    858 bool LayerRendererChromium::useRenderSurface(RenderSurfaceChromium* renderSurface)
    859 {
    860     if (m_currentRenderSurface == renderSurface)
    861         return true;
    862 
    863     m_currentRenderSurface = renderSurface;
    864 
    865     if ((renderSurface == m_defaultRenderSurface && !m_compositeOffscreen) || (!renderSurface && m_compositeOffscreen)) {
    866         GLC(m_context.get(), m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0));
    867         if (renderSurface)
    868             setDrawViewportRect(renderSurface->m_contentRect, true);
    869         else
    870             setDrawViewportRect(m_defaultRenderSurface->m_contentRect, true);
    871         return true;
    872     }
    873 
    874     GLC(m_context.get(), m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_offscreenFramebufferId));
    875 
    876     if (!renderSurface->prepareContentsTexture())
    877         return false;
    878 
    879     renderSurface->m_contentsTexture->framebufferTexture2D();
    880 
    881 #if !defined ( NDEBUG )
    882     if (m_context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
    883         ASSERT_NOT_REACHED();
    884         return false;
    885     }
    886 #endif
    887 
    888     setDrawViewportRect(renderSurface->m_contentRect, false);
    889     return true;
    890 }
    891 
    892 void LayerRendererChromium::drawLayer(CCLayerImpl* layer, RenderSurfaceChromium* targetSurface)
    893 {
    894     if (layer->renderSurface() && layer->renderSurface() != targetSurface) {
    895         layer->renderSurface()->draw(layer->getDrawRect());
    896         return;
    897     }
    898 
    899     if (!layer->drawsContent())
    900         return;
    901 
    902     if (layer->bounds().isEmpty()) {
    903         layer->unreserveContentsTexture();
    904         return;
    905     }
    906 
    907     setScissorToRect(layer->scissorRect());
    908 
    909     // Check if the layer falls within the visible bounds of the page.
    910     IntRect layerRect = layer->getDrawRect();
    911     bool isLayerVisible = layer->scissorRect().intersects(layerRect);
    912     if (!isLayerVisible) {
    913         layer->unreserveContentsTexture();
    914         return;
    915     }
    916 
    917     // FIXME: Need to take into account the commulative render surface transforms all the way from
    918     //        the default render surface in order to determine visibility.
    919     TransformationMatrix combinedDrawMatrix = (layer->targetRenderSurface() ? layer->targetRenderSurface()->drawTransform().multiply(layer->drawTransform()) : layer->drawTransform());
    920 
    921     if (!layer->doubleSided()) {
    922         FloatRect layerRect(FloatPoint(0, 0), FloatSize(layer->bounds()));
    923         FloatQuad mappedLayer = combinedDrawMatrix.mapQuad(FloatQuad(layerRect));
    924         FloatSize horizontalDir = mappedLayer.p2() - mappedLayer.p1();
    925         FloatSize verticalDir = mappedLayer.p4() - mappedLayer.p1();
    926         FloatPoint3D xAxis(horizontalDir.width(), horizontalDir.height(), 0);
    927         FloatPoint3D yAxis(verticalDir.width(), verticalDir.height(), 0);
    928         FloatPoint3D zAxis = xAxis.cross(yAxis);
    929         if (zAxis.z() < 0) {
    930             layer->unreserveContentsTexture();
    931             return;
    932         }
    933     }
    934 
    935     layer->draw(layer->scissorRect());
    936 
    937     // Draw the debug border if there is one.
    938     layer->drawDebugBorder();
    939 }
    940 
    941 // Sets the scissor region to the given rectangle. The coordinate system for the
    942 // scissorRect has its origin at the top left corner of the current visible rect.
    943 void LayerRendererChromium::setScissorToRect(const IntRect& scissorRect)
    944 {
    945     IntRect contentRect = (m_currentRenderSurface ? m_currentRenderSurface->m_contentRect : m_defaultRenderSurface->m_contentRect);
    946 
    947     // The scissor coordinates must be supplied in viewport space so we need to offset
    948     // by the relative position of the top left corner of the current render surface.
    949     int scissorX = scissorRect.x() - contentRect.x();
    950     // When rendering to the default render surface we're rendering upside down so the top
    951     // of the GL scissor is the bottom of our layer.
    952     // But, if rendering to offscreen texture, we reverse our sense of 'upside down'.
    953     int scissorY;
    954     if (m_currentRenderSurface == m_defaultRenderSurface && !m_compositeOffscreen)
    955         scissorY = m_currentRenderSurface->m_contentRect.height() - (scissorRect.maxY() - m_currentRenderSurface->m_contentRect.y());
    956     else
    957         scissorY = scissorRect.y() - contentRect.y();
    958     GLC(m_context.get(), m_context->scissor(scissorX, scissorY, scissorRect.width(), scissorRect.height()));
    959 }
    960 
    961 bool LayerRendererChromium::makeContextCurrent()
    962 {
    963     m_context->makeContextCurrent();
    964     return true;
    965 }
    966 
    967 // Checks whether a given size is within the maximum allowed texture size range.
    968 bool LayerRendererChromium::checkTextureSize(const IntSize& textureSize)
    969 {
    970     if (textureSize.width() > m_maxTextureSize || textureSize.height() > m_maxTextureSize)
    971         return false;
    972     return true;
    973 }
    974 
    975 // Sets the coordinate range of content that ends being drawn onto the target render surface.
    976 // The target render surface is assumed to have an origin at 0, 0 and the width and height of
    977 // of the drawRect.
    978 void LayerRendererChromium::setDrawViewportRect(const IntRect& drawRect, bool flipY)
    979 {
    980     if (flipY)
    981         m_projectionMatrix = orthoMatrix(drawRect.x(), drawRect.maxX(), drawRect.maxY(), drawRect.y());
    982     else
    983         m_projectionMatrix = orthoMatrix(drawRect.x(), drawRect.maxX(), drawRect.y(), drawRect.maxY());
    984     GLC(m_context.get(), m_context->viewport(0, 0, drawRect.width(), drawRect.height()));
    985 }
    986 
    987 
    988 
    989 void LayerRendererChromium::resizeOnscreenContent(const IntSize& size)
    990 {
    991     if (m_context)
    992         m_context->reshape(size.width(), size.height());
    993 }
    994 
    995 bool LayerRendererChromium::initializeSharedObjects()
    996 {
    997     makeContextCurrent();
    998 
    999     // Get the max texture size supported by the system.
   1000     m_maxTextureSize = 0;
   1001     GLC(m_context.get(), m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &m_maxTextureSize));
   1002 
   1003     // Create an FBO for doing offscreen rendering.
   1004     GLC(m_context.get(), m_offscreenFramebufferId = m_context->createFramebuffer());
   1005 
   1006     m_sharedGeometry = adoptPtr(new GeometryBinding(m_context.get()));
   1007     m_borderProgram = adoptPtr(new LayerChromium::BorderProgram(m_context.get()));
   1008     m_headsUpDisplayProgram = adoptPtr(new CCHeadsUpDisplay::Program(m_context.get()));
   1009     m_canvasLayerProgram = adoptPtr(new CCCanvasLayerImpl::Program(m_context.get()));
   1010     m_videoLayerRGBAProgram = adoptPtr(new CCVideoLayerImpl::RGBAProgram(m_context.get()));
   1011     m_videoLayerYUVProgram = adoptPtr(new CCVideoLayerImpl::YUVProgram(m_context.get()));
   1012     m_pluginLayerProgram = adoptPtr(new CCPluginLayerImpl::Program(m_context.get()));
   1013     m_renderSurfaceProgram = adoptPtr(new RenderSurfaceChromium::Program(m_context.get()));
   1014     m_renderSurfaceMaskProgram = adoptPtr(new RenderSurfaceChromium::MaskProgram(m_context.get()));
   1015     m_tilerProgram = adoptPtr(new LayerTilerChromium::Program(m_context.get()));
   1016 
   1017     if (!m_sharedGeometry->initialized() || !m_borderProgram->initialized()
   1018         || !m_canvasLayerProgram->initialized()
   1019         || !m_headsUpDisplayProgram->initialized()
   1020         || !m_videoLayerRGBAProgram->initialized() || !m_videoLayerYUVProgram->initialized()
   1021         || !m_pluginLayerProgram->initialized() || !m_renderSurfaceProgram->initialized()
   1022         || !m_renderSurfaceMaskProgram->initialized() || !m_tilerProgram->initialized()) {
   1023         LOG_ERROR("Compositor failed to initialize shaders. Falling back to software.");
   1024         cleanupSharedObjects();
   1025         return false;
   1026     }
   1027 
   1028     m_textureManager = TextureManager::create(m_context.get(), textureMemoryLimitBytes, m_maxTextureSize);
   1029     return true;
   1030 }
   1031 
   1032 void LayerRendererChromium::cleanupSharedObjects()
   1033 {
   1034     makeContextCurrent();
   1035 
   1036     m_sharedGeometry.clear();
   1037     m_borderProgram.clear();
   1038     m_canvasLayerProgram.clear();
   1039     m_headsUpDisplayProgram.clear();
   1040     m_videoLayerRGBAProgram.clear();
   1041     m_videoLayerYUVProgram.clear();
   1042     m_pluginLayerProgram.clear();
   1043     m_renderSurfaceProgram.clear();
   1044     m_renderSurfaceMaskProgram.clear();
   1045     m_tilerProgram.clear();
   1046     if (m_offscreenFramebufferId)
   1047         GLC(m_context.get(), m_context->deleteFramebuffer(m_offscreenFramebufferId));
   1048 
   1049     // Clear tilers before the texture manager, as they have references to textures.
   1050     m_rootLayerContentTiler.clear();
   1051 
   1052     m_textureManager.clear();
   1053 }
   1054 
   1055 String LayerRendererChromium::layerTreeAsText() const
   1056 {
   1057     TextStream ts;
   1058     if (m_rootLayer.get()) {
   1059         ts << m_rootLayer->layerTreeAsText();
   1060         ts << "RenderSurfaces:\n";
   1061         dumpRenderSurfaces(ts, 1, m_rootLayer.get());
   1062     }
   1063     return ts.release();
   1064 }
   1065 
   1066 void LayerRendererChromium::addChildContext(GraphicsContext3D* ctx)
   1067 {
   1068     if (!ctx->getExtensions()->supports("GL_CHROMIUM_latch"))
   1069         return;
   1070 
   1071     // This is a ref-counting map, because some contexts are shared by multiple
   1072     // layers (specifically, Canvas2DLayerChromium).
   1073 
   1074     // Insert the ctx with a count of 1, or return the existing iterator.
   1075     std::pair<ChildContextMap::iterator, bool> insert_result = m_childContexts.add(ctx, 1);
   1076     if (!insert_result.second) {
   1077         // Already present in map, so increment.
   1078         ++insert_result.first->second;
   1079     } else {
   1080 // FIXME(jbates): when compositor is multithreaded and copyTexImage2D bug is fixed,
   1081 // uncomment this block:
   1082 //      // This is a new child context - set the parentToChild latch so that it
   1083 //      // can continue past its first wait latch.
   1084 //      Extensions3DChromium* ext = static_cast<Extensions3DChromium*>(ctx->getExtensions());
   1085 //      GC3Duint latchId;
   1086 //      ext->getParentToChildLatchCHROMIUM(&latchId);
   1087 //      ext->setLatchCHROMIUM(0, latchId);
   1088     }
   1089 }
   1090 
   1091 void LayerRendererChromium::removeChildContext(GraphicsContext3D* ctx)
   1092 {
   1093     if (!ctx->getExtensions()->supports("GL_CHROMIUM_latch"))
   1094         return;
   1095 
   1096     ChildContextMap::iterator i = m_childContexts.find(ctx);
   1097     if (i != m_childContexts.end()) {
   1098         if (--i->second <= 0) {
   1099             // Count reached zero, so remove from map.
   1100             m_childContexts.remove(i);
   1101         }
   1102     } else {
   1103         // error
   1104         ASSERT(0 && "m_childContexts map has mismatched add/remove calls");
   1105     }
   1106 }
   1107 
   1108 void LayerRendererChromium::dumpRenderSurfaces(TextStream& ts, int indent, LayerChromium* layer) const
   1109 {
   1110     if (layer->ccLayerImpl()->renderSurface())
   1111         layer->ccLayerImpl()->renderSurface()->dumpSurface(ts, indent);
   1112 
   1113     for (size_t i = 0; i < layer->getSublayers().size(); ++i)
   1114         dumpRenderSurfaces(ts, indent, layer->getSublayers()[i].get());
   1115 }
   1116 
   1117 } // namespace WebCore
   1118 
   1119 #endif // USE(ACCELERATED_COMPOSITING)
   1120