diff --git a/src/protocols/LinuxDMABUF.cpp b/src/protocols/LinuxDMABUF.cpp index c7de03a29..0ad804c38 100644 --- a/src/protocols/LinuxDMABUF.cpp +++ b/src/protocols/LinuxDMABUF.cpp @@ -103,9 +103,6 @@ CLinuxDMABuffer::CLinuxDMABuffer(uint32_t id, wl_client* client, Aquamarine::SDM m_listeners.bufferResourceDestroy.reset(); PROTO::linuxDma->destroyResource(this); }); - - if (!m_buffer->m_success) - LOGM(ERR, "Possibly compositor bug: buffer failed to create"); } CLinuxDMABuffer::~CLinuxDMABuffer() { @@ -217,7 +214,7 @@ void CLinuxDMABUFParamsResource::create(uint32_t id) { auto& buf = PROTO::linuxDma->m_buffers.emplace_back(makeUnique(id, m_resource->client(), *m_attrs)); - if UNLIKELY (!buf->good() || !buf->m_buffer->m_success) { + if UNLIKELY (!buf->good()) { m_resource->sendFailed(); PROTO::linuxDma->m_buffers.pop_back(); return; diff --git a/src/protocols/MesaDRM.cpp b/src/protocols/MesaDRM.cpp index 789f90b6c..7595d57f9 100644 --- a/src/protocols/MesaDRM.cpp +++ b/src/protocols/MesaDRM.cpp @@ -18,9 +18,6 @@ CMesaDRMBufferResource::CMesaDRMBufferResource(uint32_t id, wl_client* client, A m_listeners.bufferResourceDestroy.reset(); PROTO::mesaDRM->destroyResource(this); }); - - if (!m_buffer->m_success) - LOGM(ERR, "Possibly compositor bug: buffer failed to create"); } CMesaDRMBufferResource::~CMesaDRMBufferResource() { diff --git a/src/protocols/SinglePixel.cpp b/src/protocols/SinglePixel.cpp index 6ca48a356..9abde68ab 100644 --- a/src/protocols/SinglePixel.cpp +++ b/src/protocols/SinglePixel.cpp @@ -12,16 +12,9 @@ CSinglePixelBuffer::CSinglePixelBuffer(uint32_t id, wl_client* client, CHyprColo m_opaque = col_.a >= 1.F; - m_texture = makeShared(DRM_FORMAT_ARGB8888, rc(&m_color), 4, Vector2D{1, 1}); - m_resource = CWLBufferResource::create(makeShared(client, 1, id)); - m_success = m_texture->m_texID; - size = {1, 1}; - - if (!m_success) - Debug::log(ERR, "Failed creating a single pixel texture: null texture id"); } CSinglePixelBuffer::~CSinglePixelBuffer() { @@ -57,6 +50,17 @@ void CSinglePixelBuffer::endDataPtr() { ; } +SP CSinglePixelBuffer::createTexture() { + auto tex = makeShared(DRM_FORMAT_ARGB8888, rc(&m_color), 4, Vector2D{1, 1}); + + if (!tex->m_texID) { + Debug::log(ERR, "Failed creating a single pixel texture: null texture id"); + return nullptr; + } + + return tex; +} + bool CSinglePixelBuffer::good() { return m_resource->good(); } diff --git a/src/protocols/SinglePixel.hpp b/src/protocols/SinglePixel.hpp index f8bbfba9f..40fbb9689 100644 --- a/src/protocols/SinglePixel.hpp +++ b/src/protocols/SinglePixel.hpp @@ -18,6 +18,7 @@ class CSinglePixelBuffer : public IHLBuffer { virtual Aquamarine::SDMABUFAttrs dmabuf(); virtual std::tuple beginDataPtr(uint32_t flags); virtual void endDataPtr(); + virtual SP createTexture(); // bool good(); bool m_success = false; diff --git a/src/protocols/core/Compositor.cpp b/src/protocols/core/Compositor.cpp index 955ba5caf..8ad2a3734 100644 --- a/src/protocols/core/Compositor.cpp +++ b/src/protocols/core/Compositor.cpp @@ -91,12 +91,10 @@ CWLSurfaceResource::CWLSurfaceResource(SP resource_) : m_resource(re if (buf && buf->m_buffer) { m_pending.buffer = CHLBufferReference(buf->m_buffer.lock()); - m_pending.texture = buf->m_buffer->m_texture; m_pending.size = buf->m_buffer->size; m_pending.bufferSize = buf->m_buffer->size; } else { - m_pending.buffer = {}; - m_pending.texture.reset(); + m_pending.buffer = {}; m_pending.size = Vector2D{}; m_pending.bufferSize = Vector2D{}; } @@ -132,7 +130,7 @@ CWLSurfaceResource::CWLSurfaceResource(SP resource_) : m_resource(re } // null buffer attached - if (!m_pending.buffer && !m_pending.texture && m_pending.updated.bits.buffer) { + if (!m_pending.buffer && m_pending.updated.bits.buffer) { commitState(m_pending); // remove any pending states. @@ -528,6 +526,8 @@ void CWLSurfaceResource::commitState(SSurfaceState& state) { if (m_current.buffer) { if (m_current.buffer->isSynchronous()) m_current.updateSynchronousTexture(lastTexture); + else if (!m_current.buffer->isSynchronous() && state.updated.bits.buffer) // only get a new texture when a new buffer arrived + m_current.texture = m_current.buffer->createTexture(); // if the surface is a cursor, update the shm buffer // TODO: don't update the entire texture diff --git a/src/protocols/core/Shm.cpp b/src/protocols/core/Shm.cpp index 43c087bc2..30189d8b7 100644 --- a/src/protocols/core/Shm.cpp +++ b/src/protocols/core/Shm.cpp @@ -69,6 +69,10 @@ void CWLSHMBuffer::endDataPtr() { ; } +SP CWLSHMBuffer::createTexture() { + return nullptr; +} + bool CWLSHMBuffer::good() { return true; } diff --git a/src/protocols/core/Shm.hpp b/src/protocols/core/Shm.hpp index 37210398a..fba3de8da 100644 --- a/src/protocols/core/Shm.hpp +++ b/src/protocols/core/Shm.hpp @@ -43,6 +43,7 @@ class CWLSHMBuffer : public IHLBuffer { virtual Aquamarine::SSHMAttrs shm(); virtual std::tuple beginDataPtr(uint32_t flags); virtual void endDataPtr(); + virtual SP createTexture(); bool good(); diff --git a/src/protocols/types/Buffer.hpp b/src/protocols/types/Buffer.hpp index f5c1d8482..428132c5c 100644 --- a/src/protocols/types/Buffer.hpp +++ b/src/protocols/types/Buffer.hpp @@ -22,11 +22,11 @@ class IHLBuffer : public Aquamarine::IBuffer { virtual void lock(); virtual void unlock(); virtual bool locked(); + virtual SP createTexture() = 0; void onBackendRelease(const std::function& fn); void addReleasePoint(CDRMSyncPointState& point); - SP m_texture; bool m_opaque = false; SP m_resource; std::vector> m_syncReleasers; @@ -38,7 +38,6 @@ class IHLBuffer : public Aquamarine::IBuffer { private: int m_locks = 0; - std::function m_backendReleaseQueuedFn; friend class CHLBufferReference; diff --git a/src/protocols/types/DMABuffer.cpp b/src/protocols/types/DMABuffer.cpp index 464008f4e..b361c6c83 100644 --- a/src/protocols/types/DMABuffer.cpp +++ b/src/protocols/types/DMABuffer.cpp @@ -13,34 +13,14 @@ using namespace Hyprutils::OS; CDMABuffer::CDMABuffer(uint32_t id, wl_client* client, Aquamarine::SDMABUFAttrs const& attrs_) : m_attrs(attrs_) { - g_pHyprRenderer->makeEGLCurrent(); - m_listeners.resourceDestroy = events.destroy.listen([this] { closeFDs(); m_listeners.resourceDestroy.reset(); }); size = m_attrs.size; + m_opaque = NFormatUtils::isFormatOpaque(m_attrs.format); m_resource = CWLBufferResource::create(makeShared(client, 1, id)); - - auto eglImage = g_pHyprOpenGL->createEGLImage(m_attrs); - - if UNLIKELY (!eglImage) { - Debug::log(ERR, "CDMABuffer: failed to import EGLImage, retrying as implicit"); - m_attrs.modifier = DRM_FORMAT_MOD_INVALID; - eglImage = g_pHyprOpenGL->createEGLImage(m_attrs); - if UNLIKELY (!eglImage) { - Debug::log(ERR, "CDMABuffer: failed to import EGLImage"); - return; - } - } - - m_texture = makeShared(m_attrs, eglImage); // texture takes ownership of the eglImage - m_opaque = NFormatUtils::isFormatOpaque(m_attrs.format); - m_success = m_texture->m_texID; - - if UNLIKELY (!m_success) - Debug::log(ERR, "Failed to create a dmabuf: texture is null"); } CDMABuffer::~CDMABuffer() { @@ -79,8 +59,32 @@ void CDMABuffer::endDataPtr() { // FIXME: } +SP CDMABuffer::createTexture() { + g_pHyprRenderer->makeEGLCurrent(); + auto eglImage = g_pHyprOpenGL->createEGLImage(m_attrs); + + if UNLIKELY (!eglImage) { + Debug::log(ERR, "CDMABuffer: failed to import EGLImage, retrying as implicit"); + m_attrs.modifier = DRM_FORMAT_MOD_INVALID; + eglImage = g_pHyprOpenGL->createEGLImage(m_attrs); + if UNLIKELY (!eglImage) { + Debug::log(ERR, "CDMABuffer: failed to import EGLImage"); + return nullptr; + } + } + + auto tex = makeShared(m_attrs, eglImage); // texture takes ownership of the eglImage + + if UNLIKELY (!tex->m_texID) { + Debug::log(ERR, "Failed to create a dmabuf: texture is null"); + return nullptr; + } + + return tex; +} + bool CDMABuffer::good() { - return m_success; + return m_attrs.success; } void CDMABuffer::closeFDs() { diff --git a/src/protocols/types/DMABuffer.hpp b/src/protocols/types/DMABuffer.hpp index 19f2ddf7c..14c1eb750 100644 --- a/src/protocols/types/DMABuffer.hpp +++ b/src/protocols/types/DMABuffer.hpp @@ -15,12 +15,11 @@ class CDMABuffer : public IHLBuffer { virtual Aquamarine::SDMABUFAttrs dmabuf(); virtual std::tuple beginDataPtr(uint32_t flags); virtual void endDataPtr(); + virtual SP createTexture(); bool good(); void closeFDs(); Hyprutils::OS::CFileDescriptor exportSyncFile(); - bool m_success = false; - private: Aquamarine::SDMABUFAttrs m_attrs; diff --git a/src/protocols/types/SurfaceState.cpp b/src/protocols/types/SurfaceState.cpp index 6be8e173d..248ce8356 100644 --- a/src/protocols/types/SurfaceState.cpp +++ b/src/protocols/types/SurfaceState.cpp @@ -68,8 +68,10 @@ void SSurfaceState::updateFrom(SSurfaceState& ref) { updated = ref.updated; if (ref.updated.bits.buffer) { + if (!ref.buffer.m_buffer) + texture.reset(); // null buffer reset texture. + buffer = ref.buffer; - texture = ref.texture; size = ref.size; bufferSize = ref.bufferSize; }