author | Chris Lord <chrislord.net@gmail.com> |
Fri, 30 Nov 2012 23:11:37 +0000 | |
changeset 114663 | 1b666ab33a92eb35381d99b6b7303b18062eb816 |
parent 114662 | cd51ab1d33f59cd8a2961291c62a200c25dcf3fe |
child 114664 | e418cb281a3a72a7f233d93270620c28fa1b6525 |
push id | 23926 |
push user | ryanvm@gmail.com |
push date | Sat, 01 Dec 2012 15:27:30 +0000 |
treeherder | mozilla-central@ecdf0e332f17 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bgirard |
bugs | 814437 |
milestone | 20.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -1143,17 +1143,16 @@ public: * performance. */ void SetAllowResidualTranslation(bool aAllow) { mAllowResidualTranslation = aAllow; } /** * Can be used anytime */ const nsIntRegion& GetValidRegion() const { return mValidRegion; } - virtual const nsIntRegion& GetValidLowPrecisionRegion() const { return mValidRegion; } virtual ThebesLayer* AsThebesLayer() { return this; } MOZ_LAYER_DECL_NAME("ThebesLayer", TYPE_THEBES) virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface) { // The default implementation just snaps 0,0 to pixels.
--- a/gfx/layers/TiledLayerBuffer.h +++ b/gfx/layers/TiledLayerBuffer.h @@ -186,16 +186,22 @@ public: * Update the current retained layer with the updated layer data. * The BasicTiledLayerBuffer is expected to be in the ReadLock state * prior to this being called. aTiledBuffer is copy constructed and * is retained until it has been uploaded/copyed and unlocked. */ virtual void PaintedTiledLayerBuffer(const BasicTiledLayerBuffer* aTiledBuffer) = 0; virtual void MemoryPressure() = 0; + + /** + * If some part of the buffer is being rendered at a lower precision, this + * returns that region. If it is not, an empty region will be returned. + */ + virtual const nsIntRegion& GetValidLowPrecisionRegion() const = 0; }; // Normal integer division truncates towards zero, // we instead want to floor to hangle negative numbers. static inline int floor_div(int a, int b) { int rem = a % b; int div = a/b;
--- a/gfx/layers/opengl/LayerManagerOGL.cpp +++ b/gfx/layers/opengl/LayerManagerOGL.cpp @@ -1679,18 +1679,31 @@ LayerManagerOGL::ComputeRenderIntegrityI if (!incompleteRegion.IsEmpty()) { // Calculate the transform to get between screen and layer space gfx3DMatrix transformToScreen = aLayer->GetEffectiveTransform(); transformToScreen.PreMultiply(aTransform); SubtractTransformedRegion(aScreenRegion, incompleteRegion, transformToScreen); // See if there's any incomplete low-precision rendering - incompleteRegion.Sub(incompleteRegion, thebesLayer->GetValidLowPrecisionRegion()); - if (!incompleteRegion.IsEmpty()) { + TiledLayerComposer* composer = nullptr; + ShadowLayer* shadow = aLayer->AsShadowLayer(); + if (shadow) { + composer = shadow->AsTiledLayerComposer(); + 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); } } } static int GetRegionArea(const nsIntRegion& aRegion) { @@ -1743,47 +1756,68 @@ LayerManagerOGL::ComputeRenderIntegrity( 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(); + // Clip the screen rect to the document bounds + gfxRect documentBounds = + transform.TransformBounds(gfxRect(metrics.mScrollableRect.x - metrics.mScrollOffset.x, + metrics.mScrollableRect.y - metrics.mScrollOffset.y, + metrics.mScrollableRect.width, + metrics.mScrollableRect.height)); + documentBounds.RoundOut(); + screenRect = screenRect.Intersect(nsIntRect(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.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 = + lowPrecisionMultiplier = highPrecisionMultiplier = GetDisplayportCoverage(metrics.mDisplayPort, 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_ANDROID_OMTC nsIntRegion screenRegion(screenRect); nsIntRegion lowPrecisionScreenRegion(screenRect); gfx3DMatrix transform; ComputeRenderIntegrityInternal(root, screenRegion, lowPrecisionScreenRegion, transform); @@ -1793,16 +1827,16 @@ LayerManagerOGL::ComputeRenderIntegrity( float screenArea = screenRect.width * screenRect.height; float highPrecisionIntegrity = GetRegionArea(screenRegion) / screenArea; float lowPrecisionIntegrity = 1.f; if (!lowPrecisionScreenRegion.IsEqual(screenRect)) { lowPrecisionIntegrity = GetRegionArea(lowPrecisionScreenRegion) / screenArea; } return ((highPrecisionIntegrity * highPrecisionMultiplier) + - (lowPrecisionIntegrity * lowPrecisionMultiplier)) / 2.f; + (lowPrecisionIntegrity * lowPrecisionMultiplier)) / 2; } return 1.f; } } /* layers */ } /* mozilla */
--- a/gfx/layers/opengl/TiledThebesLayerOGL.h +++ b/gfx/layers/opengl/TiledThebesLayerOGL.h @@ -108,19 +108,16 @@ private: class TiledThebesLayerOGL : public ShadowThebesLayer, public LayerOGL, public TiledLayerComposer { public: TiledThebesLayerOGL(LayerManagerOGL *aManager); virtual ~TiledThebesLayerOGL(); - // Layer implementation - const nsIntRegion& GetValidLowPrecisionRegion() const { return mLowPrecisionVideoMemoryTiledBuffer.GetValidRegion(); } - // LayerOGL impl void Destroy() {} Layer* GetLayer() { return this; } virtual void RenderLayer(int aPreviousFrameBuffer, const nsIntPoint& aOffset); virtual void CleanupResources() { } // Shadow @@ -130,16 +127,17 @@ public: OptionalThebesBuffer* aNewBack, nsIntRegion* aNewBackValidRegion, OptionalThebesBuffer* aReadOnlyFront, nsIntRegion* aFrontUpdatedRegion) { NS_ABORT_IF_FALSE(false, "Not supported"); } void PaintedTiledLayerBuffer(const BasicTiledLayerBuffer* mTiledBuffer); void ProcessUploadQueue(); void ProcessLowPrecisionUploadQueue(); + const nsIntRegion& GetValidLowPrecisionRegion() const { return mLowPrecisionVideoMemoryTiledBuffer.GetValidRegion(); } void MemoryPressure(); // Renders a single given tile. void RenderTile(const TiledTexture& aTile, const gfx3DMatrix& aTransform, const nsIntPoint& aOffset, const nsIntRegion& aScreenRegion,
--- a/mobile/android/base/gfx/PanningPerfAPI.java +++ b/mobile/android/base/gfx/PanningPerfAPI.java @@ -92,19 +92,19 @@ public class PanningPerfAPI { mRecordingCheckerboard = false; // 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(mFrameTimes.size() - 1); for (int i = 0; i < mCheckerboardAmounts.size(); i++) { - long elapsedTime = mFrameTimes.get(i) - lastTime; - mCheckerboardAmounts.set(i, mCheckerboardAmounts.get(i) * elapsedTime / totalTime); - lastTime = mFrameTimes.get(i); + long elapsedTime = mFrameTimes.get(i) - lastTime; + mCheckerboardAmounts.set(i, mCheckerboardAmounts.get(i) * elapsedTime / totalTime); + lastTime = mFrameTimes.get(i); } return mCheckerboardAmounts; } public static void recordCheckerboard(float amount) { // this will be called often, so try to make it as quick as possible if (mRecordingCheckerboard) {