author | David Anderson <danderson@mozilla.com> |
Wed, 15 Feb 2017 19:03:20 -0800 | |
changeset 343244 | 7a84bd5bc7dc2232fd9eeb8900e0e2e364310535 |
parent 343243 | 5c25a3cb838e345c77cf24fd27afa53fb756ee3a |
child 343245 | 10f164e44965a5ef528ab3ec38b8e98f51e23747 |
push id | 31372 |
push user | cbook@mozilla.com |
push date | Thu, 16 Feb 2017 12:16:10 +0000 |
treeherder | mozilla-central@2737f66ad6ac [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mattwoodrow |
bugs | 1339688 |
milestone | 54.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/Compositor.h +++ b/gfx/layers/Compositor.h @@ -539,37 +539,16 @@ public: ScreenRotation GetScreenRotation() const { return mScreenRotation; } void SetScreenRotation(ScreenRotation aRotation) { mScreenRotation = aRotation; } - TimeStamp GetCompositionTime() const { - return mCompositionTime; - } - void SetCompositionTime(TimeStamp aTimeStamp) { - mCompositionTime = aTimeStamp; - if (!mCompositionTime.IsNull() && !mCompositeUntilTime.IsNull() && - mCompositionTime >= mCompositeUntilTime) { - mCompositeUntilTime = TimeStamp(); - } - } - - virtual void CompositeUntil(TimeStamp aTimeStamp) { - if (mCompositeUntilTime.IsNull() || - mCompositeUntilTime < aTimeStamp) { - mCompositeUntilTime = aTimeStamp; - } - } - TimeStamp GetCompositeUntilTime() const { - return mCompositeUntilTime; - } - // A stale Compositor has no CompositorBridgeParent; it will not process // frames and should not be used. void SetInvalid(); virtual bool IsValid() const; CompositorBridgeParent* GetCompositorBridgeParent() const { return mParent; } @@ -649,27 +628,16 @@ protected: */ nsTArray<RefPtr<TextureHost>> mNotifyNotUsedAfterComposition; /** * Last Composition end time. */ TimeStamp mLastCompositionEndTime; - /** - * Render time for the current composition. - */ - TimeStamp mCompositionTime; - /** - * When nonnull, during rendering, some compositable indicated that it will - * change its rendering at this time. In order not to miss it, we composite - * on every vsync until this time occurs (this is the latest such time). - */ - TimeStamp mCompositeUntilTime; - uint32_t mCompositorID; DiagnosticTypes mDiagnosticTypes; CompositorBridgeParent* mParent; /** * We keep track of the total number of pixels filled as we composite the * current frame. This value is an approximation and is not accurate, * especially in the presence of transforms.
--- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -73,16 +73,17 @@ class DrawTarget; namespace layers { class Animation; class AnimationData; class AsyncCanvasRenderer; class AsyncPanZoomController; class BasicLayerManager; class ClientLayerManager; +class HostLayerManager; class Layer; class LayerMetricsWrapper; class PaintedLayer; class ContainerLayer; class ImageLayer; class ColorLayer; class CompositorBridgeChild; class TextLayer; @@ -209,16 +210,18 @@ public: virtual LayerManagerComposite* AsLayerManagerComposite() { return nullptr; } virtual ClientLayerManager* AsClientLayerManager() { return nullptr; } virtual BasicLayerManager* AsBasicLayerManager() { return nullptr; } + virtual HostLayerManager* AsHostLayerManager() + { return nullptr; } virtual WebRenderLayerManager* AsWebRenderLayerManager() { return nullptr; } /** * Returns true if this LayerManager is owned by an nsIWidget, * and is used for drawing into the widget. */
--- a/gfx/layers/composite/CompositableHost.cpp +++ b/gfx/layers/composite/CompositableHost.cpp @@ -156,10 +156,19 @@ CompositableHost::DumpTextureHost(std::s } RefPtr<gfx::DataSourceSurface> dSurf = aTexture->GetAsSurface(); if (!dSurf) { return; } aStream << gfxUtils::GetAsDataURI(dSurf).get(); } +HostLayerManager* +CompositableHost::GetLayerManager() const +{ + if (!mLayer || !mLayer->Manager()) { + return nullptr; + } + return mLayer->Manager()->AsHostLayerManager(); +} + } // namespace layers } // namespace mozilla
--- a/gfx/layers/composite/CompositableHost.h +++ b/gfx/layers/composite/CompositableHost.h @@ -232,16 +232,19 @@ public: /// Called when shutting down the layer tree. /// This is a good place to clear all potential gpu resources before the widget /// is is destroyed. virtual void CleanupResources() {} virtual void BindTextureSource() {} protected: + HostLayerManager* GetLayerManager() const; + +protected: TextureInfo mTextureInfo; AsyncCompositableRef mAsyncRef; uint64_t mCompositorID; RefPtr<Compositor> mCompositor; Layer* mLayer; uint32_t mFlashCounter; // used when the pref "layers.flash-borders" is true. bool mAttached; bool mKeepAttached;
--- a/gfx/layers/composite/ImageHost.cpp +++ b/gfx/layers/composite/ImageHost.cpp @@ -72,27 +72,29 @@ ImageHost::UseTextureHost(const nsTArray newImages.Clear(); // If we only have one image we can upload it right away, otherwise we'll upload // on-demand during composition after we have picked the proper timestamp. if (mImages.Length() == 1) { SetCurrentTextureHost(mImages[0].mTextureHost); } + HostLayerManager* lm = GetLayerManager(); + // Video producers generally send replacement images with the same frameID but // slightly different timestamps in order to sync with the audio clock. This // means that any CompositeUntil() call we made in Composite() may no longer // guarantee that we'll composite until the next frame is ready. Fix that here. - if (GetCompositor() && mLastFrameID >= 0) { + if (lm && mLastFrameID >= 0) { for (size_t i = 0; i < mImages.Length(); ++i) { bool frameComesAfter = mImages[i].mFrameID > mLastFrameID || mImages[i].mProducerID != mLastProducerID; if (frameComesAfter && !mImages[i].mTimeStamp.IsNull()) { - GetCompositor()->CompositeUntil(mImages[i].mTimeStamp + - TimeDuration::FromMilliseconds(BIAS_TIME_MS)); + lm->CompositeUntil(mImages[i].mTimeStamp + + TimeDuration::FromMilliseconds(BIAS_TIME_MS)); break; } } } } void ImageHost::SetCurrentTextureHost(TextureHost* aTexture) @@ -150,18 +152,18 @@ ImageHost::RemoveTextureHost(TextureHost } } } TimeStamp ImageHost::GetCompositionTime() const { TimeStamp time; - if (GetCompositor()) { - time = GetCompositor()->GetCompositionTime(); + if (HostLayerManager* lm = GetLayerManager()) { + time = lm->GetCompositionTime(); } return time; } TextureHost* ImageHost::GetAsTextureHost(IntRect* aPictureRect) { TimedImage* img = ChooseImage(); @@ -192,30 +194,28 @@ ImageHost::Composite(LayerComposite* aLa EffectChain& aEffectChain, float aOpacity, const gfx::Matrix4x4& aTransform, const gfx::SamplingFilter aSamplingFilter, const gfx::IntRect& aClipRect, const nsIntRegion* aVisibleRegion, const Maybe<gfx::Polygon>& aGeometry) { - if (!GetCompositor()) { - // should only happen when a tab is dragged to another window and - // async-video is still sending frames but we haven't attached the - // set the new compositor yet. + HostLayerManager* lm = GetLayerManager(); + if (!lm) { return; } int imageIndex = ChooseImageIndex(); if (imageIndex < 0) { return; } if (uint32_t(imageIndex) + 1 < mImages.Length()) { - GetCompositor()->CompositeUntil(mImages[imageIndex + 1].mTimeStamp + TimeDuration::FromMilliseconds(BIAS_TIME_MS)); + lm->CompositeUntil(mImages[imageIndex + 1].mTimeStamp + TimeDuration::FromMilliseconds(BIAS_TIME_MS)); } TimedImage* img = &mImages[imageIndex]; img->mTextureHost->SetCompositor(GetCompositor()); SetCurrentTextureHost(img->mTextureHost); { AutoLockCompositableHost autoLock(this); @@ -255,17 +255,17 @@ ImageHost::Composite(LayerComposite* aLa } if (mLastFrameID != img->mFrameID || mLastProducerID != img->mProducerID) { if (mAsyncRef) { ImageCompositeNotificationInfo info; info.mImageBridgeProcessId = mAsyncRef.mProcessId; info.mNotification = ImageCompositeNotification( mAsyncRef.mHandle, - img->mTimeStamp, GetCompositor()->GetCompositionTime(), + img->mTimeStamp, lm->GetCompositionTime(), img->mFrameID, img->mProducerID); static_cast<LayerManagerComposite*>(aLayer->GetLayerManager())-> AppendImageCompositeNotification(info); } mLastFrameID = img->mFrameID; mLastProducerID = img->mProducerID; } aEffectChain.mPrimaryEffect = effect; @@ -332,17 +332,17 @@ ImageHost::Composite(LayerComposite* aLa } // Update mBias last. This can change which frame ChooseImage(Index) would // return, and we don't want to do that until we've finished compositing // since callers of ChooseImage(Index) assume the same image will be chosen // during a given composition. This must happen after autoLock's // destructor! mBias = UpdateBias( - GetCompositor()->GetCompositionTime(), mImages[imageIndex].mTimeStamp, + lm->GetCompositionTime(), mImages[imageIndex].mTimeStamp, uint32_t(imageIndex + 1) < mImages.Length() ? mImages[imageIndex + 1].mTimeStamp : TimeStamp(), mBias); } void ImageHost::SetCompositor(Compositor* aCompositor) {
--- a/gfx/layers/composite/ImageHost.h +++ b/gfx/layers/composite/ImageHost.h @@ -26,16 +26,17 @@ #include "nsRegionFwd.h" // for nsIntRegion #include "nscore.h" // for nsACString namespace mozilla { namespace layers { class Compositor; struct EffectChain; +class HostLayerManager; /** * ImageHost. Works with ImageClientSingle and ImageClientBuffered */ class ImageHost : public CompositableHost, public ImageComposite { public:
--- a/gfx/layers/composite/LayerManagerComposite.cpp +++ b/gfx/layers/composite/LayerManagerComposite.cpp @@ -406,17 +406,17 @@ LayerManagerComposite::EndTransaction(co if (mDestroyed) { NS_WARNING("Call on destroyed layer manager"); return; } // Set composition timestamp here because we need it in // ComputeEffectiveTransforms (so the correct video frame size is picked) and // also to compute invalid regions properly. - mCompositor->SetCompositionTime(aTimeStamp); + SetCompositionTime(aTimeStamp); if (mRoot && !(aFlags & END_NO_IMMEDIATE_REDRAW)) { MOZ_ASSERT(!aTimeStamp.IsNull()); UpdateAndRender(); mCompositor->FlushPendingNotifyNotUsed(); } else { // Modified the layer tree. mGeometryChanged = true;
--- a/gfx/layers/composite/LayerManagerComposite.h +++ b/gfx/layers/composite/LayerManagerComposite.h @@ -121,16 +121,20 @@ public: virtual void UpdateRenderBounds(const gfx::IntRect& aRect) {} // Called by CompositorBridgeParent when a new compositor has been created due // to a device reset. The layer manager must clear any cached resources // attached to the old compositor, and make a best effort at ignoring // layer or texture updates against the old compositor. virtual void ChangeCompositor(Compositor* aNewCompositor) = 0; + virtual HostLayerManager* AsHostLayerManager() override { + return this; + } + void ExtractImageCompositeNotifications(nsTArray<ImageCompositeNotificationInfo>* aNotifications) { aNotifications->AppendElements(Move(mImageCompositeNotifications)); } /** * LayerManagerComposite provides sophisticated debug overlays * that can request a next frame. @@ -153,30 +157,57 @@ public: } } // Indicate that we need to composite even if nothing in our layers has // changed, so that the widget can draw something different in its window // overlay. void SetWindowOverlayChanged() { mWindowOverlayChanged = true; } + void SetPaintTime(const TimeDuration& aPaintTime) { mLastPaintTime = aPaintTime; } - void SetPaintTime(const TimeDuration& aPaintTime) { mLastPaintTime = aPaintTime; } + TimeStamp GetCompositionTime() const { + return mCompositionTime; + } + void SetCompositionTime(TimeStamp aTimeStamp) { + mCompositionTime = aTimeStamp; + if (!mCompositionTime.IsNull() && !mCompositeUntilTime.IsNull() && + mCompositionTime >= mCompositeUntilTime) { + mCompositeUntilTime = TimeStamp(); + } + } + void CompositeUntil(TimeStamp aTimeStamp) { + if (mCompositeUntilTime.IsNull() || + mCompositeUntilTime < aTimeStamp) { + mCompositeUntilTime = aTimeStamp; + } + } + TimeStamp GetCompositeUntilTime() const { + return mCompositeUntilTime; + } protected: bool mDebugOverlayWantsNextFrame; nsTArray<ImageCompositeNotificationInfo> mImageCompositeNotifications; // Testing property. If hardware composer is supported, this will return // true if the last frame was deemed 'too complicated' to be rendered. float mWarningLevel; mozilla::TimeStamp mWarnTime; bool mWindowOverlayChanged; TimeDuration mLastPaintTime; TimeStamp mRenderStartTime; + + // Render time for the current composition. + TimeStamp mCompositionTime; + + // When nonnull, during rendering, some compositable indicated that it will + // change its rendering at this time. In order not to miss it, we composite + // on every vsync until this time occurs (this is the latest such time). + TimeStamp mCompositeUntilTime; }; // A layer manager implementation that uses the Compositor API // to render layers. class LayerManagerComposite final : public HostLayerManager { typedef mozilla::gfx::DrawTarget DrawTarget; typedef mozilla::gfx::IntSize IntSize;
--- a/gfx/layers/composite/TiledContentHost.cpp +++ b/gfx/layers/composite/TiledContentHost.cpp @@ -134,22 +134,27 @@ TiledContentHost::Detach(Layer* aLayer, } CompositableHost::Detach(aLayer,aFlags); } bool TiledContentHost::UseTiledLayerBuffer(ISurfaceAllocator* aAllocator, const SurfaceDescriptorTiles& aTiledDescriptor) { + HostLayerManager* lm = GetLayerManager(); + if (!lm) { + return false; + } + if (aTiledDescriptor.resolution() < 1) { - if (!mLowPrecisionTiledBuffer.UseTiles(aTiledDescriptor, mCompositor, aAllocator)) { + if (!mLowPrecisionTiledBuffer.UseTiles(aTiledDescriptor, lm, aAllocator)) { return false; } } else { - if (!mTiledBuffer.UseTiles(aTiledDescriptor, mCompositor, aAllocator)) { + if (!mTiledBuffer.UseTiles(aTiledDescriptor, lm, aAllocator)) { return false; } } return true; } void UseTileTexture(CompositableTextureHostRef& aTexture, @@ -240,26 +245,26 @@ public: protected: nsTArray<TileHost> mTiles; size_t mFirstPossibility; }; bool TiledLayerBufferComposite::UseTiles(const SurfaceDescriptorTiles& aTiles, - Compositor* aCompositor, + HostLayerManager* aLayerManager, ISurfaceAllocator* aAllocator) { if (mResolution != aTiles.resolution() || aTiles.tileSize() != mTileSize) { Clear(); } MOZ_ASSERT(aAllocator); - MOZ_ASSERT(aCompositor); - if (!aAllocator || !aCompositor) { + MOZ_ASSERT(aLayerManager); + if (!aAllocator || !aLayerManager) { return false; } if (aTiles.resolution() == 0 || IsNaN(aTiles.resolution())) { // There are divisions by mResolution so this protects the compositor process // against malicious content processes and fuzzing. return false; } @@ -289,17 +294,17 @@ TiledLayerBufferComposite::UseTiles(cons tileDesc.type() == TileDescriptor::TPlaceholderTileDescriptor, "Unrecognised tile descriptor type"); continue; } const TexturedTileDescriptor& texturedDesc = tileDesc.get_TexturedTileDescriptor(); tile.mTextureHost = TextureHost::AsTextureHost(texturedDesc.textureParent()); - tile.mTextureHost->SetCompositor(aCompositor); + tile.mTextureHost->SetCompositor(aLayerManager->GetCompositor()); tile.mTextureHost->DeserializeReadLock(texturedDesc.sharedLock(), aAllocator); if (texturedDesc.textureOnWhite().type() == MaybeTexture::TPTextureParent) { tile.mTextureHostOnWhite = TextureHost::AsTextureHost( texturedDesc.textureOnWhite().get_PTextureParent() ); tile.mTextureHostOnWhite->DeserializeReadLock( texturedDesc.sharedLockOnWhite(), aAllocator @@ -317,18 +322,18 @@ TiledLayerBufferComposite::UseTiles(cons if (aTiles.isProgressive() && texturedDesc.wasPlaceholder()) { // This is a progressive paint, and the tile used to be a placeholder. // We need to begin fading it in (if enabled via layers.tiles.fade-in.enabled) tile.mFadeStart = TimeStamp::Now(); - aCompositor->CompositeUntil(tile.mFadeStart + - TimeDuration::FromMilliseconds(gfxPrefs::LayerTileFadeInDuration())); + aLayerManager->CompositeUntil( + tile.mFadeStart + TimeDuration::FromMilliseconds(gfxPrefs::LayerTileFadeInDuration())); } } // Step 2, attempt to recycle unused texture sources from the old tile set into new tiles. // // For gralloc, binding a new TextureHost to the existing TextureSource is the fastest way // to ensure that any implicit locking on the old gralloc image is released. for (TileHost& tile : mRetainedTiles) { @@ -347,23 +352,23 @@ TiledLayerBufferComposite::UseTiles(cons } const TileDescriptor& tileDesc = tileDescriptors[i]; const TexturedTileDescriptor& texturedDesc = tileDesc.get_TexturedTileDescriptor(); UseTileTexture(tile.mTextureHost, tile.mTextureSource, texturedDesc.updateRect(), - aCompositor); + aLayerManager->GetCompositor()); if (tile.mTextureHostOnWhite) { UseTileTexture(tile.mTextureHostOnWhite, tile.mTextureSourceOnWhite, texturedDesc.updateRect(), - aCompositor); + aLayerManager->GetCompositor()); } } mTiles = newTiles; mTileSize = aTiles.tileSize(); mTileOrigin = aTiles.tileOrigin(); mValidRegion = aTiles.validRegion(); mResolution = aTiles.resolution();
--- a/gfx/layers/composite/TiledContentHost.h +++ b/gfx/layers/composite/TiledContentHost.h @@ -120,17 +120,17 @@ class TiledLayerBufferComposite { friend class TiledLayerBuffer<TiledLayerBufferComposite, TileHost>; public: TiledLayerBufferComposite(); ~TiledLayerBufferComposite(); bool UseTiles(const SurfaceDescriptorTiles& aTileDescriptors, - Compositor* aCompositor, + HostLayerManager* aLayerManager, ISurfaceAllocator* aAllocator); void Clear(); TileHost GetPlaceholderTile() const { return TileHost(); } // Stores the absolute resolution of the containing frame, calculated // by the sum of the resolutions of all parent layers' FrameMetrics.
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp +++ b/gfx/layers/ipc/CompositorBridgeParent.cpp @@ -1002,28 +1002,27 @@ CompositorBridgeParent::CompositeToTarge mLayerManager->SetDebugOverlayWantsNextFrame(false); mLayerManager->EndTransaction(time); if (!aTarget) { TimeStamp end = TimeStamp::Now(); DidComposite(start, end); } - if (mCompositor) { - // We're not really taking advantage of the stored composite-again-time here. - // We might be able to skip the next few composites altogether. However, - // that's a bit complex to implement and we'll get most of the advantage - // by skipping compositing when we detect there's nothing invalid. This is why - // we do "composite until" rather than "composite again at". - if (!mCompositor->GetCompositeUntilTime().IsNull() || - mLayerManager->DebugOverlayWantsNextFrame()) { + // We're not really taking advantage of the stored composite-again-time here. + // We might be able to skip the next few composites altogether. However, + // that's a bit complex to implement and we'll get most of the advantage + // by skipping compositing when we detect there's nothing invalid. This is why + // we do "composite until" rather than "composite again at". + // + // TODO(bug 1328602) Figure out what we should do here with the render thread. + if (!mLayerManager->GetCompositeUntilTime().IsNull() || + mLayerManager->DebugOverlayWantsNextFrame()) + { ScheduleComposition(); - } - } else { - // TODO(bug 1328602) Figure out what we should do here with the render thread. } #ifdef COMPOSITOR_PERFORMANCE_WARNING TimeDuration executionTime = TimeStamp::Now() - mCompositorScheduler->GetLastComposeTime(); TimeDuration frameBudget = TimeDuration::FromMilliseconds(15); int32_t frameRate = CalculateCompositionFrameRate(); if (frameRate > 0) { frameBudget = TimeDuration::FromSeconds(1.0 / frameRate); @@ -1036,21 +1035,18 @@ CompositorBridgeParent::CompositeToTarge // 0 -> Full-tilt composite if (gfxPrefs::LayersCompositionFrameRate() == 0 || mLayerManager->GetCompositor()->GetDiagnosticTypes() & DiagnosticTypes::FLASH_BORDERS) { // Special full-tilt composite mode for performance testing ScheduleComposition(); } - if (mCompositor) { - mCompositor->SetCompositionTime(TimeStamp()); - } else { - // TODO(bug 1328602) Need an equivalent that works with the rende thread. - } + // TODO(bug 1328602) Need an equivalent that works with the rende thread. + mLayerManager->SetCompositionTime(TimeStamp()); mozilla::Telemetry::AccumulateTimeDelta(mozilla::Telemetry::COMPOSITE_TIME, start); } mozilla::ipc::IPCResult CompositorBridgeParent::RecvRemotePluginsReady() { #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
--- a/gfx/layers/wr/WebRenderCompositorOGL.cpp +++ b/gfx/layers/wr/WebRenderCompositorOGL.cpp @@ -101,28 +101,16 @@ WebRenderCompositorOGL::MakeCurrent(Make if (mDestroyed) { NS_WARNING("Call on destroyed layer manager"); return; } mGLContext->MakeCurrent(aFlags & ForceMakeCurrent); } void -WebRenderCompositorOGL::CompositeUntil(TimeStamp aTimeStamp) -{ - Compositor::CompositeUntil(aTimeStamp); - // We're not really taking advantage of the stored composite-again-time here. - // We might be able to skip the next few composites altogether. However, - // that's a bit complex to implement and we'll get most of the advantage - // by skipping compositing when we detect there's nothing invalid. This is why - // we do "composite until" rather than "composite again at". - ScheduleComposition(); -} - -void WebRenderCompositorOGL::AddExternalImageId(uint64_t aExternalImageId, CompositableHost* aHost) { MOZ_ASSERT(!mCompositableHosts.Get(aExternalImageId)); mCompositableHosts.Put(aExternalImageId, aHost); } void WebRenderCompositorOGL::RemoveExternalImageId(uint64_t aExternalImageId)
--- a/gfx/layers/wr/WebRenderCompositorOGL.h +++ b/gfx/layers/wr/WebRenderCompositorOGL.h @@ -107,18 +107,16 @@ public: #endif // MOZ_DUMP_PAINTING virtual LayersBackend GetBackendType() const override { return LayersBackend::LAYERS_WR; } virtual bool IsValid() const override { return true; } - virtual void CompositeUntil(TimeStamp aTimeStamp) override; - GLContext* gl() const { return mGLContext; } void AddExternalImageId(uint64_t aExternalImageId, CompositableHost* aHost); void RemoveExternalImageId(uint64_t aExternalImageId); void UpdateExternalImages(); void ScheduleComposition(); private: