Bug 1141468 - Clean up prerendering code in nsDisplayTransform to be easier to follow. r=mstange

--HG--
extra : rebase_source : ae9ded54e633e2ebffaeb8fef0b47a2d041dab1f
This commit is contained in:
Matt Woodrow 2016-05-18 15:12:44 +12:00
Родитель 4258a918f0
Коммит 654125d823
5 изменённых файлов: 26 добавлений и 47 удалений

Просмотреть файл

@ -3903,7 +3903,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
}
nsIntRect itemDrawRect = ScaleToOutsidePixels(itemContent, snap);
bool prerenderedTransform = itemType == nsDisplayItem::TYPE_TRANSFORM &&
static_cast<nsDisplayTransform*>(item)->ShouldPrerender();
static_cast<nsDisplayTransform*>(item)->MayBeAnimated(mBuilder);
ParentLayerIntRect clipRect;
const DisplayItemClip& itemClip = item->GetClip();
if (itemClip.HasClip()) {

Просмотреть файл

@ -217,8 +217,6 @@ public:
void DidEndTransaction();
enum {
CONTAINER_NOT_CLIPPED_BY_ANCESTORS = 0x01,
/**
* Set this when pulling an opaque background color from behind the
* container layer into the container doesn't change the visual results,
@ -226,7 +224,7 @@ public:
* For example, this is compatible with opacity or clipping/masking, but
* not with non-OVER blend modes or filters.
*/
CONTAINER_ALLOW_PULL_BACKGROUND_COLOR = 0x02
CONTAINER_ALLOW_PULL_BACKGROUND_COLOR = 0x01
};
/**
* Build a container layer for a display item that contains a child

Просмотреть файл

@ -5269,6 +5269,7 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
, mNoExtendContext(false)
, mIsTransformSeparator(false)
, mTransformPreserves3DInited(false)
, mIsFullyVisible(false)
{
MOZ_COUNT_CTOR(nsDisplayTransform);
MOZ_ASSERT(aFrame, "Must have a frame!");
@ -5318,16 +5319,13 @@ nsDisplayTransform::Init(nsDisplayListBuilder* aBuilder)
mHasBounds = false;
mStoredList.SetClip(aBuilder, DisplayItemClip::NoClip());
mStoredList.SetVisibleRect(mChildrenVisibleRect);
// If this is true, then BuildDisplayListForStacking context should have already
// set the correct visible region and made sure we built all the necessary
// descendant display items.
mPrerender = ShouldPrerenderTransformedContent(aBuilder, mFrame);
}
nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
nsIFrame *aFrame, nsDisplayList *aList,
const nsRect& aChildrenVisibleRect,
uint32_t aIndex)
uint32_t aIndex,
bool aIsFullyVisible)
: nsDisplayItem(aBuilder, aFrame)
, mStoredList(aBuilder, aFrame, aList)
, mTransformGetter(nullptr)
@ -5338,6 +5336,7 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
, mNoExtendContext(false)
, mIsTransformSeparator(false)
, mTransformPreserves3DInited(false)
, mIsFullyVisible(aIsFullyVisible)
{
MOZ_COUNT_CTOR(nsDisplayTransform);
MOZ_ASSERT(aFrame, "Must have a frame!");
@ -5360,6 +5359,7 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
, mNoExtendContext(false)
, mIsTransformSeparator(false)
, mTransformPreserves3DInited(false)
, mIsFullyVisible(false)
{
MOZ_COUNT_CTOR(nsDisplayTransform);
MOZ_ASSERT(aFrame, "Must have a frame!");
@ -5383,6 +5383,7 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
, mNoExtendContext(false)
, mIsTransformSeparator(true)
, mTransformPreserves3DInited(false)
, mIsFullyVisible(false)
{
MOZ_COUNT_CTOR(nsDisplayTransform);
MOZ_ASSERT(aFrame, "Must have a frame!");
@ -5783,15 +5784,10 @@ nsDisplayOpacity::CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder)
return false;
}
bool
nsDisplayTransform::ShouldPrerender() {
return mPrerender;
}
bool
nsDisplayTransform::CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder)
{
return mPrerender;
return mIsFullyVisible;
}
/* static */ bool
@ -5935,7 +5931,7 @@ nsDisplayTransform::ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuild
// The visible rect of a Preserves-3D frame is just an intermediate
// result. It should always build a layer to make sure it is
// rendering correctly.
return ShouldPrerender() || mFrame->Combines3DTransformWithAncestors();
return MayBeAnimated(aBuilder) || mFrame->Combines3DTransformWithAncestors();
}
already_AddRefed<Layer> nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBuilder,
@ -5948,9 +5944,7 @@ already_AddRefed<Layer> nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu
*/
const Matrix4x4& newTransformMatrix = GetTransformForRendering();
uint32_t flags = ShouldPrerender() ?
FrameLayerBuilder::CONTAINER_NOT_CLIPPED_BY_ANCESTORS : 0;
flags |= FrameLayerBuilder::CONTAINER_ALLOW_PULL_BACKGROUND_COLOR;
uint32_t flags = FrameLayerBuilder::CONTAINER_ALLOW_PULL_BACKGROUND_COLOR;
RefPtr<ContainerLayer> container = aManager->GetLayerBuilder()->
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mStoredList.GetChildren(),
aContainerParameters, &newTransformMatrix, flags);
@ -5970,7 +5964,7 @@ already_AddRefed<Layer> nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu
nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(container, aBuilder,
this, mFrame,
eCSSProperty_transform);
if (ShouldPrerender()) {
if (mIsFullyVisible) {
if (MayBeAnimated(aBuilder)) {
// Only allow async updates to the transform if we're an animated layer, since that's what
// triggers us to set the correct AGR in the constructor and makes sure FrameLayerBuilder
@ -6038,8 +6032,7 @@ bool nsDisplayTransform::ComputeVisibility(nsDisplayListBuilder *aBuilder,
* think that it's painting in its original rectangular coordinate space.
* If we can't untransform, take the entire overflow rect */
nsRect untransformedVisibleRect;
if (ShouldPrerender() ||
!UntransformVisibleRect(aBuilder, &untransformedVisibleRect))
if (!UntransformVisibleRect(aBuilder, &untransformedVisibleRect))
{
untransformedVisibleRect = mFrame->GetVisualOverflowRectRelativeToSelf();
}
@ -6184,9 +6177,7 @@ nsDisplayTransform::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
return nsRect();
}
nsRect untransformedBounds = ShouldPrerender() ?
mFrame->GetVisualOverflowRectRelativeToSelf() :
mStoredList.GetBounds(aBuilder, aSnap);
nsRect untransformedBounds = mStoredList.GetBounds(aBuilder, aSnap);
// GetTransform always operates in dev pixels.
float factor = mFrame->PresContext()->AppUnitsPerDevPixel();
mBounds = nsLayoutUtils::MatrixTransformRect(untransformedBounds,
@ -6223,9 +6214,7 @@ nsDisplayTransform::ComputeBounds(nsDisplayListBuilder* aBuilder)
* nsDisplayListBuilder.
*/
bool snap;
nsRect untransformedBounds = ShouldPrerender() ?
mFrame->GetVisualOverflowRectRelativeToSelf() :
mStoredList.GetBounds(aBuilder, &snap);
nsRect untransformedBounds = mStoredList.GetBounds(aBuilder, &snap);
// GetTransform always operates in dev pixels.
float factor = mFrame->PresContext()->AppUnitsPerDevPixel();
nsRect rect =
@ -6257,14 +6246,7 @@ nsRegion nsDisplayTransform::GetOpaqueRegion(nsDisplayListBuilder *aBuilder,
{
*aSnap = false;
nsRect untransformedVisible;
// If we're going to prerender all our content, pretend like we
// don't have opqaue content so that everything under us is rendered
// as well. That will increase graphics memory usage if our frame
// covers the entire window, but it allows our transform to be
// updated extremely cheaply, without invalidating any other
// content.
if (ShouldPrerender() ||
!UntransformVisibleRect(aBuilder, &untransformedVisible)) {
if (!UntransformVisibleRect(aBuilder, &untransformedVisible)) {
return nsRegion();
}
@ -6592,8 +6574,7 @@ nsDisplayVR::BuildLayer(nsDisplayListBuilder* aBuilder,
const ContainerLayerParameters& aContainerParameters)
{
ContainerLayerParameters newContainerParameters = aContainerParameters;
uint32_t flags = FrameLayerBuilder::CONTAINER_NOT_CLIPPED_BY_ANCESTORS |
FrameLayerBuilder::CONTAINER_ALLOW_PULL_BACKGROUND_COLOR;
uint32_t flags = FrameLayerBuilder::CONTAINER_ALLOW_PULL_BACKGROUND_COLOR;
RefPtr<ContainerLayer> container = aManager->GetLayerBuilder()->
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, &mList,
newContainerParameters, nullptr, flags);

Просмотреть файл

@ -3898,7 +3898,7 @@ public:
*/
nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
nsDisplayList *aList, const nsRect& aChildrenVisibleRect,
uint32_t aIndex = 0);
uint32_t aIndex = 0, bool aIsFullyVisible = false);
nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
nsDisplayItem *aItem, const nsRect& aChildrenVisibleRect,
uint32_t aIndex = 0);
@ -4116,12 +4116,6 @@ public:
bool MayBeAnimated(nsDisplayListBuilder* aBuilder);
/**
* Check if this element will be prerendered. This must be done after the
* display list has been fully built.
*/
bool ShouldPrerender();
virtual void WriteDebugInfo(std::stringstream& aStream) override;
// Force the layer created for this item not to extend 3D context.
@ -4206,7 +4200,6 @@ private:
nsRect mBounds;
// True for mBounds is valid.
bool mHasBounds;
bool mPrerender;
// Be forced not to extend 3D context. Since we don't create a
// transform item, a container layer, for every frames in a
// preserves3d context, the transform items of a child preserves3d
@ -4219,6 +4212,9 @@ private:
bool mIsTransformSeparator;
// True if mTransformPreserves3D have been initialized.
bool mTransformPreserves3DInited;
// True if the entire untransformed area has been treated as
// visible during display list construction.
bool mIsFullyVisible;
};
/* A display item that applies a perspective transformation to a single

Просмотреть файл

@ -2513,8 +2513,12 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
if (!aBuilder->IsForGenerateGlyphMask() &&
!aBuilder->IsForPaintingSelectionBG()) {
bool isFullyVisible =
dirtyRectOutsideSVGEffects.Contains(GetVisualOverflowRectRelativeToSelf());
nsDisplayTransform *transformItem =
new (aBuilder) nsDisplayTransform(aBuilder, this, &resultList, dirtyRect);
new (aBuilder) nsDisplayTransform(aBuilder, this,
&resultList, dirtyRect, 0,
isFullyVisible);
resultList.AppendNewToTop(transformItem);
}