mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
Bug 1098495 - Retain a container's intermediate surface's content. r=mattwoodrow
--HG-- extra : rebase_source : cdb691c1127445eeeb2e4fda5a0ef4f2223703fc
This commit is contained in:
parent
6aea7c3edf
commit
66c7911436
@ -151,13 +151,7 @@ struct LayerPropertiesBase : public LayerProperties
|
||||
result = OldTransformedBounds();
|
||||
AddRegion(result, NewTransformedBounds());
|
||||
|
||||
// If we don't have to generate invalidations separately for child
|
||||
// layers then we can just stop here since we've already invalidated the entire
|
||||
// old and new bounds.
|
||||
if (!aCallback) {
|
||||
ClearInvalidations(mLayer);
|
||||
return result;
|
||||
}
|
||||
// We can't bail out early because we need to update mChildrenChanged.
|
||||
}
|
||||
|
||||
AddRegion(result, ComputeChangeInternal(aCallback, aGeometryChanged));
|
||||
@ -227,19 +221,16 @@ struct ContainerLayerProperties : public LayerPropertiesBase
|
||||
ContainerLayer* container = mLayer->AsContainerLayer();
|
||||
nsIntRegion result;
|
||||
|
||||
bool childrenChanged = false;
|
||||
|
||||
if (mPreXScale != container->GetPreXScale() ||
|
||||
mPreYScale != container->GetPreYScale()) {
|
||||
aGeometryChanged = true;
|
||||
result = OldTransformedBounds();
|
||||
AddRegion(result, NewTransformedBounds());
|
||||
childrenChanged = true;
|
||||
|
||||
// If we don't have to generate invalidations separately for child
|
||||
// layers then we can just stop here since we've already invalidated the entire
|
||||
// old and new bounds.
|
||||
if (!aCallback) {
|
||||
ClearInvalidations(mLayer);
|
||||
return result;
|
||||
}
|
||||
// Can't bail out early, we need to update the child container layers
|
||||
}
|
||||
|
||||
// A low frame rate is especially visible to users when scrolling, so we
|
||||
@ -270,13 +261,18 @@ struct ContainerLayerProperties : public LayerPropertiesBase
|
||||
// encounter them in the new list):
|
||||
for (uint32_t j = i; j < childsOldIndex; ++j) {
|
||||
AddRegion(result, mChildren[j]->OldTransformedBounds());
|
||||
childrenChanged |= true;
|
||||
}
|
||||
// Invalidate any regions of the child that have changed:
|
||||
AddRegion(result, mChildren[childsOldIndex]->ComputeChange(aCallback, aGeometryChanged));
|
||||
// Invalidate any regions of the child that have changed:
|
||||
nsIntRegion region = mChildren[childsOldIndex]->ComputeChange(aCallback, aGeometryChanged);
|
||||
i = childsOldIndex + 1;
|
||||
if (!region.IsEmpty()) {
|
||||
AddRegion(result, region);
|
||||
childrenChanged |= true;
|
||||
}
|
||||
} else {
|
||||
// We've already seen this child in mChildren (which means it must
|
||||
// have been reordered) and invalidated its old area. We need to
|
||||
// have been reordered) and invalidated its old area. We need to
|
||||
// invalidate its new area too:
|
||||
invalidateChildsCurrentArea = true;
|
||||
}
|
||||
@ -297,10 +293,12 @@ struct ContainerLayerProperties : public LayerPropertiesBase
|
||||
ClearInvalidations(child);
|
||||
}
|
||||
}
|
||||
childrenChanged |= invalidateChildsCurrentArea;
|
||||
}
|
||||
|
||||
// Process remaining removed children.
|
||||
while (i < mChildren.Length()) {
|
||||
childrenChanged |= true;
|
||||
AddRegion(result, mChildren[i]->OldTransformedBounds());
|
||||
i++;
|
||||
}
|
||||
@ -309,7 +307,12 @@ struct ContainerLayerProperties : public LayerPropertiesBase
|
||||
aCallback(container, result);
|
||||
}
|
||||
|
||||
if (childrenChanged) {
|
||||
container->SetChildrenChanged(true);
|
||||
}
|
||||
|
||||
result.Transform(gfx::To3DMatrix(mLayer->GetLocalTransform()));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -830,7 +830,8 @@ ContainerLayer::ContainerLayer(LayerManager* aManager, void* aImplData)
|
||||
mInheritedYScale(1.0f),
|
||||
mUseIntermediateSurface(false),
|
||||
mSupportsComponentAlphaChildren(false),
|
||||
mMayHaveReadbackChild(false)
|
||||
mMayHaveReadbackChild(false),
|
||||
mChildrenChanged(false)
|
||||
{
|
||||
mContentFlags = 0; // Clear NO_TEXT, NO_TEXT_OVER_TRANSPARENT
|
||||
}
|
||||
|
@ -1889,6 +1889,10 @@ public:
|
||||
*/
|
||||
static bool HasOpaqueAncestorLayer(Layer* aLayer);
|
||||
|
||||
void SetChildrenChanged(bool aVal) {
|
||||
mChildrenChanged = aVal;
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class ReadbackProcessor;
|
||||
|
||||
@ -1931,6 +1935,9 @@ protected:
|
||||
bool mUseIntermediateSurface;
|
||||
bool mSupportsComponentAlphaChildren;
|
||||
bool mMayHaveReadbackChild;
|
||||
// This is updated by ComputeDifferences. This will be true if we need to invalidate
|
||||
// the intermediate surface.
|
||||
bool mChildrenChanged;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -91,6 +91,15 @@ static void DrawLayerInfo(const RenderTargetIntRect& aClipRect,
|
||||
maxWidth);
|
||||
}
|
||||
|
||||
template<class ContainerT>
|
||||
static gfx::IntRect ContainerVisibleRect(ContainerT* aContainer)
|
||||
{
|
||||
nsIntRect visibleRect = aContainer->GetEffectiveVisibleRegion().GetBounds();
|
||||
gfx::IntRect surfaceRect = gfx::IntRect(visibleRect.x, visibleRect.y,
|
||||
visibleRect.width, visibleRect.height);
|
||||
return surfaceRect;
|
||||
}
|
||||
|
||||
static void PrintUniformityInfo(Layer* aLayer)
|
||||
{
|
||||
#ifdef MOZ_ENABLE_PROFILER_SPS
|
||||
@ -179,14 +188,28 @@ ContainerPrepare(ContainerT* aContainer,
|
||||
// DefaultComputeSupportsComponentAlphaChildren can mutate aContainer so call it unconditionally
|
||||
aContainer->DefaultComputeSupportsComponentAlphaChildren(&surfaceCopyNeeded);
|
||||
if (aContainer->UseIntermediateSurface()) {
|
||||
MOZ_PERFORMANCE_WARNING("gfx", "[%p] Container layer requires intermediate surface\n", aContainer);
|
||||
if (!surfaceCopyNeeded) {
|
||||
// If we don't need a copy we can render to the intermediate now to avoid
|
||||
// unecessary render target switching. This brings a big perf boost on mobile gpus.
|
||||
RefPtr<CompositingRenderTarget> surface = CreateTemporaryTarget(aContainer, aManager);
|
||||
RenderIntermediate(aContainer, aManager, RenderTargetPixel::ToUntyped(aClipRect), surface);
|
||||
RefPtr<CompositingRenderTarget> surface = nullptr;
|
||||
|
||||
RefPtr<CompositingRenderTarget>& lastSurf = aContainer->mLastIntermediateSurface;
|
||||
gfx::IntRect surfaceRect = ContainerVisibleRect(aContainer);
|
||||
if (lastSurf && !aContainer->mChildrenChanged && lastSurf->GetRect().IsEqualEdges(surfaceRect)) {
|
||||
surface = lastSurf;
|
||||
}
|
||||
|
||||
if (!surface) {
|
||||
// If we don't need a copy we can render to the intermediate now to avoid
|
||||
// unecessary render target switching. This brings a big perf boost on mobile gpus.
|
||||
surface = CreateOrRecycleTarget(aContainer, aManager);
|
||||
|
||||
MOZ_PERFORMANCE_WARNING("gfx", "[%p] Container layer requires intermediate surface rendering\n", aContainer);
|
||||
RenderIntermediate(aContainer, aManager, RenderTargetPixel::ToUntyped(aClipRect), surface);
|
||||
aContainer->SetChildrenChanged(false);
|
||||
}
|
||||
|
||||
aContainer->mPrepared->mTmpTarget = surface;
|
||||
} else {
|
||||
MOZ_PERFORMANCE_WARNING("gfx", "[%p] Container layer requires intermediate surface copy\n", aContainer);
|
||||
aContainer->mPrepared->mNeedsSurfaceCopy = true;
|
||||
aContainer->mLastIntermediateSurface = nullptr;
|
||||
}
|
||||
@ -269,14 +292,12 @@ RenderLayers(ContainerT* aContainer,
|
||||
}
|
||||
|
||||
template<class ContainerT> RefPtr<CompositingRenderTarget>
|
||||
CreateTemporaryTarget(ContainerT* aContainer,
|
||||
CreateOrRecycleTarget(ContainerT* aContainer,
|
||||
LayerManagerComposite* aManager)
|
||||
{
|
||||
Compositor* compositor = aManager->GetCompositor();
|
||||
nsIntRect visibleRect = aContainer->GetEffectiveVisibleRegion().GetBounds();
|
||||
SurfaceInitMode mode = INIT_MODE_CLEAR;
|
||||
gfx::IntRect surfaceRect = gfx::IntRect(visibleRect.x, visibleRect.y,
|
||||
visibleRect.width, visibleRect.height);
|
||||
gfx::IntRect surfaceRect = ContainerVisibleRect(aContainer);
|
||||
if (aContainer->GetEffectiveVisibleRegion().GetNumRects() == 1 &&
|
||||
(aContainer->GetContentFlags() & Layer::CONTENT_OPAQUE))
|
||||
{
|
||||
@ -534,3 +555,4 @@ RefLayerComposite::CleanupResources()
|
||||
|
||||
} /* layers */
|
||||
} /* mozilla */
|
||||
|
||||
|
@ -48,7 +48,7 @@ class ContainerLayerComposite : public ContainerLayer,
|
||||
const RenderTargetIntRect& aClipRect);
|
||||
template<class ContainerT>
|
||||
friend RefPtr<CompositingRenderTarget>
|
||||
CreateTemporaryTarget(ContainerT* aContainer,
|
||||
CreateOrRecycleTarget(ContainerT* aContainer,
|
||||
LayerManagerComposite* aManager,
|
||||
const RenderTargetIntRect& aClipRect);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user