fix: use glReadnPixels for X11 copying to be more memory safe

This commit is contained in:
Almamu 2025-04-01 02:43:13 +02:00
parent b7735298be
commit aee622da6c
10 changed files with 30 additions and 6 deletions

View File

@ -219,7 +219,7 @@ void CWallpaperApplication::setupProperties () {
this->setupPropertiesForProject (info);
}
void CWallpaperApplication::takeScreenshot (const std::filesystem::path& filename) {
void CWallpaperApplication::takeScreenshot (const std::filesystem::path& filename) const {
// this should be getting called at the end of the frame, so the right thing should be bound already
const int width = this->m_renderContext->getOutput ().getFullWidth ();
const int height = this->m_renderContext->getOutput ().getFullHeight ();
@ -238,7 +238,6 @@ void CWallpaperApplication::takeScreenshot (const std::filesystem::path& filenam
const uint8_t* pixel = buffer;
// read the viewport data into the pixel buffer
glPixelStorei (GL_PACK_ALIGNMENT, 1);
glReadnPixels (viewport->viewport.x, viewport->viewport.y, viewport->viewport.z, viewport->viewport.w, GL_RGB,
GL_UNSIGNED_BYTE, bufferSize, buffer);

View File

@ -106,7 +106,7 @@ class CWallpaperApplication {
*
* @param filename
*/
void takeScreenshot (const std::filesystem::path& filename);
void takeScreenshot (const std::filesystem::path& filename) const;
/** The application context that contains the current app settings */
CApplicationContext& m_context;

View File

@ -132,9 +132,16 @@ void CGLFWOpenGLDriver::dispatchEventQueue () {
this->getApp ().update (viewport);
// read the full texture into the image
if (this->m_output->haveImageBuffer ())
glReadPixels (0, 0, this->m_output->getFullWidth (), this->m_output->getFullHeight (), GL_BGRA,
GL_UNSIGNED_BYTE, this->m_output->getImageBuffer ());
if (this->m_output->haveImageBuffer ()) {
glReadnPixels (0, 0, this->m_output->getFullWidth (), this->m_output->getFullHeight (), GL_BGRA,
GL_UNSIGNED_BYTE, this->m_output->getImageBufferSize(), this->m_output->getImageBuffer ());
GLenum error = glGetError();
if (error != GL_NO_ERROR) {
sLog.exception("OpenGL error when reading texture ", error);
}
}
// TODO: FRAMETIME CONTROL SHOULD GO BACK TO THE CWALLPAPAERAPPLICATION ONCE ACTUAL PARTICLES ARE IMPLEMENTED
// TODO: AS THOSE, MORE THAN LIKELY, WILL REQUIRE OF A DIFFERENT PROCESSING RATE

View File

@ -56,6 +56,10 @@ void* CGLFWWindowOutput::getImageBuffer () const {
return nullptr;
}
uint32_t CGLFWWindowOutput::getImageBufferSize () const {
return 0;
}
void CGLFWWindowOutput::updateRender () const {
if (this->m_context.settings.render.mode != Application::CApplicationContext::NORMAL_WINDOW)
return;

View File

@ -13,6 +13,7 @@ class CGLFWWindowOutput final : public COutput {
bool renderMultiple () const override;
bool haveImageBuffer () const override;
void* getImageBuffer () const override;
uint32_t getImageBufferSize () const override;
void updateRender () const override;
private:

View File

@ -38,6 +38,7 @@ class COutput {
virtual bool haveImageBuffer () const = 0;
const std::map<std::string, COutputViewport*>& getViewports () const;
virtual void* getImageBuffer () const = 0;
virtual uint32_t getImageBufferSize () const = 0;
virtual void updateRender () const = 0;
protected:

View File

@ -51,4 +51,8 @@ void* CWaylandOutput::getImageBuffer () const {
return nullptr;
}
uint32_t CWaylandOutput::getImageBufferSize () const {
return 0;
}
void CWaylandOutput::updateRender () const {}

View File

@ -24,6 +24,7 @@ class CWaylandOutput final : public COutput {
bool renderMultiple () const override;
bool haveImageBuffer () const override;
void* getImageBuffer () const override;
uint32_t getImageBufferSize () const override;
void updateRender () const override;
private:

View File

@ -83,6 +83,10 @@ bool CX11Output::haveImageBuffer () const {
return true;
}
uint32_t CX11Output::getImageBufferSize () const {
return this->m_imageSize;
}
void CX11Output::loadScreenInfo () {
// reset the viewports
this->m_viewports.clear ();
@ -163,6 +167,7 @@ void CX11Output::loadScreenInfo () {
// set the window background as our pixmap
XSetWindowBackgroundPixmap (this->m_display, this->m_root, this->m_pixmap);
// allocate space for the image's data
this->m_imageSize = this->m_fullWidth * this->m_fullHeight * 4;
this->m_imageData = new char [this->m_fullWidth * this->m_fullHeight * 4];
// create an image so we can copy it over
this->m_image = XCreateImage (this->m_display, CopyFromParent, 24, ZPixmap, 0, this->m_imageData, this->m_fullWidth,

View File

@ -21,6 +21,7 @@ class CX11Output final : public COutput {
bool renderMultiple () const override;
bool haveImageBuffer () const override;
void* getImageBuffer () const override;
uint32_t getImageBufferSize () const override;
void updateRender () const override;
private:
@ -32,6 +33,7 @@ class CX11Output final : public COutput {
Window m_root;
GC m_gc;
char* m_imageData;
uint32_t m_imageSize;
XImage* m_image;
std::vector<COutputViewport*> m_screens;
};