Bug 1042104. Part 1: Cache prerender flag in nsDisplayTransform. r=tn

--HG--
extra : rebase_source : 79f39bb1b0d29cc28b4d492fbf6a497f99ec9dac
This commit is contained in:
Robert O'Callahan 2014-07-30 00:09:35 +12:00
Родитель 372f537079
Коммит cdaa7cd2e4
3 изменённых файлов: 28 добавлений и 17 удалений

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

@ -2861,9 +2861,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList,
// that the transform item can potentially move under into a layer // that the transform item can potentially move under into a layer
// above this item. // above this item.
if (itemType == nsDisplayItem::TYPE_TRANSFORM && if (itemType == nsDisplayItem::TYPE_TRANSFORM &&
nsDisplayTransform::ShouldPrerenderTransformedContent(mBuilder, static_cast<nsDisplayTransform*>(item)->ShouldPrerender()) {
item->Frame(),
false)) {
if (!itemClip.HasClip()) { if (!itemClip.HasClip()) {
// The transform item can move anywhere, treat all other content // The transform item can move anywhere, treat all other content
// as being above this item. // as being above this item.

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

@ -4326,7 +4326,7 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
MOZ_COUNT_CTOR(nsDisplayTransform); MOZ_COUNT_CTOR(nsDisplayTransform);
NS_ABORT_IF_FALSE(aFrame, "Must have a frame!"); NS_ABORT_IF_FALSE(aFrame, "Must have a frame!");
NS_ABORT_IF_FALSE(!aFrame->IsTransformed(), "Can't specify a transform getter for a transformed frame!"); NS_ABORT_IF_FALSE(!aFrame->IsTransformed(), "Can't specify a transform getter for a transformed frame!");
mStoredList.SetClip(aBuilder, DisplayItemClip::NoClip()); Init(aBuilder);
} }
void void
@ -4338,6 +4338,13 @@ nsDisplayTransform::SetReferenceFrameToAncestor(nsDisplayListBuilder* aBuilder)
mVisibleRect = aBuilder->GetDirtyRect() + mToReferenceFrame; mVisibleRect = aBuilder->GetDirtyRect() + mToReferenceFrame;
} }
void
nsDisplayTransform::Init(nsDisplayListBuilder* aBuilder)
{
mStoredList.SetClip(aBuilder, DisplayItemClip::NoClip());
mPrerender = ShouldPrerenderTransformedContent(aBuilder, mFrame);
}
nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
nsIFrame *aFrame, nsDisplayList *aList, nsIFrame *aFrame, nsDisplayList *aList,
const nsRect& aChildrenVisibleRect, const nsRect& aChildrenVisibleRect,
@ -4351,7 +4358,7 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
MOZ_COUNT_CTOR(nsDisplayTransform); MOZ_COUNT_CTOR(nsDisplayTransform);
NS_ABORT_IF_FALSE(aFrame, "Must have a frame!"); NS_ABORT_IF_FALSE(aFrame, "Must have a frame!");
SetReferenceFrameToAncestor(aBuilder); SetReferenceFrameToAncestor(aBuilder);
mStoredList.SetClip(aBuilder, DisplayItemClip::NoClip()); Init(aBuilder);
} }
nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
@ -4367,7 +4374,7 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
MOZ_COUNT_CTOR(nsDisplayTransform); MOZ_COUNT_CTOR(nsDisplayTransform);
NS_ABORT_IF_FALSE(aFrame, "Must have a frame!"); NS_ABORT_IF_FALSE(aFrame, "Must have a frame!");
SetReferenceFrameToAncestor(aBuilder); SetReferenceFrameToAncestor(aBuilder);
mStoredList.SetClip(aBuilder, DisplayItemClip::NoClip()); Init(aBuilder);
} }
/* Returns the delta specified by the -moz-transform-origin property. /* Returns the delta specified by the -moz-transform-origin property.
@ -4690,9 +4697,12 @@ nsDisplayOpacity::CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder)
bool bool
nsDisplayTransform::CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) nsDisplayTransform::CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder)
{ {
return ShouldPrerenderTransformedContent(aBuilder, if (mPrerender) {
Frame(), return true;
nsLayoutUtils::IsAnimationLoggingEnabled()); }
DebugOnly<bool> prerender = ShouldPrerenderTransformedContent(aBuilder, mFrame, true);
NS_ASSERTION(!prerender, "Something changed under us!");
return false;
} }
/* static */ bool /* static */ bool
@ -4789,7 +4799,7 @@ nsDisplayTransform::GetTransform()
bool bool
nsDisplayTransform::ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) nsDisplayTransform::ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder)
{ {
return ShouldPrerenderTransformedContent(aBuilder, mFrame, false); return ShouldPrerender();
} }
already_AddRefed<Layer> nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBuilder, already_AddRefed<Layer> nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBuilder,
@ -4803,8 +4813,7 @@ already_AddRefed<Layer> nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu
return nullptr; return nullptr;
} }
bool prerender = ShouldPrerenderTransformedContent(aBuilder, mFrame, false); uint32_t flags = ShouldPrerender() ?
uint32_t flags = prerender ?
FrameLayerBuilder::CONTAINER_NOT_CLIPPED_BY_ANCESTORS : 0; FrameLayerBuilder::CONTAINER_NOT_CLIPPED_BY_ANCESTORS : 0;
nsRefPtr<ContainerLayer> container = aManager->GetLayerBuilder()-> nsRefPtr<ContainerLayer> container = aManager->GetLayerBuilder()->
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mStoredList.GetChildren(), BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mStoredList.GetChildren(),
@ -4825,7 +4834,7 @@ already_AddRefed<Layer> nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu
nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(container, aBuilder, nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(container, aBuilder,
this, mFrame, this, mFrame,
eCSSProperty_transform); eCSSProperty_transform);
if (prerender) { if (ShouldPrerender()) {
container->SetUserData(nsIFrame::LayerIsPrerenderedDataKey(), container->SetUserData(nsIFrame::LayerIsPrerenderedDataKey(),
/*the value is irrelevant*/nullptr); /*the value is irrelevant*/nullptr);
container->SetContentFlags(container->GetContentFlags() | Layer::CONTENT_MAY_CHANGE_TRANSFORM); container->SetContentFlags(container->GetContentFlags() | Layer::CONTENT_MAY_CHANGE_TRANSFORM);
@ -4878,7 +4887,7 @@ bool nsDisplayTransform::ComputeVisibility(nsDisplayListBuilder *aBuilder,
* think that it's painting in its original rectangular coordinate space. * think that it's painting in its original rectangular coordinate space.
* If we can't untransform, take the entire overflow rect */ * If we can't untransform, take the entire overflow rect */
nsRect untransformedVisibleRect; nsRect untransformedVisibleRect;
if (ShouldPrerenderTransformedContent(aBuilder, mFrame) || if (ShouldPrerender() ||
!UntransformVisibleRect(aBuilder, &untransformedVisibleRect)) !UntransformVisibleRect(aBuilder, &untransformedVisibleRect))
{ {
untransformedVisibleRect = mFrame->GetVisualOverflowRectRelativeToSelf(); untransformedVisibleRect = mFrame->GetVisualOverflowRectRelativeToSelf();
@ -5005,8 +5014,7 @@ nsDisplayTransform::GetHitDepthAtPoint(nsDisplayListBuilder* aBuilder, const nsP
*/ */
nsRect nsDisplayTransform::GetBounds(nsDisplayListBuilder *aBuilder, bool* aSnap) nsRect nsDisplayTransform::GetBounds(nsDisplayListBuilder *aBuilder, bool* aSnap)
{ {
nsRect untransformedBounds = nsRect untransformedBounds = ShouldPrerender() ?
ShouldPrerenderTransformedContent(aBuilder, mFrame) ?
mFrame->GetVisualOverflowRectRelativeToSelf() : mFrame->GetVisualOverflowRectRelativeToSelf() :
mStoredList.GetBounds(aBuilder, aSnap); mStoredList.GetBounds(aBuilder, aSnap);
*aSnap = false; *aSnap = false;
@ -5044,7 +5052,7 @@ nsRegion nsDisplayTransform::GetOpaqueRegion(nsDisplayListBuilder *aBuilder,
// covers the entire window, but it allows our transform to be // covers the entire window, but it allows our transform to be
// updated extremely cheaply, without invalidating any other // updated extremely cheaply, without invalidating any other
// content. // content.
if (ShouldPrerenderTransformedContent(aBuilder, mFrame) || if (ShouldPrerender() ||
!UntransformVisibleRect(aBuilder, &untransformedVisible)) { !UntransformVisibleRect(aBuilder, &untransformedVisible)) {
return nsRegion(); return nsRegion();
} }

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

@ -3369,11 +3369,15 @@ public:
bool aLogAnimations = false); bool aLogAnimations = false);
bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE; bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
bool ShouldPrerender() const { return mPrerender; }
#ifdef MOZ_DUMP_PAINTING #ifdef MOZ_DUMP_PAINTING
virtual void WriteDebugInfo(nsACString& aTo) MOZ_OVERRIDE; virtual void WriteDebugInfo(nsACString& aTo) MOZ_OVERRIDE;
#endif #endif
private: private:
void SetReferenceFrameToAncestor(nsDisplayListBuilder* aBuilder); void SetReferenceFrameToAncestor(nsDisplayListBuilder* aBuilder);
void Init(nsDisplayListBuilder* aBuilder);
static gfx3DMatrix GetResultingTransformMatrixInternal(const FrameTransformProperties& aProperties, static gfx3DMatrix GetResultingTransformMatrixInternal(const FrameTransformProperties& aProperties,
const nsPoint& aOrigin, const nsPoint& aOrigin,
@ -3387,6 +3391,7 @@ private:
ComputeTransformFunction mTransformGetter; ComputeTransformFunction mTransformGetter;
nsRect mChildrenVisibleRect; nsRect mChildrenVisibleRect;
uint32_t mIndex; uint32_t mIndex;
bool mPrerender;
}; };
/** /**