Bug 706179 Part 3: Turn on the use of scaling for layers in FrameLayerBuilder r=mattwoodrow

This commit is contained in:
David Zbarsky 2012-08-03 14:29:22 -07:00
parent 4d39917778
commit a2c20d2493
14 changed files with 148 additions and 67 deletions

View File

@ -228,8 +228,8 @@ Layer::Layer(LayerManager* aManager, void* aImplData) :
mPrevSibling(nullptr),
mImplData(aImplData),
mMaskLayer(nullptr),
mXScale(1.0f),
mYScale(1.0f),
mPostXScale(1.0f),
mPostYScale(1.0f),
mOpacity(1.0),
mContentFlags(0),
mUseClipRect(false),
@ -605,7 +605,10 @@ const gfx3DMatrix
Layer::GetTransform()
{
gfx3DMatrix transform = mTransform;
transform.Scale(mXScale, mYScale, 1);
if (ContainerLayer* c = AsContainerLayer()) {
transform.Scale(c->GetPreXScale(), c->GetPreYScale(), 1.0f);
}
transform.ScalePost(mPostXScale, mPostYScale, 1.0f);
return transform;
}
@ -617,7 +620,10 @@ Layer::GetLocalTransform()
transform = shadow->GetShadowTransform();
else
transform = mTransform;
transform.Scale(mXScale, mYScale, 1);
if (ContainerLayer* c = AsContainerLayer()) {
transform.Scale(c->GetPreXScale(), c->GetPreYScale(), 1.0f);
}
transform.ScalePost(mPostXScale, mPostYScale, 1.0f);
return transform;
}
@ -658,7 +664,7 @@ Layer::ComputeEffectiveTransformForMaskLayer(const gfx3DMatrix& aTransformToSurf
void
ContainerLayer::FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
{
aAttrs = ContainerLayerAttributes(GetFrameMetrics());
aAttrs = ContainerLayerAttributes(GetFrameMetrics(), mPreXScale, mPreYScale);
}
bool
@ -944,6 +950,9 @@ Layer::PrintInfo(nsACString& aTo, const char* aPrefix)
if (mUseClipRect) {
AppendToString(aTo, mClipRect, " [clip=", "]");
}
if (1.0 != mPostXScale || 1.0 != mPostYScale) {
aTo.AppendPrintf(" [postScale=%g, %g]", mPostXScale, mPostYScale);
}
if (!mTransform.IsIdentity()) {
AppendToString(aTo, mTransform, " [transform=", "]");
}
@ -986,6 +995,9 @@ ContainerLayer::PrintInfo(nsACString& aTo, const char* aPrefix)
if (UseIntermediateSurface()) {
aTo += " [usesTmpSurf]";
}
if (1.0 != mPreXScale || 1.0 != mPreYScale) {
aTo.AppendPrintf(" [preScale=%g, %g]", mPreXScale, mPreYScale);
}
return aTo;
}

View File

@ -654,10 +654,10 @@ public:
Mutated();
}
void SetScale(float aXScale, float aYScale)
void SetPostScale(float aXScale, float aYScale)
{
mXScale = aXScale;
mYScale = aYScale;
mPostXScale = aXScale;
mPostYScale = aYScale;
Mutated();
}
@ -698,8 +698,8 @@ public:
virtual Layer* GetLastChild() { return nullptr; }
const gfx3DMatrix GetTransform();
const gfx3DMatrix& GetBaseTransform() { return mTransform; }
float GetXScale() { return mXScale; }
float GetYScale() { return mYScale; }
float GetPostXScale() { return mPostXScale; }
float GetPostYScale() { return mPostYScale; }
bool GetIsFixedPosition() { return mIsFixedPosition; }
gfxPoint GetFixedPositionAnchor() { return mAnchor; }
Layer* GetMaskLayer() { return mMaskLayer; }
@ -953,8 +953,8 @@ protected:
gfx::UserData mUserData;
nsIntRegion mVisibleRegion;
gfx3DMatrix mTransform;
float mXScale;
float mYScale;
float mPostXScale;
float mPostYScale;
gfx3DMatrix mEffectiveTransform;
AnimationArray mAnimations;
InfallibleTArray<AnimData> mAnimationData;
@ -1108,6 +1108,13 @@ public:
Mutated();
}
void SetPreScale(float aXScale, float aYScale)
{
mPreXScale = aXScale;
mPreYScale = aYScale;
Mutated();
}
virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs);
void SortChildrenBy3DZOrder(nsTArray<Layer*>& aArray);
@ -1119,6 +1126,8 @@ public:
virtual Layer* GetFirstChild() { return mFirstChild; }
virtual Layer* GetLastChild() { return mLastChild; }
const FrameMetrics& GetFrameMetrics() { return mFrameMetrics; }
float GetPreXScale() { return mPreXScale; }
float GetPreYScale() { return mPreYScale; }
MOZ_LAYER_DECL_NAME("ContainerLayer", TYPE_CONTAINER)
@ -1169,6 +1178,8 @@ protected:
: Layer(aManager, aImplData),
mFirstChild(nullptr),
mLastChild(nullptr),
mPreXScale(1.0f),
mPreYScale(1.0f),
mUseIntermediateSurface(false),
mSupportsComponentAlphaChildren(false),
mMayHaveReadbackChild(false)
@ -1192,6 +1203,8 @@ protected:
Layer* mFirstChild;
Layer* mLastChild;
FrameMetrics mFrameMetrics;
float mPreXScale;
float mPreYScale;
bool mUseIntermediateSurface;
bool mSupportsComponentAlphaChildren;
bool mMayHaveReadbackChild;

View File

@ -697,8 +697,7 @@ void AsyncPanZoomController::RequestContentRepaint() {
}
bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSampleTime,
const FrameMetrics& aFrame,
Layer* aLayer,
ContainerLayer* aLayer,
gfx3DMatrix* aNewTransform) {
// The eventual return value of this function. The compositor needs to know
// whether or not to advance by a frame as soon as it can. For example, if a
@ -716,7 +715,7 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
nsIntPoint metricsScrollOffset(0, 0);
nsIntPoint scrollOffset;
float localScaleX, localScaleY;
const FrameMetrics& frame = aLayer->GetFrameMetrics();
{
MonitorAutoLock mon(mMonitor);
@ -731,8 +730,8 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
localScaleX = mFrameMetrics.mResolution.width;
localScaleY = mFrameMetrics.mResolution.height;
if (aFrame.IsScrollable()) {
metricsScrollOffset = aFrame.mViewportScrollOffset;
if (frame.IsScrollable()) {
metricsScrollOffset = frame.mViewportScrollOffset;
}
scrollOffset = mFrameMetrics.mViewportScrollOffset;
@ -748,9 +747,12 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
// The transform already takes the resolution scale into account. Since we
// will apply the resolution scale again when computing the effective
// transform, we must apply the inverse resolution scale here.
aNewTransform->Scale(1.0f/aLayer->GetXScale(),
1.0f/aLayer->GetYScale(),
aNewTransform->Scale(1.0f/aLayer->GetPreXScale(),
1.0f/aLayer->GetPreYScale(),
1);
aNewTransform->ScalePost(1.0f/aLayer->GetPostXScale(),
1.0f/aLayer->GetPostYScale(),
1);
mLastSampleTime = aSampleTime;

View File

@ -20,6 +20,7 @@ namespace layers {
class CompositorParent;
class GestureEventListener;
class ContainerLayer;
/**
* Controller for all panning and zooming logic. Any time a user input is
@ -117,8 +118,7 @@ public:
* composite.
*/
bool SampleContentTransformForFrame(const TimeStamp& aSampleTime,
const FrameMetrics& aFrame,
Layer* aLayer,
ContainerLayer* aLayer,
gfx3DMatrix* aNewTransform);
/**

View File

@ -418,6 +418,16 @@ private:
gfx3DMatrix m(aContainer->GetTransform());
m.Translate(gfxPoint3D(-fm.mViewportScrollOffset.x,
-fm.mViewportScrollOffset.y, 0));
// The transform already takes the resolution scale into account. Since we
// will apply the resolution scale again when computing the effective
// transform, we must apply the inverse resolution scale here.
m.Scale(1.0f/c->GetPreXScale(),
1.0f/c->GetPreYScale(),
1);
m.ScalePost(1.0f/c->GetPostXScale(),
1.0f/c->GetPostYScale(),
1);
aContainer->AsShadowLayer()->SetShadowTransform(m);
}
@ -519,11 +529,19 @@ CompositorParent::TransformFixedLayers(Layer* aLayer,
gfxPoint translation(aTranslation.x - (anchor.x - anchor.x / aScaleDiff.x),
aTranslation.y - (anchor.y - anchor.y / aScaleDiff.y));
// We are only translating the transform, so it is OK to translate the
// transform without the resolution scale. This allows us to avoid applying
// the resolution scale and its inverse an extra time.
gfx3DMatrix layerTransform = aLayer->GetBaseTransform();
// The transform already takes the resolution scale into account. Since we
// will apply the resolution scale again when computing the effective
// transform, we must apply the inverse resolution scale here.
gfx3DMatrix layerTransform = aLayer->GetTransform();
Translate2D(layerTransform, translation);
if (ContainerLayer* c = aLayer->AsContainerLayer()) {
layerTransform.Scale(1.0f/c->GetPreXScale(),
1.0f/c->GetPreYScale(),
1);
}
layerTransform.ScalePost(1.0f/aLayer->GetPostXScale(),
1.0f/aLayer->GetPostYScale(),
1);
ShadowLayer* shadow = aLayer->AsShadowLayer();
shadow->SetShadowTransform(layerTransform);
@ -691,8 +709,7 @@ CompositorParent::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFrame,
gfx3DMatrix newTransform;
*aWantNextFrame |=
controller->SampleContentTransformForFrame(aCurrentFrame,
container->GetFrameMetrics(),
aLayer,
container,
&newTransform);
shadow->SetShadowTransform(newTransform);
@ -724,7 +741,7 @@ CompositorParent::TransformShadowTree(TimeStamp aCurrentFrame)
// FIXME/bug 775437: unify this interface with the ~native-fennec
// derived code
//
//
// Attempt to apply an async content transform to any layer that has
// an async pan zoom controller (which means that it is rendered
// async using Gecko). If this fails, fall back to transforming the
@ -814,9 +831,12 @@ CompositorParent::TransformShadowTree(TimeStamp aCurrentFrame)
// will apply the resolution scale again when computing the effective
// transform, we must apply the inverse resolution scale here.
gfx3DMatrix computedTransform = treeTransform * currentTransform;
computedTransform.Scale(1.0f/layer->GetXScale(),
1.0f/layer->GetYScale(),
computedTransform.Scale(1.0f/container->GetPreXScale(),
1.0f/container->GetPreYScale(),
1);
computedTransform.ScalePost(1.0f/container->GetPostXScale(),
1.0f/container->GetPostYScale(),
1);
shadow->SetShadowTransform(computedTransform);
TransformFixedLayers(layer, offset, scaleDiff);
}

View File

@ -165,8 +165,8 @@ struct Animation {
struct CommonLayerAttributes {
nsIntRegion visibleRegion;
TransformMatrix transform;
float xScale;
float yScale;
float postXScale;
float postYScale;
PRUint32 contentFlags;
Opacity opacity;
bool useClipRect;
@ -181,11 +181,15 @@ struct CommonLayerAttributes {
struct ThebesLayerAttributes {
nsIntRegion validRegion;
};
struct ContainerLayerAttributes{ FrameMetrics metrics; };
struct ColorLayerAttributes { Color color; };
struct CanvasLayerAttributes { GraphicsFilterType filter; };
struct RefLayerAttributes { int64_t id; };
struct ImageLayerAttributes {
struct ContainerLayerAttributes {
FrameMetrics metrics;
float preXScale;
float preYScale;
};
struct ColorLayerAttributes { Color color; };
struct CanvasLayerAttributes { GraphicsFilterType filter; };
struct RefLayerAttributes { int64_t id; };
struct ImageLayerAttributes {
GraphicsFilterType filter;
bool forceSingleTile;
};

View File

@ -298,8 +298,8 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies)
LayerAttributes attrs;
CommonLayerAttributes& common = attrs.common();
common.visibleRegion() = mutant->GetVisibleRegion();
common.xScale() = mutant->GetXScale();
common.yScale() = mutant->GetYScale();
common.postXScale() = mutant->GetPostXScale();
common.postYScale() = mutant->GetPostYScale();
common.transform() = mutant->GetBaseTransform();
common.contentFlags() = mutant->GetContentFlags();
common.opacity() = mutant->GetOpacity();

View File

@ -217,7 +217,7 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
layer->SetOpacity(common.opacity().value());
layer->SetClipRect(common.useClipRect() ? &common.clipRect() : NULL);
layer->SetBaseTransform(common.transform().value());
layer->SetScale(common.xScale(), common.yScale());
layer->SetPostScale(common.postXScale(), common.postYScale());
static bool fixedPositionLayersEnabled = getenv("MOZ_ENABLE_FIXED_POSITION_LAYERS") != 0;
if (fixedPositionLayersEnabled) {
layer->SetIsFixedPosition(common.isFixedPosition());
@ -248,13 +248,17 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
break;
}
case Specific::TContainerLayerAttributes:
case Specific::TContainerLayerAttributes: {
MOZ_LAYERS_LOG(("[ParentSide] container layer"));
static_cast<ContainerLayer*>(layer)->SetFrameMetrics(
specific.get_ContainerLayerAttributes().metrics());
ContainerLayer* containerLayer =
static_cast<ContainerLayer*>(layer);
const ContainerLayerAttributes& attrs =
specific.get_ContainerLayerAttributes();
containerLayer->SetFrameMetrics(attrs.metrics());
containerLayer->SetPreScale(attrs.preXScale(), attrs.preYScale());
break;
}
case Specific::TColorLayerAttributes:
MOZ_LAYERS_LOG(("[ParentSide] color layer"));

View File

@ -182,6 +182,25 @@ gfx3DMatrix::TranslatePost(const gfxPoint3D& aPoint)
_43 += _44 * aPoint.z;
}
void
gfx3DMatrix::ScalePost(float aX, float aY, float aZ)
{
_11 *= aX;
_21 *= aX;
_31 *= aX;
_41 *= aX;
_12 *= aY;
_22 *= aY;
_32 *= aY;
_42 *= aY;
_13 *= aZ;
_23 *= aZ;
_33 *= aZ;
_43 *= aZ;
}
void
gfx3DMatrix::SkewXY(double aSkew)
{

View File

@ -213,7 +213,7 @@ public:
* a single transformation and post-multiply it onto the current
* matrix.
*/
/**
* Add a translation by aPoint after the matrix.
* This is functionally equivalent to:
@ -221,6 +221,8 @@ public:
*/
void TranslatePost(const gfxPoint3D& aPoint);
void ScalePost(float aX, float aY, float aZ);
/**
* Transforms a point according to this matrix.
*/

View File

@ -947,7 +947,6 @@ ContainerState::CreateOrRecycleColorLayer()
// We will reapply any necessary clipping.
layer->SetClipRect(nullptr);
layer->SetMaskLayer(nullptr);
layer->SetScale(1.0f, 1.0f);
} else {
// Create a new layer
layer = mManager->CreateColorLayer();
@ -971,7 +970,6 @@ ContainerState::CreateOrRecycleImageLayer()
// We will reapply any necessary clipping.
layer->SetClipRect(nullptr);
layer->SetMaskLayer(nullptr);
layer->SetScale(1.0f, 1.0f);
} else {
// Create a new layer
layer = mManager->CreateImageLayer();
@ -1063,7 +1061,6 @@ ContainerState::CreateOrRecycleThebesLayer(nsIFrame* aActiveScrolledRoot)
// We will reapply any necessary clipping.
layer->SetClipRect(nullptr);
layer->SetMaskLayer(nullptr);
layer->SetScale(1.0f, 1.0f);
data = static_cast<ThebesDisplayItemLayerUserData*>
(layer->GetUserData(&gThebesDisplayItemLayerUserData));
@ -1118,7 +1115,6 @@ ContainerState::CreateOrRecycleThebesLayer(nsIFrame* aActiveScrolledRoot)
gfxMatrix matrix;
matrix.Translate(gfxPoint(pixOffset.x, pixOffset.y));
layer->SetBaseTransform(gfx3DMatrix::From2D(matrix));
layer->SetScale(1.0f, 1.0f);
// FIXME: Temporary workaround for bug 681192 and bug 724786.
#ifndef MOZ_JAVA_COMPOSITOR
@ -1270,10 +1266,8 @@ ContainerState::PopThebesLayerData()
nsRefPtr<ImageLayer> imageLayer = CreateOrRecycleImageLayer();
imageLayer->SetContainer(imageContainer);
data->mImage->ConfigureLayer(imageLayer);
// The layer's current transform is applied first, then the result is scaled.
gfx3DMatrix transform = imageLayer->GetTransform()*
gfx3DMatrix::ScalingMatrix(mParameters.mXScale, mParameters.mYScale, 1.0f);
imageLayer->SetBaseTransform(transform);
imageLayer->SetPostScale(mParameters.mXScale,
mParameters.mYScale);
if (data->mItemClip.mHaveClipRect) {
nsIntRect clip = ScaleToNearestPixels(data->mItemClip.mClipRect);
imageLayer->IntersectClipRect(clip);
@ -1286,8 +1280,8 @@ ContainerState::PopThebesLayerData()
// Copy transform
colorLayer->SetBaseTransform(data->mLayer->GetBaseTransform());
colorLayer->SetScale(data->mLayer->GetXScale(), data->mLayer->GetYScale());
colorLayer->SetPostScale(data->mLayer->GetPostXScale(), data->mLayer->GetPostYScale());
// Clip colorLayer to its visible region, since ColorLayers are
// allowed to paint outside the visible region. Here we rely on the
// fact that uniform display items fill rectangles; obviously the
@ -1782,10 +1776,8 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
// If it's not a ContainerLayer, we need to apply the scale transform
// ourselves.
if (!ownLayer->AsContainerLayer()) {
// The layer's current transform is applied first, then the result is scaled.
gfx3DMatrix transform = ownLayer->GetTransform()*
gfx3DMatrix::ScalingMatrix(mParameters.mXScale, mParameters.mYScale, 1.0f);
ownLayer->SetBaseTransform(transform);
ownLayer->SetPostScale(mParameters.mXScale,
mParameters.mYScale);
}
ownLayer->SetIsFixedPosition(
@ -2129,9 +2121,10 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder,
scale = gfxSize(1.0, 1.0);
}
// Apply the inverse of our resolution-scale before the rest of our transform
transform = gfx3DMatrix::ScalingMatrix(1.0/scale.width, 1.0/scale.height, 1.0)*transform;
// Store the inverse of our resolution-scale on the layer
aLayer->SetBaseTransform(transform);
aLayer->SetPreScale(1.0f/float(scale.width),
1.0f/float(scale.height));
FrameLayerBuilder::ContainerParameters
result(scale.width, scale.height, aIncomingScale);
@ -2338,7 +2331,7 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
Clip clip;
state.ProcessDisplayItems(aChildren, clip, stateFlags);
// Set CONTENT_COMPONENT_ALPHA if any of our children have it.
// This is suboptimal ... a child could have text that's over transparent
// pixels in its own layer, but over opaque parts of previous siblings.

View File

@ -989,8 +989,8 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
return;
}
// Root is being scaled up by the X/Y resolution. Scale it back down.
root->SetScale(1.0f/containerParameters.mXScale,
1.0f/containerParameters.mYScale);
root->SetPostScale(1.0f/containerParameters.mXScale,
1.0f/containerParameters.mYScale);
ViewID id = presContext->IsRootContentDocument() ? FrameMetrics::ROOT_SCROLL_ID
: FrameMetrics::NULL_SCROLL_ID;
@ -1650,7 +1650,6 @@ nsDisplayBackground::ConfigureLayer(ImageLayer* aLayer)
transform.Scale(mDestRect.width/imageSize.width,
mDestRect.height/imageSize.height);
aLayer->SetBaseTransform(gfx3DMatrix::From2D(transform));
aLayer->SetVisibleRegion(nsIntRect(0, 0, imageSize.width, imageSize.height));
}

View File

@ -1290,7 +1290,6 @@ nsDisplayImage::ConfigureLayer(ImageLayer *aLayer)
transform.Scale(destRect.Width()/imageWidth,
destRect.Height()/imageHeight);
aLayer->SetBaseTransform(gfx3DMatrix::From2D(transform));
aLayer->SetVisibleRegion(nsIntRect(0, 0, imageWidth, imageHeight));
}

View File

@ -249,7 +249,7 @@ TransformShadowTree(nsDisplayListBuilder* aBuilder, nsFrameLoader* aFrameLoader,
const FrameMetrics* metrics = GetFrameMetrics(aLayer);
gfx3DMatrix shadowTransform = aLayer->GetBaseTransform();
gfx3DMatrix shadowTransform = aLayer->GetTransform();
ViewTransform layerTransform = aTransform;
if (metrics && metrics->IsScrollable()) {
@ -297,6 +297,18 @@ TransformShadowTree(nsDisplayListBuilder* aBuilder, nsFrameLoader* aFrameLoader,
}
}
// The transform already takes the resolution scale into account. Since we
// will apply the resolution scale again when computing the effective
// transform, we must apply the inverse resolution scale here.
if (ContainerLayer* c = aLayer->AsContainerLayer()) {
shadowTransform.Scale(1.0f/c->GetPreXScale(),
1.0f/c->GetPreYScale(),
1);
}
shadowTransform.ScalePost(1.0f/aLayer->GetPostXScale(),
1.0f/aLayer->GetPostYScale(),
1);
shadow->SetShadowTransform(shadowTransform);
for (Layer* child = aLayer->GetFirstChild();
child; child = child->GetNextSibling()) {
@ -612,6 +624,8 @@ RenderFrameParent::BuildLayer(nsDisplayListBuilder* aBuilder,
if (mContainer) {
ClearContainer(mContainer);
mContainer->SetPreScale(1.0f, 1.0f);
mContainer->SetPostScale(1.0f, 1.0f);
}
ContainerLayer* shadowRoot = GetRootLayer();