Bug 1961723 [Linux] Use WaylandBufferDMABUFHolder at NativeLayerWayland to hold wl_buffers for external dmabuf surfaces r=lsalzman
WaylandBufferDMABUFHolder stores wl_buffer for external dmabuf surface and allows us to use existing wl_buffer for dmabuf surface instead of creating a new one. That saves GPU resources and GPU power (MPV does the same). In this patch add WaylandBufferDMABUFHolder to NativeLayerRootWayland and cache wl_buffers there for surfaces which can be recycled. Differential Revision: https://phabricator.services.mozilla.com/D248228
This commit is contained in:
committed by
stransky@redhat.com
parent
388084e23c
commit
b0c857d67b
@@ -513,6 +513,32 @@ GdkWindow* NativeLayerRootWayland::GetGdkWindow() const {
|
||||
return mSurface->GetGdkWindow();
|
||||
}
|
||||
|
||||
// Try to match stored wl_buffer with provided DMABufSurface or create
|
||||
// a new one.
|
||||
RefPtr<WaylandBuffer> NativeLayerRootWayland::BorrowExternalBuffer(
|
||||
RefPtr<DMABufSurface> aDMABufSurface) {
|
||||
LOG("NativeLayerRootWayland::BorrowExternalBuffer() WaylandSurface [%p] UID "
|
||||
"%d PID %d",
|
||||
aDMABufSurface.get(), aDMABufSurface->GetUID(), aDMABufSurface->GetPID());
|
||||
|
||||
RefPtr waylandBuffer =
|
||||
widget::WaylandBufferDMABUF::CreateExternal(aDMABufSurface);
|
||||
for (auto& b : mExternalBuffers) {
|
||||
if (b.Matches(aDMABufSurface)) {
|
||||
waylandBuffer->SetExternalWLBuffer(b.GetWLBuffer());
|
||||
return waylandBuffer.forget();
|
||||
}
|
||||
}
|
||||
|
||||
wl_buffer* wlbuffer = waylandBuffer->CreateAndTakeWLBuffer();
|
||||
if (!wlbuffer) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mExternalBuffers.EmplaceBack(aDMABufSurface, wlbuffer);
|
||||
return waylandBuffer.forget();
|
||||
}
|
||||
|
||||
NativeLayerWayland::NativeLayerWayland(NativeLayerRootWayland* aRootLayer,
|
||||
const IntSize& aSize, bool aIsOpaque)
|
||||
: mMutex("NativeLayerWayland"),
|
||||
@@ -1008,9 +1034,12 @@ void NativeLayerWaylandExternal::AttachExternalImage(
|
||||
mSize = texture->GetSize(0);
|
||||
mDisplayRect = IntRect(IntPoint{}, mSize);
|
||||
mBufferInvalided = true;
|
||||
mFrontBuffer =
|
||||
widget::WaylandBufferDMABUF::CreateExternal(mTextureHost->GetSurface());
|
||||
mIsHDR = mTextureHost->GetSurface()->IsHDRSurface();
|
||||
|
||||
auto surface = mTextureHost->GetSurface();
|
||||
mFrontBuffer = surface->CanRecycle()
|
||||
? mRootLayer->BorrowExternalBuffer(surface)
|
||||
: widget::WaylandBufferDMABUF::CreateExternal(surface);
|
||||
mIsHDR = surface->IsHDRSurface();
|
||||
|
||||
LOG("NativeLayerWaylandExternal::AttachExternalImage() host [%p] "
|
||||
"DMABufSurface [%p] DMABuf UID %d [%d x %d] HDR %d Opaque %d",
|
||||
|
||||
@@ -61,6 +61,9 @@ class NativeLayerRootWayland final : public NativeLayerRoot {
|
||||
|
||||
void FrameCallbackHandler(uint32_t aTime);
|
||||
|
||||
RefPtr<widget::WaylandBuffer> BorrowExternalBuffer(
|
||||
RefPtr<DMABufSurface> aDMABufSurface);
|
||||
|
||||
#ifdef MOZ_LOGGING
|
||||
nsAutoCString GetDebugTag() const;
|
||||
void* GetLoggingWidget() const;
|
||||
@@ -119,6 +122,10 @@ class NativeLayerRootWayland final : public NativeLayerRoot {
|
||||
// they have been added or removed.
|
||||
nsTArray<RefPtr<NativeLayerWayland>> mMainThreadUpdateSublayers;
|
||||
|
||||
// External buffers (DMABuf) used by the layers.
|
||||
// We want to cache and reuse wl_buffer of external images.
|
||||
nsTArray<widget::WaylandBufferDMABUFHolder> mExternalBuffers;
|
||||
|
||||
// We're between CompositorBeginFrame() / CompositorEndFrame() calls.
|
||||
mozilla::Atomic<bool, mozilla::Relaxed> mFrameInProcess{false};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user