зеркало из https://github.com/mozilla/pjs.git
Bug 716439; backend of the mask layers system for basic layers (software). r=roc
This commit is contained in:
Родитель
9a2c42a10c
Коммит
5f5b8df4dc
|
@ -70,7 +70,9 @@ ThebesLayerBuffer::GetQuadrantRectangle(XSide aXSide, YSide aYSide)
|
|||
void
|
||||
ThebesLayerBuffer::DrawBufferQuadrant(gfxContext* aTarget,
|
||||
XSide aXSide, YSide aYSide,
|
||||
float aOpacity)
|
||||
float aOpacity,
|
||||
gfxASurface* aMask,
|
||||
const gfxMatrix* aMaskTransform)
|
||||
{
|
||||
// The rectangle that we're going to fill. Basically we're going to
|
||||
// render the buffer at mBufferRect + quadrantTranslation to get the
|
||||
|
@ -103,26 +105,41 @@ ThebesLayerBuffer::DrawBufferQuadrant(gfxContext* aTarget,
|
|||
pattern->SetMatrix(transform);
|
||||
aTarget->SetPattern(pattern);
|
||||
|
||||
if (aOpacity != 1.0) {
|
||||
aTarget->Save();
|
||||
aTarget->Clip();
|
||||
aTarget->Paint(aOpacity);
|
||||
aTarget->Restore();
|
||||
if (aMask) {
|
||||
if (aOpacity == 1.0) {
|
||||
aTarget->SetMatrix(*aMaskTransform);
|
||||
aTarget->Mask(aMask);
|
||||
} else {
|
||||
aTarget->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
|
||||
aTarget->Paint(aOpacity);
|
||||
aTarget->PopGroupToSource();
|
||||
aTarget->SetMatrix(*aMaskTransform);
|
||||
aTarget->Mask(aMask);
|
||||
}
|
||||
} else {
|
||||
aTarget->Fill();
|
||||
if (aOpacity == 1.0) {
|
||||
aTarget->Fill();
|
||||
} else {
|
||||
aTarget->Save();
|
||||
aTarget->Clip();
|
||||
aTarget->Paint(aOpacity);
|
||||
aTarget->Restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ThebesLayerBuffer::DrawBufferWithRotation(gfxContext* aTarget, float aOpacity)
|
||||
ThebesLayerBuffer::DrawBufferWithRotation(gfxContext* aTarget, float aOpacity,
|
||||
gfxASurface* aMask,
|
||||
const gfxMatrix* aMaskTransform)
|
||||
{
|
||||
SAMPLE_LABEL("ThebesLayerBuffer", "DrawBufferWithRotation");
|
||||
// Draw four quadrants. We could use REPEAT_, but it's probably better
|
||||
// not to, to be performance-safe.
|
||||
DrawBufferQuadrant(aTarget, LEFT, TOP, aOpacity);
|
||||
DrawBufferQuadrant(aTarget, RIGHT, TOP, aOpacity);
|
||||
DrawBufferQuadrant(aTarget, LEFT, BOTTOM, aOpacity);
|
||||
DrawBufferQuadrant(aTarget, RIGHT, BOTTOM, aOpacity);
|
||||
DrawBufferQuadrant(aTarget, LEFT, TOP, aOpacity, aMask, aMaskTransform);
|
||||
DrawBufferQuadrant(aTarget, RIGHT, TOP, aOpacity, aMask, aMaskTransform);
|
||||
DrawBufferQuadrant(aTarget, LEFT, BOTTOM, aOpacity, aMask, aMaskTransform);
|
||||
DrawBufferQuadrant(aTarget, RIGHT, BOTTOM, aOpacity, aMask, aMaskTransform);
|
||||
}
|
||||
|
||||
already_AddRefed<gfxContext>
|
||||
|
|
|
@ -171,9 +171,18 @@ protected:
|
|||
TOP, BOTTOM
|
||||
};
|
||||
nsIntRect GetQuadrantRectangle(XSide aXSide, YSide aYSide);
|
||||
/*
|
||||
* If aMask is non-null, then it is used as an alpha mask for rendering this
|
||||
* buffer. aMaskTransform must be non-null if aMask is non-null, and is used
|
||||
* to adjust the coordinate space of the mask.
|
||||
*/
|
||||
void DrawBufferQuadrant(gfxContext* aTarget, XSide aXSide, YSide aYSide,
|
||||
float aOpacity);
|
||||
void DrawBufferWithRotation(gfxContext* aTarget, float aOpacity);
|
||||
float aOpacity,
|
||||
gfxASurface* aMask,
|
||||
const gfxMatrix* aMaskTransform);
|
||||
void DrawBufferWithRotation(gfxContext* aTarget, float aOpacity,
|
||||
gfxASurface* aMask = nsnull,
|
||||
const gfxMatrix* aMaskTransform = nsnull);
|
||||
|
||||
/**
|
||||
* |BufferRect()| is the rect of device pixels that this
|
||||
|
|
|
@ -50,7 +50,7 @@ public:
|
|||
* set up to account for all the properties of the layer (transform,
|
||||
* opacity, etc).
|
||||
*/
|
||||
virtual void Paint(gfxContext* aContext) {}
|
||||
virtual void Paint(gfxContext* aContext, Layer* aMaskLayer) {}
|
||||
|
||||
/**
|
||||
* Like Paint() but called for ThebesLayers with the additional parameters
|
||||
|
@ -59,6 +59,7 @@ public:
|
|||
* effective visible region (snapped or unsnapped, it doesn't matter).
|
||||
*/
|
||||
virtual void PaintThebes(gfxContext* aContext,
|
||||
Layer* aMasklayer,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
ReadbackProcessor* aReadback) {}
|
||||
|
@ -99,6 +100,14 @@ public:
|
|||
mOperator = aOperator;
|
||||
}
|
||||
gfxContext::GraphicsOperator GetOperator() const { return mOperator; }
|
||||
|
||||
/**
|
||||
* Return a surface for this layer. Will use an existing surface, if
|
||||
* possible, or may create a temporary surface.
|
||||
* Implement this method for any layers that might be used as a mask.
|
||||
* Should only return null if a surface cannor be created.
|
||||
*/
|
||||
virtual already_AddRefed<gfxASurface> GetAsSurface() { return nsnull; }
|
||||
|
||||
bool GetClipToVisibleRegion() { return mClipToVisibleRegion; }
|
||||
void SetClipToVisibleRegion(bool aClip) { mClipToVisibleRegion = aClip; }
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -69,7 +69,8 @@ BasicTiledLayerBuffer::PaintThebes(BasicTiledThebesLayer* aLayer,
|
|||
const nsIntRegion& aNewValidRegion,
|
||||
const nsIntRegion& aPaintRegion,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData)
|
||||
void* aCallbackData,
|
||||
Layer* aMaskLayer)
|
||||
{
|
||||
mThebesLayer = aLayer;
|
||||
mCallback = aCallback;
|
||||
|
@ -95,6 +96,7 @@ BasicTiledLayerBuffer::PaintThebes(BasicTiledThebesLayer* aLayer,
|
|||
start = PR_IntervalNow();
|
||||
#endif
|
||||
SAMPLE_LABEL("BasicTiledLayerBuffer", "PaintThebesSingleBufferDraw");
|
||||
|
||||
mCallback(mThebesLayer, ctxt, aPaintRegion, aPaintRegion, mCallbackData);
|
||||
}
|
||||
|
||||
|
@ -213,6 +215,7 @@ BasicTiledThebesLayer::FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
|
|||
|
||||
void
|
||||
BasicTiledThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
Layer* aMaskLayer,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
ReadbackProcessor* aReadback)
|
||||
|
@ -232,7 +235,7 @@ BasicTiledThebesLayer::PaintThebes(gfxContext* aContext,
|
|||
if (regionToPaint.IsEmpty())
|
||||
return;
|
||||
|
||||
mTiledBuffer.PaintThebes(this, mVisibleRegion, regionToPaint, aCallback, aCallbackData);
|
||||
mTiledBuffer.PaintThebes(this, mVisibleRegion, regionToPaint, aCallback, aCallbackData, aMaskLayer);
|
||||
mTiledBuffer.ReadLock();
|
||||
mValidRegion = mVisibleRegion;
|
||||
|
||||
|
|
|
@ -86,7 +86,8 @@ public:
|
|||
const nsIntRegion& aNewValidRegion,
|
||||
const nsIntRegion& aPaintRegion,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData);
|
||||
void* aCallbackData,
|
||||
Layer* aMaskLayer);
|
||||
|
||||
BasicTiledLayerTile GetPlaceholderTile() const {
|
||||
return mPlaceholder;
|
||||
|
@ -184,6 +185,7 @@ public:
|
|||
}
|
||||
|
||||
virtual void PaintThebes(gfxContext* aContext,
|
||||
Layer* aMaskLayer,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
ReadbackProcessor* aReadback);
|
||||
|
|
Загрузка…
Ссылка в новой задаче