diff --git a/src/gl/shaders/gl_postprocessshader.cpp b/src/gl/shaders/gl_postprocessshader.cpp index e57196462..0e87275e0 100644 --- a/src/gl/shaders/gl_postprocessshader.cpp +++ b/src/gl/shaders/gl_postprocessshader.cpp @@ -226,16 +226,15 @@ void PostProcessShaderInstance::BindTextures() if (it == mTextureHandles.end()) { // Why does this completely circumvent the normal way of handling textures? - int width, height; - auto buffer = tex->CreateTexBuffer(0, width, height); + // This absolutely needs fixing because it will also circumvent any potential caching system that may get implemented. + auto buffer = tex->CreateTexBuffer(0); GLuint handle = 0; glGenTextures(1, &handle); glBindTexture(GL_TEXTURE_2D, handle); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, buffer); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, buffer.mWidth, buffer.mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, buffer.mBuffer); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - delete[] buffer; mTextureHandles[tex] = handle; } else diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index 7018e61c9..7f4093af8 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -100,7 +100,7 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int bool firstCall = glTex->glTexID == 0; if (firstCall) glGenTextures(1,&glTex->glTexID); - unsigned textureBinding = UINT_MAX; + int textureBinding = UINT_MAX; if (texunit == -1) glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding); if (texunit > 0) glActiveTexture(GL_TEXTURE0+texunit); if (texunit >= 0) lastbound[texunit] = glTex->glTexID; @@ -448,24 +448,25 @@ bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, i int w = 0, h = 0; // Create this texture - unsigned char * buffer = nullptr; + + FTextureBuffer texbuffer; if (!tex->isHardwareCanvas()) { - buffer = tex->CreateTexBuffer(translation, w, h, flags | CTF_ProcessData); + texbuffer = tex->CreateTexBuffer(translation, flags | CTF_ProcessData); + w = texbuffer.mWidth; + h = texbuffer.mHeight; } else { w = tex->GetWidth(); h = tex->GetHeight(); } - if (!CreateTexture(buffer, w, h, texunit, needmipmap, translation, "FHardwareTexture.BindOrCreate")) + if (!CreateTexture(texbuffer.mBuffer, w, h, texunit, needmipmap, translation, "FHardwareTexture.BindOrCreate")) { // could not create texture - delete[] buffer; return false; } - delete[] buffer; } if (tex->isHardwareCanvas()) static_cast(tex)->NeedUpdate(); GLRenderer->mSamplerManager->Bind(texunit, clampmode, 255); diff --git a/src/hwrenderer/textures/hw_material.cpp b/src/hwrenderer/textures/hw_material.cpp index 0ee2f3bb9..30d22a7ec 100644 --- a/src/hwrenderer/textures/hw_material.cpp +++ b/src/hwrenderer/textures/hw_material.cpp @@ -341,19 +341,19 @@ void FMaterial::SetSpriteRect() bool FMaterial::TrimBorders(uint16_t *rect) { - int w; - int h; - unsigned char *buffer = sourcetex->CreateTexBuffer(0, w, h); + auto texbuffer = sourcetex->CreateTexBuffer(0); + int w = texbuffer.mWidth; + int h = texbuffer.mHeight; + auto Buffer = texbuffer.mBuffer; - if (buffer == NULL) + if (texbuffer.mBuffer == nullptr) { return false; } if (w != mWidth || h != mHeight) { // external Hires replacements cannot be trimmed. - delete [] buffer; return false; } @@ -365,14 +365,13 @@ bool FMaterial::TrimBorders(uint16_t *rect) rect[1] = 0; rect[2] = 1; rect[3] = 1; - delete[] buffer; return true; } int first, last; for(first = 0; first < size; first++) { - if (buffer[first*4+3] != 0) break; + if (Buffer[first*4+3] != 0) break; } if (first >= size) { @@ -381,13 +380,12 @@ bool FMaterial::TrimBorders(uint16_t *rect) rect[1] = 0; rect[2] = 1; rect[3] = 1; - delete [] buffer; return true; } for(last = size-1; last >= first; last--) { - if (buffer[last*4+3] != 0) break; + if (Buffer[last*4+3] != 0) break; } rect[1] = first / w; @@ -396,7 +394,7 @@ bool FMaterial::TrimBorders(uint16_t *rect) rect[0] = 0; rect[2] = w; - unsigned char *bufferoff = buffer + (rect[1] * w * 4); + unsigned char *bufferoff = Buffer + (rect[1] * w * 4); h = rect[3]; for(int x = 0; x < w; x++) @@ -416,13 +414,11 @@ outl: { if (bufferoff[(x+y*w)*4+3] != 0) { - delete [] buffer; return true; } } rect[2]--; } - delete [] buffer; return true; } diff --git a/src/posix/cocoa/i_video.mm b/src/posix/cocoa/i_video.mm index d10c590b2..f5fd5b00b 100644 --- a/src/posix/cocoa/i_video.mm +++ b/src/posix/cocoa/i_video.mm @@ -656,12 +656,11 @@ bool I_SetCursor(FTexture *cursorpic) { // Create bitmap image representation - int w, h; - auto sbuffer = cursorpic->CreateTexBuffer(0, w, h); + auto sbuffer = cursorpic->CreateTexBuffer(0); - const NSInteger imageWidth = w; - const NSInteger imageHeight = h; - const NSInteger imagePitch = w * 4; + const NSInteger imageWidth = sbuffer.mWidth; + const NSInteger imageHeight = sbuffer.mHeight; + const NSInteger imagePitch = sbuffer.mWidth * 4; NSBitmapImageRep* bitmapImageRep = [NSBitmapImageRep alloc]; [bitmapImageRep initWithBitmapDataPlanes:NULL @@ -678,8 +677,7 @@ bool I_SetCursor(FTexture *cursorpic) // Load bitmap data to representation uint8_t* buffer = [bitmapImageRep bitmapData]; - memcpy(buffer, sbuffer, imagePitch * imageHeight); - delete [] sbuffer; + memcpy(buffer, sbuffer.mBuffer, imagePitch * imageHeight); // Swap red and blue components in each pixel diff --git a/src/textures/hires/hirestex.cpp b/src/textures/hires/hirestex.cpp index 824e61d5e..1e05d22bd 100644 --- a/src/textures/hires/hirestex.cpp +++ b/src/textures/hires/hirestex.cpp @@ -397,7 +397,7 @@ bool FTexture::LoadHiresTexture(FTextureBuffer &texbuffer) if (dwdata[i] == 0xffffff00 || dwdata[i] == 0xffff00ff) dwdata[i] = 0; } } - FContentId contentId; + FContentIdBuilder contentId; contentId.id = 0; contentId.imageID = HiresTexture->GetImage()->GetId(); texbuffer.mBuffer = buffer; diff --git a/src/textures/hires/hqresize.cpp b/src/textures/hires/hqresize.cpp index 31bcbfa15..b9da15ad4 100644 --- a/src/textures/hires/hqresize.cpp +++ b/src/textures/hires/hqresize.cpp @@ -348,23 +348,23 @@ static void xbrzOldScale(size_t factor, const uint32_t* src, uint32_t* trg, int //=========================================================================== // -// [BB] Upsamples the texture in inputBuffer, frees inputBuffer and returns +// [BB] Upsamples the texture in texbuffer.mBuffer, frees texbuffer.mBuffer and returns // the upsampled buffer. // //=========================================================================== void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasAlpha) { - // [BB] Make sure that outWidth and outHeight denote the size of + // [BB] Make sure that inWidth and inHeight denote the size of // the returned buffer even if we don't upsample the input buffer. - int outWidth = texbuffer.mWidth; - int outHeight = texbuffer.mHeight; + int inWidth = texbuffer.mWidth; + int inHeight = texbuffer.mHeight; // [BB] Don't resample if the width or height of the input texture is bigger than gl_texture_hqresize_maxinputsize. - if ( ( outWidth > gl_texture_hqresize_maxinputsize ) || ( outHeight > gl_texture_hqresize_maxinputsize ) ) + if ((inWidth > gl_texture_hqresize_maxinputsize) || (inHeight > gl_texture_hqresize_maxinputsize)) return; // [BB] Don't try to upsample textures based off FCanvasTexture. (This should never get here in the first place!) - if ( bHasCanvas ) + if (bHasCanvas) return; // already scaled? @@ -401,47 +401,53 @@ void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasA if (mult < 2) type = 0; - switch (type) + + if (type == 1) { - case 1: - switch(mult) - { - case 2: - return scaleNxHelper( &scale2x, 2, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - case 3: - return scaleNxHelper( &scale3x, 3, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - default: - return scaleNxHelper( &scale4x, 4, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - } - case 2: - switch(mult) - { - case 2: - return hqNxHelper( &hq2x_32, 2, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - case 3: - return hqNxHelper( &hq3x_32, 3, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - default: - return hqNxHelper( &hq4x_32, 4, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - } -#ifdef HAVE_MMX - case 3: - switch(mult) - { - case 2: - return hqNxAsmHelper( &HQnX_asm::hq2x_32, 2, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - case 3: - return hqNxAsmHelper( &HQnX_asm::hq3x_32, 3, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - default: - return hqNxAsmHelper( &HQnX_asm::hq4x_32, 4, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - } -#endif - case 4: - return xbrzHelper(xbrz::scale, mult, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - case 5: - return xbrzHelper(xbrzOldScale, mult, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - case 6: - return normalNxHelper( &normalNx, mult, inputBuffer, inWidth, inHeight, outWidth, outHeight ); + if (mult == 2) + texbuffer.mBuffer = scaleNxHelper(&scale2x, 2, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else if (mult == 3) + texbuffer.mBuffer = scaleNxHelper(&scale3x, 3, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else if (mult == 4) + texbuffer.mBuffer = scaleNxHelper(&scale4x, 4, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else return; } + else if (type == 2) + { + if (mult == 2) + texbuffer.mBuffer = hqNxHelper(&hq2x_32, 2, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else if (mult == 3) + texbuffer.mBuffer = hqNxHelper(&hq3x_32, 3, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else if (mult == 4) + texbuffer.mBuffer = hqNxHelper(&hq4x_32, 4, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else return; + } +#ifdef HAVE_MMX + else if (type == 3) + { + if (mult == 2) + texbuffer.mBuffer = hqNxAsmHelper(&HQnX_asm::hq2x_32, 2, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else if (mult == 3) + texbuffer.mBuffer = hqNxAsmHelper(&HQnX_asm::hq3x_32, 3, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else if (mult == 4) + texbuffer.mBuffer = hqNxAsmHelper(&HQnX_asm::hq4x_32, 4, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else return; + } +#endif + else if (type == 4) + texbuffer.mBuffer = xbrzHelper(xbrz::scale, mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else if (type == 5) + texbuffer.mBuffer = xbrzHelper(xbrzOldScale, mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else if (type == 6) + texbuffer.mBuffer = normalNxHelper(&normalNx, mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else + return; + + // Encode the scaling method in the content ID. + FContentIdBuilder contentId; + contentId.id = texbuffer.mContentId; + contentId.scaler = type; + contentId.scalefactor = mult; + texbuffer.mContentId = contentId.id; } - return inputBuffer; } diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 538ece45c..eb8f48f96 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -671,7 +671,8 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags) if (flags & CTF_CheckHires) { - if (LoadHiresTexture(result)) return result; + // No image means that this cannot be checked, + if (GetImage() && LoadHiresTexture(result)) return result; } int exx = !!(flags & CTF_Expand); @@ -699,18 +700,23 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags) // A translated image is not conclusive for setting the texture's transparency info. } - FContentId builder; - builder.id = 0; - builder.imageID = GetImage()->GetId(); - builder.translation = MAX(0, translation); - builder.expand = exx; + if (GetImage()) + { + FContentIdBuilder builder; + builder.id = 0; + builder.imageID = GetImage()->GetId(); + builder.translation = MAX(0, translation); + builder.expand = exx; + result.mContentId = builder.id; + } + else result.mContentId = 0; // for non-image backed textures this has no meaning so leave it at 0. result.mBuffer = buffer; result.mWidth = W; result.mHeight = H; - result.mContentId = builder.id; - if (flags & CTF_ProcessData) + // Only do postprocessing for image-backed textures. (i.e. not for the burn texture which can also pass through here.) + if (GetImage() && flags & CTF_ProcessData) { CreateUpsampledTextureBuffer(result, !!isTransparent); ProcessData(result.mBuffer, result.mWidth, result.mHeight, false); @@ -731,9 +737,8 @@ bool FTexture::GetTranslucency() { if (!bHasCanvas) { - int w, h; - unsigned char *buffer = CreateTexBuffer(0, w, h); - delete[] buffer; + // This will calculate all we need, so just discard the result. + CreateTexBuffer(0); } else { diff --git a/src/textures/textures.h b/src/textures/textures.h index 47e4da28f..b96fc5b07 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -42,7 +42,6 @@ #include "colormatcher.h" #include "r_data/renderstyle.h" #include "r_data/r_translate.h" -#include "hwrenderer/textures/hw_texmanager.h" #include // 15 because 0th texture is our texture @@ -226,7 +225,7 @@ namespace OpenGLRenderer class FHardwareTexture; } -union FContentId +union FContentIdBuilder { uint64_t id; struct