From 16799c26526c17cf40f4f6593d82754e50235013 Mon Sep 17 00:00:00 2001 From: Ikalco <73481042+ikalco@users.noreply.github.com> Date: Thu, 23 Jan 2025 16:26:49 -0600 Subject: [PATCH 1/4] move renderer to EGLRenderer --- include/aquamarine/allocator/DRMDumb.hpp | 2 +- include/aquamarine/allocator/GBM.hpp | 2 +- include/aquamarine/backend/DRM.hpp | 4 +- include/aquamarine/buffer/Buffer.hpp | 1 - .../aquamarine/renderer/EGLRenderer.hpp | 23 ++--- src/allocator/DRMDumb.cpp | 2 +- src/allocator/GBM.cpp | 2 +- src/backend/drm/DRM.cpp | 6 +- .../Renderer.cpp => renderer/EGLRenderer.cpp} | 88 +++++++++---------- 9 files changed, 65 insertions(+), 65 deletions(-) rename src/backend/drm/Renderer.hpp => include/aquamarine/renderer/EGLRenderer.hpp (88%) rename src/{backend/drm/Renderer.cpp => renderer/EGLRenderer.cpp} (91%) diff --git a/include/aquamarine/allocator/DRMDumb.hpp b/include/aquamarine/allocator/DRMDumb.hpp index a5eca2c..a13ab85 100644 --- a/include/aquamarine/allocator/DRMDumb.hpp +++ b/include/aquamarine/allocator/DRMDumb.hpp @@ -63,6 +63,6 @@ namespace Aquamarine { int drmfd = -1; friend class CDRMDumbBuffer; - friend class CDRMRenderer; + friend class CEGLRenderer; }; }; diff --git a/include/aquamarine/allocator/GBM.hpp b/include/aquamarine/allocator/GBM.hpp index 09e6cb9..716b496 100644 --- a/include/aquamarine/allocator/GBM.hpp +++ b/include/aquamarine/allocator/GBM.hpp @@ -66,6 +66,6 @@ namespace Aquamarine { std::string drmName = ""; friend class CGBMBuffer; - friend class CDRMRenderer; + friend class CEGLRenderer; }; }; diff --git a/include/aquamarine/backend/DRM.hpp b/include/aquamarine/backend/DRM.hpp index 9f7f718..280af12 100644 --- a/include/aquamarine/backend/DRM.hpp +++ b/include/aquamarine/backend/DRM.hpp @@ -14,7 +14,7 @@ namespace Aquamarine { class CDRMFB; class CDRMOutput; struct SDRMConnector; - class CDRMRenderer; + class CEGLRenderer; class CDRMDumbAllocator; typedef std::function FIdleCallback; @@ -411,7 +411,7 @@ namespace Aquamarine { struct { Hyprutils::Memory::CSharedPointer allocator; - Hyprutils::Memory::CSharedPointer renderer; // may be null if creation fails + Hyprutils::Memory::CSharedPointer renderer; // may be null if creation fails } rendererState; Hyprutils::Memory::CWeakPointer backend; diff --git a/include/aquamarine/buffer/Buffer.hpp b/include/aquamarine/buffer/Buffer.hpp index a96008f..ee18130 100644 --- a/include/aquamarine/buffer/Buffer.hpp +++ b/include/aquamarine/buffer/Buffer.hpp @@ -73,5 +73,4 @@ namespace Aquamarine { private: int locks = 0; }; - }; diff --git a/src/backend/drm/Renderer.hpp b/include/aquamarine/renderer/EGLRenderer.hpp similarity index 88% rename from src/backend/drm/Renderer.hpp rename to include/aquamarine/renderer/EGLRenderer.hpp index 5749754..8f20cf4 100644 --- a/src/backend/drm/Renderer.hpp +++ b/include/aquamarine/renderer/EGLRenderer.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include "FormatUtils.hpp" #include #include @@ -21,11 +22,11 @@ namespace Aquamarine { GLuint target = GL_TEXTURE_2D; }; - class CDRMRendererBufferAttachment : public IAttachment { + class CEGLRendererBufferAttachment : public IAttachment { public: - CDRMRendererBufferAttachment(Hyprutils::Memory::CWeakPointer renderer_, Hyprutils::Memory::CSharedPointer buffer, EGLImageKHR image, GLuint fbo_, + CEGLRendererBufferAttachment(Hyprutils::Memory::CWeakPointer renderer_, Hyprutils::Memory::CSharedPointer buffer, EGLImageKHR image, GLuint fbo_, GLuint rbo_, SGLTex tex); - virtual ~CDRMRendererBufferAttachment() { + virtual ~CEGLRendererBufferAttachment() { ; } virtual eAttachmentType type() { @@ -37,13 +38,13 @@ namespace Aquamarine { SGLTex tex; Hyprutils::Signal::CHyprSignalListener bufferDestroy; - Hyprutils::Memory::CWeakPointer renderer; + Hyprutils::Memory::CWeakPointer renderer; }; - class CDRMRenderer { + class CEGLRenderer { public: - ~CDRMRenderer(); - static Hyprutils::Memory::CSharedPointer attempt(Hyprutils::Memory::CSharedPointer allocator_, + ~CEGLRenderer(); + static Hyprutils::Memory::CSharedPointer attempt(Hyprutils::Memory::CSharedPointer allocator_, Hyprutils::Memory::CSharedPointer backend_); int drmFD = -1; @@ -60,7 +61,7 @@ namespace Aquamarine { void setEGL(); void restoreEGL(); - void onBufferAttachmentDrop(CDRMRendererBufferAttachment* attachment); + void onBufferAttachmentDrop(CEGLRendererBufferAttachment* attachment); struct { struct SShader { @@ -96,11 +97,11 @@ namespace Aquamarine { SGLTex glTex(Hyprutils::Memory::CSharedPointer buf); - Hyprutils::Memory::CWeakPointer self; + Hyprutils::Memory::CWeakPointer self; std::vector formats; private: - CDRMRenderer() = default; + CEGLRenderer() = default; EGLImageKHR createEGLImage(const SDMABUFAttrs& attrs); std::optional>> getModsForFormat(EGLint format); @@ -112,4 +113,4 @@ namespace Aquamarine { Hyprutils::Memory::CWeakPointer backend; }; -}; \ No newline at end of file +}; diff --git a/src/allocator/DRMDumb.cpp b/src/allocator/DRMDumb.cpp index e1fb32f..27506f4 100644 --- a/src/allocator/DRMDumb.cpp +++ b/src/allocator/DRMDumb.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "FormatUtils.hpp" #include "Shared.hpp" #include @@ -10,7 +11,6 @@ #include #include #include -#include "../backend/drm/Renderer.hpp" using namespace Aquamarine; using namespace Hyprutils::Memory; diff --git a/src/allocator/GBM.cpp b/src/allocator/GBM.cpp index d5f69db..e55bb5e 100644 --- a/src/allocator/GBM.cpp +++ b/src/allocator/GBM.cpp @@ -3,12 +3,12 @@ #include #include #include +#include #include "FormatUtils.hpp" #include "Shared.hpp" #include #include #include -#include "../backend/drm/Renderer.hpp" using namespace Aquamarine; using namespace Hyprutils::Memory; diff --git a/src/backend/drm/DRM.cpp b/src/backend/drm/DRM.cpp index af4681f..7c0d2a8 100644 --- a/src/backend/drm/DRM.cpp +++ b/src/backend/drm/DRM.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -32,7 +33,6 @@ extern "C" { #include "FormatUtils.hpp" #include "Shared.hpp" #include "hwdata.hpp" -#include "Renderer.hpp" using namespace Aquamarine; using namespace Hyprutils::Memory; @@ -562,7 +562,7 @@ bool Aquamarine::CDRMBackend::initMgpu() { return false; } - rendererState.renderer = CDRMRenderer::attempt(newAllocator, backend.lock()); + rendererState.renderer = CEGLRenderer::attempt(newAllocator, backend.lock()); if (!rendererState.renderer) { backend->log(AQ_LOG_ERROR, "drm: initMgpu: no renderer"); @@ -937,7 +937,7 @@ void Aquamarine::CDRMBackend::onReady() { if (!a) backend->log(AQ_LOG_ERROR, "drm: onReady: no renderer for gl formats"); else { - auto r = CDRMRenderer::attempt(a, backend.lock()); + auto r = CEGLRenderer::attempt(a, backend.lock()); if (!r) backend->log(AQ_LOG_ERROR, "drm: onReady: no renderer for gl formats"); else { diff --git a/src/backend/drm/Renderer.cpp b/src/renderer/EGLRenderer.cpp similarity index 91% rename from src/backend/drm/Renderer.cpp rename to src/renderer/EGLRenderer.cpp index 7db32ce..fb78ee9 100644 --- a/src/backend/drm/Renderer.cpp +++ b/src/renderer/EGLRenderer.cpp @@ -1,14 +1,14 @@ -#include "Renderer.hpp" #include #include #include #include #include #include -#include "Math.hpp" +#include "../backend/drm/Math.hpp" #include "Shared.hpp" #include "FormatUtils.hpp" #include +#include using namespace Aquamarine; using namespace Hyprutils::Memory; @@ -108,7 +108,7 @@ inline void loadGLProc(void* pProc, const char* name) { // ------------------- -std::optional>> CDRMRenderer::getModsForFormat(EGLint format) { +std::optional>> CEGLRenderer::getModsForFormat(EGLint format) { // TODO: return std::expected when clang supports it EGLint len = 0; @@ -140,7 +140,7 @@ std::optional>> CDRMRenderer::getModsForFo return result; } -bool CDRMRenderer::initDRMFormats() { +bool CEGLRenderer::initDRMFormats() { std::vector formats; EGLint len = 0; @@ -198,7 +198,7 @@ bool CDRMRenderer::initDRMFormats() { return true; } -Aquamarine::CDRMRenderer::~CDRMRenderer() { +Aquamarine::CEGLRenderer::~CEGLRenderer() { eglMakeCurrent(egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(egl.display, egl.context); @@ -207,8 +207,8 @@ Aquamarine::CDRMRenderer::~CDRMRenderer() { eglReleaseThread(); } -SP CDRMRenderer::attempt(Hyprutils::Memory::CSharedPointer allocator_, SP backend_) { - SP renderer = SP(new CDRMRenderer()); +SP CEGLRenderer::attempt(Hyprutils::Memory::CSharedPointer allocator_, SP backend_) { + SP renderer = SP(new CEGLRenderer()); renderer->drmFD = allocator_->drmFD(); renderer->backend = backend_; gBackend = backend_; @@ -216,14 +216,14 @@ SP CDRMRenderer::attempt(Hyprutils::Memory::CSharedPointerlog(AQ_LOG_ERROR, "CDRMRenderer: fail, no gbm support"); + backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, no gbm support"); return nullptr; } // init egl if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE) { - backend_->log(AQ_LOG_ERROR, "CDRMRenderer: fail, eglBindAPI failed"); + backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, eglBindAPI failed"); return nullptr; } @@ -240,45 +240,45 @@ SP CDRMRenderer::attempt(Hyprutils::Memory::CSharedPointeregl.eglDupNativeFenceFDANDROID, "eglDupNativeFenceFDANDROID"); if (!renderer->egl.eglCreateSyncKHR) { - backend_->log(AQ_LOG_ERROR, "CDRMRenderer: fail, no eglCreateSyncKHR"); + backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, no eglCreateSyncKHR"); return nullptr; } if (!renderer->egl.eglDupNativeFenceFDANDROID) { - backend_->log(AQ_LOG_ERROR, "CDRMRenderer: fail, no eglDupNativeFenceFDANDROID"); + backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, no eglDupNativeFenceFDANDROID"); return nullptr; } if (!renderer->egl.eglGetPlatformDisplayEXT) { - backend_->log(AQ_LOG_ERROR, "CDRMRenderer: fail, no eglGetPlatformDisplayEXT"); + backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, no eglGetPlatformDisplayEXT"); return nullptr; } if (!renderer->egl.eglCreateImageKHR) { - backend_->log(AQ_LOG_ERROR, "CDRMRenderer: fail, no eglCreateImageKHR"); + backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, no eglCreateImageKHR"); return nullptr; } if (!renderer->egl.eglQueryDmaBufFormatsEXT) { - backend_->log(AQ_LOG_ERROR, "CDRMRenderer: fail, no eglQueryDmaBufFormatsEXT"); + backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, no eglQueryDmaBufFormatsEXT"); return nullptr; } if (!renderer->egl.eglQueryDmaBufModifiersEXT) { - backend_->log(AQ_LOG_ERROR, "CDRMRenderer: fail, no eglQueryDmaBufModifiersEXT"); + backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, no eglQueryDmaBufModifiersEXT"); return nullptr; } std::vector attrs = {EGL_NONE}; renderer->egl.display = renderer->egl.eglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_KHR, allocator_->gbmDevice, attrs.data()); if (renderer->egl.display == EGL_NO_DISPLAY) { - backend_->log(AQ_LOG_ERROR, "CDRMRenderer: fail, eglGetPlatformDisplayEXT failed"); + backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, eglGetPlatformDisplayEXT failed"); return nullptr; } EGLint major, minor; if (eglInitialize(renderer->egl.display, &major, &minor) == EGL_FALSE) { - backend_->log(AQ_LOG_ERROR, "CDRMRenderer: fail, eglInitialize failed"); + backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, eglInitialize failed"); return nullptr; } @@ -297,12 +297,12 @@ SP CDRMRenderer::attempt(Hyprutils::Memory::CSharedPointerlog(AQ_LOG_ERROR, "CDRMRenderer: fail, no EXT_image_dma_buf_import_modifiers ext"); + backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, no EXT_image_dma_buf_import_modifiers ext"); return nullptr; } if (!EGLEXTENSIONS2.contains("EXT_image_dma_buf_import")) { - backend_->log(AQ_LOG_ERROR, "CDRMRenderer: fail, no EXT_image_dma_buf_import ext"); + backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, no EXT_image_dma_buf_import ext"); return nullptr; } @@ -317,7 +317,7 @@ SP CDRMRenderer::attempt(Hyprutils::Memory::CSharedPointeregl.context = eglCreateContext(renderer->egl.display, EGL_NO_CONFIG_KHR, EGL_NO_CONTEXT, attrs.data()); if (renderer->egl.context == EGL_NO_CONTEXT) { - backend_->log(AQ_LOG_ERROR, "CDRMRenderer: fail, eglCreateContext failed"); + backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, eglCreateContext failed"); return nullptr; } @@ -325,9 +325,9 @@ SP CDRMRenderer::attempt(Hyprutils::Memory::CSharedPointeregl.display, renderer->egl.context, EGL_CONTEXT_PRIORITY_LEVEL_IMG, &priority); if (priority != EGL_CONTEXT_PRIORITY_HIGH_IMG) - backend_->log(AQ_LOG_DEBUG, "CDRMRenderer: didnt get a high priority context"); + backend_->log(AQ_LOG_DEBUG, "CEGLRenderer: didnt get a high priority context"); else - backend_->log(AQ_LOG_DEBUG, "CDRMRenderer: got a high priority context"); + backend_->log(AQ_LOG_DEBUG, "CEGLRenderer: got a high priority context"); } // init shaders @@ -335,13 +335,13 @@ SP CDRMRenderer::attempt(Hyprutils::Memory::CSharedPointersetEGL(); if (!renderer->initDRMFormats()) { - backend_->log(AQ_LOG_ERROR, "CDRMRenderer: fail, initDRMFormats failed"); + backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, initDRMFormats failed"); return nullptr; } renderer->gl.shader.program = createProgram(VERT_SRC, FRAG_SRC); if (renderer->gl.shader.program == 0) { - backend_->log(AQ_LOG_ERROR, "CDRMRenderer: fail, shader failed"); + backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, shader failed"); return nullptr; } @@ -352,7 +352,7 @@ SP CDRMRenderer::attempt(Hyprutils::Memory::CSharedPointergl.shaderExt.program = createProgram(VERT_SRC, FRAG_SRC_EXT); if (renderer->gl.shaderExt.program == 0) { - backend_->log(AQ_LOG_ERROR, "CDRMRenderer: fail, shaderExt failed"); + backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, shaderExt failed"); return nullptr; } @@ -363,22 +363,22 @@ SP CDRMRenderer::attempt(Hyprutils::Memory::CSharedPointerrestoreEGL(); - backend_->log(AQ_LOG_DEBUG, "CDRMRenderer: success"); + backend_->log(AQ_LOG_DEBUG, "CEGLRenderer: success"); return renderer; } -void CDRMRenderer::setEGL() { +void CEGLRenderer::setEGL() { savedEGLState.display = eglGetCurrentDisplay(); savedEGLState.context = eglGetCurrentContext(); savedEGLState.draw = eglGetCurrentSurface(EGL_DRAW); savedEGLState.read = eglGetCurrentSurface(EGL_READ); if (!eglMakeCurrent(egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE, egl.context)) - backend->log(AQ_LOG_WARNING, "CDRMRenderer: setEGL eglMakeCurrent failed"); + backend->log(AQ_LOG_WARNING, "CEGLRenderer: setEGL eglMakeCurrent failed"); } -void CDRMRenderer::restoreEGL() { +void CEGLRenderer::restoreEGL() { EGLDisplay dpy = savedEGLState.display ? savedEGLState.display : egl.display; // egl can't handle this @@ -386,10 +386,10 @@ void CDRMRenderer::restoreEGL() { return; if (!eglMakeCurrent(dpy, savedEGLState.draw, savedEGLState.read, savedEGLState.context)) - backend->log(AQ_LOG_WARNING, "CDRMRenderer: restoreEGL eglMakeCurrent failed"); + backend->log(AQ_LOG_WARNING, "CEGLRenderer: restoreEGL eglMakeCurrent failed"); } -EGLImageKHR CDRMRenderer::createEGLImage(const SDMABUFAttrs& attrs) { +EGLImageKHR CEGLRenderer::createEGLImage(const SDMABUFAttrs& attrs) { std::vector attribs; attribs.push_back(EGL_WIDTH); @@ -468,7 +468,7 @@ EGLImageKHR CDRMRenderer::createEGLImage(const SDMABUFAttrs& attrs) { } \ } -SGLTex CDRMRenderer::glTex(Hyprutils::Memory::CSharedPointer buffa) { +SGLTex CEGLRenderer::glTex(Hyprutils::Memory::CSharedPointer buffa) { SGLTex tex; const auto dma = buffa->dmabuf(); @@ -484,7 +484,7 @@ SGLTex CDRMRenderer::glTex(Hyprutils::Memory::CSharedPointer buffa) { if (fmt.drmFormat != dma.format || fmt.modifier != dma.modifier) continue; - backend->log(AQ_LOG_DEBUG, std::format("CDRMRenderer::glTex: found format+mod, external = {}", fmt.external)); + backend->log(AQ_LOG_DEBUG, std::format("CEGLRenderer::glTex: found format+mod, external = {}", fmt.external)); external = fmt.external; break; } @@ -509,7 +509,7 @@ inline const float fullVerts[] = { 0, 1, // bottom left }; -void CDRMRenderer::waitOnSync(int fd) { +void CEGLRenderer::waitOnSync(int fd) { TRACE(backend->log(AQ_LOG_TRACE, std::format("EGL (waitOnSync): attempting to wait on fd {}", fd))); std::vector attribs; @@ -544,7 +544,7 @@ void CDRMRenderer::waitOnSync(int fd) { TRACE(backend->log(AQ_LOG_TRACE, "EGL (waitOnSync): failed to destroy sync")); } -int CDRMRenderer::recreateBlitSync() { +int CEGLRenderer::recreateBlitSync() { TRACE(backend->log(AQ_LOG_TRACE, "EGL (recreateBlitSync): recreating blit sync")); if (egl.lastBlitSync) { @@ -586,7 +586,7 @@ int CDRMRenderer::recreateBlitSync() { return fd; } -void CDRMRenderer::clearBuffer(IBuffer* buf) { +void CEGLRenderer::clearBuffer(IBuffer* buf) { setEGL(); auto dmabuf = buf->dmabuf(); @@ -632,7 +632,7 @@ void CDRMRenderer::clearBuffer(IBuffer* buf) { restoreEGL(); } -CDRMRenderer::SBlitResult CDRMRenderer::blit(SP from, SP to, int waitFD) { +CEGLRenderer::SBlitResult CEGLRenderer::blit(SP from, SP to, int waitFD) { setEGL(); if (from->dmabuf().size != to->dmabuf().size) { @@ -655,7 +655,7 @@ CDRMRenderer::SBlitResult CDRMRenderer::blit(SP from, SP to, i auto attachment = from->attachments.get(AQ_ATTACHMENT_DRM_RENDERER_DATA); if (attachment) { TRACE(backend->log(AQ_LOG_TRACE, "EGL (blit): From attachment found")); - auto att = (CDRMRendererBufferAttachment*)attachment.get(); + auto att = (CEGLRendererBufferAttachment*)attachment.get(); fromTex = att->tex; } @@ -665,7 +665,7 @@ CDRMRenderer::SBlitResult CDRMRenderer::blit(SP from, SP to, i // should never remove anything, but JIC. We'll leak an EGLImage if this removes anything. from->attachments.removeByType(AQ_ATTACHMENT_DRM_RENDERER_DATA); - from->attachments.add(makeShared(self, from, nullptr, 0, 0, fromTex)); + from->attachments.add(makeShared(self, from, nullptr, 0, 0, fromTex)); } } @@ -689,7 +689,7 @@ CDRMRenderer::SBlitResult CDRMRenderer::blit(SP from, SP to, i auto attachment = to->attachments.get(AQ_ATTACHMENT_DRM_RENDERER_DATA); if (attachment) { TRACE(backend->log(AQ_LOG_TRACE, "EGL (blit): To attachment found")); - auto att = (CDRMRendererBufferAttachment*)attachment.get(); + auto att = (CEGLRendererBufferAttachment*)attachment.get(); rboImage = att->eglImage; fboID = att->fbo; rboID = att->rbo; @@ -720,7 +720,7 @@ CDRMRenderer::SBlitResult CDRMRenderer::blit(SP from, SP to, i // should never remove anything, but JIC. We'll leak an RBO and FBO if this removes anything. to->attachments.removeByType(AQ_ATTACHMENT_DRM_RENDERER_DATA); - to->attachments.add(makeShared(self, to, rboImage, fboID, rboID, SGLTex{})); + to->attachments.add(makeShared(self, to, rboImage, fboID, rboID, SGLTex{})); } } @@ -806,7 +806,7 @@ CDRMRenderer::SBlitResult CDRMRenderer::blit(SP from, SP to, i return {.success = true, .syncFD = explicitFD == -1 ? std::nullopt : std::optional{explicitFD}}; } -void CDRMRenderer::onBufferAttachmentDrop(CDRMRendererBufferAttachment* attachment) { +void CEGLRenderer::onBufferAttachmentDrop(CEGLRendererBufferAttachment* attachment) { setEGL(); TRACE(backend->log(AQ_LOG_TRACE, @@ -826,7 +826,7 @@ void CDRMRenderer::onBufferAttachmentDrop(CDRMRendererBufferAttachment* attachme restoreEGL(); } -bool CDRMRenderer::verifyDestinationDMABUF(const SDMABUFAttrs& attrs) { +bool CEGLRenderer::verifyDestinationDMABUF(const SDMABUFAttrs& attrs) { for (auto const& fmt : formats) { if (fmt.drmFormat != attrs.format) continue; @@ -841,7 +841,7 @@ bool CDRMRenderer::verifyDestinationDMABUF(const SDMABUFAttrs& attrs) { return false; } -CDRMRendererBufferAttachment::CDRMRendererBufferAttachment(Hyprutils::Memory::CWeakPointer renderer_, Hyprutils::Memory::CSharedPointer buffer, +CEGLRendererBufferAttachment::CEGLRendererBufferAttachment(Hyprutils::Memory::CWeakPointer renderer_, Hyprutils::Memory::CSharedPointer buffer, EGLImageKHR image, GLuint fbo_, GLuint rbo_, SGLTex tex_) : eglImage(image), fbo(fbo_), rbo(rbo_), renderer(renderer_), tex(tex_) { bufferDestroy = buffer->events.destroy.registerListener([this](std::any d) { renderer->onBufferAttachmentDrop(this); }); From 64a32a1637423a77c9a8b324c1b7cf5fbc22eee9 Mon Sep 17 00:00:00 2001 From: Ikalco <73481042+ikalco@users.noreply.github.com> Date: Thu, 23 Jan 2025 22:33:07 -0600 Subject: [PATCH 2/4] consolidate EGL state and initialization --- include/aquamarine/renderer/EGLRenderer.hpp | 42 +- src/backend/drm/DRM.cpp | 4 +- src/renderer/EGLRenderer.cpp | 473 ++++++++++++++------ 3 files changed, 369 insertions(+), 150 deletions(-) diff --git a/include/aquamarine/renderer/EGLRenderer.hpp b/include/aquamarine/renderer/EGLRenderer.hpp index 8f20cf4..5b9a755 100644 --- a/include/aquamarine/renderer/EGLRenderer.hpp +++ b/include/aquamarine/renderer/EGLRenderer.hpp @@ -44,8 +44,10 @@ namespace Aquamarine { class CEGLRenderer { public: ~CEGLRenderer(); - static Hyprutils::Memory::CSharedPointer attempt(Hyprutils::Memory::CSharedPointer allocator_, - Hyprutils::Memory::CSharedPointer backend_); + + static Hyprutils::Memory::CSharedPointer attempt(Hyprutils::Memory::CSharedPointer backend_, int drmFD, bool GLES2 = true); + static Hyprutils::Memory::CSharedPointer attempt(Hyprutils::Memory::CSharedPointer backend_, + Hyprutils::Memory::CSharedPointer allocator_, bool GLES2 = true); int drmFD = -1; @@ -71,11 +73,6 @@ namespace Aquamarine { } gl; struct { - EGLDisplay display = nullptr; - EGLContext context = nullptr; - EGLSync lastBlitSync = nullptr; - int lastBlitSyncFD = -1; - PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = nullptr; PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR = nullptr; PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR = nullptr; @@ -87,6 +84,28 @@ namespace Aquamarine { PFNEGLWAITSYNCKHRPROC eglWaitSyncKHR = nullptr; PFNEGLCREATESYNCKHRPROC eglCreateSyncKHR = nullptr; PFNEGLDUPNATIVEFENCEFDANDROIDPROC eglDupNativeFenceFDANDROID = nullptr; + PFNEGLDEBUGMESSAGECONTROLKHRPROC eglDebugMessageControlKHR = nullptr; + PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT = nullptr; + PFNEGLQUERYDEVICESTRINGEXTPROC eglQueryDeviceStringEXT = nullptr; + } proc; + + struct { + bool EXT_read_format_bgra = false; + bool EXT_texture_format_BGRA8888 = false; + bool EXT_platform_device = false; + bool KHR_platform_gbm = false; + bool EXT_image_dma_buf_import = false; + bool EXT_image_dma_buf_import_modifiers = false; + bool KHR_display_reference = false; + bool IMG_context_priority = false; + bool EXT_create_context_robustness = false; + } exts; + + struct { + EGLDisplay display = nullptr; + EGLContext context = nullptr; + EGLSync lastBlitSync = nullptr; + int lastBlitSyncFD = -1; } egl; struct { @@ -104,11 +123,16 @@ namespace Aquamarine { CEGLRenderer() = default; EGLImageKHR createEGLImage(const SDMABUFAttrs& attrs); - std::optional>> getModsForFormat(EGLint format); - bool initDRMFormats(); bool verifyDestinationDMABUF(const SDMABUFAttrs& attrs); void waitOnSync(int fd); int recreateBlitSync(); + + void loadEGLAPI(); + EGLDeviceEXT eglDeviceFromDRMFD(int drmFD); + void initContext(bool GLES2); + void initResources(); + bool initDRMFormats(); + std::optional>> getModsForFormat(EGLint format); bool hasModifiers = false; Hyprutils::Memory::CWeakPointer backend; diff --git a/src/backend/drm/DRM.cpp b/src/backend/drm/DRM.cpp index 7c0d2a8..190b002 100644 --- a/src/backend/drm/DRM.cpp +++ b/src/backend/drm/DRM.cpp @@ -562,7 +562,7 @@ bool Aquamarine::CDRMBackend::initMgpu() { return false; } - rendererState.renderer = CEGLRenderer::attempt(newAllocator, backend.lock()); + rendererState.renderer = CEGLRenderer::attempt(backend.lock(), newAllocator); if (!rendererState.renderer) { backend->log(AQ_LOG_ERROR, "drm: initMgpu: no renderer"); @@ -937,7 +937,7 @@ void Aquamarine::CDRMBackend::onReady() { if (!a) backend->log(AQ_LOG_ERROR, "drm: onReady: no renderer for gl formats"); else { - auto r = CEGLRenderer::attempt(a, backend.lock()); + auto r = CEGLRenderer::attempt(backend.lock(), a); if (!r) backend->log(AQ_LOG_ERROR, "drm: onReady: no renderer for gl formats"); else { diff --git a/src/renderer/EGLRenderer.cpp b/src/renderer/EGLRenderer.cpp index fb78ee9..d4976c5 100644 --- a/src/renderer/EGLRenderer.cpp +++ b/src/renderer/EGLRenderer.cpp @@ -17,11 +17,11 @@ using namespace Hyprutils::Math; #define WP CWeakPointer // static funcs -WP gBackend; +static WP gBackend; // ------------------- shader utils -GLuint compileShader(const GLuint& type, std::string src) { +static GLuint compileShader(const GLuint& type, std::string src) { auto shader = glCreateShader(type); auto shaderSource = src.c_str(); @@ -38,7 +38,7 @@ GLuint compileShader(const GLuint& type, std::string src) { return shader; } -GLuint createProgram(const std::string& vert, const std::string& frag) { +static GLuint createProgram(const std::string& vert, const std::string& frag) { auto vertCompiled = compileShader(GL_VERTEX_SHADER, vert); if (vertCompiled == 0) return 0; @@ -97,22 +97,112 @@ void main() { // ------------------- egl stuff -inline void loadGLProc(void* pProc, const char* name) { +static inline void loadGLProc(void* pProc, const char* name) { void* proc = (void*)eglGetProcAddress(name); if (!proc) { - gBackend->log(AQ_LOG_ERROR, std::format("eglGetProcAddress({}) failed", name)); + gBackend->log(AQ_LOG_ERROR, std::format("eglGetProcAddress({}) failed, the display driver doesn't support it", name)); abort(); } *(void**)pProc = proc; } +static enum eBackendLogLevel eglLogToLevel(EGLint type) { + switch (type) { + case EGL_DEBUG_MSG_CRITICAL_KHR: return AQ_LOG_CRITICAL; + case EGL_DEBUG_MSG_ERROR_KHR: return AQ_LOG_ERROR; + case EGL_DEBUG_MSG_WARN_KHR: return AQ_LOG_WARNING; + case EGL_DEBUG_MSG_INFO_KHR: return AQ_LOG_DEBUG; + default: return AQ_LOG_DEBUG; + } +} + +static const char* eglErrorToString(EGLint error) { + switch (error) { + case EGL_SUCCESS: return "EGL_SUCCESS"; + case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED"; + case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS"; + case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC"; + case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE"; + case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT"; + case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG"; + case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE"; + case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY"; + case EGL_BAD_DEVICE_EXT: return "EGL_BAD_DEVICE_EXT"; + case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE"; + case EGL_BAD_MATCH: return "EGL_BAD_MATCH"; + case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER"; + case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP"; + case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW"; + case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST"; + default: return "Unknown"; + } +} + +static void eglLog(EGLenum error, const char* command, EGLint type, EGLLabelKHR thread, EGLLabelKHR obj, const char* msg) { + gBackend->log(eglLogToLevel(type), std::format("[EGL] Command {} errored out with {} (0x{}): {}", command, eglErrorToString(error), error, msg)); +} + +static bool drmDeviceHasName(const drmDevice* device, const std::string& name) { + for (size_t i = 0; i < DRM_NODE_MAX; i++) { + if (!(device->available_nodes & (1 << i))) + continue; + + if (device->nodes[i] == name) + return true; + } + return false; +} + // ------------------- +EGLDeviceEXT CEGLRenderer::eglDeviceFromDRMFD(int drmFD) { + EGLint nDevices = 0; + if (!proc.eglQueryDevicesEXT(0, nullptr, &nDevices)) { + backend->log(AQ_LOG_ERROR, "CEGLRenderer(drm): eglQueryDevicesEXT failed"); + return EGL_NO_DEVICE_EXT; + } + + if (nDevices <= 0) { + backend->log(AQ_LOG_ERROR, "CEGLRenderer(drm): no devices"); + return EGL_NO_DEVICE_EXT; + } + + std::vector devices; + devices.resize(nDevices); + + if (!proc.eglQueryDevicesEXT(nDevices, devices.data(), &nDevices)) { + backend->log(AQ_LOG_ERROR, "CEGLRenderer(drm): eglQueryDevicesEXT failed (2)"); + return EGL_NO_DEVICE_EXT; + } + + drmDevice* drmDev = nullptr; + if (int ret = drmGetDevice(drmFD, &drmDev); ret < 0) { + backend->log(AQ_LOG_ERROR, "CEGLRenderer(drm): drmGetDevice failed"); + drmFreeDevice(&drmDev); + return EGL_NO_DEVICE_EXT; + } + + for (auto const& d : devices) { + auto devName = proc.eglQueryDeviceStringEXT(d, EGL_DRM_DEVICE_FILE_EXT); + if (!devName) + continue; + + if (drmDeviceHasName(drmDev, devName)) { + backend->log(AQ_LOG_DEBUG, std::format("CEGLRenderer(drm): Using device {}", devName)); + drmFreeDevice(&drmDev); + return d; + } + } + + drmFreeDevice(&drmDev); + return EGL_NO_DEVICE_EXT; +} + std::optional>> CEGLRenderer::getModsForFormat(EGLint format) { // TODO: return std::expected when clang supports it EGLint len = 0; - if (!egl.eglQueryDmaBufModifiersEXT(egl.display, format, 0, nullptr, nullptr, &len)) { + if (!proc.eglQueryDmaBufModifiersEXT(egl.display, format, 0, nullptr, nullptr, &len)) { backend->log(AQ_LOG_ERROR, std::format("EGL: eglQueryDmaBufModifiersEXT failed for format {}", fourccToName(format))); return std::nullopt; } @@ -126,15 +216,20 @@ std::optional>> CEGLRenderer::getModsForFo mods.resize(len); external.resize(len); - egl.eglQueryDmaBufModifiersEXT(egl.display, format, len, mods.data(), external.data(), &len); + proc.eglQueryDmaBufModifiersEXT(egl.display, format, len, mods.data(), external.data(), &len); std::vector> result; result.reserve(mods.size()); + + bool linearIsExternal = false; for (size_t i = 0; i < mods.size(); ++i) { + if (external.at(i) && mods.at(i) == DRM_FORMAT_MOD_LINEAR) + linearIsExternal = true; result.emplace_back(mods.at(i), external.at(i)); } - if (std::ranges::find(mods, DRM_FORMAT_MOD_LINEAR) == mods.end() && mods.size() == 0) + // if the driver doesn't mark linear as external, add it. It's allowed unless the driver says otherwise. (e.g. nvidia) + if (!linearIsExternal && std::ranges::find(mods, DRM_FORMAT_MOD_LINEAR) == mods.end() && mods.size() == 0) result.emplace_back(DRM_FORMAT_MOD_LINEAR, true); return result; @@ -144,9 +239,9 @@ bool CEGLRenderer::initDRMFormats() { std::vector formats; EGLint len = 0; - egl.eglQueryDmaBufFormatsEXT(egl.display, 0, nullptr, &len); + proc.eglQueryDmaBufFormatsEXT(egl.display, 0, nullptr, &len); formats.resize(len); - egl.eglQueryDmaBufFormatsEXT(egl.display, len, formats.data(), &len); + proc.eglQueryDmaBufFormatsEXT(egl.display, len, formats.data(), &len); if (formats.size() == 0) { backend->log(AQ_LOG_ERROR, "EGL: Failed to get formats"); @@ -156,15 +251,18 @@ bool CEGLRenderer::initDRMFormats() { TRACE(backend->log(AQ_LOG_TRACE, "EGL: Supported formats:")); std::vector dmaFormats; + dmaFormats.reserve(formats.size()); for (auto const& fmt : formats) { std::vector> mods; - auto ret = getModsForFormat(fmt); - if (!ret.has_value()) - continue; + if (exts.EXT_image_dma_buf_import_modifiers) { + auto ret = getModsForFormat(fmt); + if (!ret.has_value()) + continue; - mods = *ret; + mods = *ret; + } hasModifiers = hasModifiers || mods.size() > 0; @@ -199,171 +297,268 @@ bool CEGLRenderer::initDRMFormats() { } Aquamarine::CEGLRenderer::~CEGLRenderer() { - eglMakeCurrent(egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - eglDestroyContext(egl.display, egl.context); + if (egl.display) + eglMakeCurrent(egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + + if (egl.display && egl.context != EGL_NO_CONTEXT && egl.context != nullptr) + eglDestroyContext(egl.display, egl.context); - eglTerminate(egl.display); + if (egl.display) + eglTerminate(egl.display); eglReleaseThread(); } -SP CEGLRenderer::attempt(Hyprutils::Memory::CSharedPointer allocator_, SP backend_) { - SP renderer = SP(new CEGLRenderer()); - renderer->drmFD = allocator_->drmFD(); - renderer->backend = backend_; - gBackend = backend_; - +void CEGLRenderer::loadEGLAPI() { const std::string EGLEXTENSIONS = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); - if (!EGLEXTENSIONS.contains("KHR_platform_gbm")) { - backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, no gbm support"); - return nullptr; + backend->log(AQ_LOG_DEBUG, std::format("Supported EGL client extensions: ({}) {}", std::count(EGLEXTENSIONS.begin(), EGLEXTENSIONS.end(), ' '), EGLEXTENSIONS)); + + exts.KHR_display_reference = EGLEXTENSIONS.contains("KHR_display_reference"); + exts.EXT_platform_device = EGLEXTENSIONS.contains("EXT_platform_device"); + exts.KHR_platform_gbm = EGLEXTENSIONS.contains("KHR_platform_gbm"); + + loadGLProc(&proc.eglGetPlatformDisplayEXT, "eglGetPlatformDisplayEXT"); + loadGLProc(&proc.eglCreateImageKHR, "eglCreateImageKHR"); + loadGLProc(&proc.eglDestroyImageKHR, "eglDestroyImageKHR"); + loadGLProc(&proc.eglQueryDmaBufFormatsEXT, "eglQueryDmaBufFormatsEXT"); + loadGLProc(&proc.eglQueryDmaBufModifiersEXT, "eglQueryDmaBufModifiersEXT"); + loadGLProc(&proc.glEGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES"); + loadGLProc(&proc.glEGLImageTargetRenderbufferStorageOES, "glEGLImageTargetRenderbufferStorageOES"); + loadGLProc(&proc.eglDestroySyncKHR, "eglDestroySyncKHR"); + loadGLProc(&proc.eglWaitSyncKHR, "eglWaitSyncKHR"); + loadGLProc(&proc.eglCreateSyncKHR, "eglCreateSyncKHR"); + loadGLProc(&proc.eglDupNativeFenceFDANDROID, "eglDupNativeFenceFDANDROID"); + loadGLProc(&proc.glEGLImageTargetRenderbufferStorageOES, "glEGLImageTargetRenderbufferStorageOES"); + + if (EGLEXTENSIONS.contains("EGL_EXT_device_base") || EGLEXTENSIONS.contains("EGL_EXT_device_enumeration")) + loadGLProc(&proc.eglQueryDevicesEXT, "eglQueryDevicesEXT"); + + if (EGLEXTENSIONS.contains("EGL_EXT_device_base") || EGLEXTENSIONS.contains("EGL_EXT_device_query")) + loadGLProc(&proc.eglQueryDeviceStringEXT, "eglQueryDeviceStringEXT"); + + if (EGLEXTENSIONS.contains("EGL_KHR_debug")) { + loadGLProc(&proc.eglDebugMessageControlKHR, "eglDebugMessageControlKHR"); + static const EGLAttrib debugAttrs[] = { + EGL_DEBUG_MSG_CRITICAL_KHR, EGL_TRUE, EGL_DEBUG_MSG_ERROR_KHR, EGL_TRUE, EGL_DEBUG_MSG_WARN_KHR, EGL_TRUE, EGL_DEBUG_MSG_INFO_KHR, EGL_TRUE, EGL_NONE, + }; + proc.eglDebugMessageControlKHR(::eglLog, debugAttrs); } - // init egl - - if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE) { - backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, eglBindAPI failed"); - return nullptr; + if (EGLEXTENSIONS.contains("EXT_platform_device")) { + loadGLProc(&proc.eglQueryDevicesEXT, "eglQueryDevicesEXT"); + loadGLProc(&proc.eglQueryDeviceStringEXT, "eglQueryDeviceStringEXT"); } - loadGLProc(&renderer->egl.eglGetPlatformDisplayEXT, "eglGetPlatformDisplayEXT"); - loadGLProc(&renderer->egl.eglCreateImageKHR, "eglCreateImageKHR"); - loadGLProc(&renderer->egl.eglDestroyImageKHR, "eglDestroyImageKHR"); - loadGLProc(&renderer->egl.glEGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES"); - loadGLProc(&renderer->egl.glEGLImageTargetRenderbufferStorageOES, "glEGLImageTargetRenderbufferStorageOES"); - loadGLProc(&renderer->egl.eglQueryDmaBufFormatsEXT, "eglQueryDmaBufFormatsEXT"); - loadGLProc(&renderer->egl.eglQueryDmaBufModifiersEXT, "eglQueryDmaBufModifiersEXT"); - loadGLProc(&renderer->egl.eglDestroySyncKHR, "eglDestroySyncKHR"); - loadGLProc(&renderer->egl.eglWaitSyncKHR, "eglWaitSyncKHR"); - loadGLProc(&renderer->egl.eglCreateSyncKHR, "eglCreateSyncKHR"); - loadGLProc(&renderer->egl.eglDupNativeFenceFDANDROID, "eglDupNativeFenceFDANDROID"); - - if (!renderer->egl.eglCreateSyncKHR) { - backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, no eglCreateSyncKHR"); - return nullptr; - } + RASSERT(eglBindAPI(EGL_OPENGL_ES_API) != EGL_FALSE, "Couldn't bind to EGL's opengl ES API. This means your gpu driver f'd up. This is not a Hyprland or Aquamarine issue."); +} - if (!renderer->egl.eglDupNativeFenceFDANDROID) { - backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, no eglDupNativeFenceFDANDROID"); - return nullptr; - } +void CEGLRenderer::initContext(bool GLES2) { + RASSERT(egl.display != nullptr && egl.display != EGL_NO_DISPLAY, "CEGLRenderer: Can't create EGL context without display"); - if (!renderer->egl.eglGetPlatformDisplayEXT) { - backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, no eglGetPlatformDisplayEXT"); - return nullptr; + EGLint major, minor; + if (eglInitialize(egl.display, &major, &minor) == EGL_FALSE) { + backend->log(AQ_LOG_ERROR, "CEGLRenderer: fail, eglInitialize failed"); + return; } - if (!renderer->egl.eglCreateImageKHR) { - backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, no eglCreateImageKHR"); - return nullptr; + std::string EGLEXTENSIONS = eglQueryString(egl.display, EGL_EXTENSIONS); + + exts.IMG_context_priority = EGLEXTENSIONS.contains("IMG_context_priority"); + exts.EXT_create_context_robustness = EGLEXTENSIONS.contains("EXT_create_context_robustness"); + exts.EXT_image_dma_buf_import = EGLEXTENSIONS.contains("EXT_image_dma_buf_import"); + exts.EXT_image_dma_buf_import_modifiers = EGLEXTENSIONS.contains("EXT_image_dma_buf_import_modifiers"); + + std::vector attrs; + + if (exts.IMG_context_priority) { + backend->log(AQ_LOG_DEBUG, "CEGLRenderer: IMG_context_priority supported, requesting high"); + attrs.push_back(EGL_CONTEXT_PRIORITY_LEVEL_IMG); + attrs.push_back(EGL_CONTEXT_PRIORITY_HIGH_IMG); } - if (!renderer->egl.eglQueryDmaBufFormatsEXT) { - backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, no eglQueryDmaBufFormatsEXT"); - return nullptr; + if (exts.EXT_create_context_robustness) { + backend->log(AQ_LOG_DEBUG, "CEGLRenderer: EXT_create_context_robustness supported, requesting lose on reset"); + attrs.push_back(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT); + attrs.push_back(EGL_LOSE_CONTEXT_ON_RESET_EXT); } - if (!renderer->egl.eglQueryDmaBufModifiersEXT) { - backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, no eglQueryDmaBufModifiersEXT"); - return nullptr; + attrs.push_back(EGL_CONTEXT_OPENGL_DEBUG); + attrs.push_back(Aquamarine::isTrace() ? EGL_TRUE : EGL_FALSE); + + auto attrsNoVer = attrs; + + if (GLES2) { + attrs.push_back(EGL_CONTEXT_MAJOR_VERSION); + attrs.push_back(2); + attrs.push_back(EGL_CONTEXT_MINOR_VERSION); + attrs.push_back(0); + } else { + attrs.push_back(EGL_CONTEXT_MAJOR_VERSION); + attrs.push_back(3); + attrs.push_back(EGL_CONTEXT_MINOR_VERSION); + attrs.push_back(2); } - std::vector attrs = {EGL_NONE}; - renderer->egl.display = renderer->egl.eglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_KHR, allocator_->gbmDevice, attrs.data()); - if (renderer->egl.display == EGL_NO_DISPLAY) { - backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, eglGetPlatformDisplayEXT failed"); - return nullptr; + attrs.push_back(EGL_NONE); + + egl.context = eglCreateContext(egl.display, EGL_NO_CONFIG_KHR, EGL_NO_CONTEXT, attrs.data()); + if (egl.context == EGL_NO_CONTEXT) { + if (GLES2) { + backend->log(AQ_LOG_ERROR, "CEGLRenderer: Can't create renderer, eglCreateContext failed with GLES 2.0"); + return; + } + + backend->log(AQ_LOG_ERROR, "CEGLRenderer: eglCreateContext failed with GLES 3.2, retrying GLES 3.0"); + + attrs = attrsNoVer; + attrs.push_back(EGL_CONTEXT_MAJOR_VERSION); + attrs.push_back(3); + attrs.push_back(EGL_CONTEXT_MINOR_VERSION); + attrs.push_back(0); + + attrs.push_back(EGL_NONE); + + egl.context = eglCreateContext(egl.display, EGL_NO_CONFIG_KHR, EGL_NO_CONTEXT, attrs.data()); + if (egl.context == EGL_NO_CONTEXT) { + backend->log(AQ_LOG_ERROR, "CEGLRenderer: Can't create renderer, eglCreateContext failed with both GLES 3.2 and GLES 3.0"); + return; + } } - EGLint major, minor; - if (eglInitialize(renderer->egl.display, &major, &minor) == EGL_FALSE) { - backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, eglInitialize failed"); - return nullptr; + if (exts.IMG_context_priority) { + EGLint priority = EGL_CONTEXT_PRIORITY_MEDIUM_IMG; + eglQueryContext(egl.display, egl.context, EGL_CONTEXT_PRIORITY_LEVEL_IMG, &priority); + if (priority != EGL_CONTEXT_PRIORITY_HIGH_IMG) + backend->log(AQ_LOG_DEBUG, "CEGLRenderer: Failed to get a high priority context"); + else + backend->log(AQ_LOG_DEBUG, "CEGLRenderer: Got a high priority context"); } - attrs.clear(); + setEGL(); - const std::string EGLEXTENSIONS2 = eglQueryString(renderer->egl.display, EGL_EXTENSIONS); + EGLEXTENSIONS = (const char*)glGetString(GL_EXTENSIONS); - if (EGLEXTENSIONS2.contains("IMG_context_priority")) { - attrs.push_back(EGL_CONTEXT_PRIORITY_LEVEL_IMG); - attrs.push_back(EGL_CONTEXT_PRIORITY_HIGH_IMG); + std::string gpuName = "unknown"; + char* drmName = drmGetDeviceNameFromFd2(drmFD); + if (drmName != nullptr) { + gpuName = std::string{drmName}; + free(drmName); } - if (EGLEXTENSIONS2.contains("EXT_create_context_robustness")) { - attrs.push_back(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT); - attrs.push_back(EGL_LOSE_CONTEXT_ON_RESET_EXT); - } + backend->log(AQ_LOG_DEBUG, std::format("Creating {}CEGLRenderer on gpu {}", GLES2 ? "GLES2 " : "", gpuName)); + backend->log(AQ_LOG_DEBUG, std::format("Using: {}", (char*)glGetString(GL_VERSION))); + backend->log(AQ_LOG_DEBUG, std::format("Vendor: {}", (char*)glGetString(GL_VENDOR))); + backend->log(AQ_LOG_DEBUG, std::format("Renderer: {}", (char*)glGetString(GL_RENDERER))); + backend->log(AQ_LOG_DEBUG, std::format("Supported context extensions: ({}) {}", std::count(EGLEXTENSIONS.begin(), EGLEXTENSIONS.end(), ' '), EGLEXTENSIONS)); + + exts.EXT_read_format_bgra = EGLEXTENSIONS.contains("GL_EXT_read_format_bgra"); + exts.EXT_texture_format_BGRA8888 = EGLEXTENSIONS.contains("GL_EXT_texture_format_BGRA8888"); + + restoreEGL(); +} + +void CEGLRenderer::initResources() { + setEGL(); + + if (!exts.EXT_image_dma_buf_import || !initDRMFormats()) + backend->log(AQ_LOG_ERROR, "CEGLRenderer: initDRMFormats failed, dma-buf won't work"); + + gl.shader.program = createProgram(VERT_SRC, FRAG_SRC); + if (gl.shader.program == 0) + backend->log(AQ_LOG_ERROR, "CEGLRenderer: texture shader failed"); + + gl.shader.proj = glGetUniformLocation(gl.shader.program, "proj"); + gl.shader.posAttrib = glGetAttribLocation(gl.shader.program, "pos"); + gl.shader.texAttrib = glGetAttribLocation(gl.shader.program, "texcoord"); + gl.shader.tex = glGetUniformLocation(gl.shader.program, "tex"); + + gl.shaderExt.program = createProgram(VERT_SRC, FRAG_SRC_EXT); + if (gl.shaderExt.program == 0) + backend->log(AQ_LOG_ERROR, "CEGLRenderer: external texture shader failed"); + + gl.shaderExt.proj = glGetUniformLocation(gl.shaderExt.program, "proj"); + gl.shaderExt.posAttrib = glGetAttribLocation(gl.shaderExt.program, "pos"); + gl.shaderExt.texAttrib = glGetAttribLocation(gl.shaderExt.program, "texcoord"); + gl.shaderExt.tex = glGetUniformLocation(gl.shaderExt.program, "tex"); - if (!EGLEXTENSIONS2.contains("EXT_image_dma_buf_import_modifiers")) { - backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, no EXT_image_dma_buf_import_modifiers ext"); + restoreEGL(); +} + +SP CEGLRenderer::attempt(SP backend_, int drmFD, bool GLES2) { + SP renderer = SP(new CEGLRenderer()); + renderer->drmFD = drmFD; + renderer->backend = backend_; + gBackend = backend_; + + renderer->loadEGLAPI(); + + if (!renderer->exts.EXT_platform_device) { + backend_->log(AQ_LOG_ERROR, "CEGLRenderer(drm): Can't create renderer, EGL doesn't support EXT_platform_device"); return nullptr; } - if (!EGLEXTENSIONS2.contains("EXT_image_dma_buf_import")) { - backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, no EXT_image_dma_buf_import ext"); + EGLDeviceEXT device = renderer->eglDeviceFromDRMFD(drmFD); + if (device == EGL_NO_DEVICE_EXT) { + backend_->log(AQ_LOG_ERROR, "CEGLRenderer(drm): Can't create renderer, no matching devices found"); return nullptr; } - attrs.push_back(EGL_CONTEXT_MAJOR_VERSION); - attrs.push_back(2); - attrs.push_back(EGL_CONTEXT_MINOR_VERSION); - attrs.push_back(0); - attrs.push_back(EGL_CONTEXT_OPENGL_DEBUG); - attrs.push_back(EGL_FALSE); + std::vector attrs; + if (renderer->exts.KHR_display_reference) { + attrs.push_back(EGL_TRACK_REFERENCES_KHR); + attrs.push_back(EGL_TRUE); + } attrs.push_back(EGL_NONE); - renderer->egl.context = eglCreateContext(renderer->egl.display, EGL_NO_CONFIG_KHR, EGL_NO_CONTEXT, attrs.data()); - if (renderer->egl.context == EGL_NO_CONTEXT) { - backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, eglCreateContext failed"); + renderer->egl.display = renderer->proc.eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, device, attrs.data()); + if (renderer->egl.display == EGL_NO_DISPLAY) { + backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, eglGetPlatformDisplayEXT failed"); return nullptr; } - if (EGLEXTENSIONS2.contains("IMG_context_priority")) { - EGLint priority = EGL_CONTEXT_PRIORITY_MEDIUM_IMG; - eglQueryContext(renderer->egl.display, renderer->egl.context, EGL_CONTEXT_PRIORITY_LEVEL_IMG, &priority); - if (priority != EGL_CONTEXT_PRIORITY_HIGH_IMG) - backend_->log(AQ_LOG_DEBUG, "CEGLRenderer: didnt get a high priority context"); - else - backend_->log(AQ_LOG_DEBUG, "CEGLRenderer: got a high priority context"); - } + renderer->initContext(GLES2); + if (renderer->egl.context == nullptr || renderer->egl.context == EGL_NO_CONTEXT) + return nullptr; + + renderer->initResources(); - // init shaders + return renderer; +} - renderer->setEGL(); +SP CEGLRenderer::attempt(SP backend_, Hyprutils::Memory::CSharedPointer allocator_, bool GLES2) { + SP renderer = SP(new CEGLRenderer()); + renderer->drmFD = allocator_->drmFD(); + renderer->backend = backend_; + gBackend = backend_; - if (!renderer->initDRMFormats()) { - backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, initDRMFormats failed"); + renderer->loadEGLAPI(); + + if (!renderer->exts.KHR_platform_gbm) { + backend_->log(AQ_LOG_ERROR, "CEGLRenderer(gbm): Can't create renderer, EGL doesn't support KHR_platform_gbm"); return nullptr; } - renderer->gl.shader.program = createProgram(VERT_SRC, FRAG_SRC); - if (renderer->gl.shader.program == 0) { - backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, shader failed"); - return nullptr; + std::vector attrs; + if (renderer->exts.KHR_display_reference) { + attrs.push_back(EGL_TRACK_REFERENCES_KHR); + attrs.push_back(EGL_TRUE); } - renderer->gl.shader.proj = glGetUniformLocation(renderer->gl.shader.program, "proj"); - renderer->gl.shader.posAttrib = glGetAttribLocation(renderer->gl.shader.program, "pos"); - renderer->gl.shader.texAttrib = glGetAttribLocation(renderer->gl.shader.program, "texcoord"); - renderer->gl.shader.tex = glGetUniformLocation(renderer->gl.shader.program, "tex"); + attrs.push_back(EGL_NONE); - renderer->gl.shaderExt.program = createProgram(VERT_SRC, FRAG_SRC_EXT); - if (renderer->gl.shaderExt.program == 0) { - backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, shaderExt failed"); + renderer->egl.display = renderer->proc.eglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_KHR, allocator_->gbmDevice, attrs.data()); + if (renderer->egl.display == EGL_NO_DISPLAY) { + backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, eglGetPlatformDisplayEXT failed"); return nullptr; } - renderer->gl.shaderExt.proj = glGetUniformLocation(renderer->gl.shaderExt.program, "proj"); - renderer->gl.shaderExt.posAttrib = glGetAttribLocation(renderer->gl.shaderExt.program, "pos"); - renderer->gl.shaderExt.texAttrib = glGetAttribLocation(renderer->gl.shaderExt.program, "texcoord"); - renderer->gl.shaderExt.tex = glGetUniformLocation(renderer->gl.shaderExt.program, "tex"); - - renderer->restoreEGL(); + renderer->initContext(GLES2); + if (renderer->egl.context == nullptr || renderer->egl.context == EGL_NO_CONTEXT) + return nullptr; - backend_->log(AQ_LOG_DEBUG, "CEGLRenderer: success"); + renderer->initResources(); return renderer; } @@ -448,7 +643,7 @@ EGLImageKHR CEGLRenderer::createEGLImage(const SDMABUFAttrs& attrs) { attribs.push_back(EGL_NONE); - EGLImageKHR image = egl.eglCreateImageKHR(egl.display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, nullptr, (int*)attribs.data()); + EGLImageKHR image = proc.eglCreateImageKHR(egl.display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, nullptr, (int*)attribs.data()); if (image == EGL_NO_IMAGE_KHR) { backend->log(AQ_LOG_ERROR, std::format("EGL: EGLCreateImageKHR failed: {}", eglGetError())); return EGL_NO_IMAGE_KHR; @@ -496,7 +691,7 @@ SGLTex CEGLRenderer::glTex(Hyprutils::Memory::CSharedPointer buffa) { GLCALL(glBindTexture(tex.target, tex.texid)); GLCALL(glTexParameteri(tex.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); GLCALL(glTexParameteri(tex.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); - GLCALL(egl.glEGLImageTargetTexture2DOES(tex.target, tex.image)); + GLCALL(proc.glEGLImageTargetTexture2DOES(tex.target, tex.image)); GLCALL(glBindTexture(tex.target, 0)); return tex; @@ -523,7 +718,7 @@ void CEGLRenderer::waitOnSync(int fd) { attribs.push_back(dupFd); attribs.push_back(EGL_NONE); - EGLSyncKHR sync = egl.eglCreateSyncKHR(egl.display, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs.data()); + EGLSyncKHR sync = proc.eglCreateSyncKHR(egl.display, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs.data()); if (sync == EGL_NO_SYNC_KHR) { TRACE(backend->log(AQ_LOG_TRACE, "EGL (waitOnSync): failed to create an egl sync for explicit")); if (dupFd >= 0) @@ -532,15 +727,15 @@ void CEGLRenderer::waitOnSync(int fd) { } // we got a sync, now we just tell egl to wait before sampling - if (egl.eglWaitSyncKHR(egl.display, sync, 0) != EGL_TRUE) { - if (egl.eglDestroySyncKHR(egl.display, sync) != EGL_TRUE) + if (proc.eglWaitSyncKHR(egl.display, sync, 0) != EGL_TRUE) { + if (proc.eglDestroySyncKHR(egl.display, sync) != EGL_TRUE) TRACE(backend->log(AQ_LOG_TRACE, "EGL (waitOnSync): failed to destroy sync")); TRACE(backend->log(AQ_LOG_TRACE, "EGL (waitOnSync): failed to wait on the sync object")); return; } - if (egl.eglDestroySyncKHR(egl.display, sync) != EGL_TRUE) + if (proc.eglDestroySyncKHR(egl.display, sync) != EGL_TRUE) TRACE(backend->log(AQ_LOG_TRACE, "EGL (waitOnSync): failed to destroy sync")); } @@ -551,7 +746,7 @@ int CEGLRenderer::recreateBlitSync() { TRACE(backend->log(AQ_LOG_TRACE, std::format("EGL (recreateBlitSync): cleaning up old sync (fd {})", egl.lastBlitSyncFD))); // cleanup last sync - if (egl.eglDestroySyncKHR(egl.display, egl.lastBlitSync) != EGL_TRUE) + if (proc.eglDestroySyncKHR(egl.display, egl.lastBlitSync) != EGL_TRUE) TRACE(backend->log(AQ_LOG_TRACE, "EGL (recreateBlitSync): failed to destroy old sync")); if (egl.lastBlitSyncFD >= 0) @@ -561,7 +756,7 @@ int CEGLRenderer::recreateBlitSync() { egl.lastBlitSync = nullptr; } - EGLSyncKHR sync = egl.eglCreateSyncKHR(egl.display, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr); + EGLSyncKHR sync = proc.eglCreateSyncKHR(egl.display, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr); if (sync == EGL_NO_SYNC_KHR) { TRACE(backend->log(AQ_LOG_TRACE, "EGL (recreateBlitSync): failed to create an egl sync for explicit")); return -1; @@ -570,10 +765,10 @@ int CEGLRenderer::recreateBlitSync() { // we need to flush otherwise we might not get a valid fd glFlush(); - int fd = egl.eglDupNativeFenceFDANDROID(egl.display, sync); + int fd = proc.eglDupNativeFenceFDANDROID(egl.display, sync); if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { TRACE(backend->log(AQ_LOG_TRACE, "EGL (recreateBlitSync): failed to dup egl fence fd")); - if (egl.eglDestroySyncKHR(egl.display, sync) != EGL_TRUE) + if (proc.eglDestroySyncKHR(egl.display, sync) != EGL_TRUE) TRACE(backend->log(AQ_LOG_TRACE, "EGL (recreateBlitSync): failed to destroy new sync")); return -1; } @@ -605,7 +800,7 @@ void CEGLRenderer::clearBuffer(IBuffer* buf) { GLCALL(glGenRenderbuffers(1, &rboID)); GLCALL(glBindRenderbuffer(GL_RENDERBUFFER, rboID)); - GLCALL(egl.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, (GLeglImageOES)rboImage)); + GLCALL(proc.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, (GLeglImageOES)rboImage)); GLCALL(glBindRenderbuffer(GL_RENDERBUFFER, 0)); GLCALL(glGenFramebuffers(1, &fboID)); @@ -627,7 +822,7 @@ void CEGLRenderer::clearBuffer(IBuffer* buf) { glDeleteFramebuffers(1, &fboID); glDeleteRenderbuffers(1, &rboID); - egl.eglDestroyImageKHR(egl.display, rboImage); + proc.eglDestroyImageKHR(egl.display, rboImage); restoreEGL(); } @@ -706,7 +901,7 @@ CEGLRenderer::SBlitResult CEGLRenderer::blit(SP from, SP to, i GLCALL(glGenRenderbuffers(1, &rboID)); GLCALL(glBindRenderbuffer(GL_RENDERBUFFER, rboID)); - GLCALL(egl.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, (GLeglImageOES)rboImage)); + GLCALL(proc.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, (GLeglImageOES)rboImage)); GLCALL(glBindRenderbuffer(GL_RENDERBUFFER, 0)); GLCALL(glGenFramebuffers(1, &fboID)); @@ -819,9 +1014,9 @@ void CEGLRenderer::onBufferAttachmentDrop(CEGLRendererBufferAttachment* attachme if (attachment->fbo) GLCALL(glDeleteFramebuffers(1, &attachment->fbo)); if (attachment->eglImage) - egl.eglDestroyImageKHR(egl.display, attachment->eglImage); + proc.eglDestroyImageKHR(egl.display, attachment->eglImage); if (attachment->tex.image) - egl.eglDestroyImageKHR(egl.display, attachment->tex.image); + proc.eglDestroyImageKHR(egl.display, attachment->tex.image); restoreEGL(); } From 854936a50424b687ee5e32853759edf4a3a76ec4 Mon Sep 17 00:00:00 2001 From: Ikalco <73481042+ikalco@users.noreply.github.com> Date: Thu, 23 Jan 2025 23:26:35 -0600 Subject: [PATCH 3/4] move over eglSync --- include/aquamarine/renderer/EGLRenderer.hpp | 18 ++++++ src/renderer/EGLRenderer.cpp | 62 +++++++++++++++++---- 2 files changed, 69 insertions(+), 11 deletions(-) diff --git a/include/aquamarine/renderer/EGLRenderer.hpp b/include/aquamarine/renderer/EGLRenderer.hpp index 5b9a755..af2233e 100644 --- a/include/aquamarine/renderer/EGLRenderer.hpp +++ b/include/aquamarine/renderer/EGLRenderer.hpp @@ -41,6 +41,23 @@ namespace Aquamarine { Hyprutils::Memory::CWeakPointer renderer; }; + class CEGLSync { + public: + ~CEGLSync(); + + EGLSyncKHR sync = nullptr; + + int fd(); + bool wait(); + + private: + CEGLSync() = default; + + int m_iFd = -1; + + friend class CEGLRenderer; + }; + class CEGLRenderer { public: ~CEGLRenderer(); @@ -123,6 +140,7 @@ namespace Aquamarine { CEGLRenderer() = default; EGLImageKHR createEGLImage(const SDMABUFAttrs& attrs); + Hyprutils::Memory::CSharedPointer createEGLSync(int fenceFD); bool verifyDestinationDMABUF(const SDMABUFAttrs& attrs); void waitOnSync(int fd); int recreateBlitSync(); diff --git a/src/renderer/EGLRenderer.cpp b/src/renderer/EGLRenderer.cpp index d4976c5..235c926 100644 --- a/src/renderer/EGLRenderer.cpp +++ b/src/renderer/EGLRenderer.cpp @@ -16,6 +16,18 @@ using namespace Hyprutils::Math; #define SP CSharedPointer #define WP CWeakPointer +// macros +#define GLCALL(__CALL__) \ + { \ + __CALL__; \ + auto err = glGetError(); \ + if (err != GL_NO_ERROR) { \ + backend->log(AQ_LOG_ERROR, \ + std::format("[GLES] Error in call at {}@{}: 0x{:x}", __LINE__, \ + ([]() constexpr -> std::string { return std::string(__FILE__).substr(std::string(__FILE__).find_last_of('/') + 1); })(), err)); \ + } \ + } + // static funcs static WP gBackend; @@ -584,6 +596,45 @@ void CEGLRenderer::restoreEGL() { backend->log(AQ_LOG_WARNING, "CEGLRenderer: restoreEGL eglMakeCurrent failed"); } +SP CEGLRenderer::createEGLSync(int fenceFD) { + std::vector attribs; + int dupFd = -1; + if (fenceFD > 0) { + dupFd = fcntl(fenceFD, F_DUPFD_CLOEXEC, 0); + if (dupFd < 0) { + backend->log(AQ_LOG_ERROR, "createEGLSync: dup failed"); + return nullptr; + } + // reserve number of elements to avoid reallocations + attribs.reserve(3); + attribs.push_back(EGL_SYNC_NATIVE_FENCE_FD_ANDROID); + attribs.push_back(dupFd); + attribs.push_back(EGL_NONE); + } + + EGLSyncKHR sync = proc.eglCreateSyncKHR(egl.display, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs.data()); + if (sync == EGL_NO_SYNC_KHR) { + backend->log(AQ_LOG_ERROR, "eglCreateSyncKHR failed"); + if (dupFd >= 0) + close(dupFd); + return nullptr; + } + + // we need to flush otherwise we might not get a valid fd + glFlush(); + + int fd = proc.eglDupNativeFenceFDANDROID(egl.display, sync); + if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { + backend->log(AQ_LOG_ERROR, "eglDupNativeFenceFDANDROID failed"); + return nullptr; + } + + auto eglsync = SP(new CEGLSync); + eglsync->sync = sync; + eglsync->m_iFd = fd; + return eglsync; +} + EGLImageKHR CEGLRenderer::createEGLImage(const SDMABUFAttrs& attrs) { std::vector attribs; @@ -652,17 +703,6 @@ EGLImageKHR CEGLRenderer::createEGLImage(const SDMABUFAttrs& attrs) { return image; } -#define GLCALL(__CALL__) \ - { \ - __CALL__; \ - auto err = glGetError(); \ - if (err != GL_NO_ERROR) { \ - backend->log(AQ_LOG_ERROR, \ - std::format("[GLES] Error in call at {}@{}: 0x{:x}", __LINE__, \ - ([]() constexpr -> std::string { return std::string(__FILE__).substr(std::string(__FILE__).find_last_of('/') + 1); })(), err)); \ - } \ - } - SGLTex CEGLRenderer::glTex(Hyprutils::Memory::CSharedPointer buffa) { SGLTex tex; From e93a32f2a9040b8b811abfdd7e740e62535baa2a Mon Sep 17 00:00:00 2001 From: Ikalco <73481042+ikalco@users.noreply.github.com> Date: Thu, 30 Jan 2025 22:38:47 -0600 Subject: [PATCH 4/4] unbreak abi --- include/aquamarine/allocator/DRMDumb.hpp | 2 +- include/aquamarine/allocator/GBM.hpp | 2 +- include/aquamarine/backend/DRM.hpp | 4 +- include/aquamarine/buffer/Buffer.hpp | 1 + src/allocator/DRMDumb.cpp | 2 +- src/allocator/GBM.cpp | 2 +- src/backend/drm/DRM.cpp | 6 +- .../drm/Renderer.cpp} | 147 +++++++----------- .../backend/drm/Renderer.hpp | 41 ++--- 9 files changed, 75 insertions(+), 132 deletions(-) rename src/{renderer/EGLRenderer.cpp => backend/drm/Renderer.cpp} (89%) rename include/aquamarine/renderer/EGLRenderer.hpp => src/backend/drm/Renderer.hpp (84%) diff --git a/include/aquamarine/allocator/DRMDumb.hpp b/include/aquamarine/allocator/DRMDumb.hpp index a13ab85..a5eca2c 100644 --- a/include/aquamarine/allocator/DRMDumb.hpp +++ b/include/aquamarine/allocator/DRMDumb.hpp @@ -63,6 +63,6 @@ namespace Aquamarine { int drmfd = -1; friend class CDRMDumbBuffer; - friend class CEGLRenderer; + friend class CDRMRenderer; }; }; diff --git a/include/aquamarine/allocator/GBM.hpp b/include/aquamarine/allocator/GBM.hpp index 716b496..09e6cb9 100644 --- a/include/aquamarine/allocator/GBM.hpp +++ b/include/aquamarine/allocator/GBM.hpp @@ -66,6 +66,6 @@ namespace Aquamarine { std::string drmName = ""; friend class CGBMBuffer; - friend class CEGLRenderer; + friend class CDRMRenderer; }; }; diff --git a/include/aquamarine/backend/DRM.hpp b/include/aquamarine/backend/DRM.hpp index 280af12..9f7f718 100644 --- a/include/aquamarine/backend/DRM.hpp +++ b/include/aquamarine/backend/DRM.hpp @@ -14,7 +14,7 @@ namespace Aquamarine { class CDRMFB; class CDRMOutput; struct SDRMConnector; - class CEGLRenderer; + class CDRMRenderer; class CDRMDumbAllocator; typedef std::function FIdleCallback; @@ -411,7 +411,7 @@ namespace Aquamarine { struct { Hyprutils::Memory::CSharedPointer allocator; - Hyprutils::Memory::CSharedPointer renderer; // may be null if creation fails + Hyprutils::Memory::CSharedPointer renderer; // may be null if creation fails } rendererState; Hyprutils::Memory::CWeakPointer backend; diff --git a/include/aquamarine/buffer/Buffer.hpp b/include/aquamarine/buffer/Buffer.hpp index ee18130..a96008f 100644 --- a/include/aquamarine/buffer/Buffer.hpp +++ b/include/aquamarine/buffer/Buffer.hpp @@ -73,4 +73,5 @@ namespace Aquamarine { private: int locks = 0; }; + }; diff --git a/src/allocator/DRMDumb.cpp b/src/allocator/DRMDumb.cpp index 27506f4..e1fb32f 100644 --- a/src/allocator/DRMDumb.cpp +++ b/src/allocator/DRMDumb.cpp @@ -2,7 +2,6 @@ #include #include #include -#include #include "FormatUtils.hpp" #include "Shared.hpp" #include @@ -11,6 +10,7 @@ #include #include #include +#include "../backend/drm/Renderer.hpp" using namespace Aquamarine; using namespace Hyprutils::Memory; diff --git a/src/allocator/GBM.cpp b/src/allocator/GBM.cpp index e55bb5e..d5f69db 100644 --- a/src/allocator/GBM.cpp +++ b/src/allocator/GBM.cpp @@ -3,12 +3,12 @@ #include #include #include -#include #include "FormatUtils.hpp" #include "Shared.hpp" #include #include #include +#include "../backend/drm/Renderer.hpp" using namespace Aquamarine; using namespace Hyprutils::Memory; diff --git a/src/backend/drm/DRM.cpp b/src/backend/drm/DRM.cpp index 190b002..6f352ff 100644 --- a/src/backend/drm/DRM.cpp +++ b/src/backend/drm/DRM.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include @@ -33,6 +32,7 @@ extern "C" { #include "FormatUtils.hpp" #include "Shared.hpp" #include "hwdata.hpp" +#include "Renderer.hpp" using namespace Aquamarine; using namespace Hyprutils::Memory; @@ -562,7 +562,7 @@ bool Aquamarine::CDRMBackend::initMgpu() { return false; } - rendererState.renderer = CEGLRenderer::attempt(backend.lock(), newAllocator); + rendererState.renderer = CDRMRenderer::attempt(backend.lock(), newAllocator); if (!rendererState.renderer) { backend->log(AQ_LOG_ERROR, "drm: initMgpu: no renderer"); @@ -937,7 +937,7 @@ void Aquamarine::CDRMBackend::onReady() { if (!a) backend->log(AQ_LOG_ERROR, "drm: onReady: no renderer for gl formats"); else { - auto r = CEGLRenderer::attempt(backend.lock(), a); + auto r = CDRMRenderer::attempt(backend.lock(), a); if (!r) backend->log(AQ_LOG_ERROR, "drm: onReady: no renderer for gl formats"); else { diff --git a/src/renderer/EGLRenderer.cpp b/src/backend/drm/Renderer.cpp similarity index 89% rename from src/renderer/EGLRenderer.cpp rename to src/backend/drm/Renderer.cpp index 235c926..6d0923c 100644 --- a/src/renderer/EGLRenderer.cpp +++ b/src/backend/drm/Renderer.cpp @@ -1,14 +1,14 @@ +#include "Renderer.hpp" #include #include #include #include #include #include -#include "../backend/drm/Math.hpp" +#include "Math.hpp" #include "Shared.hpp" #include "FormatUtils.hpp" #include -#include using namespace Aquamarine; using namespace Hyprutils::Memory; @@ -167,15 +167,15 @@ static bool drmDeviceHasName(const drmDevice* device, const std::string& name) { // ------------------- -EGLDeviceEXT CEGLRenderer::eglDeviceFromDRMFD(int drmFD) { +EGLDeviceEXT CDRMRenderer::eglDeviceFromDRMFD(int drmFD) { EGLint nDevices = 0; if (!proc.eglQueryDevicesEXT(0, nullptr, &nDevices)) { - backend->log(AQ_LOG_ERROR, "CEGLRenderer(drm): eglQueryDevicesEXT failed"); + backend->log(AQ_LOG_ERROR, "CDRMRenderer(drm): eglQueryDevicesEXT failed"); return EGL_NO_DEVICE_EXT; } if (nDevices <= 0) { - backend->log(AQ_LOG_ERROR, "CEGLRenderer(drm): no devices"); + backend->log(AQ_LOG_ERROR, "CDRMRenderer(drm): no devices"); return EGL_NO_DEVICE_EXT; } @@ -183,13 +183,13 @@ EGLDeviceEXT CEGLRenderer::eglDeviceFromDRMFD(int drmFD) { devices.resize(nDevices); if (!proc.eglQueryDevicesEXT(nDevices, devices.data(), &nDevices)) { - backend->log(AQ_LOG_ERROR, "CEGLRenderer(drm): eglQueryDevicesEXT failed (2)"); + backend->log(AQ_LOG_ERROR, "CDRMRenderer(drm): eglQueryDevicesEXT failed (2)"); return EGL_NO_DEVICE_EXT; } drmDevice* drmDev = nullptr; if (int ret = drmGetDevice(drmFD, &drmDev); ret < 0) { - backend->log(AQ_LOG_ERROR, "CEGLRenderer(drm): drmGetDevice failed"); + backend->log(AQ_LOG_ERROR, "CDRMRenderer(drm): drmGetDevice failed"); drmFreeDevice(&drmDev); return EGL_NO_DEVICE_EXT; } @@ -200,7 +200,7 @@ EGLDeviceEXT CEGLRenderer::eglDeviceFromDRMFD(int drmFD) { continue; if (drmDeviceHasName(drmDev, devName)) { - backend->log(AQ_LOG_DEBUG, std::format("CEGLRenderer(drm): Using device {}", devName)); + backend->log(AQ_LOG_DEBUG, std::format("CDRMRenderer(drm): Using device {}", devName)); drmFreeDevice(&drmDev); return d; } @@ -210,7 +210,7 @@ EGLDeviceEXT CEGLRenderer::eglDeviceFromDRMFD(int drmFD) { return EGL_NO_DEVICE_EXT; } -std::optional>> CEGLRenderer::getModsForFormat(EGLint format) { +std::optional>> CDRMRenderer::getModsForFormat(EGLint format) { // TODO: return std::expected when clang supports it EGLint len = 0; @@ -247,7 +247,7 @@ std::optional>> CEGLRenderer::getModsForFo return result; } -bool CEGLRenderer::initDRMFormats() { +bool CDRMRenderer::initDRMFormats() { std::vector formats; EGLint len = 0; @@ -308,7 +308,7 @@ bool CEGLRenderer::initDRMFormats() { return true; } -Aquamarine::CEGLRenderer::~CEGLRenderer() { +Aquamarine::CDRMRenderer::~CDRMRenderer() { if (egl.display) eglMakeCurrent(egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); @@ -321,7 +321,7 @@ Aquamarine::CEGLRenderer::~CEGLRenderer() { eglReleaseThread(); } -void CEGLRenderer::loadEGLAPI() { +void CDRMRenderer::loadEGLAPI() { const std::string EGLEXTENSIONS = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); backend->log(AQ_LOG_DEBUG, std::format("Supported EGL client extensions: ({}) {}", std::count(EGLEXTENSIONS.begin(), EGLEXTENSIONS.end(), ' '), EGLEXTENSIONS)); @@ -365,12 +365,12 @@ void CEGLRenderer::loadEGLAPI() { RASSERT(eglBindAPI(EGL_OPENGL_ES_API) != EGL_FALSE, "Couldn't bind to EGL's opengl ES API. This means your gpu driver f'd up. This is not a Hyprland or Aquamarine issue."); } -void CEGLRenderer::initContext(bool GLES2) { - RASSERT(egl.display != nullptr && egl.display != EGL_NO_DISPLAY, "CEGLRenderer: Can't create EGL context without display"); +void CDRMRenderer::initContext(bool GLES2) { + RASSERT(egl.display != nullptr && egl.display != EGL_NO_DISPLAY, "CDRMRenderer: Can't create EGL context without display"); EGLint major, minor; if (eglInitialize(egl.display, &major, &minor) == EGL_FALSE) { - backend->log(AQ_LOG_ERROR, "CEGLRenderer: fail, eglInitialize failed"); + backend->log(AQ_LOG_ERROR, "CDRMRenderer: fail, eglInitialize failed"); return; } @@ -384,13 +384,13 @@ void CEGLRenderer::initContext(bool GLES2) { std::vector attrs; if (exts.IMG_context_priority) { - backend->log(AQ_LOG_DEBUG, "CEGLRenderer: IMG_context_priority supported, requesting high"); + backend->log(AQ_LOG_DEBUG, "CDRMRenderer: IMG_context_priority supported, requesting high"); attrs.push_back(EGL_CONTEXT_PRIORITY_LEVEL_IMG); attrs.push_back(EGL_CONTEXT_PRIORITY_HIGH_IMG); } if (exts.EXT_create_context_robustness) { - backend->log(AQ_LOG_DEBUG, "CEGLRenderer: EXT_create_context_robustness supported, requesting lose on reset"); + backend->log(AQ_LOG_DEBUG, "CDRMRenderer: EXT_create_context_robustness supported, requesting lose on reset"); attrs.push_back(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT); attrs.push_back(EGL_LOSE_CONTEXT_ON_RESET_EXT); } @@ -417,11 +417,11 @@ void CEGLRenderer::initContext(bool GLES2) { egl.context = eglCreateContext(egl.display, EGL_NO_CONFIG_KHR, EGL_NO_CONTEXT, attrs.data()); if (egl.context == EGL_NO_CONTEXT) { if (GLES2) { - backend->log(AQ_LOG_ERROR, "CEGLRenderer: Can't create renderer, eglCreateContext failed with GLES 2.0"); + backend->log(AQ_LOG_ERROR, "CDRMRenderer: Can't create renderer, eglCreateContext failed with GLES 2.0"); return; } - backend->log(AQ_LOG_ERROR, "CEGLRenderer: eglCreateContext failed with GLES 3.2, retrying GLES 3.0"); + backend->log(AQ_LOG_ERROR, "CDRMRenderer: eglCreateContext failed with GLES 3.2, retrying GLES 3.0"); attrs = attrsNoVer; attrs.push_back(EGL_CONTEXT_MAJOR_VERSION); @@ -433,7 +433,7 @@ void CEGLRenderer::initContext(bool GLES2) { egl.context = eglCreateContext(egl.display, EGL_NO_CONFIG_KHR, EGL_NO_CONTEXT, attrs.data()); if (egl.context == EGL_NO_CONTEXT) { - backend->log(AQ_LOG_ERROR, "CEGLRenderer: Can't create renderer, eglCreateContext failed with both GLES 3.2 and GLES 3.0"); + backend->log(AQ_LOG_ERROR, "CDRMRenderer: Can't create renderer, eglCreateContext failed with both GLES 3.2 and GLES 3.0"); return; } } @@ -442,9 +442,9 @@ void CEGLRenderer::initContext(bool GLES2) { EGLint priority = EGL_CONTEXT_PRIORITY_MEDIUM_IMG; eglQueryContext(egl.display, egl.context, EGL_CONTEXT_PRIORITY_LEVEL_IMG, &priority); if (priority != EGL_CONTEXT_PRIORITY_HIGH_IMG) - backend->log(AQ_LOG_DEBUG, "CEGLRenderer: Failed to get a high priority context"); + backend->log(AQ_LOG_DEBUG, "CDRMRenderer: Failed to get a high priority context"); else - backend->log(AQ_LOG_DEBUG, "CEGLRenderer: Got a high priority context"); + backend->log(AQ_LOG_DEBUG, "CDRMRenderer: Got a high priority context"); } setEGL(); @@ -458,7 +458,7 @@ void CEGLRenderer::initContext(bool GLES2) { free(drmName); } - backend->log(AQ_LOG_DEBUG, std::format("Creating {}CEGLRenderer on gpu {}", GLES2 ? "GLES2 " : "", gpuName)); + backend->log(AQ_LOG_DEBUG, std::format("Creating {}CDRMRenderer on gpu {}", GLES2 ? "GLES2 " : "", gpuName)); backend->log(AQ_LOG_DEBUG, std::format("Using: {}", (char*)glGetString(GL_VERSION))); backend->log(AQ_LOG_DEBUG, std::format("Vendor: {}", (char*)glGetString(GL_VENDOR))); backend->log(AQ_LOG_DEBUG, std::format("Renderer: {}", (char*)glGetString(GL_RENDERER))); @@ -470,15 +470,15 @@ void CEGLRenderer::initContext(bool GLES2) { restoreEGL(); } -void CEGLRenderer::initResources() { +void CDRMRenderer::initResources() { setEGL(); if (!exts.EXT_image_dma_buf_import || !initDRMFormats()) - backend->log(AQ_LOG_ERROR, "CEGLRenderer: initDRMFormats failed, dma-buf won't work"); + backend->log(AQ_LOG_ERROR, "CDRMRenderer: initDRMFormats failed, dma-buf won't work"); gl.shader.program = createProgram(VERT_SRC, FRAG_SRC); if (gl.shader.program == 0) - backend->log(AQ_LOG_ERROR, "CEGLRenderer: texture shader failed"); + backend->log(AQ_LOG_ERROR, "CDRMRenderer: texture shader failed"); gl.shader.proj = glGetUniformLocation(gl.shader.program, "proj"); gl.shader.posAttrib = glGetAttribLocation(gl.shader.program, "pos"); @@ -487,7 +487,7 @@ void CEGLRenderer::initResources() { gl.shaderExt.program = createProgram(VERT_SRC, FRAG_SRC_EXT); if (gl.shaderExt.program == 0) - backend->log(AQ_LOG_ERROR, "CEGLRenderer: external texture shader failed"); + backend->log(AQ_LOG_ERROR, "CDRMRenderer: external texture shader failed"); gl.shaderExt.proj = glGetUniformLocation(gl.shaderExt.program, "proj"); gl.shaderExt.posAttrib = glGetAttribLocation(gl.shaderExt.program, "pos"); @@ -497,8 +497,8 @@ void CEGLRenderer::initResources() { restoreEGL(); } -SP CEGLRenderer::attempt(SP backend_, int drmFD, bool GLES2) { - SP renderer = SP(new CEGLRenderer()); +SP CDRMRenderer::attempt(SP backend_, int drmFD, bool GLES2) { + SP renderer = SP(new CDRMRenderer()); renderer->drmFD = drmFD; renderer->backend = backend_; gBackend = backend_; @@ -506,13 +506,13 @@ SP CEGLRenderer::attempt(SP backend_, int drmFD, bool GL renderer->loadEGLAPI(); if (!renderer->exts.EXT_platform_device) { - backend_->log(AQ_LOG_ERROR, "CEGLRenderer(drm): Can't create renderer, EGL doesn't support EXT_platform_device"); + backend_->log(AQ_LOG_ERROR, "CDRMRenderer(drm): Can't create renderer, EGL doesn't support EXT_platform_device"); return nullptr; } EGLDeviceEXT device = renderer->eglDeviceFromDRMFD(drmFD); if (device == EGL_NO_DEVICE_EXT) { - backend_->log(AQ_LOG_ERROR, "CEGLRenderer(drm): Can't create renderer, no matching devices found"); + backend_->log(AQ_LOG_ERROR, "CDRMRenderer(drm): Can't create renderer, no matching devices found"); return nullptr; } @@ -526,7 +526,7 @@ SP CEGLRenderer::attempt(SP backend_, int drmFD, bool GL renderer->egl.display = renderer->proc.eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, device, attrs.data()); if (renderer->egl.display == EGL_NO_DISPLAY) { - backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, eglGetPlatformDisplayEXT failed"); + backend_->log(AQ_LOG_ERROR, "CDRMRenderer: fail, eglGetPlatformDisplayEXT failed"); return nullptr; } @@ -539,8 +539,8 @@ SP CEGLRenderer::attempt(SP backend_, int drmFD, bool GL return renderer; } -SP CEGLRenderer::attempt(SP backend_, Hyprutils::Memory::CSharedPointer allocator_, bool GLES2) { - SP renderer = SP(new CEGLRenderer()); +SP CDRMRenderer::attempt(SP backend_, Hyprutils::Memory::CSharedPointer allocator_, bool GLES2) { + SP renderer = SP(new CDRMRenderer()); renderer->drmFD = allocator_->drmFD(); renderer->backend = backend_; gBackend = backend_; @@ -548,7 +548,7 @@ SP CEGLRenderer::attempt(SP backend_, Hyprutils::Memory: renderer->loadEGLAPI(); if (!renderer->exts.KHR_platform_gbm) { - backend_->log(AQ_LOG_ERROR, "CEGLRenderer(gbm): Can't create renderer, EGL doesn't support KHR_platform_gbm"); + backend_->log(AQ_LOG_ERROR, "CDRMRenderer(gbm): Can't create renderer, EGL doesn't support KHR_platform_gbm"); return nullptr; } @@ -562,7 +562,7 @@ SP CEGLRenderer::attempt(SP backend_, Hyprutils::Memory: renderer->egl.display = renderer->proc.eglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_KHR, allocator_->gbmDevice, attrs.data()); if (renderer->egl.display == EGL_NO_DISPLAY) { - backend_->log(AQ_LOG_ERROR, "CEGLRenderer: fail, eglGetPlatformDisplayEXT failed"); + backend_->log(AQ_LOG_ERROR, "CDRMRenderer: fail, eglGetPlatformDisplayEXT failed"); return nullptr; } @@ -575,17 +575,17 @@ SP CEGLRenderer::attempt(SP backend_, Hyprutils::Memory: return renderer; } -void CEGLRenderer::setEGL() { +void CDRMRenderer::setEGL() { savedEGLState.display = eglGetCurrentDisplay(); savedEGLState.context = eglGetCurrentContext(); savedEGLState.draw = eglGetCurrentSurface(EGL_DRAW); savedEGLState.read = eglGetCurrentSurface(EGL_READ); if (!eglMakeCurrent(egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE, egl.context)) - backend->log(AQ_LOG_WARNING, "CEGLRenderer: setEGL eglMakeCurrent failed"); + backend->log(AQ_LOG_WARNING, "CDRMRenderer: setEGL eglMakeCurrent failed"); } -void CEGLRenderer::restoreEGL() { +void CDRMRenderer::restoreEGL() { EGLDisplay dpy = savedEGLState.display ? savedEGLState.display : egl.display; // egl can't handle this @@ -593,49 +593,10 @@ void CEGLRenderer::restoreEGL() { return; if (!eglMakeCurrent(dpy, savedEGLState.draw, savedEGLState.read, savedEGLState.context)) - backend->log(AQ_LOG_WARNING, "CEGLRenderer: restoreEGL eglMakeCurrent failed"); + backend->log(AQ_LOG_WARNING, "CDRMRenderer: restoreEGL eglMakeCurrent failed"); } -SP CEGLRenderer::createEGLSync(int fenceFD) { - std::vector attribs; - int dupFd = -1; - if (fenceFD > 0) { - dupFd = fcntl(fenceFD, F_DUPFD_CLOEXEC, 0); - if (dupFd < 0) { - backend->log(AQ_LOG_ERROR, "createEGLSync: dup failed"); - return nullptr; - } - // reserve number of elements to avoid reallocations - attribs.reserve(3); - attribs.push_back(EGL_SYNC_NATIVE_FENCE_FD_ANDROID); - attribs.push_back(dupFd); - attribs.push_back(EGL_NONE); - } - - EGLSyncKHR sync = proc.eglCreateSyncKHR(egl.display, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs.data()); - if (sync == EGL_NO_SYNC_KHR) { - backend->log(AQ_LOG_ERROR, "eglCreateSyncKHR failed"); - if (dupFd >= 0) - close(dupFd); - return nullptr; - } - - // we need to flush otherwise we might not get a valid fd - glFlush(); - - int fd = proc.eglDupNativeFenceFDANDROID(egl.display, sync); - if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { - backend->log(AQ_LOG_ERROR, "eglDupNativeFenceFDANDROID failed"); - return nullptr; - } - - auto eglsync = SP(new CEGLSync); - eglsync->sync = sync; - eglsync->m_iFd = fd; - return eglsync; -} - -EGLImageKHR CEGLRenderer::createEGLImage(const SDMABUFAttrs& attrs) { +EGLImageKHR CDRMRenderer::createEGLImage(const SDMABUFAttrs& attrs) { std::vector attribs; attribs.push_back(EGL_WIDTH); @@ -703,7 +664,7 @@ EGLImageKHR CEGLRenderer::createEGLImage(const SDMABUFAttrs& attrs) { return image; } -SGLTex CEGLRenderer::glTex(Hyprutils::Memory::CSharedPointer buffa) { +SGLTex CDRMRenderer::glTex(Hyprutils::Memory::CSharedPointer buffa) { SGLTex tex; const auto dma = buffa->dmabuf(); @@ -719,7 +680,7 @@ SGLTex CEGLRenderer::glTex(Hyprutils::Memory::CSharedPointer buffa) { if (fmt.drmFormat != dma.format || fmt.modifier != dma.modifier) continue; - backend->log(AQ_LOG_DEBUG, std::format("CEGLRenderer::glTex: found format+mod, external = {}", fmt.external)); + backend->log(AQ_LOG_DEBUG, std::format("CDRMRenderer::glTex: found format+mod, external = {}", fmt.external)); external = fmt.external; break; } @@ -744,7 +705,7 @@ inline const float fullVerts[] = { 0, 1, // bottom left }; -void CEGLRenderer::waitOnSync(int fd) { +void CDRMRenderer::waitOnSync(int fd) { TRACE(backend->log(AQ_LOG_TRACE, std::format("EGL (waitOnSync): attempting to wait on fd {}", fd))); std::vector attribs; @@ -779,7 +740,7 @@ void CEGLRenderer::waitOnSync(int fd) { TRACE(backend->log(AQ_LOG_TRACE, "EGL (waitOnSync): failed to destroy sync")); } -int CEGLRenderer::recreateBlitSync() { +int CDRMRenderer::recreateBlitSync() { TRACE(backend->log(AQ_LOG_TRACE, "EGL (recreateBlitSync): recreating blit sync")); if (egl.lastBlitSync) { @@ -821,7 +782,7 @@ int CEGLRenderer::recreateBlitSync() { return fd; } -void CEGLRenderer::clearBuffer(IBuffer* buf) { +void CDRMRenderer::clearBuffer(IBuffer* buf) { setEGL(); auto dmabuf = buf->dmabuf(); @@ -867,7 +828,7 @@ void CEGLRenderer::clearBuffer(IBuffer* buf) { restoreEGL(); } -CEGLRenderer::SBlitResult CEGLRenderer::blit(SP from, SP to, int waitFD) { +CDRMRenderer::SBlitResult CDRMRenderer::blit(SP from, SP to, int waitFD) { setEGL(); if (from->dmabuf().size != to->dmabuf().size) { @@ -890,7 +851,7 @@ CEGLRenderer::SBlitResult CEGLRenderer::blit(SP from, SP to, i auto attachment = from->attachments.get(AQ_ATTACHMENT_DRM_RENDERER_DATA); if (attachment) { TRACE(backend->log(AQ_LOG_TRACE, "EGL (blit): From attachment found")); - auto att = (CEGLRendererBufferAttachment*)attachment.get(); + auto att = (CDRMRendererBufferAttachment*)attachment.get(); fromTex = att->tex; } @@ -900,7 +861,7 @@ CEGLRenderer::SBlitResult CEGLRenderer::blit(SP from, SP to, i // should never remove anything, but JIC. We'll leak an EGLImage if this removes anything. from->attachments.removeByType(AQ_ATTACHMENT_DRM_RENDERER_DATA); - from->attachments.add(makeShared(self, from, nullptr, 0, 0, fromTex)); + from->attachments.add(makeShared(self, from, nullptr, 0, 0, fromTex)); } } @@ -924,7 +885,7 @@ CEGLRenderer::SBlitResult CEGLRenderer::blit(SP from, SP to, i auto attachment = to->attachments.get(AQ_ATTACHMENT_DRM_RENDERER_DATA); if (attachment) { TRACE(backend->log(AQ_LOG_TRACE, "EGL (blit): To attachment found")); - auto att = (CEGLRendererBufferAttachment*)attachment.get(); + auto att = (CDRMRendererBufferAttachment*)attachment.get(); rboImage = att->eglImage; fboID = att->fbo; rboID = att->rbo; @@ -955,7 +916,7 @@ CEGLRenderer::SBlitResult CEGLRenderer::blit(SP from, SP to, i // should never remove anything, but JIC. We'll leak an RBO and FBO if this removes anything. to->attachments.removeByType(AQ_ATTACHMENT_DRM_RENDERER_DATA); - to->attachments.add(makeShared(self, to, rboImage, fboID, rboID, SGLTex{})); + to->attachments.add(makeShared(self, to, rboImage, fboID, rboID, SGLTex{})); } } @@ -1041,7 +1002,7 @@ CEGLRenderer::SBlitResult CEGLRenderer::blit(SP from, SP to, i return {.success = true, .syncFD = explicitFD == -1 ? std::nullopt : std::optional{explicitFD}}; } -void CEGLRenderer::onBufferAttachmentDrop(CEGLRendererBufferAttachment* attachment) { +void CDRMRenderer::onBufferAttachmentDrop(CDRMRendererBufferAttachment* attachment) { setEGL(); TRACE(backend->log(AQ_LOG_TRACE, @@ -1061,7 +1022,7 @@ void CEGLRenderer::onBufferAttachmentDrop(CEGLRendererBufferAttachment* attachme restoreEGL(); } -bool CEGLRenderer::verifyDestinationDMABUF(const SDMABUFAttrs& attrs) { +bool CDRMRenderer::verifyDestinationDMABUF(const SDMABUFAttrs& attrs) { for (auto const& fmt : formats) { if (fmt.drmFormat != attrs.format) continue; @@ -1076,7 +1037,7 @@ bool CEGLRenderer::verifyDestinationDMABUF(const SDMABUFAttrs& attrs) { return false; } -CEGLRendererBufferAttachment::CEGLRendererBufferAttachment(Hyprutils::Memory::CWeakPointer renderer_, Hyprutils::Memory::CSharedPointer buffer, +CDRMRendererBufferAttachment::CDRMRendererBufferAttachment(Hyprutils::Memory::CWeakPointer renderer_, Hyprutils::Memory::CSharedPointer buffer, EGLImageKHR image, GLuint fbo_, GLuint rbo_, SGLTex tex_) : eglImage(image), fbo(fbo_), rbo(rbo_), renderer(renderer_), tex(tex_) { bufferDestroy = buffer->events.destroy.registerListener([this](std::any d) { renderer->onBufferAttachmentDrop(this); }); diff --git a/include/aquamarine/renderer/EGLRenderer.hpp b/src/backend/drm/Renderer.hpp similarity index 84% rename from include/aquamarine/renderer/EGLRenderer.hpp rename to src/backend/drm/Renderer.hpp index af2233e..af560d9 100644 --- a/include/aquamarine/renderer/EGLRenderer.hpp +++ b/src/backend/drm/Renderer.hpp @@ -1,7 +1,6 @@ #pragma once #include -#include #include "FormatUtils.hpp" #include #include @@ -22,11 +21,11 @@ namespace Aquamarine { GLuint target = GL_TEXTURE_2D; }; - class CEGLRendererBufferAttachment : public IAttachment { + class CDRMRendererBufferAttachment : public IAttachment { public: - CEGLRendererBufferAttachment(Hyprutils::Memory::CWeakPointer renderer_, Hyprutils::Memory::CSharedPointer buffer, EGLImageKHR image, GLuint fbo_, + CDRMRendererBufferAttachment(Hyprutils::Memory::CWeakPointer renderer_, Hyprutils::Memory::CSharedPointer buffer, EGLImageKHR image, GLuint fbo_, GLuint rbo_, SGLTex tex); - virtual ~CEGLRendererBufferAttachment() { + virtual ~CDRMRendererBufferAttachment() { ; } virtual eAttachmentType type() { @@ -38,32 +37,15 @@ namespace Aquamarine { SGLTex tex; Hyprutils::Signal::CHyprSignalListener bufferDestroy; - Hyprutils::Memory::CWeakPointer renderer; + Hyprutils::Memory::CWeakPointer renderer; }; - class CEGLSync { + class CDRMRenderer { public: - ~CEGLSync(); + ~CDRMRenderer(); - EGLSyncKHR sync = nullptr; - - int fd(); - bool wait(); - - private: - CEGLSync() = default; - - int m_iFd = -1; - - friend class CEGLRenderer; - }; - - class CEGLRenderer { - public: - ~CEGLRenderer(); - - static Hyprutils::Memory::CSharedPointer attempt(Hyprutils::Memory::CSharedPointer backend_, int drmFD, bool GLES2 = true); - static Hyprutils::Memory::CSharedPointer attempt(Hyprutils::Memory::CSharedPointer backend_, + static Hyprutils::Memory::CSharedPointer attempt(Hyprutils::Memory::CSharedPointer backend_, int drmFD, bool GLES2 = true); + static Hyprutils::Memory::CSharedPointer attempt(Hyprutils::Memory::CSharedPointer backend_, Hyprutils::Memory::CSharedPointer allocator_, bool GLES2 = true); int drmFD = -1; @@ -80,7 +62,7 @@ namespace Aquamarine { void setEGL(); void restoreEGL(); - void onBufferAttachmentDrop(CEGLRendererBufferAttachment* attachment); + void onBufferAttachmentDrop(CDRMRendererBufferAttachment* attachment); struct { struct SShader { @@ -133,14 +115,13 @@ namespace Aquamarine { SGLTex glTex(Hyprutils::Memory::CSharedPointer buf); - Hyprutils::Memory::CWeakPointer self; + Hyprutils::Memory::CWeakPointer self; std::vector formats; private: - CEGLRenderer() = default; + CDRMRenderer() = default; EGLImageKHR createEGLImage(const SDMABUFAttrs& attrs); - Hyprutils::Memory::CSharedPointer createEGLSync(int fenceFD); bool verifyDestinationDMABUF(const SDMABUFAttrs& attrs); void waitOnSync(int fd); int recreateBlitSync();