void LayerManagerComposite::UpdateAndRender() { nsIntRegion invalid; bool didEffectiveTransforms = false; nsIntRegion opaque; LayerIntRegion visible; PostProcessLayers(mRoot, opaque, visible, Nothing()); if (mClonedLayerTreeProperties) { // Effective transforms are needed by ComputeDifferences(). mRoot->ComputeEffectiveTransforms(gfx::Matrix4x4()); didEffectiveTransforms = true; // We need to compute layer tree differences even if we're not going to // immediately use the resulting damage area, since ComputeDifferences // is also responsible for invalidates intermediate surfaces in // ContainerLayers. nsIntRegion changed = mClonedLayerTreeProperties->ComputeDifferences(mRoot, nullptr, &mGeometryChanged); if (mTarget) { // Since we're composing to an external target, we're not going to use // the damage region from layers changes - we want to composite // everything in the target bounds. Instead we accumulate the layers // damage region for the next window composite. mInvalidRegion.Or(mInvalidRegion, changed); } else { invalid = Move(changed); } } if (mTarget) { invalid.Or(invalid, mTargetBounds); } else { // If we didn't have a previous layer tree, invalidate the entire render // area. if (!mClonedLayerTreeProperties) { invalid.Or(invalid, mRenderBounds); } // Add any additional invalid rects from the window manager or previous // damage computed during ComposeToTarget(). invalid.Or(invalid, mInvalidRegion); mInvalidRegion.SetEmpty(); } if (invalid.IsEmpty() && !mWindowOverlayChanged) { // Composition requested, but nothing has changed. Don't do any work. mClonedLayerTreeProperties = LayerProperties::CloneFrom(GetRoot()); return; } // We don't want our debug overlay to cause more frames to happen // so we will invalidate after we've decided if something changed. InvalidateDebugOverlay(invalid, mRenderBounds); if (!didEffectiveTransforms) { // The results of our drawing always go directly into a pixel buffer, // so we don't need to pass any global transform here. mRoot->ComputeEffectiveTransforms(gfx::Matrix4x4()); } Render(invalid, opaque); #if defined(MOZ_WIDGET_ANDROID) RenderToPresentationSurface(); #endif mGeometryChanged = false; mWindowOverlayChanged = false; // Update cached layer tree information. mClonedLayerTreeProperties = LayerProperties::CloneFrom(GetRoot()); }
void LayerManagerComposite::EndTransaction(const TimeStamp& aTimeStamp, EndTransactionFlags aFlags) { NS_ASSERTION(mInTransaction, "Didn't call BeginTransaction?"); NS_ASSERTION(!(aFlags & END_NO_COMPOSITE), "Shouldn't get END_NO_COMPOSITE here"); mInTransaction = false; if (!mIsCompositorReady) { return; } mIsCompositorReady = false; #ifdef MOZ_LAYERS_HAVE_LOG MOZ_LAYERS_LOG((" ----- (beginning paint)")); Log(); #endif if (mDestroyed) { NS_WARNING("Call on destroyed layer manager"); return; } // Set composition timestamp here because we need it in // ComputeEffectiveTransforms (so the correct video frame size is picked) and // also to compute invalid regions properly. mCompositor->SetCompositionTime(aTimeStamp); if (mRoot && mClonedLayerTreeProperties) { MOZ_ASSERT(!mTarget); nsIntRegion invalid = mClonedLayerTreeProperties->ComputeDifferences(mRoot, nullptr, &mGeometryChanged); mClonedLayerTreeProperties = nullptr; mInvalidRegion.Or(mInvalidRegion, invalid); } else if (!mTarget) { mInvalidRegion.Or(mInvalidRegion, mRenderBounds); } if (mInvalidRegion.IsEmpty() && !mTarget) { // Composition requested, but nothing has changed. Don't do any work. return; } if (mRoot && !(aFlags & END_NO_IMMEDIATE_REDRAW)) { MOZ_ASSERT(!aTimeStamp.IsNull()); // The results of our drawing always go directly into a pixel buffer, // so we don't need to pass any global transform here. mRoot->ComputeEffectiveTransforms(gfx::Matrix4x4()); nsIntRegion opaque; ApplyOcclusionCulling(mRoot, opaque); Render(); #ifdef MOZ_WIDGET_ANDROID RenderToPresentationSurface(); #endif mGeometryChanged = false; } else { // Modified layer tree mGeometryChanged = true; } mCompositor->ClearTargetContext(); mTarget = nullptr; #ifdef MOZ_LAYERS_HAVE_LOG Log(); MOZ_LAYERS_LOG(("]----- EndTransaction")); #endif }
void LayerManagerComposite::EndTransaction(DrawPaintedLayerCallback aCallback, void* aCallbackData, EndTransactionFlags aFlags) { NS_ASSERTION(mInTransaction, "Didn't call BeginTransaction?"); NS_ASSERTION(!aCallback && !aCallbackData, "Not expecting callbacks here"); mInTransaction = false; if (!mIsCompositorReady) { return; } mIsCompositorReady = false; #ifdef MOZ_LAYERS_HAVE_LOG MOZ_LAYERS_LOG((" ----- (beginning paint)")); Log(); #endif if (mDestroyed) { NS_WARNING("Call on destroyed layer manager"); return; } if (mRoot && mClonedLayerTreeProperties) { MOZ_ASSERT(!mTarget); nsIntRegion invalid = mClonedLayerTreeProperties->ComputeDifferences(mRoot, nullptr, &mGeometryChanged); mClonedLayerTreeProperties = nullptr; mInvalidRegion.Or(mInvalidRegion, invalid); } else if (!mTarget) { mInvalidRegion.Or(mInvalidRegion, mRenderBounds); } if (mRoot && !(aFlags & END_NO_IMMEDIATE_REDRAW)) { if (aFlags & END_NO_COMPOSITE) { // Apply pending tree updates before recomputing effective // properties. mRoot->ApplyPendingUpdatesToSubtree(); } // The results of our drawing always go directly into a pixel buffer, // so we don't need to pass any global transform here. mRoot->ComputeEffectiveTransforms(gfx::Matrix4x4()); nsIntRegion opaque; ApplyOcclusionCulling(mRoot, opaque); Render(); #ifdef MOZ_WIDGET_ANDROID RenderToPresentationSurface(); #endif mGeometryChanged = false; } else { // Modified layer tree mGeometryChanged = true; } mCompositor->ClearTargetContext(); mTarget = nullptr; #ifdef MOZ_LAYERS_HAVE_LOG Log(); MOZ_LAYERS_LOG(("]----- EndTransaction")); #endif }