Bug 584494. Avoid clipping in BasicThebesLayer when not necessary. r=cjones a2.0=blocking2.0:betaN

This commit is contained in:
Robert O'Callahan 2010-09-17 12:29:52 -07:00
Родитель a64e116f6b
Коммит b4b97300fb
2 изменённых файлов: 28 добавлений и 5 удалений

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

@ -495,10 +495,16 @@ public:
} }
/** /**
* CONSTRUCTION PHASE ONLY * CONSTRUCTION PHASE ONLY
* Tell this layer which region will be visible. It is the responsibility * Tell this layer which region will be visible. The visible region
* of the caller to ensure that content outside this region does not * is a region which contains all the contents of the layer that can
* contribute to the final visible window. This can be an * actually affect the rendering of the window. It can exclude areas
* overapproximation to the true visible region. * that are covered by opaque contents of other layers, and it can
* exclude areas where this layer simply contains no content at all.
* (This can be an overapproximation to the "true" visible region.)
*
* There is no general guarantee that drawing outside the bounds of the
* visible region will be ignored. So if a layer draws outside the bounds
* of its visible region, it needs to ensure that what it draws is valid.
*/ */
virtual void SetVisibleRegion(const nsIntRegion& aRegion) virtual void SetVisibleRegion(const nsIntRegion& aRegion)
{ {

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

@ -492,6 +492,15 @@ BasicThebesLayer::Paint(gfxContext* aContext,
mBuffer.DrawTo(this, canUseOpaqueSurface, target, aOpacity); mBuffer.DrawTo(this, canUseOpaqueSurface, target, aOpacity);
} }
static PRBool
IsClippingCheap(gfxContext* aTarget, const nsIntRegion& aRegion)
{
// Assume clipping is cheap if the context just has an integer
// translation, and the visible region is simple.
return !aTarget->CurrentMatrix().HasNonIntegerTranslation() &&
aRegion.GetNumRects() <= 1;
}
void void
BasicThebesLayerBuffer::DrawTo(ThebesLayer* aLayer, BasicThebesLayerBuffer::DrawTo(ThebesLayer* aLayer,
PRBool aIsOpaqueContent, PRBool aIsOpaqueContent,
@ -499,7 +508,15 @@ BasicThebesLayerBuffer::DrawTo(ThebesLayer* aLayer,
float aOpacity) float aOpacity)
{ {
aTarget->Save(); aTarget->Save();
gfxUtils::ClipToRegion(aTarget, aLayer->GetVisibleRegion()); // If the entire buffer is valid, we can just draw the whole thing,
// no need to clip. But we'll still clip if clipping is cheap ---
// that might let us copy a smaller region of the buffer.
if (!aLayer->GetValidRegion().Contains(BufferRect()) ||
IsClippingCheap(aTarget, aLayer->GetVisibleRegion())) {
// We don't want to draw invalid stuff, so we need to clip. Might as
// well clip to the smallest area possible --- the visible region.
gfxUtils::ClipToRegion(aTarget, aLayer->GetVisibleRegion());
}
if (aIsOpaqueContent) { if (aIsOpaqueContent) {
aTarget->SetOperator(gfxContext::OPERATOR_SOURCE); aTarget->SetOperator(gfxContext::OPERATOR_SOURCE);
} }