зеркало из https://github.com/mozilla/gecko-dev.git
Bug 805028 - Add LayerManagerOGL::ComputeRenderIntegrity. r=bgirard
Add a function to LayerManagerOGL that can compute how much of the last rendered area was incomplete (i.e. is pending update when progressive tile drawing is enabled).
This commit is contained in:
Родитель
c09613205b
Коммит
0206c993d6
|
@ -1453,5 +1453,87 @@ LayerManagerOGL::CreateDrawTarget(const IntSize &aSize,
|
||||||
return LayerManager::CreateDrawTarget(aSize, aFormat);
|
return LayerManager::CreateDrawTarget(aSize, aFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ void
|
||||||
|
LayerManagerOGL::ComputeRenderIntegrityInternal(Layer* aLayer,
|
||||||
|
nsIntRegion& aScreenRegion,
|
||||||
|
const gfx3DMatrix& aTransform)
|
||||||
|
{
|
||||||
|
if (aScreenRegion.IsEmpty() || aLayer->GetOpacity() <= 0.f) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the layer's a container, recurse into all of its children
|
||||||
|
ContainerLayer* container = aLayer->AsContainerLayer();
|
||||||
|
if (container) {
|
||||||
|
// Accumulate the transform of intermediate surfaces
|
||||||
|
gfx3DMatrix transform = aTransform;
|
||||||
|
if (container->UseIntermediateSurface()) {
|
||||||
|
transform = aLayer->GetEffectiveTransform();
|
||||||
|
transform.PreMultiply(aTransform);
|
||||||
|
}
|
||||||
|
for (Layer* child = aLayer->GetFirstChild(); child;
|
||||||
|
child = child->GetNextSibling()) {
|
||||||
|
ComputeRenderIntegrityInternal(child, aScreenRegion, transform);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only thebes layers can be incomplete
|
||||||
|
ThebesLayer* thebesLayer = aLayer->AsThebesLayer();
|
||||||
|
if (!thebesLayer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// See if there's any incomplete rendering
|
||||||
|
nsIntRegion incompleteRegion = aLayer->GetEffectiveVisibleRegion();
|
||||||
|
incompleteRegion.Sub(incompleteRegion, thebesLayer->GetValidRegion());
|
||||||
|
|
||||||
|
if (!incompleteRegion.IsEmpty()) {
|
||||||
|
// Calculate the transform to get between screen and layer space
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
LayerManagerOGL::ComputeRenderIntegrity()
|
||||||
|
{
|
||||||
|
// We only ever have incomplete rendering when progressive tiles are enabled.
|
||||||
|
if (!gfxPlatform::UseProgressiveTilePainting() || !GetRoot()) {
|
||||||
|
return 1.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX We assume that mWidgetSize represents the 'screen' area.
|
||||||
|
gfx3DMatrix transform;
|
||||||
|
nsIntRect screenRect(0, 0, mWidgetSize.width, mWidgetSize.height);
|
||||||
|
nsIntRegion screenRegion(screenRect);
|
||||||
|
ComputeRenderIntegrityInternal(GetRoot(), screenRegion, 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return area / (float)(screenRect.width * screenRect.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.f;
|
||||||
|
}
|
||||||
|
|
||||||
} /* layers */
|
} /* layers */
|
||||||
} /* mozilla */
|
} /* mozilla */
|
||||||
|
|
|
@ -361,6 +361,15 @@ public:
|
||||||
CreateDrawTarget(const mozilla::gfx::IntSize &aSize,
|
CreateDrawTarget(const mozilla::gfx::IntSize &aSize,
|
||||||
mozilla::gfx::SurfaceFormat aFormat);
|
mozilla::gfx::SurfaceFormat aFormat);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the 'completeness' of the rendering that intersected with the
|
||||||
|
* screen on the last render. This is only useful when progressive tile
|
||||||
|
* drawing is enabled, otherwise this will always return 1.0.
|
||||||
|
* This function's expense scales with the size of the layer tree and the
|
||||||
|
* complexity of individual layers' valid regions.
|
||||||
|
*/
|
||||||
|
float ComputeRenderIntegrity();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** Widget associated with this layer manager */
|
/** Widget associated with this layer manager */
|
||||||
nsIWidget *mWidget;
|
nsIWidget *mWidget;
|
||||||
|
@ -440,6 +449,15 @@ private:
|
||||||
*/
|
*/
|
||||||
void AddPrograms(gl::ShaderProgramType aType);
|
void AddPrograms(gl::ShaderProgramType aType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursive helper method for use by ComputeRenderIntegrity. Subtracts
|
||||||
|
* any incomplete rendering on aLayer from aScreenRegion. aTransform is the
|
||||||
|
* accumulated transform of intermediate surfaces beneath aLayer.
|
||||||
|
*/
|
||||||
|
static void ComputeRenderIntegrityInternal(Layer* aLayer,
|
||||||
|
nsIntRegion& aScreenRegion,
|
||||||
|
const gfx3DMatrix& aTransform);
|
||||||
|
|
||||||
/* Thebes layer callbacks; valid at the end of a transaciton,
|
/* Thebes layer callbacks; valid at the end of a transaciton,
|
||||||
* while rendering */
|
* while rendering */
|
||||||
DrawThebesLayerCallback mThebesLayerCallback;
|
DrawThebesLayerCallback mThebesLayerCallback;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче