From 8f54de99e026ed4a3b84f3aaf3d5a8cf323ffa97 Mon Sep 17 00:00:00 2001 From: Emile Belanger Date: Sat, 25 Sep 2021 14:31:25 +0100 Subject: [PATCH] GLES: Fix texture MapBuffer and AllocateBuffer create client side memory. --- src/common/rendering/gles/gles_hwtexture.cpp | 48 ++++++++++++++++---- src/common/rendering/gles/gles_hwtexture.h | 8 +++- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/src/common/rendering/gles/gles_hwtexture.cpp b/src/common/rendering/gles/gles_hwtexture.cpp index 5ce937b10d..00370481b6 100644 --- a/src/common/rendering/gles/gles_hwtexture.cpp +++ b/src/common/rendering/gles/gles_hwtexture.cpp @@ -81,12 +81,11 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int int texformat = GL_RGBA;// TexFormat[gl_texture_format]; bool deletebuffer=false; - /* - if (forcenocompression) - { - texformat = GL_RGBA8; - } - */ + // When running in SW mode buffer will be null, so set it to the texBuffer already created + // There could be other use cases I do not know about which means this is a bad idea.. + if (buffer == nullptr) + buffer = texBuffer; + bool firstCall = glTexID == 0; if (firstCall) { @@ -136,9 +135,19 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int sourcetype = GL_BGRA; texformat = GL_BGRA; #else - sourcetype = GL_BGRA; - texformat = GL_RGBA; + if (glTextureBytes == 1) + { + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + sourcetype = GL_RED; + texformat = GL_R8; + } + else + { + sourcetype = GL_BGRA; + texformat = GL_RGBA; + } #endif + glTexImage2D(GL_TEXTURE_2D, 0, texformat, rw, rh, 0, sourcetype, GL_UNSIGNED_BYTE, buffer); if (deletebuffer && buffer) free(buffer); @@ -155,6 +164,26 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int } +void FHardwareTexture::AllocateBuffer(int w, int h, int texelsize) +{ + int rw = GetTexDimension(w); + int rh = GetTexDimension(h); + + if (texelsize < 1 || texelsize > 4) texelsize = 4; + glTextureBytes = texelsize; + bufferpitch = w; + + if (texBuffer) + delete[] texBuffer; + + texBuffer = new uint8_t[(w * h) * texelsize]; + return; +} + +uint8_t* FHardwareTexture::MapBuffer() +{ + return texBuffer; +} //=========================================================================== // @@ -164,6 +193,9 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int FHardwareTexture::~FHardwareTexture() { if (glTexID != 0) glDeleteTextures(1, &glTexID); + + if (texBuffer) + delete[] texBuffer; } diff --git a/src/common/rendering/gles/gles_hwtexture.h b/src/common/rendering/gles/gles_hwtexture.h index 8ff673de7e..f367c5d3ad 100644 --- a/src/common/rendering/gles/gles_hwtexture.h +++ b/src/common/rendering/gles/gles_hwtexture.h @@ -42,6 +42,8 @@ private: unsigned int glTexID = 0; unsigned int glDepthID = 0; // only used by camera textures + uint8_t* texBuffer; + int glTextureBytes; bool mipmapped = false; @@ -52,6 +54,8 @@ public: { forcenofilter = disablefilter; glTextureBytes = numchannels; + + texBuffer = nullptr; } ~FHardwareTexture(); @@ -64,8 +68,8 @@ public: unsigned int Bind(int texunit, bool needmipmap); bool BindOrCreate(FTexture* tex, int texunit, int clampmode, int translation, int flags); - void AllocateBuffer(int w, int h, int texelsize) {} // Not used - uint8_t* MapBuffer() { return 0; } // Not used + void AllocateBuffer(int w, int h, int texelsize); + uint8_t* MapBuffer(); unsigned int CreateTexture(unsigned char* buffer, int w, int h, int texunit, bool mipmap, const char* name); unsigned int GetTextureHandle()