mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 16:22:00 +00:00
Bug 814437 - Count low precision rendering 0.5x towards checkerboarding. r=bgirard
This commit is contained in:
parent
261e6627b6
commit
7d410314ef
@ -1146,6 +1146,7 @@ public:
|
||||
* Can be used anytime
|
||||
*/
|
||||
const nsIntRegion& GetValidRegion() const { return mValidRegion; }
|
||||
virtual const nsIntRegion& GetValidLowPrecisionRegion() const { return mValidRegion; }
|
||||
|
||||
virtual ThebesLayer* AsThebesLayer() { return this; }
|
||||
|
||||
|
@ -1618,12 +1618,35 @@ LayerManagerOGL::CreateDrawTarget(const IntSize &aSize,
|
||||
return LayerManager::CreateDrawTarget(aSize, aFormat);
|
||||
}
|
||||
|
||||
static void
|
||||
SubtractTransformedRegion(nsIntRegion& aRegion,
|
||||
const nsIntRegion& aRegionToSubtract,
|
||||
const gfx3DMatrix& aTransform)
|
||||
{
|
||||
if (aRegionToSubtract.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// For each rect in the region, find out its bounds in screen space and
|
||||
// subtract it from the screen region.
|
||||
nsIntRegionRectIterator it(aRegionToSubtract);
|
||||
while (const nsIntRect* rect = it.Next()) {
|
||||
gfxRect incompleteRect = aTransform.TransformBounds(gfxRect(*rect));
|
||||
aRegion.Sub(aRegion, nsIntRect(incompleteRect.x,
|
||||
incompleteRect.y,
|
||||
incompleteRect.width,
|
||||
incompleteRect.height));
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
LayerManagerOGL::ComputeRenderIntegrityInternal(Layer* aLayer,
|
||||
nsIntRegion& aScreenRegion,
|
||||
nsIntRegion& aLowPrecisionScreenRegion,
|
||||
const gfx3DMatrix& aTransform)
|
||||
{
|
||||
if (aScreenRegion.IsEmpty() || aLayer->GetOpacity() <= 0.f) {
|
||||
if (aLayer->GetOpacity() <= 0.f ||
|
||||
(aScreenRegion.IsEmpty() && aLowPrecisionScreenRegion.IsEmpty())) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1638,7 +1661,7 @@ LayerManagerOGL::ComputeRenderIntegrityInternal(Layer* aLayer,
|
||||
}
|
||||
for (Layer* child = aLayer->GetFirstChild(); child;
|
||||
child = child->GetNextSibling()) {
|
||||
ComputeRenderIntegrityInternal(child, aScreenRegion, transform);
|
||||
ComputeRenderIntegrityInternal(child, aScreenRegion, aLowPrecisionScreenRegion, transform);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1658,19 +1681,27 @@ LayerManagerOGL::ComputeRenderIntegrityInternal(Layer* aLayer,
|
||||
gfx3DMatrix transformToScreen = aLayer->GetEffectiveTransform();
|
||||
transformToScreen.PreMultiply(aTransform);
|
||||
|
||||
// For each rect in the region, find out its bounds in screen space and
|
||||
// subtract it from the screen region.
|
||||
nsIntRegionRectIterator it(incompleteRegion);
|
||||
while (const nsIntRect* rect = it.Next()) {
|
||||
gfxRect incompleteRect = transformToScreen.TransformBounds(gfxRect(*rect));
|
||||
aScreenRegion.Sub(aScreenRegion, nsIntRect(incompleteRect.x,
|
||||
incompleteRect.y,
|
||||
incompleteRect.width,
|
||||
incompleteRect.height));
|
||||
SubtractTransformedRegion(aScreenRegion, incompleteRegion, transformToScreen);
|
||||
|
||||
// See if there's any incomplete low-precision rendering
|
||||
incompleteRegion.Sub(incompleteRegion, thebesLayer->GetValidLowPrecisionRegion());
|
||||
if (!incompleteRegion.IsEmpty()) {
|
||||
SubtractTransformedRegion(aLowPrecisionScreenRegion, incompleteRegion, transformToScreen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
GetRegionArea(const nsIntRegion& aRegion)
|
||||
{
|
||||
int area = 0;
|
||||
nsIntRegionRectIterator it(aRegion);
|
||||
while (const nsIntRect* rect = it.Next()) {
|
||||
area += rect->width * rect->height;
|
||||
}
|
||||
return area;
|
||||
}
|
||||
|
||||
float
|
||||
LayerManagerOGL::ComputeRenderIntegrity()
|
||||
{
|
||||
@ -1683,18 +1714,21 @@ LayerManagerOGL::ComputeRenderIntegrity()
|
||||
gfx3DMatrix transform;
|
||||
nsIntRect screenRect(0, 0, mWidgetSize.width, mWidgetSize.height);
|
||||
nsIntRegion screenRegion(screenRect);
|
||||
ComputeRenderIntegrityInternal(GetRoot(), screenRegion, transform);
|
||||
nsIntRegion lowPrecisionScreenRegion(screenRect);
|
||||
ComputeRenderIntegrityInternal(GetRoot(), screenRegion,
|
||||
lowPrecisionScreenRegion, transform);
|
||||
|
||||
if (!screenRegion.IsEqual(screenRect)) {
|
||||
// Calculate the area of the region. All rects in an nsRegion are
|
||||
// non-overlapping.
|
||||
int area = 0;
|
||||
nsIntRegionRectIterator it(screenRegion);
|
||||
while (const nsIntRect* rect = it.Next()) {
|
||||
area += rect->width * rect->height;
|
||||
float screenArea = screenRect.width * screenRect.height;
|
||||
float highPrecisionIntegrity = GetRegionArea(screenRegion) / screenArea;
|
||||
float lowPrecisionIntegrity = 1.f;
|
||||
if (!lowPrecisionScreenRegion.IsEqual(screenRect)) {
|
||||
lowPrecisionIntegrity = GetRegionArea(lowPrecisionScreenRegion) / screenArea;
|
||||
}
|
||||
|
||||
return area / (float)(screenRect.width * screenRect.height);
|
||||
return (highPrecisionIntegrity + lowPrecisionIntegrity) / 2.f;
|
||||
}
|
||||
|
||||
return 1.f;
|
||||
|
@ -399,11 +399,13 @@ private:
|
||||
|
||||
/**
|
||||
* Recursive helper method for use by ComputeRenderIntegrity. Subtracts
|
||||
* any incomplete rendering on aLayer from aScreenRegion. aTransform is the
|
||||
* any incomplete rendering on aLayer from aScreenRegion. Any low-precision
|
||||
* rendering is included in aLowPrecisionScreenRegion. aTransform is the
|
||||
* accumulated transform of intermediate surfaces beneath aLayer.
|
||||
*/
|
||||
static void ComputeRenderIntegrityInternal(Layer* aLayer,
|
||||
nsIntRegion& aScreenRegion,
|
||||
nsIntRegion& aLowPrecisionScreenRegion,
|
||||
const gfx3DMatrix& aTransform);
|
||||
|
||||
/* Thebes layer callbacks; valid at the end of a transaciton,
|
||||
|
@ -113,6 +113,9 @@ public:
|
||||
TiledThebesLayerOGL(LayerManagerOGL *aManager);
|
||||
virtual ~TiledThebesLayerOGL();
|
||||
|
||||
// Layer implementation
|
||||
const nsIntRegion& GetValidLowPrecisionRegion() const { return mLowPrecisionVideoMemoryTiledBuffer.GetValidRegion(); }
|
||||
|
||||
// LayerOGL impl
|
||||
void Destroy() {}
|
||||
Layer* GetLayer() { return this; }
|
||||
|
Loading…
Reference in New Issue
Block a user