Bug 716439; backend of the mask layers system for basic layers (software). r=roc
This commit is contained in:
@@ -108,6 +108,78 @@ static void ContainerInsertAfter(Layer* aChild, Layer* aAfter, Container* aConta
|
||||
template<class Container>
|
||||
static void ContainerRemoveChild(Layer* aChild, Container* aContainer);
|
||||
|
||||
/*
|
||||
* Extract a mask surface for a mask layer
|
||||
* Returns a surface for the mask layer if a mask layer is present and has a
|
||||
* valid surface and transform; nsnull otherwise.
|
||||
* The transform for the layer will be put in aMaskTransform
|
||||
*/
|
||||
already_AddRefed<gfxASurface>
|
||||
GetMaskSurfaceAndTransform(Layer* aMaskLayer, gfxMatrix* aMaskTransform)
|
||||
{
|
||||
if (aMaskLayer) {
|
||||
nsRefPtr<gfxASurface> maskSurface =
|
||||
static_cast<BasicImplData*>(aMaskLayer->ImplData())->GetAsSurface();
|
||||
if (maskSurface) {
|
||||
bool maskIs2D =
|
||||
aMaskLayer->GetEffectiveTransform().CanDraw2D(aMaskTransform);
|
||||
NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
|
||||
return maskSurface.forget();
|
||||
}
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// Paint the current source to a context using a mask, if present
|
||||
void
|
||||
PaintWithMask(gfxContext* aContext, float aOpacity, Layer* aMaskLayer)
|
||||
{
|
||||
gfxMatrix maskTransform;
|
||||
if (nsRefPtr<gfxASurface> maskSurface =
|
||||
GetMaskSurfaceAndTransform(aMaskLayer, &maskTransform)) {
|
||||
if (aOpacity < 1.0) {
|
||||
aContext->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
|
||||
aContext->Paint(aOpacity);
|
||||
aContext->PopGroupToSource();
|
||||
}
|
||||
aContext->SetMatrix(maskTransform);
|
||||
aContext->Mask(maskSurface);
|
||||
return;
|
||||
}
|
||||
|
||||
// if there is no mask, just paint normally
|
||||
aContext->Paint(aOpacity);
|
||||
}
|
||||
|
||||
// Fill the current path with the current source, using a
|
||||
// mask and opacity, if present
|
||||
void
|
||||
FillWithMask(gfxContext* aContext, float aOpacity, Layer* aMaskLayer)
|
||||
{
|
||||
gfxMatrix maskTransform;
|
||||
if (nsRefPtr<gfxASurface> maskSurface =
|
||||
GetMaskSurfaceAndTransform(aMaskLayer, &maskTransform)) {
|
||||
if (aOpacity < 1.0) {
|
||||
aContext->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
|
||||
aContext->FillWithOpacity(aOpacity);
|
||||
aContext->PopGroupToSource();
|
||||
aContext->SetMatrix(maskTransform);
|
||||
aContext->Mask(maskSurface);
|
||||
} else {
|
||||
aContext->Save();
|
||||
aContext->Clip();
|
||||
aContext->SetMatrix(maskTransform);
|
||||
aContext->Mask(maskSurface);
|
||||
aContext->NewPath();
|
||||
aContext->Restore();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// if there is no mask, just fill normally
|
||||
aContext->FillWithOpacity(aOpacity);
|
||||
}
|
||||
|
||||
class BasicContainerLayer : public ContainerLayer, public BasicImplData {
|
||||
template<class Container>
|
||||
friend void ContainerInsertAfter(Layer* aChild, Layer* aAfter, Container* aContainer);
|
||||
@@ -155,6 +227,7 @@ public:
|
||||
if (!idealTransform.CanDraw2D()) {
|
||||
mEffectiveTransform = idealTransform;
|
||||
ComputeEffectiveTransformsForChildren(gfx3DMatrix());
|
||||
ComputeEffectiveTransformForMaskLayer(gfx3DMatrix());
|
||||
mUseIntermediateSurface = true;
|
||||
return;
|
||||
}
|
||||
@@ -164,12 +237,16 @@ public:
|
||||
// need to apply any compensation using the residual from SnapTransform.
|
||||
ComputeEffectiveTransformsForChildren(idealTransform);
|
||||
|
||||
ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
|
||||
|
||||
/* If we have a single child, 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
|
||||
*/
|
||||
mUseIntermediateSurface = GetEffectiveOpacity() != 1.0 && HasMultipleChildren();
|
||||
mUseIntermediateSurface = GetMaskLayer() ||
|
||||
(GetEffectiveOpacity() != 1.0 && HasMultipleChildren());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -335,7 +412,8 @@ public:
|
||||
* drawn before this is called. The contents of the buffer are drawn
|
||||
* to aTarget.
|
||||
*/
|
||||
void DrawTo(ThebesLayer* aLayer, gfxContext* aTarget, float aOpacity);
|
||||
void DrawTo(ThebesLayer* aLayer, gfxContext* aTarget, float aOpacity,
|
||||
Layer* aMaskLayer);
|
||||
|
||||
virtual already_AddRefed<gfxASurface>
|
||||
CreateBuffer(ContentType aType, const nsIntSize& aSize, PRUint32 aFlags);
|
||||
@@ -401,6 +479,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void PaintThebes(gfxContext* aContext,
|
||||
Layer* aMaskLayer,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
ReadbackProcessor* aReadback);
|
||||
@@ -438,6 +517,7 @@ public:
|
||||
mResidualTranslation = gfxPoint(0,0);
|
||||
mValidRegion.SetEmpty();
|
||||
}
|
||||
ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
|
||||
return;
|
||||
}
|
||||
ThebesLayer::ComputeEffectiveTransforms(aTransformToSurface);
|
||||
@@ -563,6 +643,7 @@ BasicLayerManager::PushGroupForLayer(gfxContext* aContext, Layer* aLayer,
|
||||
|
||||
void
|
||||
BasicThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
Layer* aMaskLayer,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
ReadbackProcessor* aReadback)
|
||||
@@ -583,7 +664,7 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
canUseOpaqueSurface ? gfxASurface::CONTENT_COLOR :
|
||||
gfxASurface::CONTENT_COLOR_ALPHA;
|
||||
float opacity = GetEffectiveOpacity();
|
||||
|
||||
|
||||
if (!BasicManager()->IsRetained() ||
|
||||
(!canUseOpaqueSurface &&
|
||||
(mContentFlags & CONTENT_COMPONENT_ALPHA) &&
|
||||
@@ -607,7 +688,7 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
|
||||
bool needsClipToVisibleRegion = GetClipToVisibleRegion();
|
||||
bool needsGroup =
|
||||
opacity != 1.0 || GetOperator() != gfxContext::OPERATOR_OVER;
|
||||
opacity != 1.0 || GetOperator() != gfxContext::OPERATOR_OVER || aMaskLayer;
|
||||
nsRefPtr<gfxContext> groupContext;
|
||||
if (needsGroup) {
|
||||
groupContext =
|
||||
@@ -627,7 +708,7 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
gfxUtils::ClipToRegion(aContext, toDraw);
|
||||
}
|
||||
AutoSetOperator setOperator(aContext, GetOperator());
|
||||
aContext->Paint(opacity);
|
||||
PaintWithMask(aContext, opacity, aMaskLayer);
|
||||
}
|
||||
|
||||
aContext->Restore();
|
||||
@@ -688,7 +769,7 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
clipExtents = aContext->GetClipExtents();
|
||||
if (!IsHidden() && !clipExtents.IsEmpty()) {
|
||||
AutoSetOperator setOperator(aContext, GetOperator());
|
||||
mBuffer.DrawTo(this, aContext, opacity);
|
||||
mBuffer.DrawTo(this, aContext, opacity, aMaskLayer);
|
||||
}
|
||||
|
||||
for (PRUint32 i = 0; i < readbackUpdates.Length(); ++i) {
|
||||
@@ -700,7 +781,7 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
if (ctx) {
|
||||
NS_ASSERTION(opacity == 1.0, "Should only read back opaque layers");
|
||||
ctx->Translate(gfxPoint(offset.x, offset.y));
|
||||
mBuffer.DrawTo(this, ctx, 1.0);
|
||||
mBuffer.DrawTo(this, ctx, 1.0, aMaskLayer);
|
||||
update.mLayer->GetSink()->EndUpdate(ctx, update.mUpdateRect + offset);
|
||||
}
|
||||
}
|
||||
@@ -718,7 +799,8 @@ IsClippingCheap(gfxContext* aTarget, const nsIntRegion& aRegion)
|
||||
void
|
||||
BasicThebesLayerBuffer::DrawTo(ThebesLayer* aLayer,
|
||||
gfxContext* aTarget,
|
||||
float aOpacity)
|
||||
float aOpacity,
|
||||
Layer* aMaskLayer)
|
||||
{
|
||||
aTarget->Save();
|
||||
// If the entire buffer is valid, we can just draw the whole thing,
|
||||
@@ -736,7 +818,16 @@ BasicThebesLayerBuffer::DrawTo(ThebesLayer* aLayer,
|
||||
// and may cause gray lines.
|
||||
gfxUtils::ClipToRegionSnapped(aTarget, aLayer->GetEffectiveVisibleRegion());
|
||||
}
|
||||
DrawBufferWithRotation(aTarget, aOpacity);
|
||||
|
||||
// Pull out the mask surface and transform here, because the mask
|
||||
// is internal to basic layers
|
||||
gfxMatrix maskTransform;
|
||||
if (nsRefPtr<gfxASurface> maskSurface =
|
||||
GetMaskSurfaceAndTransform(aMaskLayer, &maskTransform)) {
|
||||
DrawBufferWithRotation(aTarget, aOpacity, maskSurface, &maskTransform);
|
||||
} else {
|
||||
DrawBufferWithRotation(aTarget, aOpacity);
|
||||
}
|
||||
aTarget->Restore();
|
||||
}
|
||||
|
||||
@@ -785,12 +876,15 @@ public:
|
||||
ImageLayer::SetVisibleRegion(aRegion);
|
||||
}
|
||||
|
||||
virtual void Paint(gfxContext* aContext);
|
||||
virtual void Paint(gfxContext* aContext, Layer* aMaskLayer);
|
||||
|
||||
static void PaintContext(gfxPattern* aPattern,
|
||||
const nsIntRegion& aVisible,
|
||||
float aOpacity,
|
||||
gfxContext* aContext);
|
||||
gfxContext* aContext,
|
||||
Layer* aMaskLayer);
|
||||
|
||||
virtual already_AddRefed<gfxASurface> GetAsSurface();
|
||||
|
||||
protected:
|
||||
BasicLayerManager* BasicManager()
|
||||
@@ -800,23 +894,25 @@ protected:
|
||||
|
||||
already_AddRefed<gfxPattern>
|
||||
GetAndPaintCurrentImage(gfxContext* aContext,
|
||||
float aOpacity);
|
||||
float aOpacity,
|
||||
Layer* aMaskLayer);
|
||||
|
||||
gfxIntSize mSize;
|
||||
};
|
||||
|
||||
void
|
||||
BasicImageLayer::Paint(gfxContext* aContext)
|
||||
BasicImageLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
||||
{
|
||||
if (IsHidden())
|
||||
return;
|
||||
nsRefPtr<gfxPattern> dontcare =
|
||||
GetAndPaintCurrentImage(aContext, GetEffectiveOpacity());
|
||||
GetAndPaintCurrentImage(aContext, GetEffectiveOpacity(), aMaskLayer);
|
||||
}
|
||||
|
||||
already_AddRefed<gfxPattern>
|
||||
BasicImageLayer::GetAndPaintCurrentImage(gfxContext* aContext,
|
||||
float aOpacity)
|
||||
float aOpacity,
|
||||
Layer* aMaskLayer)
|
||||
{
|
||||
if (!mContainer)
|
||||
return nsnull;
|
||||
@@ -853,7 +949,7 @@ BasicImageLayer::GetAndPaintCurrentImage(gfxContext* aContext,
|
||||
AutoSetOperator setOperator(aContext, GetOperator());
|
||||
PaintContext(pat,
|
||||
nsIntRegion(nsIntRect(0, 0, size.width, size.height)),
|
||||
aOpacity, aContext);
|
||||
aOpacity, aContext, aMaskLayer);
|
||||
|
||||
GetContainer()->NotifyPaintedImage(image);
|
||||
|
||||
@@ -864,7 +960,8 @@ BasicImageLayer::GetAndPaintCurrentImage(gfxContext* aContext,
|
||||
BasicImageLayer::PaintContext(gfxPattern* aPattern,
|
||||
const nsIntRegion& aVisible,
|
||||
float aOpacity,
|
||||
gfxContext* aContext)
|
||||
gfxContext* aContext,
|
||||
Layer* aMaskLayer)
|
||||
{
|
||||
// Set PAD mode so that when the video is being scaled, we do not sample
|
||||
// outside the bounds of the video image.
|
||||
@@ -888,12 +985,24 @@ BasicImageLayer::PaintContext(gfxPattern* aPattern,
|
||||
gfxUtils::PathFromRegion(aContext, aVisible);
|
||||
aPattern->SetExtend(extend);
|
||||
aContext->SetPattern(aPattern);
|
||||
aContext->FillWithOpacity(aOpacity);
|
||||
FillWithMask(aContext, aOpacity, aMaskLayer);
|
||||
|
||||
// Reset extend mode for callers that need to reuse the pattern
|
||||
aPattern->SetExtend(extend);
|
||||
}
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
BasicImageLayer::GetAsSurface()
|
||||
{
|
||||
if (!mContainer) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
gfxIntSize dontCare;
|
||||
return mContainer->GetCurrentAsSurface(&dontCare);
|
||||
}
|
||||
|
||||
|
||||
class BasicColorLayer : public ColorLayer, public BasicImplData {
|
||||
public:
|
||||
BasicColorLayer(BasicLayerManager* aLayerManager) :
|
||||
@@ -913,16 +1022,17 @@ public:
|
||||
ColorLayer::SetVisibleRegion(aRegion);
|
||||
}
|
||||
|
||||
virtual void Paint(gfxContext* aContext)
|
||||
virtual void Paint(gfxContext* aContext, Layer* aMaskLayer)
|
||||
{
|
||||
if (IsHidden())
|
||||
return;
|
||||
AutoSetOperator setOperator(aContext, GetOperator());
|
||||
PaintColorTo(mColor, GetEffectiveOpacity(), aContext);
|
||||
PaintColorTo(mColor, GetEffectiveOpacity(), aContext, aMaskLayer);
|
||||
}
|
||||
|
||||
static void PaintColorTo(gfxRGBA aColor, float aOpacity,
|
||||
gfxContext* aContext);
|
||||
gfxContext* aContext,
|
||||
Layer* aMaskLayer);
|
||||
|
||||
protected:
|
||||
BasicLayerManager* BasicManager()
|
||||
@@ -933,10 +1043,11 @@ protected:
|
||||
|
||||
/*static*/ void
|
||||
BasicColorLayer::PaintColorTo(gfxRGBA aColor, float aOpacity,
|
||||
gfxContext* aContext)
|
||||
gfxContext* aContext,
|
||||
Layer* aMaskLayer)
|
||||
{
|
||||
aContext->SetColor(aColor);
|
||||
aContext->Paint(aOpacity);
|
||||
PaintWithMask(aContext, aOpacity, aMaskLayer);
|
||||
}
|
||||
|
||||
class BasicCanvasLayer : public CanvasLayer,
|
||||
@@ -961,10 +1072,11 @@ public:
|
||||
}
|
||||
|
||||
virtual void Initialize(const Data& aData);
|
||||
virtual void Paint(gfxContext* aContext);
|
||||
virtual void Paint(gfxContext* aContext, Layer* aMaskLayer);
|
||||
|
||||
virtual void PaintWithOpacity(gfxContext* aContext,
|
||||
float aOpacity);
|
||||
float aOpacity,
|
||||
Layer* aMaskLayer = nsnull);
|
||||
|
||||
protected:
|
||||
BasicLayerManager* BasicManager()
|
||||
@@ -1126,18 +1238,19 @@ BasicCanvasLayer::UpdateSurface(gfxASurface* aDestSurface)
|
||||
}
|
||||
|
||||
void
|
||||
BasicCanvasLayer::Paint(gfxContext* aContext)
|
||||
BasicCanvasLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
||||
{
|
||||
if (IsHidden())
|
||||
return;
|
||||
UpdateSurface();
|
||||
FireDidTransactionCallback();
|
||||
PaintWithOpacity(aContext, GetEffectiveOpacity());
|
||||
PaintWithOpacity(aContext, GetEffectiveOpacity(), aMaskLayer);
|
||||
}
|
||||
|
||||
void
|
||||
BasicCanvasLayer::PaintWithOpacity(gfxContext* aContext,
|
||||
float aOpacity)
|
||||
float aOpacity,
|
||||
Layer* aMaskLayer)
|
||||
{
|
||||
NS_ASSERTION(BasicManager()->InDrawing(),
|
||||
"Can only draw in drawing phase");
|
||||
@@ -1173,7 +1286,8 @@ BasicCanvasLayer::PaintWithOpacity(gfxContext* aContext,
|
||||
// No need to snap here; our transform is already set up to snap our rect
|
||||
aContext->Rectangle(gfxRect(0, 0, mBounds.width, mBounds.height));
|
||||
aContext->SetPattern(pat);
|
||||
aContext->FillWithOpacity(aOpacity);
|
||||
|
||||
FillWithMask(aContext, aOpacity, aMaskLayer);
|
||||
|
||||
#if defined (MOZ_X11) && defined (MOZ_EGL_XRENDER_COMPOSITE)
|
||||
if (mGLContext) {
|
||||
@@ -1779,15 +1893,20 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
||||
|
||||
const nsIntRect* clipRect = aLayer->GetEffectiveClipRect();
|
||||
const gfx3DMatrix& effectiveTransform = aLayer->GetEffectiveTransform();
|
||||
// aLayer might not be a container layer, but if so we take care not to use
|
||||
// the container variable
|
||||
BasicContainerLayer* container = static_cast<BasicContainerLayer*>(aLayer);
|
||||
bool needsGroup = aLayer->GetFirstChild() &&
|
||||
container->UseIntermediateSurface();
|
||||
container->UseIntermediateSurface();
|
||||
BasicImplData* data = ToData(aLayer);
|
||||
bool needsClipToVisibleRegion =
|
||||
data->GetClipToVisibleRegion() && !aLayer->AsThebesLayer();
|
||||
NS_ASSERTION(needsGroup || !aLayer->GetFirstChild() ||
|
||||
container->GetOperator() == gfxContext::OPERATOR_OVER,
|
||||
"non-OVER operator should have forced UseIntermediateSurface");
|
||||
NS_ASSERTION(!aLayer->GetFirstChild() || !aLayer->GetMaskLayer() ||
|
||||
container->UseIntermediateSurface(),
|
||||
"ContainerLayer with mask layer should force UseIntermediateSurface");
|
||||
|
||||
// If needsSaveRestore is false, we should still save and restore
|
||||
// the CTM
|
||||
@@ -1801,9 +1920,8 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
||||
aTarget->Rectangle(gfxRect(clipRect->x, clipRect->y, clipRect->width, clipRect->height), true);
|
||||
aTarget->Clip();
|
||||
}
|
||||
} else {
|
||||
savedMatrix = aTarget->CurrentMatrix();
|
||||
}
|
||||
savedMatrix = aTarget->CurrentMatrix();
|
||||
|
||||
gfxMatrix transform;
|
||||
// Will return an identity matrix for 3d transforms, and is handled separately below.
|
||||
@@ -1872,9 +1990,12 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
||||
(void*)aLayer, data->IsHidden()));
|
||||
#endif
|
||||
if (aLayer->AsThebesLayer()) {
|
||||
data->PaintThebes(groupTarget, aCallback, aCallbackData, aReadback);
|
||||
data->PaintThebes(groupTarget,
|
||||
aLayer->GetMaskLayer(),
|
||||
aCallback, aCallbackData,
|
||||
aReadback);
|
||||
} else {
|
||||
data->Paint(groupTarget);
|
||||
data->Paint(groupTarget, aLayer->GetMaskLayer());
|
||||
}
|
||||
} else {
|
||||
ReadbackProcessor readback;
|
||||
@@ -1946,7 +2067,8 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
||||
gfxUtils::ClipToRegion(aTarget, aLayer->GetEffectiveVisibleRegion());
|
||||
}
|
||||
AutoSetOperator setOperator(aTarget, container->GetOperator());
|
||||
aTarget->Paint(aLayer->GetEffectiveOpacity());
|
||||
gfxMatrix temp = aTarget->CurrentMatrix();
|
||||
PaintWithMask(aTarget, aLayer->GetEffectiveOpacity(), aLayer->GetMaskLayer());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2371,7 +2493,7 @@ public:
|
||||
MOZ_COUNT_DTOR(BasicShadowableImageLayer);
|
||||
}
|
||||
|
||||
virtual void Paint(gfxContext* aContext);
|
||||
virtual void Paint(gfxContext* aContext, Layer* aMaskLayer);
|
||||
|
||||
virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
|
||||
{
|
||||
@@ -2431,13 +2553,15 @@ private:
|
||||
};
|
||||
|
||||
void
|
||||
BasicShadowableImageLayer::Paint(gfxContext* aContext)
|
||||
BasicShadowableImageLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
||||
{
|
||||
if (!HasShadow()) {
|
||||
BasicImageLayer::Paint(aContext);
|
||||
BasicImageLayer::Paint(aContext, aMaskLayer);
|
||||
return;
|
||||
}
|
||||
|
||||
//TODO[nrc] masking
|
||||
|
||||
if (!mContainer) {
|
||||
return;
|
||||
}
|
||||
@@ -2495,7 +2619,8 @@ BasicShadowableImageLayer::Paint(gfxContext* aContext)
|
||||
}
|
||||
|
||||
gfxIntSize oldSize = mSize;
|
||||
nsRefPtr<gfxPattern> pat = GetAndPaintCurrentImage(aContext, GetEffectiveOpacity());
|
||||
nsRefPtr<gfxPattern> pat = GetAndPaintCurrentImage
|
||||
(aContext, GetEffectiveOpacity(), aMaskLayer);
|
||||
if (!pat || !HasShadow())
|
||||
return;
|
||||
|
||||
@@ -2520,7 +2645,7 @@ BasicShadowableImageLayer::Paint(gfxContext* aContext)
|
||||
tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
PaintContext(pat,
|
||||
nsIntRegion(nsIntRect(0, 0, mSize.width, mSize.height)),
|
||||
1.0, tmpCtx);
|
||||
1.0, tmpCtx, aMaskLayer);
|
||||
|
||||
BasicManager()->PaintedImage(BasicManager()->Hold(this),
|
||||
mBackBuffer);
|
||||
@@ -2572,7 +2697,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void Initialize(const Data& aData);
|
||||
virtual void Paint(gfxContext* aContext);
|
||||
virtual void Paint(gfxContext* aContext, Layer* aMaskLayer);
|
||||
|
||||
virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
|
||||
{
|
||||
@@ -2631,13 +2756,15 @@ BasicShadowableCanvasLayer::Initialize(const Data& aData)
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowableCanvasLayer::Paint(gfxContext* aContext)
|
||||
BasicShadowableCanvasLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
||||
{
|
||||
if (!HasShadow()) {
|
||||
BasicCanvasLayer::Paint(aContext);
|
||||
BasicCanvasLayer::Paint(aContext, aMaskLayer);
|
||||
return;
|
||||
}
|
||||
|
||||
//TODO[nrc] masking
|
||||
|
||||
bool isOpaque = (GetContentFlags() & CONTENT_OPAQUE);
|
||||
if (!IsSurfaceDescriptorValid(mBackBuffer) ||
|
||||
isOpaque != mBufferIsOpaque) {
|
||||
@@ -2746,6 +2873,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void PaintThebes(gfxContext* aContext,
|
||||
Layer* aMaskLayer,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
ReadbackProcessor* aReadback);
|
||||
@@ -2815,6 +2943,7 @@ BasicShadowThebesLayer::Swap(const ThebesBuffer& aNewFront,
|
||||
|
||||
void
|
||||
BasicShadowThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
Layer* aMaskLayer,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
ReadbackProcessor* aReadback)
|
||||
@@ -2828,7 +2957,7 @@ BasicShadowThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
return;
|
||||
}
|
||||
|
||||
mFrontBuffer.DrawTo(this, aContext, GetEffectiveOpacity());
|
||||
mFrontBuffer.DrawTo(this, aContext, GetEffectiveOpacity(), aMaskLayer);
|
||||
}
|
||||
|
||||
class BasicShadowContainerLayer : public ShadowContainerLayer, public BasicImplData {
|
||||
@@ -2882,8 +3011,10 @@ public:
|
||||
* 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
|
||||
*/
|
||||
mUseIntermediateSurface = GetEffectiveOpacity() != 1.0 && HasMultipleChildren();
|
||||
mUseIntermediateSurface = GetMaskLayer() ||
|
||||
(GetEffectiveOpacity() != 1.0 && HasMultipleChildren());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2915,7 +3046,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Paint(gfxContext* aContext);
|
||||
virtual void Paint(gfxContext* aContext, Layer* aMaskLayer);
|
||||
|
||||
protected:
|
||||
BasicShadowLayerManager* BasicManager()
|
||||
@@ -2955,7 +3086,7 @@ BasicShadowImageLayer::Swap(const SharedImage& aNewFront,
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowImageLayer::Paint(gfxContext* aContext)
|
||||
BasicShadowImageLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
||||
{
|
||||
if (!IsSurfaceDescriptorValid(mFrontBuffer)) {
|
||||
return;
|
||||
@@ -2971,7 +3102,8 @@ BasicShadowImageLayer::Paint(gfxContext* aContext)
|
||||
AutoSetOperator setOperator(aContext, GetOperator());
|
||||
BasicImageLayer::PaintContext(pat,
|
||||
nsIntRegion(nsIntRect(0, 0, mSize.width, mSize.height)),
|
||||
GetEffectiveOpacity(), aContext);
|
||||
GetEffectiveOpacity(), aContext,
|
||||
aMaskLayer);
|
||||
}
|
||||
|
||||
class BasicShadowColorLayer : public ShadowColorLayer,
|
||||
@@ -2988,10 +3120,11 @@ public:
|
||||
MOZ_COUNT_DTOR(BasicShadowColorLayer);
|
||||
}
|
||||
|
||||
virtual void Paint(gfxContext* aContext)
|
||||
virtual void Paint(gfxContext* aContext, Layer* aMaskLayer)
|
||||
{
|
||||
AutoSetOperator setOperator(aContext, GetOperator());
|
||||
BasicColorLayer::PaintColorTo(mColor, GetEffectiveOpacity(), aContext);
|
||||
BasicColorLayer::PaintColorTo(mColor, GetEffectiveOpacity(),
|
||||
aContext, aMaskLayer);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3025,7 +3158,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Paint(gfxContext* aContext);
|
||||
virtual void Paint(gfxContext* aContext, Layer* aMaskLayer);
|
||||
|
||||
private:
|
||||
BasicShadowLayerManager* BasicManager()
|
||||
@@ -3074,7 +3207,7 @@ BasicShadowCanvasLayer::Swap(const CanvasSurface& aNewFront, bool needYFlip,
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowCanvasLayer::Paint(gfxContext* aContext)
|
||||
BasicShadowCanvasLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
||||
{
|
||||
NS_ASSERTION(BasicManager()->InDrawing(),
|
||||
"Can only draw in drawing phase");
|
||||
@@ -3104,6 +3237,7 @@ BasicShadowCanvasLayer::Paint(gfxContext* aContext)
|
||||
// No need to snap here; our transform has already taken care of it
|
||||
aContext->Rectangle(r);
|
||||
aContext->SetPattern(pat);
|
||||
//TODO[nrc] masking
|
||||
aContext->FillWithOpacity(GetEffectiveOpacity());
|
||||
|
||||
if (mNeedsYFlip) {
|
||||
|
||||
Reference in New Issue
Block a user