Bug 716403 - Annotate layers with the fixed margins from the PresShell. r=nrc,roc

This annotates fixed layers with the margins that have been applied from
nsIPresShell->GetContentDocumentFixedPositionMargins. Using SyncViewportInfo
in CompositorParent, this allows for async fixed position margin setting.
This commit is contained in:
Chris Lord 2013-03-01 15:46:34 +00:00
parent afe21f51a7
commit f56a95adbd
9 changed files with 64 additions and 5 deletions

View File

@ -18,6 +18,7 @@ struct Margin :
typedef BaseMargin<Float, Margin> Super;
// Constructors
Margin() : Super(0, 0, 0, 0) {}
Margin(const Margin& aMargin) : Super(aMargin) {}
Margin(Float aLeft, Float aTop, Float aRight, Float aBottom)
: Super(aLeft, aTop, aRight, aBottom) {}

View File

@ -320,6 +320,7 @@ Layer::Layer(LayerManager* aManager, void* aImplData) :
mUseClipRect(false),
mUseTileSourceRect(false),
mIsFixedPosition(false),
mMargins(0, 0, 0, 0),
mDebugColorIndex(0),
mAnimationGeneration(0)
{}

View File

@ -844,6 +844,16 @@ public:
*/
void SetFixedPositionAnchor(const gfxPoint& aAnchor) { mAnchor = aAnchor; }
/**
* CONSTRUCTION PHASE ONLY
* If a layer represents a fixed position element or elements that are on
* a document that has had fixed position element margins set on it, these
* will be mirrored here. This allows for asynchronous animation of the
* margins by reconciling the difference between this value and a value that
* is updated more frequently.
*/
void SetFixedPositionMargins(const gfx::Margin& aMargins) { mMargins = aMargins; }
// These getters can be used anytime.
float GetOpacity() { return mOpacity; }
const nsIntRect* GetClipRect() { return mUseClipRect ? &mClipRect : nullptr; }
@ -860,6 +870,7 @@ public:
float GetPostYScale() { return mPostYScale; }
bool GetIsFixedPosition() { return mIsFixedPosition; }
gfxPoint GetFixedPositionAnchor() { return mAnchor; }
const gfx::Margin& GetFixedPositionMargins() { return mMargins; }
Layer* GetMaskLayer() { return mMaskLayer; }
// Note that all lengths in animation data are either in CSS pixels or app
@ -1208,6 +1219,7 @@ protected:
bool mUseTileSourceRect;
bool mIsFixedPosition;
gfxPoint mAnchor;
gfx::Margin mMargins;
DebugOnly<uint32_t> mDebugColorIndex;
// If this layer is used for OMTA, then this counter is used to ensure we
// stay in sync with the animation manager

View File

@ -652,17 +652,23 @@ CompositorParent::TransformFixedLayers(Layer* aLayer,
gfxPoint translation(aTranslation - (anchor - anchor / aScaleDiff));
// Offset this translation by the fixed layer margins, depending on what
// side of the viewport the layer is anchored to.
// side of the viewport the layer is anchored to, reconciling the
// difference between the current fixed layer margins and the Gecko-side
// fixed layer margins.
// aFixedLayerMargins are the margins we expect to be at at the current
// time, obtained via SyncViewportInfo, and fixedMargins are the margins
// that were used during layout.
const gfx::Margin& fixedMargins = aLayer->GetFixedPositionMargins();
if (anchor.x > 0) {
translation.x -= aFixedLayerMargins.right;
translation.x -= aFixedLayerMargins.right - fixedMargins.right;
} else {
translation.x += aFixedLayerMargins.left;
translation.x += aFixedLayerMargins.left - fixedMargins.left;
}
if (anchor.y > 0) {
translation.y -= aFixedLayerMargins.bottom;
translation.y -= aFixedLayerMargins.bottom - fixedMargins.bottom;
} else {
translation.y += aFixedLayerMargins.top;
translation.y += aFixedLayerMargins.top - fixedMargins.top;
}
// The transform already takes the resolution scale into account. Since we

View File

@ -26,6 +26,7 @@ using mozilla::TimeStamp;
using mozilla::ScreenRotation;
using nsCSSProperty;
using mozilla::dom::ScreenOrientation;
using mozilla::gfx::Margin;
/**
* The layers protocol is spoken between thread contexts that manage
@ -185,6 +186,7 @@ struct CommonLayerAttributes {
nsIntRect clipRect;
bool isFixedPosition;
gfxPoint fixedPositionAnchor;
Margin fixedPositionMargin;
nullable PLayer maskLayer;
// Animated colors will only honored for ColorLayers.
Animation[] animations;

View File

@ -344,6 +344,7 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies)
*mutant->GetClipRect() : nsIntRect());
common.isFixedPosition() = mutant->GetIsFixedPosition();
common.fixedPositionAnchor() = mutant->GetFixedPositionAnchor();
common.fixedPositionMargin() = mutant->GetFixedPositionMargins();
if (Layer* maskLayer = mutant->GetMaskLayer()) {
common.maskLayerChild() = Shadow(maskLayer->AsShadowableLayer());
} else {

View File

@ -248,6 +248,7 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
layer->SetPostScale(common.postXScale(), common.postYScale());
layer->SetIsFixedPosition(common.isFixedPosition());
layer->SetFixedPositionAnchor(common.fixedPositionAnchor());
layer->SetFixedPositionMargins(common.fixedPositionMargin());
if (PLayerParent* maskLayer = common.maskLayerParent()) {
layer->SetMaskLayer(cast(maskLayer)->AsLayer());
} else {

View File

@ -836,6 +836,28 @@ struct ParamTraits<mozilla::gfx::Rect>
}
};
template<>
struct ParamTraits<mozilla::gfx::Margin>
{
typedef mozilla::gfx::Margin paramType;
static void Write(Message* msg, const paramType& param)
{
WriteParam(msg, param.left);
WriteParam(msg, param.top);
WriteParam(msg, param.right);
WriteParam(msg, param.bottom);
}
static bool Read(const Message* msg, void** iter, paramType* result)
{
return (ReadParam(msg, iter, &result->left) &&
ReadParam(msg, iter, &result->top) &&
ReadParam(msg, iter, &result->right) &&
ReadParam(msg, iter, &result->bottom));
}
};
template<>
struct ParamTraits<nsRect>
{

View File

@ -2978,6 +2978,19 @@ nsDisplayFixedPosition::BuildLayer(nsDisplayListBuilder* aBuilder,
layer->SetFixedPositionAnchor(anchor);
// Also make sure the layer is aware of any fixed position margins that have
// been set.
nsMargin fixedMargins = presContext->PresShell()->GetContentDocumentFixedPositionMargins();
mozilla::gfx::Margin fixedLayerMargins(NSAppUnitsToFloatPixels(fixedMargins.left, factor) *
aContainerParameters.mXScale,
NSAppUnitsToFloatPixels(fixedMargins.top, factor) *
aContainerParameters.mYScale,
NSAppUnitsToFloatPixels(fixedMargins.right, factor) *
aContainerParameters.mXScale,
NSAppUnitsToFloatPixels(fixedMargins.bottom, factor) *
aContainerParameters.mYScale);
layer->SetFixedPositionMargins(fixedLayerMargins);
return layer.forget();
}