mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-25 23:05:58 +01:00
parent
5d100bdcbb
commit
68783d904d
4 changed files with 76 additions and 71 deletions
|
@ -457,12 +457,12 @@ bool CScreencopyProtocolManager::copyFrameShm(SScreencopyFrame* frame, timespec*
|
||||||
|
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, fb.m_iFb);
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, fb.m_iFb);
|
||||||
|
|
||||||
GLint glf, glt;
|
const auto PFORMAT = g_pHyprOpenGL->getPixelFormatFromDRM(format);
|
||||||
glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &glf);
|
if (!PFORMAT) {
|
||||||
glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &glt);
|
g_pHyprRenderer->endRender();
|
||||||
if (glf == 0 || glt == 0) {
|
wlr_texture_destroy(sourceTex);
|
||||||
glf = drmFormatToGL(frame->pMonitor->drmFormat);
|
wlr_buffer_end_data_ptr_access(frame->buffer);
|
||||||
glt = glFormatToType(glf);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_pHyprRenderer->endRender();
|
g_pHyprRenderer->endRender();
|
||||||
|
@ -473,16 +473,15 @@ bool CScreencopyProtocolManager::copyFrameShm(SScreencopyFrame* frame, timespec*
|
||||||
|
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
|
|
||||||
const auto FMT = g_pHyprOpenGL->getPreferredReadFormat(frame->pMonitor);
|
const wlr_pixel_format_info* drmFmtWlr = drm_get_pixel_format_info(format);
|
||||||
const wlr_pixel_format_info* drmFmtWlr = drm_get_pixel_format_info(FMT);
|
|
||||||
uint32_t packStride = pixel_format_info_min_stride(drmFmtWlr, frame->box.w);
|
uint32_t packStride = pixel_format_info_min_stride(drmFmtWlr, frame->box.w);
|
||||||
|
|
||||||
if (packStride == stride) {
|
if (packStride == stride) {
|
||||||
glReadPixels(frame->box.x, frame->box.y, frame->box.w, frame->box.h, glf, glt, data);
|
glReadPixels(frame->box.x, frame->box.y, frame->box.w, frame->box.h, PFORMAT->glFormat, PFORMAT->glType, data);
|
||||||
} else {
|
} else {
|
||||||
for (size_t i = 0; i < frame->box.h; ++i) {
|
for (size_t i = 0; i < frame->box.h; ++i) {
|
||||||
uint32_t y = frame->box.x + i;
|
uint32_t y = frame->box.x + i;
|
||||||
glReadPixels(frame->box.x, y, frame->box.w, 1, glf, glt, ((unsigned char*)data) + i * stride);
|
glReadPixels(frame->box.x, y, frame->box.w, 1, PFORMAT->glFormat, PFORMAT->glType, ((unsigned char*)data) + i * stride);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -387,19 +387,18 @@ bool CToplevelExportProtocolManager::copyFrameShm(SScreencopyFrame* frame, times
|
||||||
if (frame->overlayCursor)
|
if (frame->overlayCursor)
|
||||||
g_pHyprRenderer->renderSoftwareCursors(PMONITOR, fakeDamage, g_pInputManager->getMouseCoordsInternal() - frame->pWindow->m_vRealPosition.vec());
|
g_pHyprRenderer->renderSoftwareCursors(PMONITOR, fakeDamage, g_pInputManager->getMouseCoordsInternal() - frame->pWindow->m_vRealPosition.vec());
|
||||||
|
|
||||||
GLint glf, glt;
|
const auto PFORMAT = g_pHyprOpenGL->getPixelFormatFromDRM(format);
|
||||||
glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &glf);
|
if (!PFORMAT) {
|
||||||
glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &glt);
|
g_pHyprRenderer->endRender();
|
||||||
if (glf == 0 || glt == 0) {
|
wlr_buffer_end_data_ptr_access(frame->buffer);
|
||||||
glf = drmFormatToGL(frame->pMonitor->drmFormat);
|
return false;
|
||||||
glt = glFormatToType(glf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_pHyprOpenGL->m_RenderData.mainFB->bind();
|
g_pHyprOpenGL->m_RenderData.mainFB->bind();
|
||||||
|
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
|
|
||||||
glReadPixels(0, 0, frame->box.width, frame->box.height, glf, glt, data);
|
glReadPixels(0, 0, frame->box.width, frame->box.height, PFORMAT->glFormat, PFORMAT->glType, data);
|
||||||
|
|
||||||
g_pHyprRenderer->endRender();
|
g_pHyprRenderer->endRender();
|
||||||
|
|
||||||
|
|
|
@ -2067,14 +2067,6 @@ void CHyprOpenGLImpl::setMonitorTransformEnabled(bool enabled) {
|
||||||
m_bEndFrame = !enabled;
|
m_bEndFrame = !enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SGLPixelFormat {
|
|
||||||
uint32_t drmFormat = DRM_FORMAT_INVALID;
|
|
||||||
GLint glInternalFormat = 0;
|
|
||||||
GLint glFormat = 0;
|
|
||||||
GLint glType = 0;
|
|
||||||
bool withAlpha = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline const SGLPixelFormat GLES2_FORMATS[] = {
|
inline const SGLPixelFormat GLES2_FORMATS[] = {
|
||||||
{
|
{
|
||||||
.drmFormat = DRM_FORMAT_ARGB8888,
|
.drmFormat = DRM_FORMAT_ARGB8888,
|
||||||
|
@ -2179,9 +2171,6 @@ inline const SGLPixelFormat GLES2_FORMATS[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t CHyprOpenGLImpl::getPreferredReadFormat(CMonitor* pMonitor) {
|
uint32_t CHyprOpenGLImpl::getPreferredReadFormat(CMonitor* pMonitor) {
|
||||||
if (g_pHyprRenderer->isNvidia())
|
|
||||||
return DRM_FORMAT_XBGR8888;
|
|
||||||
|
|
||||||
GLint glf = -1, glt = -1, as = -1;
|
GLint glf = -1, glt = -1, as = -1;
|
||||||
glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &glf);
|
glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &glf);
|
||||||
glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &glt);
|
glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &glt);
|
||||||
|
@ -2202,3 +2191,12 @@ uint32_t CHyprOpenGLImpl::getPreferredReadFormat(CMonitor* pMonitor) {
|
||||||
|
|
||||||
return DRM_FORMAT_XBGR8888;
|
return DRM_FORMAT_XBGR8888;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SGLPixelFormat* CHyprOpenGLImpl::getPixelFormatFromDRM(uint32_t drmFormat) {
|
||||||
|
for (auto& fmt : GLES2_FORMATS) {
|
||||||
|
if (fmt.drmFormat == drmFormat)
|
||||||
|
return &fmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
|
@ -41,6 +41,14 @@ struct SRenderModifData {
|
||||||
float scale = 1.f;
|
float scale = 1.f;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SGLPixelFormat {
|
||||||
|
uint32_t drmFormat = DRM_FORMAT_INVALID;
|
||||||
|
GLint glInternalFormat = 0;
|
||||||
|
GLint glFormat = 0;
|
||||||
|
GLint glType = 0;
|
||||||
|
bool withAlpha = false;
|
||||||
|
};
|
||||||
|
|
||||||
struct SMonitorRenderData {
|
struct SMonitorRenderData {
|
||||||
CFramebuffer offloadFB;
|
CFramebuffer offloadFB;
|
||||||
CFramebuffer mirrorFB; // these are used for some effects,
|
CFramebuffer mirrorFB; // these are used for some effects,
|
||||||
|
@ -108,66 +116,67 @@ class CHyprOpenGLImpl {
|
||||||
public:
|
public:
|
||||||
CHyprOpenGLImpl();
|
CHyprOpenGLImpl();
|
||||||
|
|
||||||
void begin(CMonitor*, CRegion*, CFramebuffer* fb = nullptr /* if provided, it's not a real frame */);
|
void begin(CMonitor*, CRegion*, CFramebuffer* fb = nullptr /* if provided, it's not a real frame */);
|
||||||
void end();
|
void end();
|
||||||
|
|
||||||
void renderRect(CBox*, const CColor&, int round = 0);
|
void renderRect(CBox*, const CColor&, int round = 0);
|
||||||
void renderRectWithBlur(CBox*, const CColor&, int round = 0, float blurA = 1.f);
|
void renderRectWithBlur(CBox*, const CColor&, int round = 0, float blurA = 1.f);
|
||||||
void renderRectWithDamage(CBox*, const CColor&, CRegion* damage, int round = 0);
|
void renderRectWithDamage(CBox*, const CColor&, CRegion* damage, int round = 0);
|
||||||
void renderTexture(wlr_texture*, CBox*, float a, int round = 0, bool allowCustomUV = false);
|
void renderTexture(wlr_texture*, CBox*, float a, int round = 0, bool allowCustomUV = false);
|
||||||
void renderTexture(const CTexture&, CBox*, float a, int round = 0, bool discardActive = false, bool allowCustomUV = false);
|
void renderTexture(const CTexture&, CBox*, float a, int round = 0, bool discardActive = false, bool allowCustomUV = false);
|
||||||
void renderTextureWithBlur(const CTexture&, CBox*, float a, wlr_surface* pSurface, int round = 0, bool blockBlurOptimization = false, float blurA = 1.f);
|
void renderTextureWithBlur(const CTexture&, CBox*, float a, wlr_surface* pSurface, int round = 0, bool blockBlurOptimization = false, float blurA = 1.f);
|
||||||
void renderRoundedShadow(CBox*, int round, int range, const CColor& color, float a = 1.0);
|
void renderRoundedShadow(CBox*, int round, int range, const CColor& color, float a = 1.0);
|
||||||
void renderBorder(CBox*, const CGradientValueData&, int round, int borderSize, float a = 1.0, int outerRound = -1 /* use round */);
|
void renderBorder(CBox*, const CGradientValueData&, int round, int borderSize, float a = 1.0, int outerRound = -1 /* use round */);
|
||||||
void renderTextureMatte(const CTexture& tex, CBox* pBox, CFramebuffer& matte);
|
void renderTextureMatte(const CTexture& tex, CBox* pBox, CFramebuffer& matte);
|
||||||
|
|
||||||
void setMonitorTransformEnabled(bool enabled);
|
void setMonitorTransformEnabled(bool enabled);
|
||||||
|
|
||||||
void saveMatrix();
|
void saveMatrix();
|
||||||
void setMatrixScaleTranslate(const Vector2D& translate, const float& scale);
|
void setMatrixScaleTranslate(const Vector2D& translate, const float& scale);
|
||||||
void restoreMatrix();
|
void restoreMatrix();
|
||||||
|
|
||||||
void blend(bool enabled);
|
void blend(bool enabled);
|
||||||
|
|
||||||
void makeWindowSnapshot(CWindow*);
|
void makeWindowSnapshot(CWindow*);
|
||||||
void makeRawWindowSnapshot(CWindow*, CFramebuffer*);
|
void makeRawWindowSnapshot(CWindow*, CFramebuffer*);
|
||||||
void makeLayerSnapshot(SLayerSurface*);
|
void makeLayerSnapshot(SLayerSurface*);
|
||||||
void renderSnapshot(CWindow**);
|
void renderSnapshot(CWindow**);
|
||||||
void renderSnapshot(SLayerSurface**);
|
void renderSnapshot(SLayerSurface**);
|
||||||
|
|
||||||
void clear(const CColor&);
|
void clear(const CColor&);
|
||||||
void clearWithTex();
|
void clearWithTex();
|
||||||
void scissor(const CBox*, bool transform = true);
|
void scissor(const CBox*, bool transform = true);
|
||||||
void scissor(const pixman_box32*, bool transform = true);
|
void scissor(const pixman_box32*, bool transform = true);
|
||||||
void scissor(const int x, const int y, const int w, const int h, bool transform = true);
|
void scissor(const int x, const int y, const int w, const int h, bool transform = true);
|
||||||
|
|
||||||
void destroyMonitorResources(CMonitor*);
|
void destroyMonitorResources(CMonitor*);
|
||||||
|
|
||||||
void markBlurDirtyForMonitor(CMonitor*);
|
void markBlurDirtyForMonitor(CMonitor*);
|
||||||
|
|
||||||
void preWindowPass();
|
void preWindowPass();
|
||||||
bool preBlurQueued();
|
bool preBlurQueued();
|
||||||
void preRender(CMonitor*);
|
void preRender(CMonitor*);
|
||||||
|
|
||||||
void saveBufferForMirror();
|
void saveBufferForMirror();
|
||||||
void renderMirrored();
|
void renderMirrored();
|
||||||
|
|
||||||
void applyScreenShader(const std::string& path);
|
void applyScreenShader(const std::string& path);
|
||||||
|
|
||||||
void bindOffMain();
|
void bindOffMain();
|
||||||
void renderOffToMain(CFramebuffer* off);
|
void renderOffToMain(CFramebuffer* off);
|
||||||
void bindBackOnMain();
|
void bindBackOnMain();
|
||||||
|
|
||||||
uint32_t getPreferredReadFormat(CMonitor* pMonitor);
|
uint32_t getPreferredReadFormat(CMonitor* pMonitor);
|
||||||
|
const SGLPixelFormat* getPixelFormatFromDRM(uint32_t drmFormat);
|
||||||
|
|
||||||
SCurrentRenderData m_RenderData;
|
SCurrentRenderData m_RenderData;
|
||||||
|
|
||||||
GLint m_iCurrentOutputFb = 0;
|
GLint m_iCurrentOutputFb = 0;
|
||||||
|
|
||||||
bool m_bReloadScreenShader = true; // at launch it can be set
|
bool m_bReloadScreenShader = true; // at launch it can be set
|
||||||
|
|
||||||
CWindow* m_pCurrentWindow = nullptr; // hack to get the current rendered window
|
CWindow* m_pCurrentWindow = nullptr; // hack to get the current rendered window
|
||||||
SLayerSurface* m_pCurrentLayer = nullptr; // hack to get the current rendered layer
|
SLayerSurface* m_pCurrentLayer = nullptr; // hack to get the current rendered layer
|
||||||
|
|
||||||
std::unordered_map<CWindow*, CFramebuffer> m_mWindowFramebuffers;
|
std::unordered_map<CWindow*, CFramebuffer> m_mWindowFramebuffers;
|
||||||
std::unordered_map<SLayerSurface*, CFramebuffer> m_mLayerFramebuffers;
|
std::unordered_map<SLayerSurface*, CFramebuffer> m_mLayerFramebuffers;
|
||||||
|
|
Loading…
Reference in a new issue