From 6962e151a23f0935151ebe2db92a8b407e1e851c Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Wed, 3 Aug 2016 11:59:08 -0400 Subject: [PATCH] Bug 1273356 - Remove the unused and incorrect ComputeRenderIntegrity codepath for computing checkerboard. r=rbarker MozReview-Commit-ID: 4i1rmeqrkZ1 --- .../composite/LayerManagerComposite.cpp | 215 ------------------ gfx/layers/composite/LayerManagerComposite.h | 20 -- gfx/layers/ipc/CompositorBridgeParent.cpp | 10 - gfx/layers/ipc/CompositorBridgeParent.h | 2 - .../java/org/mozilla/gecko/GeckoAppShell.java | 2 - .../mozilla/gecko/gfx/GeckoLayerClient.java | 1 - .../org/mozilla/gecko/gfx/LayerRenderer.java | 39 ---- .../org/mozilla/gecko/gfx/PanningPerfAPI.java | 60 +---- mozglue/android/jni-stubs.inc | 19 -- widget/android/AndroidJNI.cpp | 6 - widget/android/nsWindow.cpp | 12 - widget/android/nsWindow.h | 1 - 12 files changed, 3 insertions(+), 384 deletions(-) diff --git a/gfx/layers/composite/LayerManagerComposite.cpp b/gfx/layers/composite/LayerManagerComposite.cpp index a1d1527ef368..7f620b23907e 100644 --- a/gfx/layers/composite/LayerManagerComposite.cpp +++ b/gfx/layers/composite/LayerManagerComposite.cpp @@ -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( - 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 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 LayerManagerComposite::CreatePaintedLayerComposite() { diff --git a/gfx/layers/composite/LayerManagerComposite.h b/gfx/layers/composite/LayerManagerComposite.h index 7e68e398fa40..fbc9492246ab 100644 --- a/gfx/layers/composite/LayerManagerComposite.h +++ b/gfx/layers/composite/LayerManagerComposite.h @@ -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. */ diff --git a/gfx/layers/ipc/CompositorBridgeParent.cpp b/gfx/layers/ipc/CompositorBridgeParent.cpp index 55b25e95fa38..474fa9747f6a 100644 --- a/gfx/layers/ipc/CompositorBridgeParent.cpp +++ b/gfx/layers/ipc/CompositorBridgeParent.cpp @@ -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) { diff --git a/gfx/layers/ipc/CompositorBridgeParent.h b/gfx/layers/ipc/CompositorBridgeParent.h index 8e0fd32dc3bc..3e03a5d4adce 100644 --- a/gfx/layers/ipc/CompositorBridgeParent.h +++ b/gfx/layers/ipc/CompositorBridgeParent.h @@ -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); diff --git a/mobile/android/base/java/org/mozilla/gecko/GeckoAppShell.java b/mobile/android/base/java/org/mozilla/gecko/GeckoAppShell.java index 2d9a2683ff31..447bc19b0a49 100644 --- a/mobile/android/base/java/org/mozilla/gecko/GeckoAppShell.java +++ b/mobile/android/base/java/org/mozilla/gecko/GeckoAppShell.java @@ -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); diff --git a/mobile/android/base/java/org/mozilla/gecko/gfx/GeckoLayerClient.java b/mobile/android/base/java/org/mozilla/gecko/gfx/GeckoLayerClient.java index 876d489131db..06075492f1d7 100644 --- a/mobile/android/base/java/org/mozilla/gecko/gfx/GeckoLayerClient.java +++ b/mobile/android/base/java/org/mozilla/gecko/gfx/GeckoLayerClient.java @@ -936,7 +936,6 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget if (mLayerRenderer == null) { return null; } - mLayerRenderer.checkMonitoringEnabled(); mLayerRenderer.createDefaultProgram(); mLayerRendererInitialized = true; } diff --git a/mobile/android/base/java/org/mozilla/gecko/gfx/LayerRenderer.java b/mobile/android/base/java/org/mozilla/gecko/gfx/LayerRenderer.java index 14db65ce5853..77dc2ec781da 100644 --- a/mobile/android/base/java/org/mozilla/gecko/gfx/LayerRenderer.java +++ b/mobile/android/base/java/org/mozilla/gecko/gfx/LayerRenderer.java @@ -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); } diff --git a/mobile/android/base/java/org/mozilla/gecko/gfx/PanningPerfAPI.java b/mobile/android/base/java/org/mozilla/gecko/gfx/PanningPerfAPI.java index 4507e30dbf22..42eb2b88b8d3 100644 --- a/mobile/android/base/java/org/mozilla/gecko/gfx/PanningPerfAPI.java +++ b/mobile/android/base/java/org/mozilla/gecko/gfx/PanningPerfAPI.java @@ -25,26 +25,17 @@ public class PanningPerfAPI { private static List mFrameTimes; private static long mFrameStartTime; - private static boolean mRecordingCheckerboard; - private static List mCheckerboardAmounts; - private static long mCheckerboardStartTime; - private static void initialiseRecordingArrays() { if (mFrameTimes == null) { mFrameTimes = new ArrayList(EXPECTED_FRAME_COUNT); } else { mFrameTimes.clear(); } - if (mCheckerboardAmounts == null) { - mCheckerboardAmounts = new ArrayList(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 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(); } } diff --git a/mozglue/android/jni-stubs.inc b/mozglue/android/jni-stubs.inc index 2a93194b1f55..3c9359207379 100644 --- a/mozglue/android/jni-stubs.inc +++ b/mozglue/android/jni-stubs.inc @@ -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 diff --git a/widget/android/AndroidJNI.cpp b/widget/android/AndroidJNI.cpp index 119a8e5cff65..c401dc25a9ae 100644 --- a/widget/android/AndroidJNI.cpp +++ b/widget/android/AndroidJNI.cpp @@ -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) { diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp index ef0987b8aebd..3a9a224ceadd 100644 --- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -3643,18 +3643,6 @@ nsWindow::ScheduleResumeComposition() } } -float -nsWindow::ComputeRenderIntegrity() -{ - if (gGeckoViewWindow) { - if (RefPtr bridge = gGeckoViewWindow->GetCompositorBridgeParent()) { - return bridge->ComputeRenderIntegrity(); - } - } - - return 1.f; -} - bool nsWindow::WidgetPaintsBackground() { diff --git a/widget/android/nsWindow.h b/widget/android/nsWindow.h index c986c3beae98..3c468438feaf 100644 --- a/widget/android/nsWindow.h +++ b/widget/android/nsWindow.h @@ -179,7 +179,6 @@ public: static void InvalidateAndScheduleComposite(); static void SchedulePauseComposition(); static void ScheduleResumeComposition(); - static float ComputeRenderIntegrity(); virtual bool WidgetPaintsBackground() override;