Changeset 92037 in webkit


Ignore:
Timestamp:
Jul 29, 2011 6:26:02 PM (13 years ago)
Author:
jamesr@google.com
Message:

[chromium] Reorder functions in LayerRendererChromium.cpp to make bug 58840 easier to review
https://bugs.webkit.org/show_bug.cgi?id=65354

Reviewed by Kenneth Russell.

This moves a few function definitions in LayerRendererChromium around to make the patch on bug 58840 easier to
review. In that patch, updatePropertiesAndRenderSurfaces() becomes a templated free function instead of a
member function, so it has to be near the top of the .cpp.

  • platform/graphics/chromium/LayerRendererChromium.cpp:

(WebCore::calculateVisibleRect):
(WebCore::isScaleOrTranslation):
(WebCore::LayerRendererChromium::updatePropertiesAndRenderSurfaces):
(WebCore::LayerRendererChromium::updateLayers):

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r92035 r92037  
     12011-07-29  James Robinson  <jamesr@chromium.org>
     2
     3        [chromium] Reorder functions in LayerRendererChromium.cpp to make bug 58840 easier to review
     4        https://bugs.webkit.org/show_bug.cgi?id=65354
     5
     6        Reviewed by Kenneth Russell.
     7
     8        This moves a few function definitions in LayerRendererChromium around to make the patch on bug 58840 easier to
     9        review.  In that patch, updatePropertiesAndRenderSurfaces() becomes a templated free function instead of a
     10        member function, so it has to be near the top of the .cpp.
     11
     12        * platform/graphics/chromium/LayerRendererChromium.cpp:
     13        (WebCore::calculateVisibleRect):
     14        (WebCore::isScaleOrTranslation):
     15        (WebCore::LayerRendererChromium::updatePropertiesAndRenderSurfaces):
     16        (WebCore::LayerRendererChromium::updateLayers):
     17
    1182011-07-29  Jeff Miller  <jeffm@apple.com>
    219
  • trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp

    r91821 r92037  
    7878#endif
    7979
    80 static TransformationMatrix orthoMatrix(float left, float right, float bottom, float top)
    81 {
    82     float deltaX = right - left;
    83     float deltaY = top - bottom;
    84     TransformationMatrix ortho;
    85     if (!deltaX || !deltaY)
    86         return ortho;
    87     ortho.setM11(2.0f / deltaX);
    88     ortho.setM41(-(right + left) / deltaX);
    89     ortho.setM22(2.0f / deltaY);
    90     ortho.setM42(-(top + bottom) / deltaY);
    91 
    92     // Z component of vertices is always set to zero as we don't use the depth buffer
    93     // while drawing.
    94     ortho.setM33(0);
    95 
    96     return ortho;
    97 }
    98 
    99 // Returns true if the matrix has no rotation, skew or perspective components to it.
    100 static bool isScaleOrTranslation(const TransformationMatrix& m)
    101 {
    102     return !m.m12() && !m.m13() && !m.m14()
    103            && !m.m21() && !m.m23() && !m.m24()
    104            && !m.m31() && !m.m32() && !m.m43()
    105            && m.m44();
    106 
    107 }
    108 
    109 PassRefPtr<LayerRendererChromium> LayerRendererChromium::create(CCLayerTreeHostClient* client, PassOwnPtr<LayerPainterChromium> contentPaint, bool accelerateDrawing)
    110 {
    111     RefPtr<GraphicsContext3D> context = client->createLayerTreeHostContext3D();
    112     if (!context)
    113         return 0;
    114 
    115     RefPtr<LayerRendererChromium> layerRenderer(adoptRef(new LayerRendererChromium(client, context, contentPaint, accelerateDrawing)));
    116     layerRenderer->init();
    117     if (!layerRenderer->hardwareCompositing())
    118         return 0;
    119 
    120     return layerRenderer.release();
    121 }
    122 
    123 LayerRendererChromium::LayerRendererChromium(CCLayerTreeHostClient* client,
    124                                              PassRefPtr<GraphicsContext3D> context,
    125                                              PassOwnPtr<LayerPainterChromium> contentPaint,
    126                                              bool accelerateDrawing)
    127     : CCLayerTreeHost(client)
    128     , m_viewportScrollPosition(IntPoint(-1, -1))
    129     , m_rootLayer(0)
    130     , m_accelerateDrawing(false)
    131     , m_currentRenderSurface(0)
    132     , m_offscreenFramebufferId(0)
    133     , m_compositeOffscreen(false)
    134     , m_context(context)
    135     , m_contextSupportsTextureFormatBGRA(false)
    136     , m_contextSupportsReadFormatBGRA(false)
    137     , m_animating(false)
    138     , m_defaultRenderSurface(0)
    139 {
    140     WebCore::Extensions3D* extensions = m_context->getExtensions();
    141     m_contextSupportsMapSub = extensions->supports("GL_CHROMIUM_map_sub");
    142     if (m_contextSupportsMapSub)
    143         extensions->ensureEnabled("GL_CHROMIUM_map_sub");
    144     m_contextSupportsTextureFormatBGRA = extensions->supports("GL_EXT_texture_format_BGRA8888");
    145     if (m_contextSupportsTextureFormatBGRA)
    146         extensions->ensureEnabled("GL_EXT_texture_format_BGRA8888");
    147     m_contextSupportsReadFormatBGRA = extensions->supports("GL_EXT_read_format_bgra");
    148     if (m_contextSupportsReadFormatBGRA)
    149         extensions->ensureEnabled("GL_EXT_read_format_bgra");
    150 
    151 #if USE(SKIA)
    152     m_accelerateDrawing = accelerateDrawing && skiaContext();
    153 #endif
    154     m_hardwareCompositing = initializeSharedObjects();
    155 
    156 #if USE(SKIA)
    157     if (m_accelerateDrawing)
    158         m_rootLayerTextureUpdater = LayerTextureUpdaterSkPicture::create(m_context.get(), contentPaint, skiaContext());
    159     else
    160 #endif
    161         m_rootLayerTextureUpdater = LayerTextureUpdaterBitmap::create(m_context.get(), contentPaint, m_contextSupportsMapSub);
    162 
    163     m_rootLayerContentTiler = LayerTilerChromium::create(this, IntSize(256, 256), LayerTilerChromium::NoBorderTexels);
    164     ASSERT(m_rootLayerContentTiler);
    165 
    166     m_headsUpDisplay = CCHeadsUpDisplay::create(this);
    167 }
    168 
    169 LayerRendererChromium::~LayerRendererChromium()
    170 {
    171     m_headsUpDisplay.clear(); // Explicitly destroy the HUD before the TextureManager dies.
    172     cleanupSharedObjects();
    173 }
    174 
    175 GraphicsContext3D* LayerRendererChromium::context()
    176 {
    177     return m_context.get();
    178 }
    179 
    180 #if USE(SKIA)
    181 GrContext* LayerRendererChromium::skiaContext()
    182 {
    183     if (!m_skiaContext && m_contextSupportsTextureFormatBGRA && m_contextSupportsReadFormatBGRA) {
    184         m_context->makeContextCurrent();
    185         m_skiaContext = adoptPtr(GrContext::CreateGLShaderContext());
    186         // Limit the number of textures we hold in the bitmap->texture cache.
    187         static const int maxTextureCacheCount = 512;
    188         // Limit the bytes allocated toward textures in the bitmap->texture cache.
    189         static const size_t maxTextureCacheBytes = 50 * 1024 * 1024;
    190         m_skiaContext->setTextureCacheLimits(maxTextureCacheCount, maxTextureCacheBytes);
    191     }
    192     return m_skiaContext.get();
    193 }
    194 #endif
    195 
    196 void LayerRendererChromium::debugGLCall(GraphicsContext3D* context, const char* command, const char* file, int line)
    197 {
    198     unsigned long error = context->getError();
    199     if (error != GraphicsContext3D::NO_ERROR)
    200         LOG_ERROR("GL command failed: File: %s\n\tLine %d\n\tcommand: %s, error %x\n", file, line, command, static_cast<int>(error));
    201 }
    202 
    203 void LayerRendererChromium::invalidateRootLayerRect(const IntRect& dirtyRect)
    204 {
    205     m_rootLayerContentTiler->invalidateRect(dirtyRect);
    206 }
    207 
    208 void LayerRendererChromium::releaseTextures()
    209 {
    210     // Reduces texture memory usage to textureMemoryLowLimitBytes by deleting non root layer
    211     // textures.
    212     m_rootLayerContentTiler->protectTileTextures(m_viewportVisibleRect);
    213     m_contentsTextureManager->reduceMemoryToLimit(textureMemoryLowLimitBytes);
    214     m_contentsTextureManager->unprotectAllTextures();
    215     // Evict all RenderSurface textures.
    216     m_renderSurfaceTextureManager->unprotectAllTextures();
    217     m_renderSurfaceTextureManager->reduceMemoryToLimit(0);
    218 }
    219 
    220 void LayerRendererChromium::updateRootLayerContents()
    221 {
    222     TRACE_EVENT("LayerRendererChromium::updateRootLayerContents", this, 0);
    223     m_rootLayerContentTiler->prepareToUpdate(m_viewportVisibleRect, m_rootLayerTextureUpdater.get());
    224 }
    225 
    226 void LayerRendererChromium::drawRootLayer()
    227 {
    228     TransformationMatrix scroll;
    229     scroll.translate(-m_viewportVisibleRect.x(), -m_viewportVisibleRect.y());
    230 
    231     m_rootLayerContentTiler->draw(m_viewportVisibleRect, scroll, 1.0f);
    232 }
    233 
    234 void LayerRendererChromium::setViewport(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition)
    235 {
    236     bool visibleRectChanged = m_viewportVisibleRect.size() != visibleRect.size();
    237 
    238     m_viewportVisibleRect = visibleRect;
    239     m_viewportContentRect = contentRect;
    240     m_viewportScrollPosition = scrollPosition;
    241 
    242     if (visibleRectChanged) {
    243         // Reset the current render surface to force an update of the viewport and
    244         // projection matrix next time useRenderSurface is called.
    245         m_currentRenderSurface = 0;
    246         m_rootLayerContentTiler->invalidateEntireLayer();
    247     }
    248     setNeedsCommitAndRedraw();
    249 }
    250 
    251 void LayerRendererChromium::updateLayers()
    252 {
    253     if (m_viewportVisibleRect.isEmpty())
    254         return;
    255 
    256     // FIXME: use the frame begin time from the overall compositor scheduler.
    257     // This value is currently inaccessible because it is up in Chromium's
    258     // RenderWidget.
    259     m_headsUpDisplay->onFrameBegin(currentTime());
    260     ASSERT(m_hardwareCompositing);
    261 
    262     if (!m_rootLayer)
    263         return;
    264 
    265     updateRootLayerContents();
    266 
    267     // Recheck that we still have a root layer. This may become null if
    268     // compositing gets turned off during a paint operation.
    269     if (!m_rootLayer)
    270         return;
    271 
    272     {
    273         TRACE_EVENT("LayerRendererChromium::synchronizeTrees", this, 0);
    274         m_rootCCLayerImpl = TreeSynchronizer::synchronizeTrees(m_rootLayer.get(), m_rootCCLayerImpl.get());
    275     }
    276 
    277     m_computedRenderSurfaceLayerList = adoptPtr(new LayerList());
    278     updateLayers(*m_computedRenderSurfaceLayerList);
    279 }
    280 
    281 void LayerRendererChromium::drawLayers()
    282 {
    283     ASSERT(m_hardwareCompositing);
    284     ASSERT(m_computedRenderSurfaceLayerList);
    285     // Before drawLayers:
    286     if (hardwareCompositing()) {
    287         // FIXME: The multithreaded compositor case will not work as long as
    288         // copyTexImage2D resolves to the parent texture, because the main
    289         // thread can execute WebGL calls on the child context at any time,
    290         // potentially clobbering the parent texture that is being renderered
    291         // by the compositor thread.
    292         ChildContextMap::iterator i = m_childContexts.begin();
    293         for (; i != m_childContexts.end(); ++i) {
    294             i->first->flush();
    295         }
    296     }
    297 
    298     m_renderSurfaceTextureManager->setMemoryLimitBytes(textureMemoryHighLimitBytes - m_contentsTextureManager->currentMemoryUseBytes());
    299     drawLayers(*m_computedRenderSurfaceLayerList);
    300 
    301     m_contentsTextureManager->unprotectAllTextures();
    302     m_contentsTextureManager->reduceMemoryToLimit(textureMemoryReclaimLimitBytes);
    303 
    304     if (textureMemoryReclaimLimitBytes > m_contentsTextureManager->currentMemoryUseBytes())
    305         m_renderSurfaceTextureManager->reduceMemoryToLimit(textureMemoryReclaimLimitBytes - m_contentsTextureManager->currentMemoryUseBytes());
    306     else
    307         m_renderSurfaceTextureManager->reduceMemoryToLimit(0);
    308 
    309     if (isCompositingOffscreen())
    310         copyOffscreenTextureToDisplay();
    311 }
    312 
    313 void LayerRendererChromium::updateLayers(LayerList& renderSurfaceLayerList)
    314 {
    315     TRACE_EVENT("LayerRendererChromium::updateLayers", this, 0);
    316     CCLayerImpl* rootDrawLayer = m_rootLayer->ccLayerImpl();
    317 
    318     if (!rootDrawLayer->renderSurface())
    319         rootDrawLayer->createRenderSurface();
    320     ASSERT(rootDrawLayer->renderSurface());
    321 
    322     rootDrawLayer->renderSurface()->setContentRect(IntRect(IntPoint(0, 0), m_viewportVisibleRect.size()));
    323 
    324     IntRect rootScissorRect(m_viewportVisibleRect);
    325     // The scissorRect should not include the scroll offset.
    326     rootScissorRect.move(-m_viewportScrollPosition.x(), -m_viewportScrollPosition.y());
    327     rootDrawLayer->setScissorRect(rootScissorRect);
    328 
    329     m_defaultRenderSurface = rootDrawLayer->renderSurface();
    330 
    331     renderSurfaceLayerList.append(rootDrawLayer);
    332 
    333     TransformationMatrix identityMatrix;
    334     m_defaultRenderSurface->clearLayerList();
    335     // Unfortunately, updatePropertiesAndRenderSurfaces() currently both updates the layers and updates the draw state
    336     // (transforms, etc). It'd be nicer if operations on the presentation layers happened later, but the draw
    337     // transforms are needed by large layers to determine visibility. Tiling will fix this by eliminating the
    338     // concept of a large content layer.
    339     updatePropertiesAndRenderSurfaces(rootDrawLayer, identityMatrix, renderSurfaceLayerList, m_defaultRenderSurface->layerList());
    340 
    341 #ifndef NDEBUG
    342     s_inPaintLayerContents = true;
    343 #endif
    344     paintLayerContents(renderSurfaceLayerList);
    345 #ifndef NDEBUG
    346     s_inPaintLayerContents = false;
    347 #endif
    348     // Update compositor resources for root layer.
    349     {
    350         TRACE_EVENT("LayerRendererChromium::updateLayer::updateRoot", this, 0);
    351         m_rootLayerContentTiler->updateRect(m_rootLayerTextureUpdater.get());
    352     }
    353 
    354     m_contentsTextureManager->reduceMemoryToLimit(textureMemoryReclaimLimitBytes);
    355     updateCompositorResources(renderSurfaceLayerList);
    356 }
    357 
    35880static IntRect calculateVisibleRect(const IntRect& targetSurfaceRect, const IntRect& layerBoundRect, const TransformationMatrix& transform)
    35981{
     
    379101}
    380102
    381 static IntRect calculateVisibleLayerRect(const IntRect& targetSurfaceRect, const IntSize& bounds, const IntSize& contentBounds, const TransformationMatrix& tilingTransform)
    382 {
    383     if (targetSurfaceRect.isEmpty() || contentBounds.isEmpty())
    384         return targetSurfaceRect;
    385 
    386     const IntRect layerBoundRect = IntRect(IntPoint(), contentBounds);
    387     TransformationMatrix transform = tilingTransform;
    388 
    389     transform.scaleNonUniform(bounds.width() / static_cast<double>(contentBounds.width()),
    390                               bounds.height() / static_cast<double>(contentBounds.height()));
    391     transform.translate(-contentBounds.width() / 2.0, -contentBounds.height() / 2.0);
    392 
    393     return calculateVisibleRect(targetSurfaceRect, layerBoundRect, transform);
    394 }
    395 
    396 static void paintContentsIfDirty(LayerChromium* layer, const IntRect& visibleLayerRect)
    397 {
    398     if (layer->drawsContent()) {
    399         layer->setVisibleLayerRect(visibleLayerRect);
    400         layer->paintContentsIfDirty();
    401     }
    402 }
    403 
    404 void LayerRendererChromium::paintLayerContents(const LayerList& renderSurfaceLayerList)
    405 {
    406     for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) {
    407         CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex].get();
    408         RenderSurfaceChromium* renderSurface = renderSurfaceLayer->renderSurface();
    409         ASSERT(renderSurface);
    410 
    411         // Make sure any renderSurfaceLayer is associated with this layerRenderer.
    412         // This is a defensive assignment in case the owner of this layer hasn't
    413         // set the layerRenderer on this layer already.
    414         renderSurfaceLayer->setLayerRenderer(this);
    415 
    416         // Render surfaces whose drawable area has zero width or height
    417         // will have no layers associated with them and should be skipped.
    418         if (!renderSurface->layerList().size())
    419             continue;
    420 
    421         if (!renderSurface->drawOpacity())
    422             continue;
    423 
    424         LayerList& layerList = renderSurface->layerList();
    425         ASSERT(layerList.size());
    426         for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex) {
    427             CCLayerImpl* ccLayerImpl = layerList[layerIndex].get();
    428 
    429             // Layers that start a new render surface will be painted when the render
    430             // surface's list is processed.
    431             if (ccLayerImpl->renderSurface() && ccLayerImpl->renderSurface() != renderSurface)
    432                 continue;
    433 
    434             LayerChromium* layer = ccLayerImpl->owner();
    435 
    436             layer->setLayerRenderer(this);
    437 
    438             if (!layer->opacity())
    439                 continue;
    440 
    441             if (layer->maskLayer())
    442                 layer->maskLayer()->setLayerRenderer(this);
    443             if (layer->replicaLayer()) {
    444                 layer->replicaLayer()->setLayerRenderer(this);
    445                 if (layer->replicaLayer()->maskLayer())
    446                     layer->replicaLayer()->maskLayer()->setLayerRenderer(this);
    447             }
    448 
    449             if (layer->bounds().isEmpty())
    450                 continue;
    451 
    452             IntRect targetSurfaceRect = ccLayerImpl->targetRenderSurface() ? ccLayerImpl->targetRenderSurface()->contentRect() : m_defaultRenderSurface->contentRect();
    453             if (layer->ccLayerImpl()->usesLayerScissor())
    454                 targetSurfaceRect.intersect(layer->ccLayerImpl()->scissorRect());
    455             IntRect visibleLayerRect = calculateVisibleLayerRect(targetSurfaceRect, layer->bounds(), layer->contentBounds(), ccLayerImpl->drawTransform());
    456 
    457             paintContentsIfDirty(layer, visibleLayerRect);
    458 
    459             if (LayerChromium* maskLayer = layer->maskLayer()) {
    460                 paintContentsIfDirty(maskLayer, IntRect(IntPoint(), maskLayer->contentBounds()));
    461             }
    462 
    463             if (LayerChromium* replicaLayer = layer->replicaLayer()) {
    464                 paintContentsIfDirty(replicaLayer, visibleLayerRect);
    465 
    466                 if (LayerChromium* replicaMaskLayer = replicaLayer->maskLayer()) {
    467                     paintContentsIfDirty(replicaMaskLayer, IntRect(IntPoint(), replicaMaskLayer->contentBounds()));
    468                 }
    469             }
    470         }
    471     }
    472 }
    473 
    474 void LayerRendererChromium::drawLayers(const LayerList& renderSurfaceLayerList)
    475 {
    476     if (m_viewportVisibleRect.isEmpty() || !m_rootLayer)
    477         return;
    478 
    479     TRACE_EVENT("LayerRendererChromium::drawLayers", this, 0);
    480     CCLayerImpl* rootDrawLayer = m_rootLayer->ccLayerImpl();
    481     makeContextCurrent();
    482 
    483     // The GL viewport covers the entire visible area, including the scrollbars.
    484     GLC(m_context.get(), m_context->viewport(0, 0, m_viewportVisibleRect.width(), m_viewportVisibleRect.height()));
    485 
    486     // Bind the common vertex attributes used for drawing all the layers.
    487     m_sharedGeometry->prepareForDraw();
    488 
    489     // FIXME: These calls can be made once, when the compositor context is initialized.
    490     GLC(m_context.get(), m_context->disable(GraphicsContext3D::DEPTH_TEST));
    491     GLC(m_context.get(), m_context->disable(GraphicsContext3D::CULL_FACE));
    492 
    493     // Blending disabled by default. Root layer alpha channel on Windows is incorrect when Skia uses ClearType.
    494     GLC(m_context.get(), m_context->disable(GraphicsContext3D::BLEND));
    495 
    496     useRenderSurface(m_defaultRenderSurface);
    497 
    498     // Clear to blue to make it easier to spot unrendered regions.
    499     m_context->clearColor(0, 0, 1, 1);
    500     m_context->colorMask(true, true, true, true);
    501     m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
    502     // Mask out writes to alpha channel: subpixel antialiasing via Skia results in invalid
    503     // zero alpha values on text glyphs. The root layer is always opaque.
    504     m_context->colorMask(true, true, true, false);
    505 
    506     drawRootLayer();
    507 
    508     // Re-enable color writes to layers, which may be partially transparent.
    509     m_context->colorMask(true, true, true, true);
    510 
    511     GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND));
    512     GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
    513     GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST));
    514 
    515     // Update the contents of the render surfaces. We traverse the array from
    516     // back to front to guarantee that nested render surfaces get rendered in the
    517     // correct order.
    518     for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) {
    519         CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex].get();
    520         RenderSurfaceChromium* renderSurface = renderSurfaceLayer->renderSurface();
    521         ASSERT(renderSurface);
    522 
    523         renderSurface->setSkipsDraw(true);
    524 
    525         // Render surfaces whose drawable area has zero width or height
    526         // will have no layers associated with them and should be skipped.
    527         if (!renderSurface->layerList().size())
    528             continue;
    529 
    530         // Skip completely transparent render surfaces.
    531         if (!renderSurface->drawOpacity())
    532             continue;
    533 
    534         if (useRenderSurface(renderSurface)) {
    535             renderSurface->setSkipsDraw(false);
    536 
    537             if (renderSurfaceLayer != rootDrawLayer) {
    538                 GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
    539                 GLC(m_context.get(), m_context->clearColor(0, 0, 0, 0));
    540                 GLC(m_context.get(), m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT));
    541                 GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST));
    542             }
    543 
    544             LayerList& layerList = renderSurface->layerList();
    545             for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex)
    546                 drawLayer(layerList[layerIndex].get(), renderSurface);
    547         }
    548     }
    549 
    550     if (m_headsUpDisplay->enabled()) {
    551         GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND));
    552         GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
    553         GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
    554         useRenderSurface(m_defaultRenderSurface);
    555         m_headsUpDisplay->draw();
    556     }
    557 
    558     GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
    559     GLC(m_context.get(), m_context->disable(GraphicsContext3D::BLEND));
    560 }
    561 
    562 void LayerRendererChromium::finish()
    563 {
    564     TRACE_EVENT("LayerRendererChromium::finish", this, 0);
    565     m_context->finish();
    566 }
    567 
    568 void LayerRendererChromium::present()
    569 {
    570     TRACE_EVENT("LayerRendererChromium::present", this, 0);
    571     // We're done! Time to swapbuffers!
    572 
    573     // Note that currently this has the same effect as swapBuffers; we should
    574     // consider exposing a different entry point on GraphicsContext3D.
    575     m_context->prepareTexture();
    576 
    577     m_headsUpDisplay->onPresent();
    578 }
    579 
    580 void LayerRendererChromium::setRootLayer(PassRefPtr<LayerChromium> layer)
    581 {
    582     m_rootLayer = layer;
    583     if (m_rootLayer)
    584         m_rootLayer->setLayerRenderer(this);
    585     m_rootLayerContentTiler->invalidateEntireLayer();
    586 }
    587 
    588 void LayerRendererChromium::setLayerRendererRecursive(LayerChromium* layer)
    589 {
    590     const Vector<RefPtr<LayerChromium> >& children = layer->children();
    591     for (size_t i = 0; i < children.size(); ++i)
    592         setLayerRendererRecursive(children[i].get());
    593 
    594     if (layer->maskLayer())
    595         setLayerRendererRecursive(layer->maskLayer());
    596     if (layer->replicaLayer())
    597         setLayerRendererRecursive(layer->replicaLayer());
    598 
    599     layer->setLayerRenderer(this);
    600 }
    601 
    602 void LayerRendererChromium::transferRootLayer(LayerRendererChromium* other)
    603 {
    604     other->setLayerRendererRecursive(m_rootLayer.get());
    605     other->m_rootLayer = m_rootLayer.release();
    606 }
    607 
    608 void LayerRendererChromium::getFramebufferPixels(void *pixels, const IntRect& rect)
    609 {
    610     ASSERT(rect.maxX() <= m_viewportVisibleRect.width() && rect.maxY() <= m_viewportVisibleRect.height());
    611 
    612     if (!pixels)
    613         return;
    614 
    615     makeContextCurrent();
    616 
    617     GLC(m_context.get(), m_context->readPixels(rect.x(), rect.y(), rect.width(), rect.height(),
    618                                          GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels));
    619 }
    620 
    621 // FIXME: This method should eventually be replaced by a proper texture manager.
    622 unsigned LayerRendererChromium::createLayerTexture()
    623 {
    624     unsigned textureId = 0;
    625     GLC(m_context.get(), textureId = m_context->createTexture());
    626     GLC(m_context.get(), m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId));
    627     // Do basic linear filtering on resize.
    628     GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR));
    629     GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR));
    630     // NPOT textures in GL ES only work when the wrap mode is set to GraphicsContext3D::CLAMP_TO_EDGE.
    631     GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE));
    632     GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE));
    633     return textureId;
    634 }
    635 
    636 void LayerRendererChromium::deleteLayerTexture(unsigned textureId)
    637 {
    638     if (!textureId)
    639         return;
    640 
    641     GLC(m_context.get(), m_context->deleteTexture(textureId));
    642 }
    643 
    644 // Returns true if any part of the layer falls within the visibleRect
    645 bool LayerRendererChromium::isLayerVisible(LayerChromium* layer, const TransformationMatrix& matrix, const IntRect& visibleRect)
    646 {
    647     // Form the matrix used by the shader to map the corners of the layer's
    648     // bounds into clip space.
    649     TransformationMatrix renderMatrix = matrix;
    650     renderMatrix.scale3d(layer->bounds().width(), layer->bounds().height(), 1);
    651     renderMatrix = m_projectionMatrix * renderMatrix;
    652 
    653     FloatRect layerRect(-0.5, -0.5, 1, 1);
    654     FloatRect mappedRect = renderMatrix.mapRect(layerRect);
    655 
    656     // The layer is visible if it intersects any part of a rectangle whose origin
    657     // is at (-1, -1) and size is 2x2.
    658     return mappedRect.intersects(FloatRect(-1, -1, 2, 2));
     103// Returns true if the matrix has no rotation, skew or perspective components to it.
     104static bool isScaleOrTranslation(const TransformationMatrix& m)
     105{
     106    return !m.m12() && !m.m13() && !m.m14()
     107           && !m.m21() && !m.m23() && !m.m24()
     108           && !m.m31() && !m.m32() && !m.m43()
     109           && m.m44();
     110
    659111}
    660112
     
    906358    }
    907359
    908     // If preserves-3d then sort all the descendants in 3D so that they can be 
     360    // If preserves-3d then sort all the descendants in 3D so that they can be
    909361    // drawn from back to front. If the preserves-3d property is also set on the parent then
    910362    // skip the sorting as the parent will sort all the descendants anyway.
    911363    if (layer->preserves3D() && (!layer->parent() || !layer->parent()->preserves3D()))
    912364        m_layerSorter.sort(&descendants.at(thisLayerIndex), descendants.end());
     365}
     366
     367static TransformationMatrix orthoMatrix(float left, float right, float bottom, float top)
     368{
     369    float deltaX = right - left;
     370    float deltaY = top - bottom;
     371    TransformationMatrix ortho;
     372    if (!deltaX || !deltaY)
     373        return ortho;
     374    ortho.setM11(2.0f / deltaX);
     375    ortho.setM41(-(right + left) / deltaX);
     376    ortho.setM22(2.0f / deltaY);
     377    ortho.setM42(-(top + bottom) / deltaY);
     378
     379    // Z component of vertices is always set to zero as we don't use the depth buffer
     380    // while drawing.
     381    ortho.setM33(0);
     382
     383    return ortho;
     384}
     385
     386PassRefPtr<LayerRendererChromium> LayerRendererChromium::create(CCLayerTreeHostClient* client, PassOwnPtr<LayerPainterChromium> contentPaint, bool accelerateDrawing)
     387{
     388    RefPtr<GraphicsContext3D> context = client->createLayerTreeHostContext3D();
     389    if (!context)
     390        return 0;
     391
     392    RefPtr<LayerRendererChromium> layerRenderer(adoptRef(new LayerRendererChromium(client, context, contentPaint, accelerateDrawing)));
     393    layerRenderer->init();
     394    if (!layerRenderer->hardwareCompositing())
     395        return 0;
     396
     397    return layerRenderer.release();
     398}
     399
     400LayerRendererChromium::LayerRendererChromium(CCLayerTreeHostClient* client,
     401                                             PassRefPtr<GraphicsContext3D> context,
     402                                             PassOwnPtr<LayerPainterChromium> contentPaint,
     403                                             bool accelerateDrawing)
     404    : CCLayerTreeHost(client)
     405    , m_viewportScrollPosition(IntPoint(-1, -1))
     406    , m_rootLayer(0)
     407    , m_accelerateDrawing(false)
     408    , m_currentRenderSurface(0)
     409    , m_offscreenFramebufferId(0)
     410    , m_compositeOffscreen(false)
     411    , m_context(context)
     412    , m_contextSupportsTextureFormatBGRA(false)
     413    , m_contextSupportsReadFormatBGRA(false)
     414    , m_animating(false)
     415    , m_defaultRenderSurface(0)
     416{
     417    WebCore::Extensions3D* extensions = m_context->getExtensions();
     418    m_contextSupportsMapSub = extensions->supports("GL_CHROMIUM_map_sub");
     419    if (m_contextSupportsMapSub)
     420        extensions->ensureEnabled("GL_CHROMIUM_map_sub");
     421    m_contextSupportsTextureFormatBGRA = extensions->supports("GL_EXT_texture_format_BGRA8888");
     422    if (m_contextSupportsTextureFormatBGRA)
     423        extensions->ensureEnabled("GL_EXT_texture_format_BGRA8888");
     424    m_contextSupportsReadFormatBGRA = extensions->supports("GL_EXT_read_format_bgra");
     425    if (m_contextSupportsReadFormatBGRA)
     426        extensions->ensureEnabled("GL_EXT_read_format_bgra");
     427
     428#if USE(SKIA)
     429    m_accelerateDrawing = accelerateDrawing && skiaContext();
     430#endif
     431    m_hardwareCompositing = initializeSharedObjects();
     432
     433#if USE(SKIA)
     434    if (m_accelerateDrawing)
     435        m_rootLayerTextureUpdater = LayerTextureUpdaterSkPicture::create(m_context.get(), contentPaint, skiaContext());
     436    else
     437#endif
     438        m_rootLayerTextureUpdater = LayerTextureUpdaterBitmap::create(m_context.get(), contentPaint, m_contextSupportsMapSub);
     439
     440    m_rootLayerContentTiler = LayerTilerChromium::create(this, IntSize(256, 256), LayerTilerChromium::NoBorderTexels);
     441    ASSERT(m_rootLayerContentTiler);
     442
     443    m_headsUpDisplay = CCHeadsUpDisplay::create(this);
     444}
     445
     446LayerRendererChromium::~LayerRendererChromium()
     447{
     448    m_headsUpDisplay.clear(); // Explicitly destroy the HUD before the TextureManager dies.
     449    cleanupSharedObjects();
     450}
     451
     452GraphicsContext3D* LayerRendererChromium::context()
     453{
     454    return m_context.get();
     455}
     456
     457#if USE(SKIA)
     458GrContext* LayerRendererChromium::skiaContext()
     459{
     460    if (!m_skiaContext && m_contextSupportsTextureFormatBGRA && m_contextSupportsReadFormatBGRA) {
     461        m_context->makeContextCurrent();
     462        m_skiaContext = adoptPtr(GrContext::CreateGLShaderContext());
     463        // Limit the number of textures we hold in the bitmap->texture cache.
     464        static const int maxTextureCacheCount = 512;
     465        // Limit the bytes allocated toward textures in the bitmap->texture cache.
     466        static const size_t maxTextureCacheBytes = 50 * 1024 * 1024;
     467        m_skiaContext->setTextureCacheLimits(maxTextureCacheCount, maxTextureCacheBytes);
     468    }
     469    return m_skiaContext.get();
     470}
     471#endif
     472
     473void LayerRendererChromium::debugGLCall(GraphicsContext3D* context, const char* command, const char* file, int line)
     474{
     475    unsigned long error = context->getError();
     476    if (error != GraphicsContext3D::NO_ERROR)
     477        LOG_ERROR("GL command failed: File: %s\n\tLine %d\n\tcommand: %s, error %x\n", file, line, command, static_cast<int>(error));
     478}
     479
     480void LayerRendererChromium::invalidateRootLayerRect(const IntRect& dirtyRect)
     481{
     482    m_rootLayerContentTiler->invalidateRect(dirtyRect);
     483}
     484
     485void LayerRendererChromium::releaseTextures()
     486{
     487    // Reduces texture memory usage to textureMemoryLowLimitBytes by deleting non root layer
     488    // textures.
     489    m_rootLayerContentTiler->protectTileTextures(m_viewportVisibleRect);
     490    m_contentsTextureManager->reduceMemoryToLimit(textureMemoryLowLimitBytes);
     491    m_contentsTextureManager->unprotectAllTextures();
     492    // Evict all RenderSurface textures.
     493    m_renderSurfaceTextureManager->unprotectAllTextures();
     494    m_renderSurfaceTextureManager->reduceMemoryToLimit(0);
     495}
     496
     497void LayerRendererChromium::updateRootLayerContents()
     498{
     499    TRACE_EVENT("LayerRendererChromium::updateRootLayerContents", this, 0);
     500    m_rootLayerContentTiler->prepareToUpdate(m_viewportVisibleRect, m_rootLayerTextureUpdater.get());
     501}
     502
     503void LayerRendererChromium::drawRootLayer()
     504{
     505    TransformationMatrix scroll;
     506    scroll.translate(-m_viewportVisibleRect.x(), -m_viewportVisibleRect.y());
     507
     508    m_rootLayerContentTiler->draw(m_viewportVisibleRect, scroll, 1.0f);
     509}
     510
     511void LayerRendererChromium::setViewport(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition)
     512{
     513    bool visibleRectChanged = m_viewportVisibleRect.size() != visibleRect.size();
     514
     515    m_viewportVisibleRect = visibleRect;
     516    m_viewportContentRect = contentRect;
     517    m_viewportScrollPosition = scrollPosition;
     518
     519    if (visibleRectChanged) {
     520        // Reset the current render surface to force an update of the viewport and
     521        // projection matrix next time useRenderSurface is called.
     522        m_currentRenderSurface = 0;
     523        m_rootLayerContentTiler->invalidateEntireLayer();
     524    }
     525    setNeedsCommitAndRedraw();
     526}
     527
     528void LayerRendererChromium::updateLayers()
     529{
     530    if (m_viewportVisibleRect.isEmpty())
     531        return;
     532
     533    // FIXME: use the frame begin time from the overall compositor scheduler.
     534    // This value is currently inaccessible because it is up in Chromium's
     535    // RenderWidget.
     536    m_headsUpDisplay->onFrameBegin(currentTime());
     537    ASSERT(m_hardwareCompositing);
     538
     539    if (!m_rootLayer)
     540        return;
     541
     542    updateRootLayerContents();
     543
     544    // Recheck that we still have a root layer. This may become null if
     545    // compositing gets turned off during a paint operation.
     546    if (!m_rootLayer)
     547        return;
     548
     549    {
     550        TRACE_EVENT("LayerRendererChromium::synchronizeTrees", this, 0);
     551        m_rootCCLayerImpl = TreeSynchronizer::synchronizeTrees(m_rootLayer.get(), m_rootCCLayerImpl.get());
     552    }
     553
     554    m_computedRenderSurfaceLayerList = adoptPtr(new LayerList());
     555    updateLayers(*m_computedRenderSurfaceLayerList);
     556}
     557
     558void LayerRendererChromium::drawLayers()
     559{
     560    ASSERT(m_hardwareCompositing);
     561    ASSERT(m_computedRenderSurfaceLayerList);
     562    // Before drawLayers:
     563    if (hardwareCompositing()) {
     564        // FIXME: The multithreaded compositor case will not work as long as
     565        // copyTexImage2D resolves to the parent texture, because the main
     566        // thread can execute WebGL calls on the child context at any time,
     567        // potentially clobbering the parent texture that is being renderered
     568        // by the compositor thread.
     569        ChildContextMap::iterator i = m_childContexts.begin();
     570        for (; i != m_childContexts.end(); ++i) {
     571            i->first->flush();
     572        }
     573    }
     574
     575    m_renderSurfaceTextureManager->setMemoryLimitBytes(textureMemoryHighLimitBytes - m_contentsTextureManager->currentMemoryUseBytes());
     576    drawLayers(*m_computedRenderSurfaceLayerList);
     577
     578    m_contentsTextureManager->unprotectAllTextures();
     579    m_contentsTextureManager->reduceMemoryToLimit(textureMemoryReclaimLimitBytes);
     580
     581    if (textureMemoryReclaimLimitBytes > m_contentsTextureManager->currentMemoryUseBytes())
     582        m_renderSurfaceTextureManager->reduceMemoryToLimit(textureMemoryReclaimLimitBytes - m_contentsTextureManager->currentMemoryUseBytes());
     583    else
     584        m_renderSurfaceTextureManager->reduceMemoryToLimit(0);
     585
     586    if (isCompositingOffscreen())
     587        copyOffscreenTextureToDisplay();
     588}
     589
     590void LayerRendererChromium::updateLayers(LayerList& renderSurfaceLayerList)
     591{
     592    TRACE_EVENT("LayerRendererChromium::updateLayers", this, 0);
     593    CCLayerImpl* rootDrawLayer = m_rootLayer->ccLayerImpl();
     594
     595    if (!rootDrawLayer->renderSurface())
     596        rootDrawLayer->createRenderSurface();
     597    ASSERT(rootDrawLayer->renderSurface());
     598
     599    rootDrawLayer->renderSurface()->setContentRect(IntRect(IntPoint(0, 0), m_viewportVisibleRect.size()));
     600
     601    IntRect rootScissorRect(m_viewportVisibleRect);
     602    // The scissorRect should not include the scroll offset.
     603    rootScissorRect.move(-m_viewportScrollPosition.x(), -m_viewportScrollPosition.y());
     604    rootDrawLayer->setScissorRect(rootScissorRect);
     605
     606    m_defaultRenderSurface = rootDrawLayer->renderSurface();
     607
     608    renderSurfaceLayerList.append(rootDrawLayer);
     609
     610    TransformationMatrix identityMatrix;
     611    m_defaultRenderSurface->clearLayerList();
     612    // Unfortunately, updatePropertiesAndRenderSurfaces() currently both updates the layers and updates the draw state
     613    // (transforms, etc). It'd be nicer if operations on the presentation layers happened later, but the draw
     614    // transforms are needed by large layers to determine visibility. Tiling will fix this by eliminating the
     615    // concept of a large content layer.
     616    updatePropertiesAndRenderSurfaces(rootDrawLayer, identityMatrix, renderSurfaceLayerList, m_defaultRenderSurface->layerList());
     617
     618#ifndef NDEBUG
     619    s_inPaintLayerContents = true;
     620#endif
     621    paintLayerContents(renderSurfaceLayerList);
     622#ifndef NDEBUG
     623    s_inPaintLayerContents = false;
     624#endif
     625    // Update compositor resources for root layer.
     626    {
     627        TRACE_EVENT("LayerRendererChromium::updateLayer::updateRoot", this, 0);
     628        m_rootLayerContentTiler->updateRect(m_rootLayerTextureUpdater.get());
     629    }
     630
     631    m_contentsTextureManager->reduceMemoryToLimit(textureMemoryReclaimLimitBytes);
     632    updateCompositorResources(renderSurfaceLayerList);
     633}
     634
     635static IntRect calculateVisibleLayerRect(const IntRect& targetSurfaceRect, const IntSize& bounds, const IntSize& contentBounds, const TransformationMatrix& tilingTransform)
     636{
     637    if (targetSurfaceRect.isEmpty() || contentBounds.isEmpty())
     638        return targetSurfaceRect;
     639
     640    const IntRect layerBoundRect = IntRect(IntPoint(), contentBounds);
     641    TransformationMatrix transform = tilingTransform;
     642
     643    transform.scaleNonUniform(bounds.width() / static_cast<double>(contentBounds.width()),
     644                              bounds.height() / static_cast<double>(contentBounds.height()));
     645    transform.translate(-contentBounds.width() / 2.0, -contentBounds.height() / 2.0);
     646
     647    return calculateVisibleRect(targetSurfaceRect, layerBoundRect, transform);
     648}
     649
     650static void paintContentsIfDirty(LayerChromium* layer, const IntRect& visibleLayerRect)
     651{
     652    if (layer->drawsContent()) {
     653        layer->setVisibleLayerRect(visibleLayerRect);
     654        layer->paintContentsIfDirty();
     655    }
     656}
     657
     658void LayerRendererChromium::paintLayerContents(const LayerList& renderSurfaceLayerList)
     659{
     660    for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) {
     661        CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex].get();
     662        RenderSurfaceChromium* renderSurface = renderSurfaceLayer->renderSurface();
     663        ASSERT(renderSurface);
     664
     665        // Make sure any renderSurfaceLayer is associated with this layerRenderer.
     666        // This is a defensive assignment in case the owner of this layer hasn't
     667        // set the layerRenderer on this layer already.
     668        renderSurfaceLayer->setLayerRenderer(this);
     669
     670        // Render surfaces whose drawable area has zero width or height
     671        // will have no layers associated with them and should be skipped.
     672        if (!renderSurface->layerList().size())
     673            continue;
     674
     675        if (!renderSurface->drawOpacity())
     676            continue;
     677
     678        LayerList& layerList = renderSurface->layerList();
     679        ASSERT(layerList.size());
     680        for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex) {
     681            CCLayerImpl* ccLayerImpl = layerList[layerIndex].get();
     682
     683            // Layers that start a new render surface will be painted when the render
     684            // surface's list is processed.
     685            if (ccLayerImpl->renderSurface() && ccLayerImpl->renderSurface() != renderSurface)
     686                continue;
     687
     688            LayerChromium* layer = ccLayerImpl->owner();
     689
     690            layer->setLayerRenderer(this);
     691
     692            if (!layer->opacity())
     693                continue;
     694
     695            if (layer->maskLayer())
     696                layer->maskLayer()->setLayerRenderer(this);
     697            if (layer->replicaLayer()) {
     698                layer->replicaLayer()->setLayerRenderer(this);
     699                if (layer->replicaLayer()->maskLayer())
     700                    layer->replicaLayer()->maskLayer()->setLayerRenderer(this);
     701            }
     702
     703            if (layer->bounds().isEmpty())
     704                continue;
     705
     706            IntRect targetSurfaceRect = ccLayerImpl->targetRenderSurface() ? ccLayerImpl->targetRenderSurface()->contentRect() : m_defaultRenderSurface->contentRect();
     707            if (layer->ccLayerImpl()->usesLayerScissor())
     708                targetSurfaceRect.intersect(layer->ccLayerImpl()->scissorRect());
     709            IntRect visibleLayerRect = calculateVisibleLayerRect(targetSurfaceRect, layer->bounds(), layer->contentBounds(), ccLayerImpl->drawTransform());
     710
     711            paintContentsIfDirty(layer, visibleLayerRect);
     712
     713            if (LayerChromium* maskLayer = layer->maskLayer()) {
     714                paintContentsIfDirty(maskLayer, IntRect(IntPoint(), maskLayer->contentBounds()));
     715            }
     716
     717            if (LayerChromium* replicaLayer = layer->replicaLayer()) {
     718                paintContentsIfDirty(replicaLayer, visibleLayerRect);
     719
     720                if (LayerChromium* replicaMaskLayer = replicaLayer->maskLayer()) {
     721                    paintContentsIfDirty(replicaMaskLayer, IntRect(IntPoint(), replicaMaskLayer->contentBounds()));
     722                }
     723            }
     724        }
     725    }
     726}
     727
     728void LayerRendererChromium::drawLayers(const LayerList& renderSurfaceLayerList)
     729{
     730    if (m_viewportVisibleRect.isEmpty() || !m_rootLayer)
     731        return;
     732
     733    TRACE_EVENT("LayerRendererChromium::drawLayers", this, 0);
     734    CCLayerImpl* rootDrawLayer = m_rootLayer->ccLayerImpl();
     735    makeContextCurrent();
     736
     737    // The GL viewport covers the entire visible area, including the scrollbars.
     738    GLC(m_context.get(), m_context->viewport(0, 0, m_viewportVisibleRect.width(), m_viewportVisibleRect.height()));
     739
     740    // Bind the common vertex attributes used for drawing all the layers.
     741    m_sharedGeometry->prepareForDraw();
     742
     743    // FIXME: These calls can be made once, when the compositor context is initialized.
     744    GLC(m_context.get(), m_context->disable(GraphicsContext3D::DEPTH_TEST));
     745    GLC(m_context.get(), m_context->disable(GraphicsContext3D::CULL_FACE));
     746
     747    // Blending disabled by default. Root layer alpha channel on Windows is incorrect when Skia uses ClearType.
     748    GLC(m_context.get(), m_context->disable(GraphicsContext3D::BLEND));
     749
     750    useRenderSurface(m_defaultRenderSurface);
     751
     752    // Clear to blue to make it easier to spot unrendered regions.
     753    m_context->clearColor(0, 0, 1, 1);
     754    m_context->colorMask(true, true, true, true);
     755    m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
     756    // Mask out writes to alpha channel: subpixel antialiasing via Skia results in invalid
     757    // zero alpha values on text glyphs. The root layer is always opaque.
     758    m_context->colorMask(true, true, true, false);
     759
     760    drawRootLayer();
     761
     762    // Re-enable color writes to layers, which may be partially transparent.
     763    m_context->colorMask(true, true, true, true);
     764
     765    GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND));
     766    GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
     767    GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST));
     768
     769    // Update the contents of the render surfaces. We traverse the array from
     770    // back to front to guarantee that nested render surfaces get rendered in the
     771    // correct order.
     772    for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) {
     773        CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex].get();
     774        RenderSurfaceChromium* renderSurface = renderSurfaceLayer->renderSurface();
     775        ASSERT(renderSurface);
     776
     777        renderSurface->setSkipsDraw(true);
     778
     779        // Render surfaces whose drawable area has zero width or height
     780        // will have no layers associated with them and should be skipped.
     781        if (!renderSurface->layerList().size())
     782            continue;
     783
     784        // Skip completely transparent render surfaces.
     785        if (!renderSurface->drawOpacity())
     786            continue;
     787
     788        if (useRenderSurface(renderSurface)) {
     789            renderSurface->setSkipsDraw(false);
     790
     791            if (renderSurfaceLayer != rootDrawLayer) {
     792                GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
     793                GLC(m_context.get(), m_context->clearColor(0, 0, 0, 0));
     794                GLC(m_context.get(), m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT));
     795                GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST));
     796            }
     797
     798            LayerList& layerList = renderSurface->layerList();
     799            for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex)
     800                drawLayer(layerList[layerIndex].get(), renderSurface);
     801        }
     802    }
     803
     804    if (m_headsUpDisplay->enabled()) {
     805        GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND));
     806        GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
     807        GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
     808        useRenderSurface(m_defaultRenderSurface);
     809        m_headsUpDisplay->draw();
     810    }
     811
     812    GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
     813    GLC(m_context.get(), m_context->disable(GraphicsContext3D::BLEND));
     814}
     815
     816void LayerRendererChromium::finish()
     817{
     818    TRACE_EVENT("LayerRendererChromium::finish", this, 0);
     819    m_context->finish();
     820}
     821
     822void LayerRendererChromium::present()
     823{
     824    TRACE_EVENT("LayerRendererChromium::present", this, 0);
     825    // We're done! Time to swapbuffers!
     826
     827    // Note that currently this has the same effect as swapBuffers; we should
     828    // consider exposing a different entry point on GraphicsContext3D.
     829    m_context->prepareTexture();
     830
     831    m_headsUpDisplay->onPresent();
     832}
     833
     834void LayerRendererChromium::setRootLayer(PassRefPtr<LayerChromium> layer)
     835{
     836    m_rootLayer = layer;
     837    if (m_rootLayer)
     838        m_rootLayer->setLayerRenderer(this);
     839    m_rootLayerContentTiler->invalidateEntireLayer();
     840}
     841
     842void LayerRendererChromium::setLayerRendererRecursive(LayerChromium* layer)
     843{
     844    const Vector<RefPtr<LayerChromium> >& children = layer->children();
     845    for (size_t i = 0; i < children.size(); ++i)
     846        setLayerRendererRecursive(children[i].get());
     847
     848    if (layer->maskLayer())
     849        setLayerRendererRecursive(layer->maskLayer());
     850    if (layer->replicaLayer())
     851        setLayerRendererRecursive(layer->replicaLayer());
     852
     853    layer->setLayerRenderer(this);
     854}
     855
     856void LayerRendererChromium::transferRootLayer(LayerRendererChromium* other)
     857{
     858    other->setLayerRendererRecursive(m_rootLayer.get());
     859    other->m_rootLayer = m_rootLayer.release();
     860}
     861
     862void LayerRendererChromium::getFramebufferPixels(void *pixels, const IntRect& rect)
     863{
     864    ASSERT(rect.maxX() <= m_viewportVisibleRect.width() && rect.maxY() <= m_viewportVisibleRect.height());
     865
     866    if (!pixels)
     867        return;
     868
     869    makeContextCurrent();
     870
     871    GLC(m_context.get(), m_context->readPixels(rect.x(), rect.y(), rect.width(), rect.height(),
     872                                         GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels));
     873}
     874
     875// FIXME: This method should eventually be replaced by a proper texture manager.
     876unsigned LayerRendererChromium::createLayerTexture()
     877{
     878    unsigned textureId = 0;
     879    GLC(m_context.get(), textureId = m_context->createTexture());
     880    GLC(m_context.get(), m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId));
     881    // Do basic linear filtering on resize.
     882    GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR));
     883    GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR));
     884    // NPOT textures in GL ES only work when the wrap mode is set to GraphicsContext3D::CLAMP_TO_EDGE.
     885    GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE));
     886    GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE));
     887    return textureId;
     888}
     889
     890void LayerRendererChromium::deleteLayerTexture(unsigned textureId)
     891{
     892    if (!textureId)
     893        return;
     894
     895    GLC(m_context.get(), m_context->deleteTexture(textureId));
     896}
     897
     898// Returns true if any part of the layer falls within the visibleRect
     899bool LayerRendererChromium::isLayerVisible(LayerChromium* layer, const TransformationMatrix& matrix, const IntRect& visibleRect)
     900{
     901    // Form the matrix used by the shader to map the corners of the layer's
     902    // bounds into clip space.
     903    TransformationMatrix renderMatrix = matrix;
     904    renderMatrix.scale3d(layer->bounds().width(), layer->bounds().height(), 1);
     905    renderMatrix = m_projectionMatrix * renderMatrix;
     906
     907    FloatRect layerRect(-0.5, -0.5, 1, 1);
     908    FloatRect mappedRect = renderMatrix.mapRect(layerRect);
     909
     910    // The layer is visible if it intersects any part of a rectangle whose origin
     911    // is at (-1, -1) and size is 2x2.
     912    return mappedRect.intersects(FloatRect(-1, -1, 2, 2));
    913913}
    914914
Note: See TracChangeset for help on using the changeset viewer.