2
0
Эх сурвалжийг харах

Merge pull request #49791 from madmiraal/fix-android-gles3-crash-3.x

[3.x] Clear glErrors instead of crashing when initializing GLES3
Rémi Verschelde 4 жил өмнө
parent
commit
f447b79bc6

+ 0 - 2
drivers/dummy/rasterizer_dummy.h

@@ -829,8 +829,6 @@ public:
 
 	virtual bool is_low_end() const { return true; }
 
-	virtual const char *gl_check_for_error(bool p_print_error = true) { return nullptr; }
-
 	RasterizerDummy() {}
 	~RasterizerDummy() {}
 };

+ 3 - 0
drivers/gles2/rasterizer_canvas_gles2.cpp

@@ -32,6 +32,7 @@
 
 #include "core/os/os.h"
 #include "core/project_settings.h"
+#include "drivers/gles2/rasterizer_gles2.h"
 #include "drivers/gles_common/rasterizer_asserts.h"
 #include "rasterizer_scene_gles2.h"
 #include "servers/visual/visual_server_raster.h"
@@ -2320,6 +2321,7 @@ void RasterizerCanvasGLES2::gl_disable_scissor() const {
 }
 
 void RasterizerCanvasGLES2::initialize() {
+	RasterizerGLES2::gl_check_errors();
 	RasterizerCanvasBaseGLES2::initialize();
 
 	batch_initialize();
@@ -2359,6 +2361,7 @@ void RasterizerCanvasGLES2::initialize() {
 		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 
 	} // only if there is a vertex buffer (batching is on)
+	RasterizerGLES2::gl_check_errors();
 }
 
 RasterizerCanvasGLES2::RasterizerCanvasGLES2() {

+ 38 - 32
drivers/gles2/rasterizer_gles2.cpp

@@ -475,40 +475,46 @@ void RasterizerGLES2::make_current() {
 void RasterizerGLES2::register_config() {
 }
 
-// returns NULL if no error, or an error string
-const char *RasterizerGLES2::gl_check_for_error(bool p_print_error) {
-	GLenum err = glGetError();
-
-	const char *err_string = nullptr;
-
-	switch (err) {
-		default: {
-			// not recognised
-		} break;
-		case GL_NO_ERROR: {
-		} break;
-		case GL_INVALID_ENUM: {
-			err_string = "GL_INVALID_ENUM";
-		} break;
-		case GL_INVALID_VALUE: {
-			err_string = "GL_INVALID_VALUE";
-		} break;
-		case GL_INVALID_OPERATION: {
-			err_string = "GL_INVALID_OPERATION";
-		} break;
-		case GL_INVALID_FRAMEBUFFER_OPERATION: {
-			err_string = "GL_INVALID_FRAMEBUFFER_OPERATION";
-		} break;
-		case GL_OUT_OF_MEMORY: {
-			err_string = "GL_OUT_OF_MEMORY";
-		} break;
-	}
-
-	if (p_print_error && err_string) {
-		print_line(err_string);
+bool RasterizerGLES2::gl_check_errors() {
+	bool error_found = false;
+	GLenum error = glGetError();
+	while (error != GL_NO_ERROR) {
+		switch (error) {
+#ifdef DEBUG_ENABLED
+			case GL_INVALID_ENUM: {
+				WARN_PRINT("GL_INVALID_ENUM: An unacceptable value is specified for an enumerated argument.");
+			} break;
+			case GL_INVALID_VALUE: {
+				WARN_PRINT("GL_INVALID_VALUE: A numeric argument is out of range.");
+			} break;
+			case GL_INVALID_OPERATION: {
+				WARN_PRINT("GL_INVALID_OPERATION: The specified operation is not allowed in the current state.");
+			} break;
+			case GL_INVALID_FRAMEBUFFER_OPERATION: {
+				WARN_PRINT("GL_INVALID_FRAMEBUFFER_OPERATION: The framebuffer object is not complete.");
+			} break;
+#endif // DEBUG_ENABLED
+			case GL_OUT_OF_MEMORY: {
+				ERR_PRINT("GL_OUT_OF_MEMORY: There is not enough memory left to execute the command. The state of the GL is undefined.");
+			} break;
+			// GL_STACK_UNDERFLOW and GL_STACK_OVERFLOW are undefined in GLES2/gl2.h, which is used when not using GLAD.
+			//case GL_STACK_UNDERFLOW: {
+			//	ERR_PRINT("GL_STACK_UNDERFLOW: An attempt has been made to perform an operation that would cause an internal stack to underflow.");
+			//} break;
+			//case GL_STACK_OVERFLOW: {
+			//	ERR_PRINT("GL_STACK_OVERFLOW: An attempt has been made to perform an operation that would cause an internal stack to overflow.");
+			//} break;
+			default: {
+#ifdef DEBUG_ENABLED
+				ERR_PRINT("Unrecognized GLError");
+#endif // DEBUG_ENABLED
+			} break;
+		}
+		error_found = true;
+		error = glGetError();
 	}
 
-	return err_string;
+	return error_found;
 }
 
 RasterizerGLES2::RasterizerGLES2() {

+ 1 - 1
drivers/gles2/rasterizer_gles2.h

@@ -70,7 +70,7 @@ public:
 
 	virtual bool is_low_end() const { return true; }
 
-	virtual const char *gl_check_for_error(bool p_print_error = true);
+	static bool gl_check_errors();
 
 	RasterizerGLES2();
 	~RasterizerGLES2();

+ 3 - 9
drivers/gles3/rasterizer_canvas_gles3.cpp

@@ -30,6 +30,7 @@
 
 #include "rasterizer_canvas_gles3.h"
 
+#include "drivers/gles3/rasterizer_gles3.h"
 #include "drivers/gles_common/rasterizer_asserts.h"
 #include "servers/visual/visual_server_raster.h"
 
@@ -65,11 +66,6 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons
 	batch_canvas_render_items(p_item_list, p_z, p_modulate, p_light, p_base_transform);
 }
 
-void RasterizerCanvasGLES3::gl_checkerror() {
-	GLenum e = glGetError();
-	CRASH_COND(e != GL_NO_ERROR);
-}
-
 void RasterizerCanvasGLES3::gl_enable_scissor(int p_x, int p_y, int p_width, int p_height) const {
 	glEnable(GL_SCISSOR_TEST);
 	glScissor(p_x, p_y, p_width, p_height);
@@ -2127,8 +2123,6 @@ void RasterizerCanvasGLES3::_batch_render_generic(const Batch &p_batch, Rasteriz
 
 	glBindVertexArray(0);
 
-	//	gl_checkerror();
-
 	switch (tex.tile_mode) {
 		case BatchTex::TILE_NORMAL: {
 			// if the texture is imported as tiled, no need to revert GL state
@@ -2149,7 +2143,7 @@ void RasterizerCanvasGLES3::_batch_render_generic(const Batch &p_batch, Rasteriz
 }
 
 void RasterizerCanvasGLES3::initialize() {
-	gl_checkerror();
+	RasterizerGLES3::gl_check_errors();
 	RasterizerCanvasBaseGLES3::initialize();
 
 	batch_initialize();
@@ -2280,7 +2274,7 @@ void RasterizerCanvasGLES3::initialize() {
 		state.canvas_shader.add_custom_define("#define USE_NINEPATCH_SCALING\n");
 	}
 
-	gl_checkerror();
+	RasterizerGLES3::gl_check_errors();
 }
 
 RasterizerCanvasGLES3::RasterizerCanvasGLES3() {

+ 0 - 2
drivers/gles3/rasterizer_canvas_gles3.h

@@ -70,8 +70,6 @@ private:
 	void gl_enable_scissor(int p_x, int p_y, int p_width, int p_height) const;
 	void gl_disable_scissor() const;
 
-	void gl_checkerror();
-
 public:
 	void initialize();
 	RasterizerCanvasGLES3();

+ 38 - 32
drivers/gles3/rasterizer_gles3.cpp

@@ -399,40 +399,46 @@ void RasterizerGLES3::make_current() {
 void RasterizerGLES3::register_config() {
 }
 
-// returns NULL if no error, or an error string
-const char *RasterizerGLES3::gl_check_for_error(bool p_print_error) {
-	GLenum err = glGetError();
-
-	const char *err_string = nullptr;
-
-	switch (err) {
-		default: {
-			// not recognised
-		} break;
-		case GL_NO_ERROR: {
-		} break;
-		case GL_INVALID_ENUM: {
-			err_string = "GL_INVALID_ENUM";
-		} break;
-		case GL_INVALID_VALUE: {
-			err_string = "GL_INVALID_VALUE";
-		} break;
-		case GL_INVALID_OPERATION: {
-			err_string = "GL_INVALID_OPERATION";
-		} break;
-		case GL_INVALID_FRAMEBUFFER_OPERATION: {
-			err_string = "GL_INVALID_FRAMEBUFFER_OPERATION";
-		} break;
-		case GL_OUT_OF_MEMORY: {
-			err_string = "GL_OUT_OF_MEMORY";
-		} break;
-	}
-
-	if (p_print_error && err_string) {
-		print_line(err_string);
+bool RasterizerGLES3::gl_check_errors() {
+	bool error_found = false;
+	GLenum error = glGetError();
+	while (error != GL_NO_ERROR) {
+		switch (error) {
+#ifdef DEBUG_ENABLED
+			case GL_INVALID_ENUM: {
+				WARN_PRINT("GL_INVALID_ENUM: An unacceptable value is specified for an enumerated argument.");
+			} break;
+			case GL_INVALID_VALUE: {
+				WARN_PRINT("GL_INVALID_VALUE: A numeric argument is out of range.");
+			} break;
+			case GL_INVALID_OPERATION: {
+				WARN_PRINT("GL_INVALID_OPERATION: The specified operation is not allowed in the current state.");
+			} break;
+			case GL_INVALID_FRAMEBUFFER_OPERATION: {
+				WARN_PRINT("GL_INVALID_FRAMEBUFFER_OPERATION: The framebuffer object is not complete.");
+			} break;
+#endif // DEBUG_ENABLED
+			case GL_OUT_OF_MEMORY: {
+				ERR_PRINT("GL_OUT_OF_MEMORY: There is not enough memory left to execute the command. The state of the GL is undefined.");
+			} break;
+			// GL_STACK_UNDERFLOW and GL_STACK_OVERFLOW are undefined in GLES2/gl2.h, which is used when not using GLAD.
+			//case GL_STACK_UNDERFLOW: {
+			//	ERR_PRINT("GL_STACK_UNDERFLOW: An attempt has been made to perform an operation that would cause an internal stack to underflow.");
+			//} break;
+			//case GL_STACK_OVERFLOW: {
+			//	ERR_PRINT("GL_STACK_OVERFLOW: An attempt has been made to perform an operation that would cause an internal stack to overflow.");
+			//} break;
+			default: {
+#ifdef DEBUG_ENABLED
+				ERR_PRINT("Unrecognized GLError");
+#endif // DEBUG_ENABLED
+			} break;
+		}
+		error_found = true;
+		error = glGetError();
 	}
 
-	return err_string;
+	return error_found;
 }
 
 RasterizerGLES3::RasterizerGLES3() {

+ 1 - 1
drivers/gles3/rasterizer_gles3.h

@@ -70,7 +70,7 @@ public:
 
 	virtual bool is_low_end() const { return false; }
 
-	virtual const char *gl_check_for_error(bool p_print_error = true);
+	static bool gl_check_errors();
 
 	RasterizerGLES3();
 	~RasterizerGLES3();

+ 0 - 2
servers/visual/rasterizer.h

@@ -1157,8 +1157,6 @@ public:
 
 	virtual bool is_low_end() const = 0;
 
-	virtual const char *gl_check_for_error(bool p_print_error = true) = 0;
-
 	virtual ~Rasterizer() {}
 };