Bug 1273356 - Remove the unused and incorrect ComputeRenderIntegrity codepath for computing checkerboard. r=rbarker

MozReview-Commit-ID: 4i1rmeqrkZ1
This commit is contained in:
Kartikaya Gupta 2016-08-03 11:59:08 -04:00
Родитель 3885b04a2a
Коммит 6962e151a2
12 изменённых файлов: 3 добавлений и 384 удалений

Просмотреть файл

@ -1192,221 +1192,6 @@ LayerManagerComposite::RenderToPresentationSurface()
}
#endif
static void
SubtractTransformedRegion(nsIntRegion& aRegion,
const nsIntRegion& aRegionToSubtract,
const Matrix4x4& 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.
for (auto iter = aRegionToSubtract.RectIter(); !iter.Done(); iter.Next()) {
const IntRect& rect = iter.Get();
Rect incompleteRect = aTransform.TransformAndClipBounds(IntRectToRect(rect),
Rect::MaxIntRect());
aRegion.Sub(aRegion, IntRect(incompleteRect.x,
incompleteRect.y,
incompleteRect.width,
incompleteRect.height));
}
}
/* static */ void
LayerManagerComposite::ComputeRenderIntegrityInternal(Layer* aLayer,
nsIntRegion& aScreenRegion,
nsIntRegion& aLowPrecisionScreenRegion,
const Matrix4x4& aTransform)
{
ForEachNode<ForwardIterator>(
aLayer,
[&aScreenRegion, &aLowPrecisionScreenRegion, &aTransform] (Layer* layer)
{
if (layer->GetOpacity() <= 0.f ||
(aScreenRegion.IsEmpty() && aLowPrecisionScreenRegion.IsEmpty())) {
return TraversalFlag::Skip;
}
// If the layer's a container, recurse into all of its children
ContainerLayer* container = layer->AsContainerLayer();
if (container) {
// Accumulate the transform of intermediate surfaces
Matrix4x4 transform = aTransform;
if (container->UseIntermediateSurface()) {
transform = layer->GetEffectiveTransform();
transform = aTransform * transform;
}
return TraversalFlag::Continue;
}
// Only painted layers can be incomplete
PaintedLayer* paintedLayer = layer->AsPaintedLayer();
if (!paintedLayer || !container) {
return TraversalFlag::Skip;
}
// See if there's any incomplete rendering
nsIntRegion incompleteRegion = layer->GetLocalVisibleRegion().ToUnknownRegion();
incompleteRegion.Sub(incompleteRegion, paintedLayer->GetValidRegion());
if (!incompleteRegion.IsEmpty()) {
// Calculate the transform to get between screen and layer space
Matrix4x4 transformToScreen = layer->GetEffectiveTransform();
transformToScreen = aTransform * transformToScreen;
SubtractTransformedRegion(aScreenRegion, incompleteRegion, transformToScreen);
// See if there's any incomplete low-precision rendering
TiledContentHost* composer = nullptr;
LayerComposite* shadow = layer->AsLayerComposite();
if (shadow) {
composer = shadow->GetCompositableHost()->AsTiledContentHost();
if (composer) {
incompleteRegion.Sub(incompleteRegion, composer->GetValidLowPrecisionRegion());
if (!incompleteRegion.IsEmpty()) {
SubtractTransformedRegion(aLowPrecisionScreenRegion, incompleteRegion, transformToScreen);
}
}
}
// If we can't get a valid low precision region, assume it's the same as
// the high precision region.
if (!composer) {
SubtractTransformedRegion(aLowPrecisionScreenRegion, incompleteRegion, transformToScreen);
}
}
return TraversalFlag::Skip;
});
}
#ifdef MOZ_WIDGET_ANDROID
static float
GetDisplayportCoverage(const CSSRect& aDisplayPort,
const Matrix4x4& aTransformToScreen,
const IntRect& aScreenRect)
{
Rect transformedDisplayport =
aTransformToScreen.TransformBounds(aDisplayPort.ToUnknownRect());
transformedDisplayport.RoundOut();
IntRect displayport = IntRect(transformedDisplayport.x,
transformedDisplayport.y,
transformedDisplayport.width,
transformedDisplayport.height);
if (!displayport.Contains(aScreenRect)) {
nsIntRegion coveredRegion;
coveredRegion.And(aScreenRect, displayport);
return coveredRegion.Area() / (float)(aScreenRect.width * aScreenRect.height);
}
return 1.0f;
}
#endif // MOZ_WIDGET_ANDROID
float
LayerManagerComposite::ComputeRenderIntegrity()
{
// We only ever have incomplete rendering when progressive tiles are enabled.
Layer* root = GetRoot();
if (!gfxPlatform::GetPlatform()->UseProgressivePaint() || !root) {
return 1.f;
}
FrameMetrics rootMetrics = LayerMetricsWrapper::TopmostScrollableMetrics(root);
if (!rootMetrics.IsScrollable()) {
// The root may not have any scrollable metrics, in which case rootMetrics
// will just be an empty FrameMetrics. Instead use the actual metrics from
// the root layer.
rootMetrics = LayerMetricsWrapper(root).Metrics();
}
ParentLayerIntRect bounds = RoundedToInt(rootMetrics.GetCompositionBounds());
IntRect screenRect(bounds.x,
bounds.y,
bounds.width,
bounds.height);
float lowPrecisionMultiplier = 1.0f;
float highPrecisionMultiplier = 1.0f;
#ifdef MOZ_WIDGET_ANDROID
// Use the transform on the primary scrollable layer and its FrameMetrics
// to find out how much of the viewport the current displayport covers
nsTArray<Layer*> rootScrollableLayers;
GetRootScrollableLayers(rootScrollableLayers);
if (rootScrollableLayers.Length() > 0) {
// This is derived from the code in
// AsyncCompositionManager::TransformScrollableLayer
Layer* rootScrollable = rootScrollableLayers[0];
const FrameMetrics& metrics = LayerMetricsWrapper::TopmostScrollableMetrics(rootScrollable);
Matrix4x4 transform = rootScrollable->GetEffectiveTransform();
transform.PostScale(metrics.GetPresShellResolution(), metrics.GetPresShellResolution(), 1);
// Clip the screen rect to the document bounds
Rect documentBounds =
transform.TransformBounds(Rect(metrics.GetScrollableRect().x - metrics.GetScrollOffset().x,
metrics.GetScrollableRect().y - metrics.GetScrollOffset().y,
metrics.GetScrollableRect().width,
metrics.GetScrollableRect().height));
documentBounds.RoundOut();
screenRect = screenRect.Intersect(IntRect(documentBounds.x, documentBounds.y,
documentBounds.width, documentBounds.height));
// If the screen rect is empty, the user has scrolled entirely into
// over-scroll and so we can be considered to have full integrity.
if (screenRect.IsEmpty()) {
return 1.0f;
}
// Work out how much of the critical display-port covers the screen
bool hasLowPrecision = false;
if (!metrics.GetCriticalDisplayPort().IsEmpty()) {
hasLowPrecision = true;
highPrecisionMultiplier =
GetDisplayportCoverage(metrics.GetCriticalDisplayPort(), transform, screenRect);
}
// Work out how much of the display-port covers the screen
if (!metrics.GetDisplayPort().IsEmpty()) {
if (hasLowPrecision) {
lowPrecisionMultiplier =
GetDisplayportCoverage(metrics.GetDisplayPort(), transform, screenRect);
} else {
lowPrecisionMultiplier = highPrecisionMultiplier =
GetDisplayportCoverage(metrics.GetDisplayPort(), transform, screenRect);
}
}
}
// If none of the screen is covered, we have zero integrity.
if (highPrecisionMultiplier <= 0.0f && lowPrecisionMultiplier <= 0.0f) {
return 0.0f;
}
#endif // MOZ_WIDGET_ANDROID
nsIntRegion screenRegion(screenRect);
nsIntRegion lowPrecisionScreenRegion(screenRect);
Matrix4x4 transform;
ComputeRenderIntegrityInternal(root, screenRegion,
lowPrecisionScreenRegion, transform);
if (!screenRegion.IsEqual(screenRect)) {
// Calculate the area of the region. All rects in an nsRegion are
// non-overlapping.
float screenArea = screenRect.width * screenRect.height;
float highPrecisionIntegrity = screenRegion.Area() / screenArea;
float lowPrecisionIntegrity = 1.f;
if (!lowPrecisionScreenRegion.IsEqual(screenRect)) {
lowPrecisionIntegrity = lowPrecisionScreenRegion.Area() / screenArea;
}
return ((highPrecisionIntegrity * highPrecisionMultiplier) +
(lowPrecisionIntegrity * lowPrecisionMultiplier)) / 2;
}
return 1.f;
}
already_AddRefed<PaintedLayerComposite>
LayerManagerComposite::CreatePaintedLayerComposite()
{

Просмотреть файл

@ -198,15 +198,6 @@ public:
bool mFailed;
};
/**
* 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();
/**
* returns true if PlatformAllocBuffer will return a buffer that supports
* direct texturing
@ -348,17 +339,6 @@ private:
/** Current root layer. */
LayerComposite* RootLayer() const;
/**
* Recursive helper method for use by ComputeRenderIntegrity. Subtracts
* 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 gfx::Matrix4x4& aTransform);
/**
* Update the invalid region and render it.
*/

Просмотреть файл

@ -1884,16 +1884,6 @@ CompositorBridgeParent::GetAPZCTreeManager(uint64_t aLayersId)
return apzctm.forget();
}
float
CompositorBridgeParent::ComputeRenderIntegrity()
{
if (mLayerManager) {
return mLayerManager->ComputeRenderIntegrity();
}
return 1.0f;
}
static void
InsertVsyncProfilerMarker(TimeStamp aVsyncTimestamp)
{

Просмотреть файл

@ -482,8 +482,6 @@ public:
*/
static void PostInsertVsyncProfilerMarker(mozilla::TimeStamp aVsyncTimestamp);
float ComputeRenderIntegrity();
widget::CompositorWidget* GetWidget() { return mWidget; }
void ForceComposeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect = nullptr);

Просмотреть файл

@ -261,8 +261,6 @@ public class GeckoAppShell
public static native void invalidateAndScheduleComposite();
public static native float computeRenderIntegrity();
public static native void addPresentationSurface(Surface surface);
public static native void removePresentationSurface(Surface surface);

Просмотреть файл

@ -936,7 +936,6 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
if (mLayerRenderer == null) {
return null;
}
mLayerRenderer.checkMonitoringEnabled();
mLayerRenderer.createDefaultProgram();
mLayerRendererInitialized = true;
}

Просмотреть файл

@ -43,7 +43,6 @@ import javax.microedition.khronos.egl.EGLConfig;
*/
public class LayerRenderer implements Tabs.OnTabsChangedListener {
private static final String LOGTAG = "GeckoLayerRenderer";
private static final String PROFTAG = "GeckoLayerRendererProf";
/*
* The amount of time a frame is allowed to take to render before we declare it a dropped
@ -78,12 +77,6 @@ public class LayerRenderer implements Tabs.OnTabsChangedListener {
private final int[] mFrameTimings;
private int mCurrentFrame, mFrameTimingsSum, mDroppedFrames;
// Render profiling output
private int mFramesRendered;
private float mCompleteFramesRendered;
private boolean mProfileRender;
private long mProfileOutputTime;
private IntBuffer mPixelBuffer;
// Used by GLES 2.0
@ -204,7 +197,6 @@ public class LayerRenderer implements Tabs.OnTabsChangedListener {
}
void onSurfaceCreated(EGLConfig config) {
checkMonitoringEnabled();
createDefaultProgram();
activateDefaultProgram();
}
@ -308,12 +300,6 @@ public class LayerRenderer implements Tabs.OnTabsChangedListener {
}
}
private void printCheckerboardStats() {
Log.d(PROFTAG, "Frames rendered over last 1000ms: " + mCompleteFramesRendered + "/" + mFramesRendered);
mFramesRendered = 0;
mCompleteFramesRendered = 0;
}
/** Used by robocop for testing purposes. Not for production use! */
IntBuffer getPixels() {
IntBuffer pixelBuffer = IntBuffer.allocate(mView.getWidth() * mView.getHeight());
@ -374,10 +360,6 @@ public class LayerRenderer implements Tabs.OnTabsChangedListener {
int averageTime = mFrameTimingsSum / mFrameTimings.length;
}
void checkMonitoringEnabled() {
mProfileRender = Log.isLoggable(PROFTAG, Log.DEBUG);
}
/*
* create a vertex shader type (GLES20.GL_VERTEX_SHADER)
* or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
@ -554,27 +536,6 @@ public class LayerRenderer implements Tabs.OnTabsChangedListener {
mHorizScrollLayer.draw(mPageContext);
}
/* Measure how much of the screen is checkerboarding */
Layer rootLayer = mView.getLayerClient().getRoot();
if ((rootLayer != null) &&
(mProfileRender || PanningPerfAPI.isRecordingCheckerboard())) {
// Calculate the incompletely rendered area of the page
float checkerboard = 1.0f - GeckoAppShell.computeRenderIntegrity();
PanningPerfAPI.recordCheckerboard(checkerboard);
if (checkerboard < 0.0f || checkerboard > 1.0f) {
Log.e(LOGTAG, "Checkerboard value out of bounds: " + checkerboard);
}
mCompleteFramesRendered += 1.0f - checkerboard;
mFramesRendered ++;
if (mFrameStartTime - mProfileOutputTime > NANOS_PER_SECOND) {
mProfileOutputTime = mFrameStartTime;
printCheckerboardStats();
}
}
runRenderTasks(mTasks, true, mFrameStartTime);
}

Просмотреть файл

@ -25,26 +25,17 @@ public class PanningPerfAPI {
private static List<Long> mFrameTimes;
private static long mFrameStartTime;
private static boolean mRecordingCheckerboard;
private static List<Float> mCheckerboardAmounts;
private static long mCheckerboardStartTime;
private static void initialiseRecordingArrays() {
if (mFrameTimes == null) {
mFrameTimes = new ArrayList<Long>(EXPECTED_FRAME_COUNT);
} else {
mFrameTimes.clear();
}
if (mCheckerboardAmounts == null) {
mCheckerboardAmounts = new ArrayList<Float>(EXPECTED_FRAME_COUNT);
} else {
mCheckerboardAmounts.clear();
}
}
@RobocopTarget
public static void startFrameTimeRecording() {
if (mRecordingFrames || mRecordingCheckerboard) {
if (mRecordingFrames) {
Log.e(LOGTAG, "Error: startFrameTimeRecording() called while already recording!");
return;
}
@ -70,58 +61,13 @@ public class PanningPerfAPI {
}
}
public static boolean isRecordingCheckerboard() {
return mRecordingCheckerboard;
}
@RobocopTarget
public static void startCheckerboardRecording() {
if (mRecordingCheckerboard || mRecordingFrames) {
Log.e(LOGTAG, "Error: startCheckerboardRecording() called while already recording!");
return;
}
mRecordingCheckerboard = true;
initialiseRecordingArrays();
mCheckerboardStartTime = SystemClock.uptimeMillis();
throw new UnsupportedOperationException();
}
@RobocopTarget
public static List<Float> stopCheckerboardRecording() {
if (!mRecordingCheckerboard) {
Log.e(LOGTAG, "Error: stopCheckerboardRecording() called when not recording!");
return null;
}
mRecordingCheckerboard = false;
// We take the number of values in mCheckerboardAmounts here, as there's
// the possibility that this function is called while recordCheckerboard
// is still executing. As values are added to this list last, we use
// this number as the canonical number of recordings.
int values = mCheckerboardAmounts.size();
if (values == 0) {
Log.w(LOGTAG, "stopCheckerboardRecording() found no checkerboard amounts!");
return mCheckerboardAmounts;
}
// The score will be the sum of all the values in mCheckerboardAmounts,
// so weight the checkerboard values by time so that frame-rate and
// run-length don't affect score.
long lastTime = 0;
float totalTime = mFrameTimes.get(values - 1);
for (int i = 0; i < values; i++) {
long elapsedTime = mFrameTimes.get(i) - lastTime;
mCheckerboardAmounts.set(i, mCheckerboardAmounts.get(i) * elapsedTime / totalTime);
lastTime += elapsedTime;
}
return mCheckerboardAmounts;
}
public static void recordCheckerboard(float amount) {
// this will be called often, so try to make it as quick as possible
if (mRecordingCheckerboard) {
mFrameTimes.add(SystemClock.uptimeMillis() - mCheckerboardStartTime);
mCheckerboardAmounts.add(amount);
}
throw new UnsupportedOperationException();
}
}

Просмотреть файл

@ -134,25 +134,6 @@ Java_org_mozilla_gecko_GeckoAppShell_invalidateAndScheduleComposite(JNIEnv * arg
#ifdef JNI_STUBS
typedef jfloat (*Java_org_mozilla_gecko_GeckoAppShell_computeRenderIntegrity_t)(JNIEnv *, jclass);
static Java_org_mozilla_gecko_GeckoAppShell_computeRenderIntegrity_t f_Java_org_mozilla_gecko_GeckoAppShell_computeRenderIntegrity;
extern "C" NS_EXPORT jfloat MOZ_JNICALL
Java_org_mozilla_gecko_GeckoAppShell_computeRenderIntegrity(JNIEnv * arg0, jclass arg1) {
if (!f_Java_org_mozilla_gecko_GeckoAppShell_computeRenderIntegrity) {
arg0->ThrowNew(arg0->FindClass("java/lang/UnsupportedOperationException"),
"JNI Function called before it was loaded");
return 0;
}
return f_Java_org_mozilla_gecko_GeckoAppShell_computeRenderIntegrity(arg0, arg1);
}
#endif
#ifdef JNI_BINDINGS
xul_dlsym("Java_org_mozilla_gecko_GeckoAppShell_computeRenderIntegrity", &f_Java_org_mozilla_gecko_GeckoAppShell_computeRenderIntegrity);
#endif
#ifdef JNI_STUBS
typedef void (*Java_org_mozilla_gecko_GeckoAppShell_addPresentationSurface_t)(JNIEnv *, jclass, jobject);
static Java_org_mozilla_gecko_GeckoAppShell_addPresentationSurface_t f_Java_org_mozilla_gecko_GeckoAppShell_addPresentationSurface;
extern "C" NS_EXPORT void MOZ_JNICALL

Просмотреть файл

@ -123,12 +123,6 @@ Java_org_mozilla_gecko_GeckoAppShell_invalidateAndScheduleComposite(JNIEnv*, jcl
nsWindow::InvalidateAndScheduleComposite();
}
NS_EXPORT float JNICALL
Java_org_mozilla_gecko_GeckoAppShell_computeRenderIntegrity(JNIEnv*, jclass)
{
return nsWindow::ComputeRenderIntegrity();
}
NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoAppShell_addPresentationSurface(JNIEnv* jenv, jclass, jobject surface)
{

Просмотреть файл

@ -3643,18 +3643,6 @@ nsWindow::ScheduleResumeComposition()
}
}
float
nsWindow::ComputeRenderIntegrity()
{
if (gGeckoViewWindow) {
if (RefPtr<CompositorBridgeParent> bridge = gGeckoViewWindow->GetCompositorBridgeParent()) {
return bridge->ComputeRenderIntegrity();
}
}
return 1.f;
}
bool
nsWindow::WidgetPaintsBackground()
{

Просмотреть файл

@ -179,7 +179,6 @@ public:
static void InvalidateAndScheduleComposite();
static void SchedulePauseComposition();
static void ScheduleResumeComposition();
static float ComputeRenderIntegrity();
virtual bool WidgetPaintsBackground() override;