☠☠ backed out by 425f0a769c49 ☠ ☠ | |
author | Robert Mader <robert.mader@posteo.de> |
Tue, 13 Jul 2021 00:55:30 +0000 | |
changeset 585362 | 59cdbaaa6a7ba6fbd4ff90f00d4b9c8eeb2a1111 |
parent 585361 | 489ce763c140fe2dae8050c0cde0bc3c381bb95f |
child 585363 | 64ece870cdbf0a7d9e64990b424e79b4e37a4465 |
push id | 146176 |
push user | robert.mader@posteo.de |
push date | Tue, 13 Jul 2021 00:58:04 +0000 |
treeherder | autoland@59cdbaaa6a7b [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | gfx-reviewers, aosmond |
bugs | 1718570 |
milestone | 92.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/NativeLayerWayland.cpp +++ b/gfx/layers/NativeLayerWayland.cpp @@ -343,17 +343,17 @@ void NativeLayerRootWayland::RequestFram } } bool NativeLayerRootWayland::CommitToScreen() { MutexAutoLock lock(mMutex); wl_surface* wlSurface = moz_container_wayland_surface_lock(mContainer); for (RefPtr<NativeLayerWayland>& layer : mSublayers) { - layer->mNativeSurface->Commit(layer->mDirtyRegion); + layer->mNativeSurface->Commit(layer->mDirtyRegion, layer->mValidRect); layer->mDirtyRegion.SetEmpty(); } if (wlSurface) { wl_surface_commit(wlSurface); moz_container_wayland_surface_unlock(mContainer, &wlSurface); }
--- a/gfx/layers/SurfacePoolWayland.cpp +++ b/gfx/layers/SurfacePoolWayland.cpp @@ -1,15 +1,18 @@ /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nullptr; c-basic-offset: 2 * -*- This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/layers/SurfacePoolWayland.h" +#include "GLBlitHelper.h" +#include "mozilla/gfx/DataSurfaceHelpers.h" + namespace mozilla::layers { using gfx::IntRect; using gl::DepthAndStencilBuffer; using gl::MozFramebuffer; #define BACK_BUFFER_NUM 3 @@ -203,40 +206,71 @@ NativeSurfaceWaylandSHM::NativeSurfaceWa RefPtr<DrawTarget> NativeSurfaceWaylandSHM::GetNextDrawTarget() { MutexAutoLock lock(mMutex); if (!mCurrentBuffer) { mCurrentBuffer = ObtainBufferFromPool(lock); } return mCurrentBuffer->Lock(); } -void NativeSurfaceWaylandSHM::Commit(const IntRegion& aInvalidRegion) { +void NativeSurfaceWaylandSHM::Commit(const IntRegion& aInvalidRegion, + const IntRect& aValidRect) { MutexAutoLock lock(mMutex); if (aInvalidRegion.IsEmpty()) { if (mCurrentBuffer) { ReturnBufferToPool(lock, mCurrentBuffer); mCurrentBuffer = nullptr; } wl_surface_commit(mWlSurface); return; } + HandlePartialUpdate(lock, aInvalidRegion, aValidRect); + for (auto iter = aInvalidRegion.RectIter(); !iter.Done(); iter.Next()) { IntRect r = iter.Get(); wl_surface_damage_buffer(mWlSurface, r.x, r.y, r.width, r.height); } MOZ_ASSERT(mCurrentBuffer); mCurrentBuffer->AttachAndCommit(mWlSurface); mCurrentBuffer = nullptr; EnforcePoolSizeLimit(lock); } +void NativeSurfaceWaylandSHM::HandlePartialUpdate( + const MutexAutoLock& aProofOfLock, const IntRegion& aInvalidRegion, + const IntRect& aValidRect) { + if (!mPreviousBuffer || mPreviousBuffer == mCurrentBuffer) { + mPreviousBuffer = mCurrentBuffer; + return; + } + + IntRegion copyRegion = IntRegion(aValidRect); + copyRegion.SubOut(aInvalidRegion); + + if (!copyRegion.IsEmpty()) { + RefPtr<gfx::DataSourceSurface> dataSourceSurface = + gfx::CreateDataSourceSurfaceFromData( + mSize, mPreviousBuffer->GetSurfaceFormat(), + (const uint8_t*)mPreviousBuffer->GetShmPool()->GetImageData(), + mSize.width * BytesPerPixel(mPreviousBuffer->GetSurfaceFormat())); + RefPtr<DrawTarget> dt = mCurrentBuffer->Lock(); + + for (auto iter = copyRegion.RectIter(); !iter.Done(); iter.Next()) { + IntRect r = iter.Get(); + dt->CopySurface(dataSourceSurface, r, IntPoint(r.x, r.y)); + } + } + + mPreviousBuffer = mCurrentBuffer; +} + RefPtr<WaylandShmBuffer> NativeSurfaceWaylandSHM::ObtainBufferFromPool( const MutexAutoLock& aProofOfLock) { if (!mAvailableBuffers.IsEmpty()) { RefPtr<WaylandShmBuffer> buffer = mAvailableBuffers.PopLastElement(); mInUseBuffers.AppendElement(buffer); return buffer; } @@ -326,46 +360,78 @@ Maybe<GLuint> NativeSurfaceWaylandDMABUF if (!mCurrentBuffer) { mCurrentBuffer = ObtainBufferFromPool(lock); } return Some(mCurrentBuffer->GetFramebuffer()->mFB); } -void NativeSurfaceWaylandDMABUF::Commit(const IntRegion& aInvalidRegion) { +void NativeSurfaceWaylandDMABUF::Commit(const IntRegion& aInvalidRegion, + const IntRect& aValidRect) { MutexAutoLock lock(mMutex); if (aInvalidRegion.IsEmpty()) { if (mCurrentBuffer) { ReturnBufferToPool(lock, mCurrentBuffer); mCurrentBuffer = nullptr; } wl_surface_commit(mWlSurface); return; } + HandlePartialUpdate(lock, aInvalidRegion, aValidRect); + + // We rely on implicit synchronization in the system compositor to make sure + // all GL operation have been finished befor presenting a new frame. + mGL->fFlush(); + for (auto iter = aInvalidRegion.RectIter(); !iter.Done(); iter.Next()) { IntRect r = iter.Get(); wl_surface_damage_buffer(mWlSurface, r.x, r.y, r.width, r.height); } MOZ_ASSERT(mCurrentBuffer); wl_surface_attach(mWlSurface, mCurrentBuffer->GetWlBuffer(), 0, 0); wl_surface_commit(mWlSurface); mCurrentBuffer = nullptr; EnforcePoolSizeLimit(lock); } +void NativeSurfaceWaylandDMABUF::HandlePartialUpdate( + const MutexAutoLock& aProofOfLock, const IntRegion& aInvalidRegion, + const IntRect& aValidRect) { + if (!mPreviousBuffer || mPreviousBuffer == mCurrentBuffer) { + mPreviousBuffer = mCurrentBuffer; + return; + } + + IntRegion copyRegion = IntRegion(aValidRect); + copyRegion.SubOut(aInvalidRegion); + + if (!copyRegion.IsEmpty()) { + mGL->MakeCurrent(); + for (auto iter = copyRegion.RectIter(); !iter.Done(); iter.Next()) { + gfx::IntRect r = iter.Get(); + mGL->BlitHelper()->BlitFramebufferToFramebuffer( + mPreviousBuffer->GetFramebuffer()->mFB, + mCurrentBuffer->GetFramebuffer()->mFB, r, r, LOCAL_GL_NEAREST); + } + } + + mPreviousBuffer = mCurrentBuffer; +} + void NativeSurfaceWaylandDMABUF::DestroyGLResources() { mInUseBuffers.Clear(); mAvailableBuffers.Clear(); mDepthBuffers.Clear(); mCurrentBuffer = nullptr; + mPreviousBuffer = nullptr; mGL = nullptr; } static const struct wl_buffer_listener sBufferListenerNativeSurfaceWaylandDMABUF = { NativeSurfaceWaylandDMABUF::BufferReleaseCallbackHandler}; RefPtr<WaylandDMABUFBuffer> NativeSurfaceWaylandDMABUF::ObtainBufferFromPool(
--- a/gfx/layers/SurfacePoolWayland.h +++ b/gfx/layers/SurfacePoolWayland.h @@ -14,16 +14,17 @@ #include "mozilla/widget/DMABufSurface.h" #include "mozilla/widget/nsWaylandDisplay.h" #include "mozilla/widget/WaylandShmBuffer.h" namespace mozilla::layers { using gfx::DrawTarget; using gfx::IntPoint; +using gfx::IntRect; using gfx::IntRegion; using gfx::IntSize; using gfx::Rect; using gl::GLContext; using widget::nsWaylandDisplay; using widget::WaylandShmBuffer; typedef void (*CallbackFunc)(void* aData, uint32_t aTime); @@ -53,17 +54,18 @@ class NativeSurfaceWayland { NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NativeSurfaceWayland); static RefPtr<NativeSurfaceWayland> Create(const IntSize& aSize, GLContext* aGL); virtual Maybe<GLuint> GetNextFramebuffer() { return Nothing(); }; virtual RefPtr<DrawTarget> GetNextDrawTarget() { return nullptr; }; - virtual void Commit(const IntRegion& aInvalidRegion) = 0; + virtual void Commit(const IntRegion& aInvalidRegion, + const IntRect& aValidRect) = 0; virtual void NotifySurfaceReady(){}; virtual void DestroyGLResources(){}; void CreateSubsurface(wl_surface* aParentSurface); void ClearSubsurface(); bool HasSubsurface() { return !!mWlSubsurface; } virtual void SetBufferTransformFlipped(bool aFlipped); @@ -95,36 +97,41 @@ class NativeSurfaceWayland { Rect mViewportSourceRect = Rect(-1, -1, -1, -1); IntSize mViewportDestinationSize = IntSize(-1, -1); nsTArray<RefPtr<CallbackMultiplexHelper>> mCallbackMultiplexHelpers; }; class NativeSurfaceWaylandSHM final : public NativeSurfaceWayland { public: RefPtr<DrawTarget> GetNextDrawTarget() override; - void Commit(const IntRegion& aInvalidRegion) override; + void Commit(const IntRegion& aInvalidRegion, + const IntRect& aValidRect) override; static void BufferReleaseCallbackHandler(void* aData, wl_buffer* aBuffer); private: friend RefPtr<NativeSurfaceWayland> NativeSurfaceWayland::Create( const IntSize& aSize, GLContext* aGL); explicit NativeSurfaceWaylandSHM(const IntSize& aSize); + void HandlePartialUpdate(const MutexAutoLock& aProofOfLock, + const IntRegion& aInvalidRegion, + const IntRect& aValidRect); RefPtr<WaylandShmBuffer> ObtainBufferFromPool( const MutexAutoLock& aProofOfLock); void ReturnBufferToPool(const MutexAutoLock& aProofOfLock, const RefPtr<WaylandShmBuffer>& aBuffer); void EnforcePoolSizeLimit(const MutexAutoLock& aProofOfLock); void BufferReleaseCallbackHandler(wl_buffer* aBuffer); nsTArray<RefPtr<WaylandShmBuffer>> mInUseBuffers; nsTArray<RefPtr<WaylandShmBuffer>> mAvailableBuffers; RefPtr<WaylandShmBuffer> mCurrentBuffer; + RefPtr<WaylandShmBuffer> mPreviousBuffer; }; class WaylandDMABUFBuffer { public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WaylandDMABUFBuffer); static RefPtr<WaylandDMABUFBuffer> Create(const LayoutDeviceIntSize& aSize, GLContext* aGL); @@ -149,28 +156,32 @@ class WaylandDMABUFBuffer { const LayoutDeviceIntSize mSize; RefPtr<DMABufSurfaceRGBA> mDMABufSurface; UniquePtr<gl::MozFramebuffer> mFB; }; class NativeSurfaceWaylandDMABUF final : public NativeSurfaceWayland { public: Maybe<GLuint> GetNextFramebuffer() override; - void Commit(const IntRegion& aInvalidRegion) override; + void Commit(const IntRegion& aInvalidRegion, + const IntRect& aValidRect) override; void DestroyGLResources() override; static void BufferReleaseCallbackHandler(void* aData, wl_buffer* aBuffer); private: friend RefPtr<NativeSurfaceWayland> NativeSurfaceWayland::Create( const IntSize& aSize, GLContext* aGL); NativeSurfaceWaylandDMABUF(const IntSize& aSize, GLContext* aGL); ~NativeSurfaceWaylandDMABUF() = default; + void HandlePartialUpdate(const MutexAutoLock& aProofOfLock, + const IntRegion& aInvalidRegion, + const IntRect& aValidRect); RefPtr<WaylandDMABUFBuffer> ObtainBufferFromPool( const MutexAutoLock& aProofOfLock); void ReturnBufferToPool(const MutexAutoLock& aProofOfLock, const RefPtr<WaylandDMABUFBuffer>& aBuffer); void EnforcePoolSizeLimit(const MutexAutoLock& aProofOfLock); UniquePtr<gl::MozFramebuffer> CreateFramebufferForTexture( const MutexAutoLock& aProofOfLock, GLContext* aGL, const IntSize& aSize, GLuint aTexture); @@ -178,16 +189,17 @@ class NativeSurfaceWaylandDMABUF final : const MutexAutoLock& aProofOfLock, GLContext* aGL, const IntSize& aSize); void BufferReleaseCallbackHandler(wl_buffer* aBuffer); RefPtr<GLContext> mGL; nsTArray<RefPtr<WaylandDMABUFBuffer>> mInUseBuffers; nsTArray<RefPtr<WaylandDMABUFBuffer>> mAvailableBuffers; RefPtr<WaylandDMABUFBuffer> mCurrentBuffer; + RefPtr<WaylandDMABUFBuffer> mPreviousBuffer; struct DepthBufferEntry final { RefPtr<GLContext> mGL; IntSize mSize; WeakPtr<gl::DepthAndStencilBuffer> mBuffer; }; nsTArray<DepthBufferEntry> mDepthBuffers;
--- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -5042,21 +5042,17 @@ - name: gfx.webrender.compositor.force-enabled type: bool value: false mirror: once - name: gfx.webrender.compositor.max_update_rects type: uint32_t -#if defined(XP_WIN) || defined(XP_MACOSX) value: 1 -#else - value: 0 -#endif mirror: once - name: gfx.webrender.compositor.surface-pool-size type: uint32_t value: 25 mirror: once # Number of damage rects we can give to the compositor for a new frame with