зеркало из https://github.com/mozilla/gecko-dev.git
Bug 814437 - Fix checkerboard measurement when using a critical displayport. r=bgirard
The checkerboard measurement depended on the displayport coverage of the viewport, which was calculated in LayerRenderer. When using a critical displayport, this value changes, but this was not being accounted for. We have all the context we need for this Gecko-side, so move this code into LayerManagerOGL::ComputeRenderIntegrity and account for displayport coverage correctly.
This commit is contained in:
Родитель
7d410314ef
Коммит
53958037df
|
@ -1702,20 +1702,87 @@ GetRegionArea(const nsIntRegion& aRegion)
|
|||
return area;
|
||||
}
|
||||
|
||||
static float
|
||||
GetDisplayportCoverage(const gfx::Rect& aDisplayPort,
|
||||
const gfx3DMatrix& aTransformToScreen,
|
||||
const nsIntRect& aScreenRect)
|
||||
{
|
||||
gfxRect transformedDisplayport =
|
||||
aTransformToScreen.TransformBounds(gfxRect(aDisplayPort.x,
|
||||
aDisplayPort.y,
|
||||
aDisplayPort.width,
|
||||
aDisplayPort.height));
|
||||
transformedDisplayport.RoundOut();
|
||||
nsIntRect displayport = nsIntRect(transformedDisplayport.x,
|
||||
transformedDisplayport.y,
|
||||
transformedDisplayport.width,
|
||||
transformedDisplayport.height);
|
||||
if (!displayport.Contains(aScreenRect)) {
|
||||
nsIntRegion coveredRegion;
|
||||
coveredRegion.And(aScreenRect, displayport);
|
||||
return GetRegionArea(coveredRegion) / (float)(aScreenRect.width * aScreenRect.height);
|
||||
}
|
||||
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
float
|
||||
LayerManagerOGL::ComputeRenderIntegrity()
|
||||
{
|
||||
// We only ever have incomplete rendering when progressive tiles are enabled.
|
||||
if (!gfxPlatform::UseProgressiveTilePainting() || !GetRoot()) {
|
||||
Layer* root = GetRoot();
|
||||
if (!gfxPlatform::UseProgressiveTilePainting() || !root) {
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
// XXX We assume that mWidgetSize represents the 'screen' area.
|
||||
gfx3DMatrix transform;
|
||||
nsIntRect screenRect(0, 0, mWidgetSize.width, mWidgetSize.height);
|
||||
const FrameMetrics& rootMetrics = root->AsContainerLayer()->GetFrameMetrics();
|
||||
nsIntRect screenRect(rootMetrics.mCompositionBounds.x,
|
||||
rootMetrics.mCompositionBounds.y,
|
||||
rootMetrics.mCompositionBounds.width,
|
||||
rootMetrics.mCompositionBounds.height);
|
||||
|
||||
float lowPrecisionMultiplier = 1.0f;
|
||||
float highPrecisionMultiplier = 1.0f;
|
||||
#ifdef MOZ_ANDROID_OMTC
|
||||
// Use the transform on the primary scrollable layer and its FrameMetrics
|
||||
// to find out how much of the viewport the current displayport covers
|
||||
bool hasLowPrecision = true;
|
||||
Layer* primaryScrollable = GetPrimaryScrollableLayer();
|
||||
if (primaryScrollable) {
|
||||
// This is derived from the code in
|
||||
// gfx/layers/ipc/CompositorParent.cpp::TransformShadowTree.
|
||||
const gfx3DMatrix& rootTransform = root->GetTransform();
|
||||
float devPixelRatioX = 1 / rootTransform.GetXScale();
|
||||
float devPixelRatioY = 1 / rootTransform.GetYScale();
|
||||
|
||||
gfx3DMatrix transform = primaryScrollable->GetEffectiveTransform();
|
||||
transform.ScalePost(devPixelRatioX, devPixelRatioY, 1);
|
||||
const FrameMetrics& metrics = primaryScrollable->AsContainerLayer()->GetFrameMetrics();
|
||||
|
||||
// Work out how much of the critical display-port covers the screen
|
||||
if (!metrics.mCriticalDisplayPort.IsEmpty()) {
|
||||
hasLowPrecision = true;
|
||||
highPrecisionMultiplier =
|
||||
GetDisplayportCoverage(metrics.mCriticalDisplayPort, transform, screenRect);
|
||||
}
|
||||
|
||||
// Work out how much of the display-port covers the screen
|
||||
if (!metrics.mDisplayPort.IsEmpty()) {
|
||||
if (hasLowPrecision) {
|
||||
lowPrecisionMultiplier =
|
||||
GetDisplayportCoverage(metrics.mDisplayPort, transform, screenRect);
|
||||
} else {
|
||||
highPrecisionMultiplier =
|
||||
GetDisplayportCoverage(metrics.mDisplayPort, transform, screenRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
nsIntRegion screenRegion(screenRect);
|
||||
nsIntRegion lowPrecisionScreenRegion(screenRect);
|
||||
ComputeRenderIntegrityInternal(GetRoot(), screenRegion,
|
||||
gfx3DMatrix transform;
|
||||
ComputeRenderIntegrityInternal(root, screenRegion,
|
||||
lowPrecisionScreenRegion, transform);
|
||||
|
||||
if (!screenRegion.IsEqual(screenRect)) {
|
||||
|
@ -1728,7 +1795,8 @@ LayerManagerOGL::ComputeRenderIntegrity()
|
|||
lowPrecisionIntegrity = GetRegionArea(lowPrecisionScreenRegion) / screenArea;
|
||||
}
|
||||
|
||||
return (highPrecisionIntegrity + lowPrecisionIntegrity) / 2.f;
|
||||
return ((highPrecisionIntegrity * highPrecisionMultiplier) +
|
||||
(lowPrecisionIntegrity * lowPrecisionMultiplier)) / 2.f;
|
||||
}
|
||||
|
||||
return 1.f;
|
||||
|
|
|
@ -598,46 +598,8 @@ public class LayerRenderer implements Tabs.OnTabsChangedListener {
|
|||
Layer rootLayer = mView.getLayerClient().getRoot();
|
||||
if ((rootLayer != null) &&
|
||||
(mProfileRender || PanningPerfAPI.isRecordingCheckerboard())) {
|
||||
// Find out how much of the viewport area is valid
|
||||
Rect viewport = RectUtils.round(mPageContext.viewport);
|
||||
Region validRegion = rootLayer.getValidRegion(mPageContext);
|
||||
|
||||
/* restrict the viewport to page bounds so we don't
|
||||
* count overscroll as checkerboard */
|
||||
if (!viewport.intersect(mAbsolutePageRect)) {
|
||||
/* if the rectangles don't intersect
|
||||
intersect() doesn't change viewport
|
||||
so we set it to empty by hand */
|
||||
viewport.setEmpty();
|
||||
}
|
||||
validRegion.op(viewport, Region.Op.INTERSECT);
|
||||
|
||||
// Check if we have total checkerboarding (there's visible
|
||||
// page area and the valid region doesn't intersect with the
|
||||
// viewport).
|
||||
int screenArea = viewport.width() * viewport.height();
|
||||
float checkerboard = (screenArea > 0 &&
|
||||
validRegion.quickReject(viewport)) ? 1.0f : 0.0f;
|
||||
|
||||
if (screenArea > 0 && checkerboard < 1.0f) {
|
||||
validRegion.op(viewport, Region.Op.REVERSE_DIFFERENCE);
|
||||
|
||||
// XXX The assumption here is that a Region never has overlapping
|
||||
// rects. This is true, as evidenced by reading the SkRegion
|
||||
// source, but is not mentioned in the Android documentation,
|
||||
// and so is liable to change.
|
||||
// If it does change, this code will need to be reevaluated.
|
||||
Rect r = new Rect();
|
||||
int checkerboardArea = 0;
|
||||
for (RegionIterator i = new RegionIterator(validRegion); i.next(r);) {
|
||||
checkerboardArea += r.width() * r.height();
|
||||
}
|
||||
|
||||
checkerboard = checkerboardArea / (float)screenArea;
|
||||
|
||||
// Add any incomplete rendering in the screen area
|
||||
checkerboard += (1.0 - checkerboard) * (1.0 - GeckoAppShell.computeRenderIntegrity());
|
||||
}
|
||||
// Calculate the incompletely rendered area of the page
|
||||
float checkerboard = 1.0f - GeckoAppShell.computeRenderIntegrity();
|
||||
|
||||
PanningPerfAPI.recordCheckerboard(checkerboard);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче