diff options
-rw-r--r-- | Userland/Libraries/LibGL/SoftwareGLContext.cpp | 559 |
1 files changed, 176 insertions, 383 deletions
diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.cpp b/Userland/Libraries/LibGL/SoftwareGLContext.cpp index 198699a473..317cc70c58 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.cpp +++ b/Userland/Libraries/LibGL/SoftwareGLContext.cpp @@ -34,6 +34,18 @@ static constexpr size_t MATRIX_STACK_LIMIT = 1024; return; \ } +#define RETURN_WITH_ERROR_IF(condition, error) \ + if (condition) { \ + m_error = error; \ + return; \ + } + +#define RETURN_VALUE_WITH_ERROR_IF(condition, error, return_value) \ + if (condition) { \ + m_error = error; \ + return return_value; \ + } + SoftwareGLContext::SoftwareGLContext(Gfx::Bitmap& frontbuffer) : m_frontbuffer(frontbuffer) , m_rasterizer(frontbuffer.size()) @@ -44,15 +56,8 @@ void SoftwareGLContext::gl_begin(GLenum mode) { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_begin, mode); - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } - - if (mode < GL_TRIANGLES || mode > GL_POLYGON) { - m_error = GL_INVALID_ENUM; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); + RETURN_WITH_ERROR_IF(mode < GL_TRIANGLES || mode > GL_POLYGON, GL_INVALID_ENUM); m_current_draw_mode = mode; m_in_draw_state = true; // Certain commands will now generate an error @@ -63,15 +68,8 @@ void SoftwareGLContext::gl_clear(GLbitfield mask) { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_clear, mask); - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } - - if (mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) { - m_error = GL_INVALID_ENUM; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); + RETURN_WITH_ERROR_IF(mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT), GL_INVALID_ENUM); if (mask & GL_COLOR_BUFFER_BIT) m_rasterizer.clear_color(m_clear_color); @@ -86,10 +84,7 @@ void SoftwareGLContext::gl_clear_color(GLclampf red, GLclampf green, GLclampf bl { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_clear_color, red, green, blue, alpha); - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); m_clear_color = { red, green, blue, alpha }; m_error = GL_NO_ERROR; @@ -99,10 +94,7 @@ void SoftwareGLContext::gl_clear_depth(GLdouble depth) { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_clear_depth, depth); - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); m_clear_depth = depth; m_error = GL_NO_ERROR; @@ -134,10 +126,7 @@ void SoftwareGLContext::gl_end() float scr_height = m_frontbuffer->height(); // Make sure we had a `glBegin` before this call... - if (!m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } + RETURN_WITH_ERROR_IF(!m_in_draw_state, GL_INVALID_OPERATION); // Let's construct some triangles if (m_current_draw_mode == GL_TRIANGLES) { @@ -185,8 +174,7 @@ void SoftwareGLContext::gl_end() triangle_list.append(triangle); } } else { - m_error = GL_INVALID_ENUM; - return; + RETURN_WITH_ERROR_IF(true, GL_INVALID_ENUM); } // Now let's transform each triangle and send that to the GPU @@ -344,10 +332,7 @@ void SoftwareGLContext::gl_frustum(GLdouble left, GLdouble right, GLdouble botto { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_frustum, left, right, bottom, top, near_val, far_val); - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); // Let's do some math! // FIXME: Are we losing too much precision by doing this? @@ -377,15 +362,8 @@ void SoftwareGLContext::gl_ortho(GLdouble left, GLdouble right, GLdouble bottom, { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_ortho, left, right, bottom, top, near_val, far_val); - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } - - if (left == right || bottom == top || near_val == far_val) { - m_error = GL_INVALID_VALUE; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); + RETURN_WITH_ERROR_IF(left == right || bottom == top || near_val == far_val, GL_INVALID_VALUE); auto rl = right - left; auto tb = top - bottom; @@ -412,19 +390,15 @@ void SoftwareGLContext::gl_ortho(GLdouble left, GLdouble right, GLdouble bottom, GLenum SoftwareGLContext::gl_get_error() { - if (m_in_draw_state) { + if (m_in_draw_state) return GL_INVALID_OPERATION; - } return m_error; } GLubyte* SoftwareGLContext::gl_get_string(GLenum name) { - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return nullptr; - } + RETURN_VALUE_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION, nullptr); switch (name) { case GL_VENDOR: @@ -438,18 +412,14 @@ GLubyte* SoftwareGLContext::gl_get_string(GLenum name) break; } - m_error = GL_INVALID_ENUM; - return nullptr; + RETURN_VALUE_WITH_ERROR_IF(true, GL_INVALID_ENUM, nullptr); } void SoftwareGLContext::gl_load_identity() { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_load_identity); - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); if (m_current_matrix_mode == GL_PROJECTION) m_projection_matrix = FloatMatrix4x4::identity(); @@ -470,10 +440,7 @@ void SoftwareGLContext::gl_load_matrix(const FloatMatrix4x4& matrix) return; } - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); if (m_current_matrix_mode == GL_PROJECTION) m_projection_matrix = matrix; @@ -489,15 +456,8 @@ void SoftwareGLContext::gl_matrix_mode(GLenum mode) { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_matrix_mode, mode); - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } - - if (mode < GL_MODELVIEW || mode > GL_PROJECTION) { - m_error = GL_INVALID_ENUM; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); + RETURN_WITH_ERROR_IF(mode < GL_MODELVIEW || mode > GL_PROJECTION, GL_INVALID_ENUM); m_current_matrix_mode = mode; m_error = GL_NO_ERROR; @@ -507,26 +467,17 @@ void SoftwareGLContext::gl_push_matrix() { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_push_matrix); - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); dbgln_if(GL_DEBUG, "glPushMatrix(): Pushing matrix to the matrix stack (matrix_mode {})", m_current_matrix_mode); switch (m_current_matrix_mode) { case GL_PROJECTION: - if (m_projection_matrix_stack.size() >= MATRIX_STACK_LIMIT) { - m_error = GL_STACK_OVERFLOW; - return; - } + RETURN_WITH_ERROR_IF(m_projection_matrix_stack.size() >= MATRIX_STACK_LIMIT, GL_STACK_OVERFLOW); m_projection_matrix_stack.append(m_projection_matrix); break; case GL_MODELVIEW: - if (m_model_view_matrix_stack.size() >= MATRIX_STACK_LIMIT) { - m_error = GL_STACK_OVERFLOW; - return; - } + RETURN_WITH_ERROR_IF(m_model_view_matrix_stack.size() >= MATRIX_STACK_LIMIT, GL_STACK_OVERFLOW); m_model_view_matrix_stack.append(m_model_view_matrix); break; default: @@ -541,27 +492,18 @@ void SoftwareGLContext::gl_pop_matrix() { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_pop_matrix); - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); dbgln_if(GL_DEBUG, "glPopMatrix(): Popping matrix from matrix stack (matrix_mode = {})", m_current_matrix_mode); // FIXME: Make sure stack::top() doesn't cause any nasty issues if it's empty (that could result in a lockup/hang) switch (m_current_matrix_mode) { case GL_PROJECTION: - if (m_projection_matrix_stack.size() == 0) { - m_error = GL_STACK_UNDERFLOW; - return; - } + RETURN_WITH_ERROR_IF(m_projection_matrix_stack.size() == 0, GL_STACK_UNDERFLOW); m_projection_matrix = m_projection_matrix_stack.take_last(); break; case GL_MODELVIEW: - if (m_model_view_matrix_stack.size() == 0) { - m_error = GL_STACK_UNDERFLOW; - return; - } + RETURN_WITH_ERROR_IF(m_model_view_matrix_stack.size() == 0, GL_STACK_UNDERFLOW); m_model_view_matrix = m_model_view_matrix_stack.take_last(); break; default: @@ -576,10 +518,7 @@ void SoftwareGLContext::gl_rotate(GLdouble angle, GLdouble x, GLdouble y, GLdoub { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_rotate, angle, x, y, z); - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); FloatVector3 axis = { (float)x, (float)y, (float)z }; axis.normalize(); @@ -597,10 +536,7 @@ void SoftwareGLContext::gl_scale(GLdouble x, GLdouble y, GLdouble z) { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_scale, x, y, z); - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); if (m_current_matrix_mode == GL_MODELVIEW) { m_model_view_matrix = m_model_view_matrix * Gfx::scale_matrix(FloatVector3 { static_cast<float>(x), static_cast<float>(y), static_cast<float>(z) }); @@ -615,10 +551,7 @@ void SoftwareGLContext::gl_translate(GLdouble x, GLdouble y, GLdouble z) { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_translate, x, y, z); - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); if (m_current_matrix_mode == GL_MODELVIEW) { m_model_view_matrix = m_model_view_matrix * Gfx::translation_matrix(FloatVector3 { (float)x, (float)y, (float)z }); @@ -668,10 +601,7 @@ void SoftwareGLContext::gl_viewport(GLint x, GLint y, GLsizei width, GLsizei hei { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_viewport, x, y, width, height); - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); (void)(x); (void)(y); @@ -684,10 +614,7 @@ void SoftwareGLContext::gl_enable(GLenum capability) { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_enable, capability); - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); auto rasterizer_options = m_rasterizer.options(); bool update_rasterizer_options = false; @@ -712,8 +639,7 @@ void SoftwareGLContext::gl_enable(GLenum capability) update_rasterizer_options = true; break; default: - m_error = GL_INVALID_ENUM; - break; + RETURN_WITH_ERROR_IF(true, GL_INVALID_ENUM); } if (update_rasterizer_options) @@ -724,10 +650,7 @@ void SoftwareGLContext::gl_disable(GLenum capability) { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_disable, capability); - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); auto rasterizer_options = m_rasterizer.options(); bool update_rasterizer_options = false; @@ -752,8 +675,7 @@ void SoftwareGLContext::gl_disable(GLenum capability) update_rasterizer_options = false; break; default: - m_error = GL_INVALID_ENUM; - break; + RETURN_WITH_ERROR_IF(true, GL_INVALID_ENUM); } if (update_rasterizer_options) @@ -762,15 +684,8 @@ void SoftwareGLContext::gl_disable(GLenum capability) void SoftwareGLContext::gl_gen_textures(GLsizei n, GLuint* textures) { - if (n < 0) { - m_error = GL_INVALID_VALUE; - return; - } - - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } + RETURN_WITH_ERROR_IF(n < 0, GL_INVALID_VALUE); + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); m_name_allocator.allocate(n, textures); @@ -784,15 +699,8 @@ void SoftwareGLContext::gl_gen_textures(GLsizei n, GLuint* textures) void SoftwareGLContext::gl_delete_textures(GLsizei n, const GLuint* textures) { - if (n < 0) { - m_error = GL_INVALID_VALUE; - return; - } - - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } + RETURN_WITH_ERROR_IF(n < 0, GL_INVALID_VALUE); + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); m_name_allocator.free(n, textures); @@ -806,47 +714,18 @@ void SoftwareGLContext::gl_delete_textures(GLsizei n, const GLuint* textures) void SoftwareGLContext::gl_tex_image_2d(GLenum target, GLint level, GLint internal_format, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* data) { - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); // We only support GL_TEXTURE_2D for now - if (target != GL_TEXTURE_2D) { - m_error = GL_INVALID_ENUM; - return; - } + RETURN_WITH_ERROR_IF(target != GL_TEXTURE_2D, GL_INVALID_ENUM); // We only support symbolic constants for now - if (!(internal_format == GL_RGB || internal_format == GL_RGBA)) { - m_error = GL_INVALID_VALUE; - return; - } - - if (type != GL_UNSIGNED_BYTE) { - m_error = GL_INVALID_VALUE; - return; - } - - if (level < 0 || level > Texture::LOG2_MAX_TEXTURE_SIZE) { - m_error = GL_INVALID_VALUE; - return; - } - - if (width < 0 || height < 0 || width > (2 + Texture::MAX_TEXTURE_SIZE) || height > (2 + Texture::MAX_TEXTURE_SIZE)) { - m_error = GL_INVALID_VALUE; - return; - } - - if ((width & 2) != 0 || (height & 2) != 0) { - m_error = GL_INVALID_VALUE; - return; - } - - if (border < 0 || border > 1) { - m_error = GL_INVALID_VALUE; - return; - } + RETURN_WITH_ERROR_IF(!(internal_format == GL_RGB || internal_format == GL_RGBA), GL_INVALID_ENUM); + RETURN_WITH_ERROR_IF(type != GL_UNSIGNED_BYTE, GL_INVALID_VALUE); + RETURN_WITH_ERROR_IF(level < 0 || level > Texture::LOG2_MAX_TEXTURE_SIZE, GL_INVALID_VALUE); + RETURN_WITH_ERROR_IF(width < 0 || height < 0 || width > (2 + Texture::MAX_TEXTURE_SIZE) || height > (2 + Texture::MAX_TEXTURE_SIZE), GL_INVALID_VALUE); + RETURN_WITH_ERROR_IF((width & 2) != 0 || (height & 2) != 0, GL_INVALID_VALUE); + RETURN_WITH_ERROR_IF(border < 0 || border > 1, GL_INVALID_VALUE); // TODO: Load texture from the currently active texture unit // This is to test the functionality of texture data upload @@ -857,10 +736,7 @@ void SoftwareGLContext::gl_front_face(GLenum face) { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_front_face, face); - if (face < GL_CW || face > GL_CCW) { - m_error = GL_INVALID_ENUM; - return; - } + RETURN_WITH_ERROR_IF(face < GL_CW || face > GL_CCW, GL_INVALID_ENUM); m_front_face = face; } @@ -869,24 +745,15 @@ void SoftwareGLContext::gl_cull_face(GLenum cull_mode) { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_cull_face, cull_mode); - if (cull_mode < GL_FRONT || cull_mode > GL_FRONT_AND_BACK) { - m_error = GL_INVALID_ENUM; - return; - } + RETURN_WITH_ERROR_IF(cull_mode < GL_FRONT || cull_mode > GL_FRONT_AND_BACK, GL_INVALID_ENUM); m_culled_sides = cull_mode; } GLuint SoftwareGLContext::gl_gen_lists(GLsizei range) { - if (range <= 0) { - m_error = GL_INVALID_VALUE; - return 0; - } - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return 0; - } + RETURN_VALUE_WITH_ERROR_IF(range <= 0, GL_INVALID_VALUE, 0); + RETURN_VALUE_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION, 0); auto initial_entry = m_listings.size(); m_listings.resize(range + initial_entry); @@ -932,14 +799,8 @@ void SoftwareGLContext::gl_delete_lists(GLuint list, GLsizei range) void SoftwareGLContext::gl_end_list() { - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } - if (!m_current_listing_index.has_value()) { - m_error = GL_INVALID_OPERATION; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); + RETURN_WITH_ERROR_IF(!m_current_listing_index.has_value(), GL_INVALID_OPERATION); m_listings[m_current_listing_index->index] = move(m_current_listing_index->listing); m_current_listing_index.clear(); @@ -947,22 +808,10 @@ void SoftwareGLContext::gl_end_list() void SoftwareGLContext::gl_new_list(GLuint list, GLenum mode) { - if (list == 0) { - m_error = GL_INVALID_VALUE; - return; - } - if (mode != GL_COMPILE && mode != GL_COMPILE_AND_EXECUTE) { - m_error = GL_INVALID_ENUM; - return; - } - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } - if (m_current_listing_index.has_value()) { - m_error = GL_INVALID_OPERATION; - return; - } + RETURN_WITH_ERROR_IF(list == 0, GL_INVALID_VALUE); + RETURN_WITH_ERROR_IF(mode != GL_COMPILE && mode != GL_COMPILE_AND_EXECUTE, GL_INVALID_ENUM); + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); + RETURN_WITH_ERROR_IF(m_current_listing_index.has_value(), GL_INVALID_OPERATION); if (m_listings.size() < list) return; @@ -972,20 +821,14 @@ void SoftwareGLContext::gl_new_list(GLuint list, GLenum mode) void SoftwareGLContext::gl_flush() { - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); // No-op since SoftwareGLContext is completely synchronous at the moment } void SoftwareGLContext::gl_finish() { - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); // No-op since SoftwareGLContext is completely synchronous at the moment } @@ -994,50 +837,43 @@ void SoftwareGLContext::gl_blend_func(GLenum src_factor, GLenum dst_factor) { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_blend_func, src_factor, dst_factor); - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); // FIXME: The list of allowed enums differs between API versions // This was taken from the 2.0 spec on https://docs.gl/gl2/glBlendFunc - if (!(src_factor == GL_ZERO - || src_factor == GL_ONE - || src_factor == GL_SRC_COLOR - || src_factor == GL_ONE_MINUS_SRC_COLOR - || src_factor == GL_DST_COLOR - || src_factor == GL_ONE_MINUS_DST_COLOR - || src_factor == GL_SRC_ALPHA - || src_factor == GL_ONE_MINUS_SRC_ALPHA - || src_factor == GL_DST_ALPHA - || src_factor == GL_ONE_MINUS_DST_ALPHA - || src_factor == GL_CONSTANT_COLOR - || src_factor == GL_ONE_MINUS_CONSTANT_COLOR - || src_factor == GL_CONSTANT_ALPHA - || src_factor == GL_ONE_MINUS_CONSTANT_ALPHA - || src_factor == GL_SRC_ALPHA_SATURATE)) { - m_error = GL_INVALID_ENUM; - return; - } - - if (!(dst_factor == GL_ZERO - || dst_factor == GL_ONE - || dst_factor == GL_SRC_COLOR - || dst_factor == GL_ONE_MINUS_SRC_COLOR - || dst_factor == GL_DST_COLOR - || dst_factor == GL_ONE_MINUS_DST_COLOR - || dst_factor == GL_SRC_ALPHA - || dst_factor == GL_ONE_MINUS_SRC_ALPHA - || dst_factor == GL_DST_ALPHA - || dst_factor == GL_ONE_MINUS_DST_ALPHA - || dst_factor == GL_CONSTANT_COLOR - || dst_factor == GL_ONE_MINUS_CONSTANT_COLOR - || dst_factor == GL_CONSTANT_ALPHA - || dst_factor == GL_ONE_MINUS_CONSTANT_ALPHA)) { - m_error = GL_INVALID_ENUM; - return; - } + RETURN_WITH_ERROR_IF(!(src_factor == GL_ZERO + || src_factor == GL_ONE + || src_factor == GL_SRC_COLOR + || src_factor == GL_ONE_MINUS_SRC_COLOR + || src_factor == GL_DST_COLOR + || src_factor == GL_ONE_MINUS_DST_COLOR + || src_factor == GL_SRC_ALPHA + || src_factor == GL_ONE_MINUS_SRC_ALPHA + || src_factor == GL_DST_ALPHA + || src_factor == GL_ONE_MINUS_DST_ALPHA + || src_factor == GL_CONSTANT_COLOR + || src_factor == GL_ONE_MINUS_CONSTANT_COLOR + || src_factor == GL_CONSTANT_ALPHA + || src_factor == GL_ONE_MINUS_CONSTANT_ALPHA + || src_factor == GL_SRC_ALPHA_SATURATE), + GL_INVALID_ENUM); + + RETURN_WITH_ERROR_IF(!(dst_factor == GL_ZERO + || dst_factor == GL_ONE + || dst_factor == GL_SRC_COLOR + || dst_factor == GL_ONE_MINUS_SRC_COLOR + || dst_factor == GL_DST_COLOR + || dst_factor == GL_ONE_MINUS_DST_COLOR + || dst_factor == GL_SRC_ALPHA + || dst_factor == GL_ONE_MINUS_SRC_ALPHA + || dst_factor == GL_DST_ALPHA + || dst_factor == GL_ONE_MINUS_DST_ALPHA + || dst_factor == GL_CONSTANT_COLOR + || dst_factor == GL_ONE_MINUS_CONSTANT_COLOR + || dst_factor == GL_CONSTANT_ALPHA + || dst_factor == GL_ONE_MINUS_CONSTANT_ALPHA), + GL_INVALID_ENUM); m_blend_source_factor = src_factor; m_blend_destination_factor = dst_factor; @@ -1052,15 +888,8 @@ void SoftwareGLContext::gl_shade_model(GLenum mode) { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_shade_model, mode); - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } - - if (mode != GL_FLAT && mode != GL_SMOOTH) { - m_error = GL_INVALID_ENUM; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); + RETURN_WITH_ERROR_IF(mode != GL_FLAT && mode != GL_SMOOTH, GL_INVALID_ENUM); auto options = m_rasterizer.options(); options.shade_smooth = (mode == GL_SMOOTH); @@ -1071,15 +900,8 @@ void SoftwareGLContext::gl_alpha_func(GLenum func, GLclampf ref) { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_alpha_func, func, ref); - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } - - if (func < GL_NEVER || func > GL_ALWAYS) { - m_error = GL_INVALID_ENUM; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); + RETURN_WITH_ERROR_IF(func < GL_NEVER || func > GL_ALWAYS, GL_INVALID_ENUM); m_alpha_test_func = func; m_alpha_test_ref_value = ref; @@ -1094,28 +916,21 @@ void SoftwareGLContext::gl_hint(GLenum target, GLenum mode) { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_hint, target, mode); - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); - if (target != GL_PERSPECTIVE_CORRECTION_HINT - && target != GL_POINT_SMOOTH_HINT - && target != GL_LINE_SMOOTH_HINT - && target != GL_POLYGON_SMOOTH_HINT - && target != GL_FOG_HINT - && target != GL_GENERATE_MIPMAP_HINT - && target != GL_TEXTURE_COMPRESSION_HINT) { - m_error = GL_INVALID_ENUM; - return; - } + RETURN_WITH_ERROR_IF(target != GL_PERSPECTIVE_CORRECTION_HINT + && target != GL_POINT_SMOOTH_HINT + && target != GL_LINE_SMOOTH_HINT + && target != GL_POLYGON_SMOOTH_HINT + && target != GL_FOG_HINT + && target != GL_GENERATE_MIPMAP_HINT + && target != GL_TEXTURE_COMPRESSION_HINT, + GL_INVALID_ENUM); - if (mode != GL_DONT_CARE - && mode != GL_FASTEST - && mode != GL_NICEST) { - m_error = GL_INVALID_ENUM; - return; - } + RETURN_WITH_ERROR_IF(mode != GL_DONT_CARE + && mode != GL_FASTEST + && mode != GL_NICEST, + GL_INVALID_ENUM); // According to the spec implementors are free to ignore glHint. So we do. } @@ -1124,104 +939,82 @@ void SoftwareGLContext::gl_read_buffer(GLenum mode) { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_read_buffer, mode); - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); // FIXME: Also allow aux buffers GL_AUX0 through GL_AUX3 here // plus any aux buffer between 0 and GL_AUX_BUFFERS - if (mode != GL_FRONT_LEFT - && mode != GL_FRONT_RIGHT - && mode != GL_BACK_LEFT - && mode != GL_BACK_RIGHT - && mode != GL_FRONT - && mode != GL_BACK - && mode != GL_LEFT - && mode != GL_RIGHT) { - m_error = GL_INVALID_ENUM; - return; - } + RETURN_WITH_ERROR_IF(mode != GL_FRONT_LEFT + && mode != GL_FRONT_RIGHT + && mode != GL_BACK_LEFT + && mode != GL_BACK_RIGHT + && mode != GL_FRONT + && mode != GL_BACK + && mode != GL_LEFT + && mode != GL_RIGHT, + GL_INVALID_ENUM); // FIXME: We do not currently have aux buffers, so make it an invalid // operation to select anything but front or back buffers. Also we do // not allow selecting the stereoscopic RIGHT buffers since we do not // have them configured. - if (mode != GL_FRONT_LEFT - && mode != GL_FRONT - && mode != GL_BACK_LEFT - && mode != GL_BACK - && mode != GL_FRONT - && mode != GL_BACK - && mode != GL_LEFT) { - m_error = GL_INVALID_OPERATION; - return; - } + RETURN_WITH_ERROR_IF(mode != GL_FRONT_LEFT + && mode != GL_FRONT + && mode != GL_BACK_LEFT + && mode != GL_BACK + && mode != GL_FRONT + && mode != GL_BACK + && mode != GL_LEFT, + GL_INVALID_OPERATION); m_current_read_buffer = mode; } void SoftwareGLContext::gl_read_pixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) { - if (m_in_draw_state) { - m_error = GL_INVALID_OPERATION; - return; - } - - // Check for negative width/height omitted because GLsizei is unsigned in our implementation - - if (format != GL_COLOR_INDEX - && format != GL_STENCIL_INDEX - && format != GL_DEPTH_COMPONENT - && format != GL_RED - && format != GL_GREEN - && format != GL_BLUE - && format != GL_ALPHA - && format != GL_RGB - && format != GL_RGBA - && format != GL_LUMINANCE - && format != GL_LUMINANCE_ALPHA) { - m_error = GL_INVALID_ENUM; - return; - } - - if (type != GL_UNSIGNED_BYTE - && type != GL_BYTE - && type != GL_BITMAP - && type != GL_UNSIGNED_SHORT - && type != GL_SHORT - && type != GL_BLUE - && type != GL_UNSIGNED_INT - && type != GL_INT - && type != GL_FLOAT) { - m_error = GL_INVALID_ENUM; - return; - } - - if (format == GL_COLOR_INDEX) { - // FIXME: We only support RGBA buffers for now. - // Once we add support for indexed color modes do the correct check here - m_error = GL_INVALID_OPERATION; - return; - } - - if (format == GL_STENCIL_INDEX) { - // FIXME: We do not have stencil buffers yet - // Once we add support for stencil buffers do the correct check here - m_error = GL_INVALID_OPERATION; - return; - } + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); + RETURN_WITH_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE); + + RETURN_WITH_ERROR_IF(format != GL_COLOR_INDEX + && format != GL_STENCIL_INDEX + && format != GL_DEPTH_COMPONENT + && format != GL_RED + && format != GL_GREEN + && format != GL_BLUE + && format != GL_ALPHA + && format != GL_RGB + && format != GL_RGBA + && format != GL_LUMINANCE + && format != GL_LUMINANCE_ALPHA, + GL_INVALID_ENUM); + + RETURN_WITH_ERROR_IF(type != GL_UNSIGNED_BYTE + && type != GL_BYTE + && type != GL_BITMAP + && type != GL_UNSIGNED_SHORT + && type != GL_SHORT + && type != GL_BLUE + && type != GL_UNSIGNED_INT + && type != GL_INT + && type != GL_FLOAT, + GL_INVALID_ENUM); + + // FIXME: We only support RGBA buffers for now. + // Once we add support for indexed color modes do the correct check here + RETURN_WITH_ERROR_IF(format == GL_COLOR_INDEX, GL_INVALID_OPERATION); + + // FIXME: We do not have stencil buffers yet + // Once we add support for stencil buffers do the correct check here + RETURN_WITH_ERROR_IF(format == GL_STENCIL_INDEX, GL_INVALID_OPERATION); if (format == GL_DEPTH_COMPONENT) { // FIXME: This check needs to be a bit more sophisticated. Currently the buffers // are hardcoded. Once we add proper structures for them we need to correct this check - if (m_current_read_buffer == GL_FRONT - || m_current_read_buffer == GL_FRONT_LEFT - || m_current_read_buffer == GL_FRONT_RIGHT) { - // Error because only back buffer has a depth buffer - m_error = GL_INVALID_OPERATION; - return; - } + + // Error because only back buffer has a depth buffer + RETURN_WITH_ERROR_IF(m_current_read_buffer == GL_FRONT + || m_current_read_buffer == GL_FRONT_LEFT + || m_current_read_buffer == GL_FRONT_RIGHT, + GL_INVALID_OPERATION); } // Some helper functions for converting float values to integer types |