зеркало из https://github.com/mozilla/gecko-dev.git
Bug 657401. Ensure that when our double-buffering logic expects layers to clip to their visible regions, we actually do. r=tnikkel
--HG-- extra : rebase_source : 16ea17d5a6a0177a26a3d38ae587290e194234b1
This commit is contained in:
Родитель
01293879f0
Коммит
79a9fa270a
|
@ -94,7 +94,8 @@ class ShadowableLayer;
|
|||
*/
|
||||
class BasicImplData {
|
||||
public:
|
||||
BasicImplData() : mHidden(PR_FALSE), mOperator(gfxContext::OPERATOR_OVER)
|
||||
BasicImplData() : mHidden(PR_FALSE),
|
||||
mClipToVisibleRegion(PR_FALSE), mOperator(gfxContext::OPERATOR_OVER)
|
||||
{
|
||||
MOZ_COUNT_CTOR(BasicImplData);
|
||||
}
|
||||
|
@ -114,6 +115,8 @@ public:
|
|||
/**
|
||||
* Like Paint() but called for ThebesLayers with the additional parameters
|
||||
* they need.
|
||||
* If mClipToVisibleRegion is set, then the layer must clip to its
|
||||
* effective visible region (snapped or unsnapped, it doesn't matter).
|
||||
*/
|
||||
virtual void PaintThebes(gfxContext* aContext,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
|
@ -157,8 +160,12 @@ public:
|
|||
}
|
||||
gfxContext::GraphicsOperator GetOperator() const { return mOperator; }
|
||||
|
||||
PRBool GetClipToVisibleRegion() { return mClipToVisibleRegion; }
|
||||
void SetClipToVisibleRegion(PRBool aClip) { mClipToVisibleRegion = aClip; }
|
||||
|
||||
protected:
|
||||
PRPackedBool mHidden;
|
||||
PRPackedBool mClipToVisibleRegion;
|
||||
gfxContext::GraphicsOperator mOperator;
|
||||
};
|
||||
|
||||
|
@ -664,7 +671,7 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
|
|||
|
||||
aContext->Save();
|
||||
|
||||
PRBool needsClipToVisibleRegion = PR_FALSE;
|
||||
PRBool needsClipToVisibleRegion = GetClipToVisibleRegion();
|
||||
PRBool needsGroup =
|
||||
opacity != 1.0 || GetOperator() != gfxContext::OPERATOR_OVER;
|
||||
nsRefPtr<gfxContext> groupContext;
|
||||
|
@ -766,7 +773,10 @@ BasicThebesLayerBuffer::DrawTo(ThebesLayer* aLayer,
|
|||
// 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.
|
||||
// Also clip to the visible region if we're told to.
|
||||
if (!aLayer->GetValidRegion().Contains(BufferRect()) ||
|
||||
(ToData(aLayer)->GetClipToVisibleRegion() &&
|
||||
!aLayer->GetVisibleRegion().Contains(BufferRect())) ||
|
||||
IsClippingCheap(aTarget, aLayer->GetEffectiveVisibleRegion())) {
|
||||
// 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.
|
||||
|
@ -1375,6 +1385,7 @@ TransformIntRect(nsIntRect& aRect, const gfxMatrix& aMatrix,
|
|||
* It can't be used as is by accelerated layers because of intermediate surfaces.
|
||||
* This must set the hidden flag to true or false on *all* layers in the subtree.
|
||||
* It also sets the operator for all layers to "OVER".
|
||||
* It clears mClipToVisibleRegion on all layers.
|
||||
* @param aClipRect the cliprect, in the root coordinate system. We assume
|
||||
* that any layer drawing is clipped to this rect. It is therefore not
|
||||
* allowed to add to the opaque region outside that rect.
|
||||
|
@ -1423,6 +1434,7 @@ MarkLayersHidden(Layer* aLayer, const nsIntRect& aClipRect,
|
|||
|
||||
BasicImplData* data = ToData(aLayer);
|
||||
data->SetOperator(gfxContext::OPERATOR_OVER);
|
||||
data->SetClipToVisibleRegion(PR_FALSE);
|
||||
|
||||
if (!aLayer->AsContainerLayer()) {
|
||||
gfxMatrix transform;
|
||||
|
@ -1513,8 +1525,11 @@ ApplyDoubleBuffering(Layer* aLayer, const nsIntRect& aVisibleRect)
|
|||
data->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
container->ForceIntermediateSurface();
|
||||
} else {
|
||||
// Tell the children to clip to their visible regions so our assumption
|
||||
// that they don't paint outside their visible regions is valid!
|
||||
for (Layer* child = aLayer->GetFirstChild(); child;
|
||||
child = child->GetNextSibling()) {
|
||||
ToData(child)->SetClipToVisibleRegion(PR_TRUE);
|
||||
ApplyDoubleBuffering(child, newVisibleRect);
|
||||
}
|
||||
}
|
||||
|
@ -1637,14 +1652,16 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
|||
BasicContainerLayer* container = static_cast<BasicContainerLayer*>(aLayer);
|
||||
PRBool needsGroup = aLayer->GetFirstChild() &&
|
||||
container->UseIntermediateSurface();
|
||||
BasicImplData* data = ToData(aLayer);
|
||||
PRBool needsClipToVisibleRegion =
|
||||
data->GetClipToVisibleRegion() && !aLayer->AsThebesLayer();
|
||||
NS_ASSERTION(needsGroup || !aLayer->GetFirstChild() ||
|
||||
container->GetOperator() == gfxContext::OPERATOR_OVER,
|
||||
"non-OVER operator should have forced UseIntermediateSurface");
|
||||
|
||||
// If needsSaveRestore is false, we should still save and restore
|
||||
// the CTM
|
||||
PRBool needsSaveRestore = needsGroup || clipRect;
|
||||
|
||||
PRBool needsSaveRestore = needsGroup || clipRect || needsClipToVisibleRegion;
|
||||
gfxMatrix savedMatrix;
|
||||
if (needsSaveRestore) {
|
||||
aTarget->Save();
|
||||
|
@ -1666,8 +1683,15 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
|||
effectiveTransform.Is2D(&transform);
|
||||
aTarget->SetMatrix(transform);
|
||||
|
||||
PRBool pushedTargetOpaqueRect = PR_FALSE;
|
||||
const nsIntRegion& visibleRegion = aLayer->GetEffectiveVisibleRegion();
|
||||
// If needsGroup is true, we'll clip to the visible region after we've popped the group
|
||||
if (needsClipToVisibleRegion && !needsGroup) {
|
||||
gfxUtils::ClipToRegion(aTarget, visibleRegion);
|
||||
// Don't need to clip to visible region again
|
||||
needsClipToVisibleRegion = PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool pushedTargetOpaqueRect = PR_FALSE;
|
||||
nsRefPtr<gfxASurface> currentSurface = aTarget->CurrentSurface();
|
||||
const gfxRect& targetOpaqueRect = currentSurface->GetOpaqueRect();
|
||||
|
||||
|
@ -1682,7 +1706,6 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
|||
pushedTargetOpaqueRect = PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool needsClipToVisibleRegion = PR_FALSE;
|
||||
nsRefPtr<gfxContext> groupTarget;
|
||||
if (needsGroup) {
|
||||
groupTarget = PushGroupForLayer(aTarget, aLayer, aLayer->GetEffectiveVisibleRegion(),
|
||||
|
@ -1694,7 +1717,6 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
|||
/* Only paint ourself, or our children - This optimization relies on this! */
|
||||
Layer* child = aLayer->GetFirstChild();
|
||||
if (!child) {
|
||||
BasicImplData* data = ToData(aLayer);
|
||||
#ifdef MOZ_LAYERS_HAVE_LOG
|
||||
MOZ_LAYERS_LOG(("%s (0x%p) is covered: %i\n", __FUNCTION__,
|
||||
(void*)aLayer, data->IsHidden()));
|
||||
|
|
Загрузка…
Ссылка в новой задаче