Bug 902525 - Part 1: Layers changes. r=roc

This commit is contained in:
Rik Cabanier 2013-09-15 16:23:52 -04:00
Родитель 4202bb63ca
Коммит 492ade5e96
4 изменённых файлов: 50 добавлений и 7 удалений

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

@ -181,6 +181,7 @@ Layer::Layer(LayerManager* aManager, void* aImplData) :
mPostXScale(1.0f),
mPostYScale(1.0f),
mOpacity(1.0),
mMixBlendMode(gfxContext::OPERATOR_OVER),
mContentFlags(0),
mUseClipRect(false),
mUseTileSourceRect(false),
@ -680,6 +681,20 @@ Layer::GetEffectiveOpacity()
}
return opacity;
}
gfxContext::GraphicsOperator
Layer::GetEffectiveMixBlendMode()
{
if(mMixBlendMode != gfxContext::OPERATOR_OVER)
return mMixBlendMode;
for (ContainerLayer* c = GetParent(); c && !c->UseIntermediateSurface();
c = c->GetParent()) {
if(c->mMixBlendMode != gfxContext::OPERATOR_OVER)
return c->mMixBlendMode;
}
return mMixBlendMode;
}
void
Layer::ComputeEffectiveTransformForMaskLayer(const gfx3DMatrix& aTransformToSurface)

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

@ -12,6 +12,7 @@
#include "FrameMetrics.h" // for FrameMetrics
#include "Units.h" // for LayerMargin, LayerPoint
#include "gfx3DMatrix.h" // for gfx3DMatrix
#include "gfxContext.h" // for GraphicsOperator
#include "gfxASurface.h" // for gfxASurface, etc
#include "gfxColor.h" // for gfxRGBA
#include "gfxMatrix.h" // for gfxMatrix
@ -732,6 +733,15 @@ public:
}
}
void SetMixBlendMode(gfxContext::GraphicsOperator aMixBlendMode)
{
if (mMixBlendMode != aMixBlendMode) {
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) MixBlendMode", this));
mMixBlendMode = aMixBlendMode;
Mutated();
}
}
/**
* CONSTRUCTION PHASE ONLY
* Set a clip rect which will be applied to this layer as it is
@ -937,6 +947,7 @@ public:
// These getters can be used anytime.
float GetOpacity() { return mOpacity; }
gfxContext::GraphicsOperator GetMixBlendMode() const { return mMixBlendMode; }
const nsIntRect* GetClipRect() { return mUseClipRect ? &mClipRect : nullptr; }
uint32_t GetContentFlags() { return mContentFlags; }
const nsIntRegion& GetVisibleRegion() { return mVisibleRegion; }
@ -1102,11 +1113,18 @@ public:
// accounting for this layer possibly being a shadow.
const nsIntRect* GetEffectiveClipRect();
const nsIntRegion& GetEffectiveVisibleRegion();
/**
* Returns the product of the opacities of this layer and all ancestors up
* to and excluding the nearest ancestor that has UseIntermediateSurface() set.
*/
float GetEffectiveOpacity();
/**
* Returns the blendmode of this layer.
*/
gfxContext::GraphicsOperator GetEffectiveMixBlendMode();
/**
* This returns the effective transform computed by
* ComputeEffectiveTransforms. Typically this is a transform that transforms
@ -1304,6 +1322,7 @@ protected:
AnimationArray mAnimations;
InfallibleTArray<AnimData> mAnimationData;
float mOpacity;
gfxContext::GraphicsOperator mMixBlendMode;
nsIntRect mClipRect;
nsIntRect mTileSourceRect;
nsIntRegion mInvalidRegion;

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

@ -57,16 +57,24 @@ BasicContainerLayer::ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToS
ComputeEffectiveTransformsForChildren(idealTransform);
ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
Layer* child = GetFirstChild();
bool hasSingleBlendingChild = false;
if (!HasMultipleChildren() && child) {
hasSingleBlendingChild = child->GetMixBlendMode() != gfxContext::OPERATOR_OVER;
}
/* If we have a single child, it can just inherit our opacity,
/* If we have a single childand it is not blending,, it can just inherit our opacity,
* otherwise we need a PushGroup and we need to mark ourselves as using
* an intermediate surface so our children don't inherit our opacity
* via GetEffectiveOpacity.
* Having a mask layer always forces our own push group
* Having a blend mode also always forces our own push group
*/
mUseIntermediateSurface =
GetMaskLayer() || (GetEffectiveOpacity() != 1.0 &&
HasMultipleChildren());
GetMaskLayer() ||
(GetMixBlendMode() != gfxContext::OPERATOR_OVER && HasMultipleChildren()) ||
(GetEffectiveOpacity() != 1.0 && (HasMultipleChildren() || hasSingleBlendingChild));
}
bool

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

@ -109,7 +109,8 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
canUseOpaqueSurface ? gfxASurface::CONTENT_COLOR :
gfxASurface::CONTENT_COLOR_ALPHA;
float opacity = GetEffectiveOpacity();
gfxContext::GraphicsOperator mixBlendMode = GetEffectiveMixBlendMode();
if (!BasicManager()->IsRetained()) {
NS_ASSERTION(readbackUpdates.IsEmpty(), "Can't do readback for non-retained layer");
@ -130,13 +131,13 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
bool needsClipToVisibleRegion = GetClipToVisibleRegion();
bool needsGroup =
opacity != 1.0 || GetOperator() != gfxContext::OPERATOR_OVER || aMaskLayer;
opacity != 1.0 || GetOperator() != gfxContext::OPERATOR_OVER || mixBlendMode != gfxContext::OPERATOR_OVER || aMaskLayer;
nsRefPtr<gfxContext> groupContext;
if (needsGroup) {
groupContext =
BasicManager()->PushGroupForLayer(aContext, this, toDraw,
&needsClipToVisibleRegion);
if (GetOperator() != gfxContext::OPERATOR_OVER) {
if (GetOperator() != gfxContext::OPERATOR_OVER || mixBlendMode != gfxContext::OPERATOR_OVER) {
needsClipToVisibleRegion = true;
}
} else {
@ -149,7 +150,7 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
if (needsClipToVisibleRegion) {
gfxUtils::ClipToRegion(aContext, toDraw);
}
AutoSetOperator setOperator(aContext, GetOperator());
AutoSetOperator setOptimizedOperator(aContext, mixBlendMode != gfxContext::OPERATOR_OVER ? mixBlendMode : GetOperator());
PaintWithMask(aContext, opacity, aMaskLayer);
}