Skip to content

Commit dd23925

Browse files
committed
[Fix] (texture): Fix several state leakage and nullptr errors.
1 parent 5ef1270 commit dd23925

2 files changed

Lines changed: 165 additions & 177 deletions

File tree

src/main/cpp/gl/texture.cpp

Lines changed: 91 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,9 @@
1616

1717
#include "../gles/gles.h"
1818
#include "../gles/loader.h"
19-
#include "../includes.h"
20-
#include "FSR1/FSR1.h"
2119
#include "framebuffer.h"
22-
#include "glsl/glsl_for_es.h"
2320
#include "log.h"
2421
#include "mg.h"
25-
#include "pixel.h"
2622
#include <GL/gl.h>
2723
#include <ankerl/unordered_dense.h>
2824

@@ -148,7 +144,7 @@ TextureTarget ConvertGLEnumToTextureTarget(GLenum target) {
148144
case GL_TEXTURE_BUFFER:
149145
return TextureTarget::TEXTURE_BUFFER;
150146
default:
151-
return TextureTarget::TEXTURE_2D;
147+
return TextureTarget::UNKNWON;
152148
}
153149
}
154150

@@ -490,6 +486,17 @@ void glTexParameterf(GLenum target, GLenum pname, GLfloat param) {
490486
CHECK_GL_ERROR
491487
}
492488

489+
#define GET_TEXTURE_OBJECT(target) \
490+
unsigned __currentUnitIndex = GetCurrentTextureUnitIndex(); \
491+
auto& __currentUnit = GetTextureUnit(__currentUnitIndex); \
492+
auto targetR = ConvertGLEnumToTextureTarget(target); \
493+
if (targetR == TextureTarget::UNKNWON) { \
494+
LOG_E("%s: Unknown texture target: %s", __func__, glEnumToString(target)) \
495+
return; \
496+
} \
497+
auto& __bindingSlot = __currentUnit.GetBindingSlot(targetR); \
498+
auto tex = __bindingSlot.GetBoundObject()
499+
493500
void glTexImage1D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLint border, GLenum format,
494501
GLenum type, const GLvoid* pixels) {
495502
LOG()
@@ -508,8 +515,7 @@ void glTexImage1D(GLenum target, GLint level, GLint internalFormat, GLsizei widt
508515
return;
509516
}
510517

511-
int currentUnitIndex = GetCurrentTextureUnitIndex();
512-
auto tex = GetTextureUnit(currentUnitIndex).GetBindingSlot(ConvertGLEnumToTextureTarget(target)).GetBoundObject();
518+
GET_TEXTURE_OBJECT(target);
513519
tex->target = ConvertGLEnumToTextureTarget(target);
514520
tex->depth = 1;
515521
tex->format = format;
@@ -549,9 +555,7 @@ void glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei widt
549555
return;
550556
}
551557

552-
auto tex = GetTextureUnit(GetCurrentTextureUnitIndex())
553-
.GetBindingSlot(ConvertGLEnumToTextureTarget(target))
554-
.GetBoundObject();
558+
GET_TEXTURE_OBJECT(target);
555559
tex->target = ConvertGLEnumToTextureTarget(target);
556560
tex->internal_format = internalFormat;
557561
tex->width = width;
@@ -618,9 +622,7 @@ void glTexImage3D(GLenum target, GLint level, GLint internalFormat, GLsizei widt
618622

619623
GLES.glTexImage3D(target, level, internalFormat, width, height, depth, border, format, type, pixels);
620624

621-
auto tex = GetTextureUnit(GetCurrentTextureUnitIndex())
622-
.GetBindingSlot(ConvertGLEnumToTextureTarget(target))
623-
.GetBoundObject();
625+
GET_TEXTURE_OBJECT(target);
624626
tex->target = ConvertGLEnumToTextureTarget(target);
625627
tex->internal_format = internalFormat;
626628
tex->width = width;
@@ -641,9 +643,7 @@ void glTexStorage1D(GLenum target, GLsizei levels, GLenum internalFormat, GLsize
641643
width)
642644
internal_convert(&internalFormat, nullptr, nullptr);
643645

644-
auto tex = GetTextureUnit(GetCurrentTextureUnitIndex())
645-
.GetBindingSlot(ConvertGLEnumToTextureTarget(target))
646-
.GetBoundObject();
646+
GET_TEXTURE_OBJECT(target);
647647
tex->target = ConvertGLEnumToTextureTarget(target);
648648
tex->internal_format = internalFormat;
649649
tex->width = width;
@@ -666,9 +666,7 @@ void glTexStorage2D(GLenum target, GLsizei levels, GLenum internalFormat, GLsize
666666
internal_convert(&internalFormat, nullptr, nullptr);
667667
GLES.glTexStorage2D(target, levels, internalFormat, width, height);
668668

669-
auto tex = GetTextureUnit(GetCurrentTextureUnitIndex())
670-
.GetBindingSlot(ConvertGLEnumToTextureTarget(target))
671-
.GetBoundObject();
669+
GET_TEXTURE_OBJECT(target);
672670
tex->target = ConvertGLEnumToTextureTarget(target);
673671
tex->internal_format = internalFormat;
674672
tex->width = width;
@@ -694,9 +692,7 @@ void glTexStorage3D(GLenum target, GLsizei levels, GLenum internalFormat, GLsize
694692

695693
GLES.glTexStorage3D(target, levels, internalFormat, width, height, depth);
696694

697-
auto tex = GetTextureUnit(GetCurrentTextureUnitIndex())
698-
.GetBindingSlot(ConvertGLEnumToTextureTarget(target))
699-
.GetBoundObject();
695+
GET_TEXTURE_OBJECT(target);
700696
tex->target = ConvertGLEnumToTextureTarget(target);
701697
tex->internal_format = internalFormat;
702698
tex->width = width;
@@ -718,9 +714,7 @@ void glCopyTexImage1D(GLenum target, GLint level, GLenum internalFormat, GLint x
718714
"y: %d, width: %d, border: %d",
719715
target, level, internalFormat, x, y, width, border)
720716

721-
auto tex = GetTextureUnit(GetCurrentTextureUnitIndex())
722-
.GetBindingSlot(ConvertGLEnumToTextureTarget(target))
723-
.GetBoundObject();
717+
GET_TEXTURE_OBJECT(target);
724718
tex->target = ConvertGLEnumToTextureTarget(target);
725719
tex->internal_format = internalFormat;
726720
tex->width = width;
@@ -818,9 +812,7 @@ void glCopyTexImage2D(GLenum target, GLint level, GLenum internalFormat, GLint x
818812
CHECK_GL_ERROR_NO_INIT
819813
}
820814

821-
auto tex = GetTextureUnit(GetCurrentTextureUnitIndex())
822-
.GetBindingSlot(ConvertGLEnumToTextureTarget(target))
823-
.GetBoundObject();
815+
GET_TEXTURE_OBJECT(target);
824816
tex->target = ConvertGLEnumToTextureTarget(target);
825817
tex->internal_format = internalFormat;
826818
tex->width = width;
@@ -907,20 +899,22 @@ void glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum int
907899
void glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat* params) {
908900
LOG()
909901
LOG_D("glGetTexLevelParameterfv,target: %d, level: %d, pname: %d", target, level, pname)
910-
GLenum rtarget = map_tex_target(target);
911-
if (rtarget == GL_PROXY_TEXTURE_2D) {
912-
switch (pname) {
913-
case GL_TEXTURE_WIDTH:
914-
(*params) = (float)nlevel(gl_state->proxy_width, level);
915-
return;
916-
case GL_TEXTURE_HEIGHT:
917-
(*params) = (float)nlevel(gl_state->proxy_height, level);
918-
return;
919-
case GL_TEXTURE_INTERNAL_FORMAT:
920-
(*params) = (float)gl_state->proxy_intformat;
921-
return;
922-
default:
923-
return;
902+
if (gl_state) {
903+
GLenum rtarget = map_tex_target(target);
904+
if (rtarget == GL_PROXY_TEXTURE_2D) {
905+
switch (pname) {
906+
case GL_TEXTURE_WIDTH:
907+
(*params) = (float)nlevel(gl_state->proxy_width, level);
908+
return;
909+
case GL_TEXTURE_HEIGHT:
910+
(*params) = (float)nlevel(gl_state->proxy_height, level);
911+
return;
912+
case GL_TEXTURE_INTERNAL_FORMAT:
913+
(*params) = (float)gl_state->proxy_intformat;
914+
return;
915+
default:
916+
return;
917+
}
924918
}
925919
}
926920
GLES.glGetTexLevelParameterfv(target, level, pname, params);
@@ -931,20 +925,22 @@ void glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* p
931925
LOG()
932926
LOG_D("glGetTexLevelParameteriv,target: %s, level: %d, pname: %s", glEnumToString(target), level,
933927
glEnumToString(pname))
934-
GLenum rtarget = map_tex_target(target);
935-
if (rtarget == GL_PROXY_TEXTURE_2D) {
936-
switch (pname) {
937-
case GL_TEXTURE_WIDTH:
938-
(*params) = nlevel(gl_state->proxy_width, level);
939-
return;
940-
case GL_TEXTURE_HEIGHT:
941-
(*params) = nlevel(gl_state->proxy_height, level);
942-
return;
943-
case GL_TEXTURE_INTERNAL_FORMAT:
944-
(*params) = (GLint)gl_state->proxy_intformat;
945-
return;
946-
default:
947-
return;
928+
if (gl_state) {
929+
GLenum rtarget = map_tex_target(target);
930+
if (rtarget == GL_PROXY_TEXTURE_2D) {
931+
switch (pname) {
932+
case GL_TEXTURE_WIDTH:
933+
(*params) = nlevel(gl_state->proxy_width, level);
934+
return;
935+
case GL_TEXTURE_HEIGHT:
936+
(*params) = nlevel(gl_state->proxy_height, level);
937+
return;
938+
case GL_TEXTURE_INTERNAL_FORMAT:
939+
(*params) = (GLint)gl_state->proxy_intformat;
940+
return;
941+
default:
942+
return;
943+
}
948944
}
949945
}
950946
LOG_D("es.glGetTexLevelParameteriv,target: %s, level: %d, pname: %s", glEnumToString(target), level,
@@ -954,8 +950,8 @@ void glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* p
954950
}
955951

956952
void glTexParameteriv(GLenum target, GLenum pname, const GLint* params) {
957-
LOG_D("glTexParameteriv, target: %s, pname: %s, params[0]: %s", params, glEnumToString(pname),
958-
params ? glEnumToString(params[0]) : "0")
953+
LOG()
954+
LOG_D("glTexParameteriv, target: %s, pname: %s", glEnumToString(target), glEnumToString(pname))
959955

960956
if (pname == GL_TEXTURE_SWIZZLE_RGBA) {
961957
LOG_D("find GL_TEXTURE_SWIZZLE_RGBA, now use glTexParameteri")
@@ -967,9 +963,7 @@ void glTexParameteriv(GLenum target, GLenum pname, const GLint* params) {
967963
GLES.glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, params[3]);
968964

969965
// save states for now
970-
auto tex = GetTextureUnit(GetCurrentTextureUnitIndex())
971-
.GetBindingSlot(ConvertGLEnumToTextureTarget(target))
972-
.GetBoundObject();
966+
GET_TEXTURE_OBJECT(target);
973967
tex->swizzle_param[0] = params[0];
974968
tex->swizzle_param[1] = params[1];
975969
tex->swizzle_param[2] = params[2];
@@ -1007,7 +1001,8 @@ void glBindTexture(GLenum target, GLuint texture) {
10071001
LOG()
10081002
LOG_D("glBindTexture(%s, %d)", glEnumToString(target), texture)
10091003
INIT_CHECK_GL_ERROR
1010-
if (hardware->emulate_texture_buffer && target == GL_TEXTURE_BUFFER) {
1004+
1005+
if (hardware && gl_state && hardware->emulate_texture_buffer && target == GL_TEXTURE_BUFFER) {
10111006
GLES.glActiveTexture(GL_TEXTURE0 + 15);
10121007
GLES.glBindTexture(GL_TEXTURE_2D, texture);
10131008
GLES.glActiveTexture(GL_TEXTURE0 + gl_state->current_tex_unit);
@@ -1018,9 +1013,19 @@ void glBindTexture(GLenum target, GLuint texture) {
10181013

10191014
int currentUnitIndex = GetCurrentTextureUnitIndex();
10201015
auto& currentUnit = GetTextureUnit(currentUnitIndex);
1021-
auto& bindingSlot = currentUnit.GetBindingSlot(ConvertGLEnumToTextureTarget(target));
1016+
auto targetR = ConvertGLEnumToTextureTarget(target);
1017+
if (targetR == TextureTarget::UNKNWON) {
1018+
LOG_E("glBindTexture: Unknown texture target: %s", glEnumToString(target));
1019+
return;
1020+
}
1021+
auto& bindingSlot = currentUnit.GetBindingSlot(targetR);
10221022
auto textureObject = GetOrCreateTextureObject(texture);
1023+
if (!textureObject) {
1024+
LOG_W("glBindTexture: Failed to get or create texture object for ID %d, it may be not tracked", texture);
1025+
return;
1026+
}
10231027
bindingSlot.Bind(textureObject);
1028+
textureObject->target = targetR;
10241029
}
10251030

10261031
void glDeleteTextures(GLsizei n, const GLuint* textures) {
@@ -1037,7 +1042,7 @@ void glDeleteTextures(GLsizei n, const GLuint* textures) {
10371042
void glActiveTexture(GLenum texture) {
10381043
LOG()
10391044
LOG_D("glActiveTexture, texture = %s", glEnumToString(texture))
1040-
if (texture < GL_TEXTURE0) {
1045+
if (texture < GL_TEXTURE0 || texture >= GL_TEXTURE0 + MAX_TEXTURE_IMAGE_UNITS) {
10411046
LOG_E("Invalid texture enum: %s", glEnumToString(texture))
10421047
return;
10431048
}
@@ -1049,8 +1054,11 @@ void glActiveTexture(GLenum texture) {
10491054
}
10501055

10511056
void glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, void* pixels) {
1052-
GLint prevFBO;
1053-
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &prevFBO);
1057+
LOG()
1058+
LOG_D("glGetTexImage, target: 0x%x, level: %d, format: 0x%x, type: 0x%x, pixels: 0x%x", target, level, format, type,
1059+
pixels)
1060+
GLint prevDrawFBO;
1061+
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &prevDrawFBO);
10541062
GLint prevReadFBO;
10551063
glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &prevReadFBO);
10561064

@@ -1066,15 +1074,17 @@ void glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, void*
10661074
textureBindingTarget = GL_TEXTURE_BINDING_2D;
10671075
} else {
10681076
LOG_E("glGetTexImage: Unsupported or complex target: 0x%x", target)
1069-
glBindFramebuffer(GL_FRAMEBUFFER, prevFBO);
1077+
glBindFramebuffer(GL_READ_FRAMEBUFFER, prevReadFBO);
1078+
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevDrawFBO);
10701079
glDeleteFramebuffers(1, &tempFBO);
10711080
return;
10721081
}
10731082
glGetIntegerv(textureBindingTarget, &textureId);
10741083

10751084
if (textureId == 0) {
10761085
LOG_E("glGetTexImage: No texture bound to the specified target.")
1077-
glBindFramebuffer(GL_FRAMEBUFFER, prevFBO);
1086+
glBindFramebuffer(GL_READ_FRAMEBUFFER, prevReadFBO);
1087+
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevDrawFBO);
10781088
glDeleteFramebuffers(1, &tempFBO);
10791089
return;
10801090
}
@@ -1085,7 +1095,8 @@ void glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, void*
10851095

10861096
if (width == 0 || height == 0) {
10871097
LOG_E("glGetTexImage: Texture level %d has zero width or height.", level)
1088-
glBindFramebuffer(GL_FRAMEBUFFER, prevFBO);
1098+
glBindFramebuffer(GL_READ_FRAMEBUFFER, prevReadFBO);
1099+
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevDrawFBO);
10891100
glDeleteFramebuffers(1, &tempFBO);
10901101
return;
10911102
}
@@ -1099,7 +1110,8 @@ void glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, void*
10991110
GLenum fboStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
11001111
if (fboStatus != GL_FRAMEBUFFER_COMPLETE) {
11011112
LOG_E("glGetTexImage: Failed to create complete framebuffer. Status: 0x%x", fboStatus)
1102-
glBindFramebuffer(GL_FRAMEBUFFER, prevFBO);
1113+
glBindFramebuffer(GL_READ_FRAMEBUFFER, prevReadFBO);
1114+
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevDrawFBO);
11031115
glDeleteFramebuffers(1, &tempFBO);
11041116
return;
11051117
}
@@ -1108,7 +1120,8 @@ void glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, void*
11081120

11091121
glReadPixels(0, 0, width, height, format, type, pixels);
11101122

1111-
glBindFramebuffer(GL_FRAMEBUFFER, prevFBO);
1123+
glBindFramebuffer(GL_READ_FRAMEBUFFER, prevReadFBO);
1124+
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevDrawFBO);
11121125
glDeleteFramebuffers(1, &tempFBO);
11131126
}
11141127

@@ -1168,7 +1181,9 @@ void glClearTexImage(GLuint texture, GLint level, GLenum format, GLenum type, co
11681181
LOG()
11691182
LOG_D("glClearTexImage, texture: %d, level: %d, format: %d, type: %d", texture, level, format, type)
11701183
INIT_CHECK_GL_ERROR_FORCE
1171-
GLuint fbo;
1184+
GLuint fbo, prevDrawFBO, prevReadFBO;
1185+
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (int*)&prevDrawFBO);
1186+
glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, (int*)&prevReadFBO);
11721187
glGenFramebuffers(1, &fbo);
11731188
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
11741189
CHECK_GL_ERROR_NO_INIT
@@ -1178,7 +1193,8 @@ void glClearTexImage(GLuint texture, GLint level, GLenum format, GLenum type, co
11781193
CHECK_GL_ERROR_NO_INIT
11791194
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
11801195
LOG_D(" -> exit")
1181-
glBindFramebuffer(GL_FRAMEBUFFER, 0);
1196+
glBindFramebuffer(GL_READ_FRAMEBUFFER, prevReadFBO);
1197+
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevDrawFBO);
11821198
glDeleteFramebuffers(1, &fbo);
11831199
CHECK_GL_ERROR_NO_INIT
11841200
return;
@@ -1221,8 +1237,8 @@ void glClearTexImage(GLuint texture, GLint level, GLenum format, GLenum type, co
12211237
GLES.glClear(GL_COLOR_BUFFER_BIT);
12221238
CHECK_GL_ERROR_NO_INIT
12231239
}
1224-
1225-
glBindFramebuffer(GL_FRAMEBUFFER, 0);
1240+
glBindFramebuffer(GL_READ_FRAMEBUFFER, prevReadFBO);
1241+
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevDrawFBO);
12261242
glDeleteFramebuffers(1, &fbo);
12271243
CHECK_GL_ERROR_NO_INIT
12281244
}

0 commit comments

Comments
 (0)