Chromium Code Reviews| Index: Source/core/rendering/RenderLayerCompositor.cpp |
| diff --git a/Source/core/rendering/RenderLayerCompositor.cpp b/Source/core/rendering/RenderLayerCompositor.cpp |
| index 5f622e0fc041910c5202ea6320c4047f00d43efd..198d6e6b7563f21d79b67627a47dbf497185644d 100644 |
| --- a/Source/core/rendering/RenderLayerCompositor.cpp |
| +++ b/Source/core/rendering/RenderLayerCompositor.cpp |
| @@ -224,7 +224,8 @@ RenderLayerCompositor::RenderLayerCompositor(RenderView* renderView) |
| , m_compositingTriggers(static_cast<ChromeClient::CompositingTriggerFlags>(ChromeClient::AllTriggers)) |
| , m_compositedLayerCount(0) |
| , m_showRepaintCounter(false) |
| - , m_reevaluateCompositingAfterLayout(false) |
| + , m_needsToRecomputeCompositingRequirements(false) |
| + , m_needsToUpdateLayerTreeGeometry(false) |
| , m_compositing(false) |
| , m_compositingLayersNeedRebuild(false) |
| , m_forceCompositingMode(false) |
| @@ -370,6 +371,19 @@ static RenderVideo* findFullscreenVideoRenderer(Document* document) |
| return toRenderVideo(renderer); |
| } |
| +void RenderLayerCompositor::finishCompositingUpdateForFrameTree(Frame* frame) |
| +{ |
| + for (Frame* child = frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) |
| + finishCompositingUpdateForFrameTree(child); |
| + |
| + // Update compositing for current frame after all descedant frames are updated. |
| + if (frame && frame->contentRenderer()) { |
| + RenderLayerCompositor* frameCompositor = frame->contentRenderer()->compositor(); |
| + if (frameCompositor && !frameCompositor->isMainFrame()) |
| + frame->contentRenderer()->compositor()->updateCompositingLayers(CompositingUpdateFinishAllDeferredWork); |
| + } |
| +} |
| + |
| void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType updateType, RenderLayer* updateRoot) |
| { |
| // Avoid updating the layers with old values. Compositing layers will be updated after the layout is finished. |
| @@ -379,42 +393,56 @@ void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType update |
| if (m_forceCompositingMode && !m_compositing) |
| enableCompositingMode(true); |
| - if (!m_reevaluateCompositingAfterLayout && !m_compositing) |
| + if (!m_needsToRecomputeCompositingRequirements && !m_compositing) |
| return; |
| AnimationUpdateBlock animationUpdateBlock(m_renderView->frameView()->frame().animation()); |
| TemporaryChange<bool> postLayoutChange(m_inPostLayoutUpdate, true); |
| - bool checkForHierarchyUpdate = m_reevaluateCompositingAfterLayout; |
| + bool needCompositingRequirementsUpdate = false; |
| + bool needHierarchyAndGeometryUpdate = false; |
| bool needGeometryUpdate = false; |
| + // CompositingUpdateFinishAllDeferredWork is the only updateType that will actually do any work in this |
| + // function. All other updateTypes will simply mark that something needed updating, and defer the actual |
| + // update. This way we only need to compute all compositing state once for every frame drawn (if needed). |
| switch (updateType) { |
| case CompositingUpdateAfterStyleChange: |
| case CompositingUpdateAfterLayout: |
| - checkForHierarchyUpdate = true; |
| + m_needsToRecomputeCompositingRequirements = true; |
| break; |
| case CompositingUpdateOnScroll: |
| - checkForHierarchyUpdate = true; // Overlap can change with scrolling, so need to check for hierarchy updates. |
| - needGeometryUpdate = true; |
| + m_needsToRecomputeCompositingRequirements = true; // Overlap can change with scrolling, so need to check for hierarchy updates. |
| + m_needsToUpdateLayerTreeGeometry = true; |
| break; |
| case CompositingUpdateOnCompositedScroll: |
| - needGeometryUpdate = true; |
| + m_needsToUpdateLayerTreeGeometry = true; |
| + break; |
| + case CompositingUpdateFinishAllDeferredWork: |
| + needCompositingRequirementsUpdate = m_needsToRecomputeCompositingRequirements; |
| + needHierarchyAndGeometryUpdate = m_compositingLayersNeedRebuild; |
| + needGeometryUpdate = m_needsToUpdateLayerTreeGeometry; |
| break; |
| } |
| - if (!checkForHierarchyUpdate && !needGeometryUpdate) |
| + if (!needCompositingRequirementsUpdate && !needHierarchyAndGeometryUpdate && !needGeometryUpdate) |
| return; |
| - bool needHierarchyUpdate = m_compositingLayersNeedRebuild; |
| + ASSERT(updateType == CompositingUpdateFinishAllDeferredWork); |
| + |
| + if (isMainFrame() && m_renderView->frameView()) |
| + finishCompositingUpdateForFrameTree(&m_renderView->frameView()->frame()); |
|
shawnsingh
2013/10/17 03:29:56
I debugged some more and determined that this need
|
| + |
| bool isFullUpdate = !updateRoot; |
| - // Only clear the flag if we're updating the entire hierarchy. |
| + // Only clear the flags if we're updating the entire hierarchy. |
| m_compositingLayersNeedRebuild = false; |
| + m_needsToUpdateLayerTreeGeometry = false; |
| updateRoot = rootRenderLayer(); |
| - if (isFullUpdate && updateType == CompositingUpdateAfterLayout) |
| - m_reevaluateCompositingAfterLayout = false; |
| + if (isFullUpdate) |
| + m_needsToRecomputeCompositingRequirements = false; |
| #if !LOG_DISABLED |
| double startTime = 0; |
| @@ -424,7 +452,7 @@ void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType update |
| } |
| #endif |
| - if (checkForHierarchyUpdate) { |
| + if (needCompositingRequirementsUpdate) { |
| // Go through the layers in presentation order, so that we can compute which RenderLayers need compositing layers. |
| // FIXME: we could maybe do this and the hierarchy udpate in one pass, but the parenting logic would be more complex. |
| CompositingRecursionData recursionData(updateRoot, true); |
| @@ -441,11 +469,11 @@ void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType update |
| Vector<RenderLayer*> unclippedDescendants; |
| computeCompositingRequirements(0, updateRoot, &overlapTestRequestMap, recursionData, layersChanged, saw3DTransform, unclippedDescendants); |
| } |
| - needHierarchyUpdate |= layersChanged; |
| + needHierarchyAndGeometryUpdate |= layersChanged; |
| } |
| #if !LOG_DISABLED |
| - if (compositingLogEnabled() && isFullUpdate && (needHierarchyUpdate || needGeometryUpdate)) { |
| + if (compositingLogEnabled() && isFullUpdate && (needHierarchyAndGeometryUpdate || needGeometryUpdate)) { |
| m_obligateCompositedLayerCount = 0; |
| m_secondaryCompositedLayerCount = 0; |
| m_obligatoryBackingStoreBytes = 0; |
| @@ -456,7 +484,7 @@ void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType update |
| } |
| #endif |
| - if (needHierarchyUpdate) { |
| + if (needHierarchyAndGeometryUpdate) { |
| // Update the hierarchy of the compositing layers. |
| Vector<GraphicsLayer*> childList; |
| { |
| @@ -490,7 +518,7 @@ void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType update |
| } |
| #if !LOG_DISABLED |
| - if (compositingLogEnabled() && isFullUpdate && (needHierarchyUpdate || needGeometryUpdate)) { |
| + if (compositingLogEnabled() && isFullUpdate && (needHierarchyAndGeometryUpdate || needGeometryUpdate)) { |
| double endTime = currentTime(); |
| LOG(Compositing, "Total layers primary secondary obligatory backing (KB) secondary backing(KB) total backing (KB) update time (ms)\n"); |
| @@ -1133,7 +1161,7 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, Vect |
| UNUSED_PARAM(depth); |
| #endif |
| if (currentCompositedLayerMapping->hasUnpositionedOverflowControlsLayers()) |
| - layer->positionNewlyCreatedOverflowControls(); |
| + layer->positionOverflowControls(); |
| pixelsWithoutPromotingAllTransitions += layer->size().height() * layer->size().width(); |
| } else { |
| @@ -1323,7 +1351,8 @@ bool RenderLayerCompositor::scrollingLayerDidChange(RenderLayer* layer) |
| String RenderLayerCompositor::layerTreeAsText(LayerTreeFlags flags) |
| { |
| - updateCompositingLayers(CompositingUpdateAfterLayout); |
| + // Before dumping the layer tree, finish any pending compositing update. |
| + updateCompositingLayers(CompositingUpdateFinishAllDeferredWork); |
| if (!m_rootContentLayer) |
| return String(); |
| @@ -1923,7 +1952,8 @@ bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer) |
| if (!composite) |
| return false; |
| - m_reevaluateCompositingAfterLayout = true; |
| + // FIXME: this seems bogus. If we don't know the layout position/size of the plugin yet, would't that be handled elsewhere? |
| + m_needsToRecomputeCompositingRequirements = true; |
| RenderWidget* pluginRenderer = toRenderWidget(renderer); |
| // If we can't reliably know the size of the plugin yet, don't change compositing state. |
| @@ -1945,7 +1975,8 @@ bool RenderLayerCompositor::requiresCompositingForFrame(RenderObject* renderer) |
| if (!frameRenderer->requiresAcceleratedCompositing()) |
| return false; |
| - m_reevaluateCompositingAfterLayout = true; |
| + // FIXME: this seems bogus. If we don't know the layout position/size of the frame yet, wouldn't that be handled elsehwere? |
| + m_needsToRecomputeCompositingRequirements = true; |
| RenderLayerCompositor* innerCompositor = frameContentsCompositor(frameRenderer); |
| if (!innerCompositor) |
| @@ -2087,7 +2118,7 @@ bool RenderLayerCompositor::requiresCompositingForPosition(RenderObject* rendere |
| RenderObject* container = renderer->container(); |
| // If the renderer is not hooked up yet then we have to wait until it is. |
| if (!container) { |
| - m_reevaluateCompositingAfterLayout = true; |
| + m_needsToRecomputeCompositingRequirements = true; |
| return false; |
| } |
| @@ -2127,7 +2158,7 @@ bool RenderLayerCompositor::requiresCompositingForPosition(RenderObject* rendere |
| // Subsequent tests depend on layout. If we can't tell now, just keep things the way they are until layout is done. |
| if (!m_inPostLayoutUpdate) { |
| - m_reevaluateCompositingAfterLayout = true; |
| + m_needsToRecomputeCompositingRequirements = true; |
| return layer->isComposited(); |
| } |
| @@ -2146,7 +2177,7 @@ bool RenderLayerCompositor::requiresCompositingForPosition(RenderObject* rendere |
| if (!viewBounds.intersects(enclosingIntRect(layerBounds))) { |
| if (viewportConstrainedNotCompositedReason) { |
| *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForBoundsOutOfView; |
| - m_reevaluateCompositingAfterLayout = true; |
| + m_needsToRecomputeCompositingRequirements = true; |
| } |
| return false; |
| } |
| @@ -2273,6 +2304,7 @@ void RenderLayerCompositor::resetTrackedRepaintRects() |
| void RenderLayerCompositor::setTracksRepaints(bool tracksRepaints) |
| { |
| + updateCompositingLayers(CompositingUpdateFinishAllDeferredWork); |
| m_isTrackingRepaints = tracksRepaints; |
| } |