Bug 627273, part 4: Basic impl of ImageLayer tiling for basic layers. r=roc,vlad

This commit is contained in:
Chris Jones 2011-01-26 00:26:37 -06:00
Родитель daeec56b20
Коммит e79b649c5b
6 изменённых файлов: 69 добавлений и 12 удалений

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

@ -200,6 +200,17 @@ LayerManager::CreateOptimalSurface(const gfxIntSize &aSize,
CreateOffscreenSurface(aSize, gfxASurface::ContentFromFormat(aFormat));
}
#ifdef DEBUG
void
LayerManager::Mutated(Layer* aLayer)
{
NS_ABORT_IF_FALSE(!aLayer->GetTileSourceRect() ||
(LAYERS_BASIC == GetBackendType() &&
Layer::TYPE_IMAGE == aLayer->GetType()),
"Tiling not supported for this manager/layer type");
}
#endif // DEBUG
//--------------------------------------------------
// Layer

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

@ -359,8 +359,15 @@ public:
/**
* CONSTRUCTION PHASE ONLY
* Called when a managee has mutated.
* Subclasses overriding this method must first call their
* superclass's impl
*/
#ifdef DEBUG
// In debug builds, we check some properties of |aLayer|.
virtual void Mutated(Layer* aLayer);
#else
virtual void Mutated(Layer* aLayer) { }
#endif
/**
* CONSTRUCTION PHASE ONLY
@ -641,6 +648,10 @@ public:
* ColorLayers, a source rect for tiling doesn't make sense at all.
*
* If aRect is null no tiling will be performed.
*
* NB: this interface is only implemented for BasicImageLayers, and
* then only for source rects the same size as the layers'
* underlying images.
*/
void SetTileSourceRect(const nsIntRect* aRect)
{

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

@ -667,7 +667,8 @@ public:
void* aCallbackData);
static void PaintContext(gfxPattern* aPattern,
const gfxIntSize& aSize,
const nsIntRegion& aVisible,
const nsIntRect* aTileSourceRect,
float aOpacity,
gfxContext* aContext);
@ -712,13 +713,16 @@ BasicImageLayer::GetAndPaintCurrentImage(gfxContext* aContext,
pat->SetFilter(mFilter);
PaintContext(pat, mSize, aOpacity, aContext);
PaintContext(pat,
nsIntRegion(nsIntRect(0, 0, mSize.width, mSize.height)),
GetTileSourceRect(), aOpacity, aContext);
return pat.forget();
}
/*static*/ void
BasicImageLayer::PaintContext(gfxPattern* aPattern,
const gfxIntSize& aSize,
const nsIntRegion& aVisible,
const nsIntRect* aTileSourceRect,
float aOpacity,
gfxContext* aContext)
{
@ -736,14 +740,34 @@ BasicImageLayer::PaintContext(gfxPattern* aPattern,
extend = gfxPattern::EXTEND_NONE;
}
aPattern->SetExtend(extend);
/* Draw RGB surface onto frame */
if (!aTileSourceRect) {
aContext->NewPath();
// No need to snap here; our transform has already taken care of it.
aContext->Rectangle(gfxRect(0, 0, aSize.width, aSize.height));
// XXX true for arbitrary regions? Don't care yet though
gfxUtils::PathFromRegion(aContext, aVisible);
aPattern->SetExtend(extend);
aContext->SetPattern(aPattern);
aContext->FillWithOpacity(aOpacity);
} else {
nsRefPtr<gfxASurface> source = aPattern->GetSurface();
NS_ABORT_IF_FALSE(source, "Expecting a surface pattern");
gfxIntSize sourceSize = source->GetSize();
nsIntRect sourceRect(0, 0, sourceSize.width, sourceSize.height);
NS_ABORT_IF_FALSE(sourceRect == *aTileSourceRect,
"Cowardly refusing to create a temporary surface for tiling");
gfxContextAutoSaveRestore saveRestore(aContext);
aContext->NewPath();
gfxUtils::PathFromRegion(aContext, aVisible);
aPattern->SetExtend(gfxPattern::EXTEND_REPEAT);
aContext->SetPattern(aPattern);
aContext->FillWithOpacity(aOpacity);
}
// Reset extend mode for callers that need to reuse the pattern
aPattern->SetExtend(extend);
}
class BasicColorLayer : public ColorLayer, BasicImplData {
@ -1890,7 +1914,9 @@ BasicShadowableImageLayer::Paint(gfxContext* aContext,
}
nsRefPtr<gfxContext> tmpCtx = new gfxContext(mBackSurface);
PaintContext(pat, mSize, 1.0, tmpCtx);
PaintContext(pat,
nsIntRegion(nsIntRect(0, 0, mSize.width, mSize.height)),
nsnull, 1.0, tmpCtx);
BasicManager()->PaintedImage(BasicManager()->Hold(this),
mBackSurface);
@ -2366,7 +2392,8 @@ BasicShadowImageLayer::Paint(gfxContext* aContext,
nsRefPtr<gfxPattern> pat = new gfxPattern(mFrontSurface);
pat->SetFilter(mFilter);
BasicImageLayer::PaintContext(pat, mSize, GetEffectiveOpacity(), aContext);
BasicImageLayer::PaintContext(
pat, GetEffectiveVisibleRegion(), GetTileSourceRect(), GetEffectiveOpacity(), aContext);
}
class BasicShadowColorLayer : public ShadowColorLayer,
@ -2631,6 +2658,8 @@ BasicShadowLayerManager::SetRoot(Layer* aLayer)
void
BasicShadowLayerManager::Mutated(Layer* aLayer)
{
BasicLayerManager::Mutated(aLayer);
NS_ASSERTION(InConstruction() || InDrawing(), "wrong phase");
if (HasShadowManager()) {
ShadowLayerForwarder::Mutated(Hold(aLayer));

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

@ -122,6 +122,8 @@ struct CommonLayerAttributes {
float opacity;
bool useClipRect;
nsIntRect clipRect;
bool useTileSourceRect;
nsIntRect tileSourceRect;
};
struct ThebesLayerAttributes {

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

@ -345,6 +345,9 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies)
common.useClipRect() = !!mutant->GetClipRect();
common.clipRect() = (common.useClipRect() ?
*mutant->GetClipRect() : nsIntRect());
common.useTileSourceRect() = !!mutant->GetTileSourceRect();
common.tileSourceRect() = (common.useTileSourceRect() ?
*mutant->GetTileSourceRect() : nsIntRect());
attrs.specific() = null_t();
mutant->FillSpecificAttributes(attrs.specific());

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

@ -296,6 +296,7 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
layer->SetOpacity(common.opacity());
layer->SetClipRect(common.useClipRect() ? &common.clipRect() : NULL);
layer->SetTransform(common.transform());
layer->SetTileSourceRect(common.useTileSourceRect() ? &common.tileSourceRect() : NULL);
typedef SpecificLayerAttributes Specific;
const SpecificLayerAttributes& specific = attrs.specific();