Bug 1961723 [Linux] Add WaylandBufferDMABUFHolder class to cache wl_buffer and allow WaylandBufferDMABUF to set wl_buffer from external source r=emilio
If DMABufSurface are recycled we don't want to create/delete wl_buffer for recycled frames as it eats GPU/power resources. Instead store wl_buffers for DMABuf surfaces and re-use them if possible. The behaviour is inspired by MPV which does the same. Differential Revision: https://phabricator.services.mozilla.com/D248224
This commit is contained in:
committed by
stransky@redhat.com
parent
d22a34224c
commit
b21bb9b241
@@ -123,9 +123,15 @@ void WaylandBuffer::DeleteWlBuffer() {
|
||||
if (!mWLBuffer) {
|
||||
return;
|
||||
}
|
||||
LOGWAYLAND("WaylandBuffer::DeleteWlBuffer() [%p] wl_buffer [%p]\n",
|
||||
(void*)this, mWLBuffer);
|
||||
MozClearPointer(mWLBuffer, wl_buffer_destroy);
|
||||
LOGWAYLAND("WaylandBuffer::DeleteWlBuffer() [%p] wl_buffer [%p] managed %d",
|
||||
(void*)this, mWLBuffer, mManagingWLBuffer);
|
||||
if (mManagingWLBuffer) {
|
||||
MozClearPointer(mWLBuffer, wl_buffer_destroy);
|
||||
} else {
|
||||
// Remove reference to this WaylandBuffer
|
||||
wl_proxy_set_user_data((wl_proxy*)mWLBuffer, nullptr);
|
||||
mWLBuffer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void WaylandBuffer::ReturnBufferDetached(WaylandSurfaceLock& aSurfaceLock) {
|
||||
@@ -137,6 +143,28 @@ void WaylandBuffer::ReturnBufferDetached(WaylandSurfaceLock& aSurfaceLock) {
|
||||
mAttachedToSurface = nullptr;
|
||||
}
|
||||
|
||||
wl_buffer* WaylandBuffer::CreateAndTakeWLBuffer() {
|
||||
LOGWAYLAND("WaylandBuffer::CreateAndTakeWLBuffer() [%p]", (void*)this);
|
||||
MOZ_DIAGNOSTIC_ASSERT(!mAttachedToSurface);
|
||||
|
||||
if (!CreateWlBuffer()) {
|
||||
return nullptr;
|
||||
}
|
||||
mManagingWLBuffer = false;
|
||||
return mWLBuffer;
|
||||
}
|
||||
|
||||
void WaylandBuffer::SetExternalWLBuffer(wl_buffer* aWLBuffer) {
|
||||
LOGWAYLAND("WaylandBuffer::SetExternalWLBuffer() [%p] wl_buffer %p",
|
||||
(void*)this, aWLBuffer);
|
||||
MOZ_DIAGNOSTIC_ASSERT(!mAttachedToSurface);
|
||||
MOZ_DIAGNOSTIC_ASSERT(!mWLBuffer);
|
||||
|
||||
mManagingWLBuffer = false;
|
||||
mWLBuffer = aWLBuffer;
|
||||
mWLBufferID = reinterpret_cast<uintptr_t>(mWLBuffer);
|
||||
}
|
||||
|
||||
struct SurfaceAndBuffer {
|
||||
SurfaceAndBuffer(WaylandSurface* aSurface, WaylandBuffer* aBuffer)
|
||||
: mSurface(aSurface), mBuffer(aBuffer) {};
|
||||
@@ -378,4 +406,27 @@ void WaylandBufferDMABUF::DumpToFile(const char* aHint) {
|
||||
}
|
||||
#endif
|
||||
|
||||
WaylandBufferDMABUFHolder::WaylandBufferDMABUFHolder(DMABufSurface* aSurface,
|
||||
wl_buffer* aWLBuffer)
|
||||
: mWLBuffer(aWLBuffer) {
|
||||
mUID = aSurface->GetUID();
|
||||
mPID = aSurface->GetPID();
|
||||
LOGWAYLAND(
|
||||
"WaylandBufferDMABUFHolder::WaylandBufferDMABUFHolder wl_buffer [%p] UID "
|
||||
"%d PID %d",
|
||||
mWLBuffer, mUID, mPID);
|
||||
}
|
||||
|
||||
WaylandBufferDMABUFHolder::~WaylandBufferDMABUFHolder() {
|
||||
LOGWAYLAND(
|
||||
"WaylandBufferDMABUFHolder::~WaylandBufferDMABUFHolder wl_buffer [%p] "
|
||||
"UID %d PID %d",
|
||||
mWLBuffer, mUID, mPID);
|
||||
MozClearPointer(mWLBuffer, wl_buffer_destroy);
|
||||
}
|
||||
|
||||
bool WaylandBufferDMABUFHolder::Matches(DMABufSurface* aSurface) const {
|
||||
return mUID == aSurface->GetUID() && mPID == aSurface->GetPID();
|
||||
}
|
||||
|
||||
} // namespace mozilla::widget
|
||||
|
||||
@@ -85,6 +85,13 @@ class WaylandBuffer {
|
||||
virtual void DumpToFile(const char* aHint) = 0;
|
||||
#endif
|
||||
|
||||
// Create and move away wl_buffer and mark is as not managed.
|
||||
// From this point wl_buffer is not owned by WaylandBuffer.
|
||||
wl_buffer* CreateAndTakeWLBuffer();
|
||||
|
||||
// Set wl_buffer from external source (WaylandBufferDMABUFHolder).
|
||||
void SetExternalWLBuffer(wl_buffer* aWLBuffer);
|
||||
|
||||
protected:
|
||||
explicit WaylandBuffer(const LayoutDeviceIntSize& aSize);
|
||||
virtual ~WaylandBuffer() = default;
|
||||
@@ -105,6 +112,11 @@ class WaylandBuffer {
|
||||
wl_buffer* mWLBuffer = nullptr;
|
||||
uintptr_t mWLBufferID = 0;
|
||||
|
||||
// Owns and manages WL buffer. If set to false, wl_buffer is managed by
|
||||
// someone else (for instance WaylandBufferDMABUFHolder)
|
||||
// and WaylandBuffer can't destroy it.
|
||||
bool mManagingWLBuffer = true;
|
||||
|
||||
// Wayland buffer is tied to WaylandSurface.
|
||||
// We keep reference to WaylandSurface until WaylandSurface returns the
|
||||
// buffer.
|
||||
@@ -192,6 +204,21 @@ class WaylandBufferDMABUF final : public WaylandBuffer {
|
||||
RefPtr<DMABufSurface> mDMABufSurface;
|
||||
};
|
||||
|
||||
class WaylandBufferDMABUFHolder final {
|
||||
public:
|
||||
bool Matches(DMABufSurface* aSurface) const;
|
||||
|
||||
wl_buffer* GetWLBuffer() { return mWLBuffer; }
|
||||
|
||||
WaylandBufferDMABUFHolder(DMABufSurface* aSurface, wl_buffer* aWLBuffer);
|
||||
~WaylandBufferDMABUFHolder();
|
||||
|
||||
private:
|
||||
wl_buffer* mWLBuffer = nullptr;
|
||||
uint32_t mUID = 0;
|
||||
uint32_t mPID = 0;
|
||||
};
|
||||
|
||||
} // namespace mozilla::widget
|
||||
|
||||
#endif // _MOZILLA_WIDGET_GTK_WAYLAND_BUFFER_H
|
||||
|
||||
Reference in New Issue
Block a user