зеркало из 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);
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
} /* mozilla */
|
||||
|
|
|
@ -361,6 +361,15 @@ public:
|
|||
CreateDrawTarget(const mozilla::gfx::IntSize &aSize,
|
||||
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:
|
||||
/** Widget associated with this layer manager */
|
||||
nsIWidget *mWidget;
|
||||
|
@ -440,6 +449,15 @@ private:
|
|||
*/
|
||||
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,
|
||||
* while rendering */
|
||||
DrawThebesLayerCallback mThebesLayerCallback;
|
||||
|
|
Загрузка…
Ссылка в новой задаче