mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 19:37:36 +00:00
LibGL: Add macro for error checking
This adds a macro `RETURN_WITH_ERROR_IF` to SoftwareGLContext to remove a lot of noise from the interface implementation.
This commit is contained in:
parent
e6b88de6a0
commit
9b4edacd8e
1 changed files with 171 additions and 378 deletions
|
@ -34,6 +34,18 @@ static constexpr size_t MATRIX_STACK_LIMIT = 1024;
|
||||||
return; \
|
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)
|
SoftwareGLContext::SoftwareGLContext(Gfx::Bitmap& frontbuffer)
|
||||||
: m_frontbuffer(frontbuffer)
|
: m_frontbuffer(frontbuffer)
|
||||||
, m_rasterizer(frontbuffer.size())
|
, 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);
|
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_begin, mode);
|
||||||
|
|
||||||
if (m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
RETURN_WITH_ERROR_IF(mode < GL_TRIANGLES || mode > GL_POLYGON, GL_INVALID_ENUM);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode < GL_TRIANGLES || mode > GL_POLYGON) {
|
|
||||||
m_error = GL_INVALID_ENUM;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_current_draw_mode = mode;
|
m_current_draw_mode = mode;
|
||||||
m_in_draw_state = true; // Certain commands will now generate an error
|
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);
|
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_clear, mask);
|
||||||
|
|
||||||
if (m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
RETURN_WITH_ERROR_IF(mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT), GL_INVALID_ENUM);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) {
|
|
||||||
m_error = GL_INVALID_ENUM;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mask & GL_COLOR_BUFFER_BIT)
|
if (mask & GL_COLOR_BUFFER_BIT)
|
||||||
m_rasterizer.clear_color(m_clear_color);
|
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);
|
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_clear_color, red, green, blue, alpha);
|
||||||
|
|
||||||
if (m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_clear_color = { red, green, blue, alpha };
|
m_clear_color = { red, green, blue, alpha };
|
||||||
m_error = GL_NO_ERROR;
|
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);
|
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_clear_depth, depth);
|
||||||
|
|
||||||
if (m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_clear_depth = depth;
|
m_clear_depth = depth;
|
||||||
m_error = GL_NO_ERROR;
|
m_error = GL_NO_ERROR;
|
||||||
|
@ -134,10 +126,7 @@ void SoftwareGLContext::gl_end()
|
||||||
float scr_height = m_frontbuffer->height();
|
float scr_height = m_frontbuffer->height();
|
||||||
|
|
||||||
// Make sure we had a `glBegin` before this call...
|
// Make sure we had a `glBegin` before this call...
|
||||||
if (!m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(!m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Let's construct some triangles
|
// Let's construct some triangles
|
||||||
if (m_current_draw_mode == GL_TRIANGLES) {
|
if (m_current_draw_mode == GL_TRIANGLES) {
|
||||||
|
@ -185,8 +174,7 @@ void SoftwareGLContext::gl_end()
|
||||||
triangle_list.append(triangle);
|
triangle_list.append(triangle);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m_error = GL_INVALID_ENUM;
|
RETURN_WITH_ERROR_IF(true, GL_INVALID_ENUM);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now let's transform each triangle and send that to the GPU
|
// 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);
|
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_frustum, left, right, bottom, top, near_val, far_val);
|
||||||
|
|
||||||
if (m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Let's do some math!
|
// Let's do some math!
|
||||||
// FIXME: Are we losing too much precision by doing this?
|
// 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);
|
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_ortho, left, right, bottom, top, near_val, far_val);
|
||||||
|
|
||||||
if (m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
RETURN_WITH_ERROR_IF(left == right || bottom == top || near_val == far_val, GL_INVALID_VALUE);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (left == right || bottom == top || near_val == far_val) {
|
|
||||||
m_error = GL_INVALID_VALUE;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto rl = right - left;
|
auto rl = right - left;
|
||||||
auto tb = top - bottom;
|
auto tb = top - bottom;
|
||||||
|
@ -412,19 +390,15 @@ void SoftwareGLContext::gl_ortho(GLdouble left, GLdouble right, GLdouble bottom,
|
||||||
|
|
||||||
GLenum SoftwareGLContext::gl_get_error()
|
GLenum SoftwareGLContext::gl_get_error()
|
||||||
{
|
{
|
||||||
if (m_in_draw_state) {
|
if (m_in_draw_state)
|
||||||
return GL_INVALID_OPERATION;
|
return GL_INVALID_OPERATION;
|
||||||
}
|
|
||||||
|
|
||||||
return m_error;
|
return m_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLubyte* SoftwareGLContext::gl_get_string(GLenum name)
|
GLubyte* SoftwareGLContext::gl_get_string(GLenum name)
|
||||||
{
|
{
|
||||||
if (m_in_draw_state) {
|
RETURN_VALUE_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION, nullptr);
|
||||||
m_error = GL_INVALID_OPERATION;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (name) {
|
switch (name) {
|
||||||
case GL_VENDOR:
|
case GL_VENDOR:
|
||||||
|
@ -438,18 +412,14 @@ GLubyte* SoftwareGLContext::gl_get_string(GLenum name)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_error = GL_INVALID_ENUM;
|
RETURN_VALUE_WITH_ERROR_IF(true, GL_INVALID_ENUM, nullptr);
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftwareGLContext::gl_load_identity()
|
void SoftwareGLContext::gl_load_identity()
|
||||||
{
|
{
|
||||||
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_load_identity);
|
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_load_identity);
|
||||||
|
|
||||||
if (m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_current_matrix_mode == GL_PROJECTION)
|
if (m_current_matrix_mode == GL_PROJECTION)
|
||||||
m_projection_matrix = FloatMatrix4x4::identity();
|
m_projection_matrix = FloatMatrix4x4::identity();
|
||||||
|
@ -470,10 +440,7 @@ void SoftwareGLContext::gl_load_matrix(const FloatMatrix4x4& matrix)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_current_matrix_mode == GL_PROJECTION)
|
if (m_current_matrix_mode == GL_PROJECTION)
|
||||||
m_projection_matrix = matrix;
|
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);
|
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_matrix_mode, mode);
|
||||||
|
|
||||||
if (m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
RETURN_WITH_ERROR_IF(mode < GL_MODELVIEW || mode > GL_PROJECTION, GL_INVALID_ENUM);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode < GL_MODELVIEW || mode > GL_PROJECTION) {
|
|
||||||
m_error = GL_INVALID_ENUM;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_current_matrix_mode = mode;
|
m_current_matrix_mode = mode;
|
||||||
m_error = GL_NO_ERROR;
|
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);
|
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_push_matrix);
|
||||||
|
|
||||||
if (m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dbgln_if(GL_DEBUG, "glPushMatrix(): Pushing matrix to the matrix stack (matrix_mode {})", m_current_matrix_mode);
|
dbgln_if(GL_DEBUG, "glPushMatrix(): Pushing matrix to the matrix stack (matrix_mode {})", m_current_matrix_mode);
|
||||||
|
|
||||||
switch (m_current_matrix_mode) {
|
switch (m_current_matrix_mode) {
|
||||||
case GL_PROJECTION:
|
case GL_PROJECTION:
|
||||||
if (m_projection_matrix_stack.size() >= MATRIX_STACK_LIMIT) {
|
RETURN_WITH_ERROR_IF(m_projection_matrix_stack.size() >= MATRIX_STACK_LIMIT, GL_STACK_OVERFLOW);
|
||||||
m_error = GL_STACK_OVERFLOW;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_projection_matrix_stack.append(m_projection_matrix);
|
m_projection_matrix_stack.append(m_projection_matrix);
|
||||||
break;
|
break;
|
||||||
case GL_MODELVIEW:
|
case GL_MODELVIEW:
|
||||||
if (m_model_view_matrix_stack.size() >= MATRIX_STACK_LIMIT) {
|
RETURN_WITH_ERROR_IF(m_model_view_matrix_stack.size() >= MATRIX_STACK_LIMIT, GL_STACK_OVERFLOW);
|
||||||
m_error = GL_STACK_OVERFLOW;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_model_view_matrix_stack.append(m_model_view_matrix);
|
m_model_view_matrix_stack.append(m_model_view_matrix);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -541,27 +492,18 @@ void SoftwareGLContext::gl_pop_matrix()
|
||||||
{
|
{
|
||||||
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_pop_matrix);
|
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_pop_matrix);
|
||||||
|
|
||||||
if (m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dbgln_if(GL_DEBUG, "glPopMatrix(): Popping matrix from matrix stack (matrix_mode = {})", m_current_matrix_mode);
|
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)
|
// 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) {
|
switch (m_current_matrix_mode) {
|
||||||
case GL_PROJECTION:
|
case GL_PROJECTION:
|
||||||
if (m_projection_matrix_stack.size() == 0) {
|
RETURN_WITH_ERROR_IF(m_projection_matrix_stack.size() == 0, GL_STACK_UNDERFLOW);
|
||||||
m_error = GL_STACK_UNDERFLOW;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_projection_matrix = m_projection_matrix_stack.take_last();
|
m_projection_matrix = m_projection_matrix_stack.take_last();
|
||||||
break;
|
break;
|
||||||
case GL_MODELVIEW:
|
case GL_MODELVIEW:
|
||||||
if (m_model_view_matrix_stack.size() == 0) {
|
RETURN_WITH_ERROR_IF(m_model_view_matrix_stack.size() == 0, GL_STACK_UNDERFLOW);
|
||||||
m_error = GL_STACK_UNDERFLOW;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_model_view_matrix = m_model_view_matrix_stack.take_last();
|
m_model_view_matrix = m_model_view_matrix_stack.take_last();
|
||||||
break;
|
break;
|
||||||
default:
|
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);
|
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_rotate, angle, x, y, z);
|
||||||
|
|
||||||
if (m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
FloatVector3 axis = { (float)x, (float)y, (float)z };
|
FloatVector3 axis = { (float)x, (float)y, (float)z };
|
||||||
axis.normalize();
|
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);
|
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_scale, x, y, z);
|
||||||
|
|
||||||
if (m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_current_matrix_mode == GL_MODELVIEW) {
|
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) });
|
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);
|
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_translate, x, y, z);
|
||||||
|
|
||||||
if (m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_current_matrix_mode == GL_MODELVIEW) {
|
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 });
|
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);
|
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_viewport, x, y, width, height);
|
||||||
|
|
||||||
if (m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
(void)(x);
|
(void)(x);
|
||||||
(void)(y);
|
(void)(y);
|
||||||
|
@ -684,10 +614,7 @@ void SoftwareGLContext::gl_enable(GLenum capability)
|
||||||
{
|
{
|
||||||
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_enable, capability);
|
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_enable, capability);
|
||||||
|
|
||||||
if (m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto rasterizer_options = m_rasterizer.options();
|
auto rasterizer_options = m_rasterizer.options();
|
||||||
bool update_rasterizer_options = false;
|
bool update_rasterizer_options = false;
|
||||||
|
@ -712,8 +639,7 @@ void SoftwareGLContext::gl_enable(GLenum capability)
|
||||||
update_rasterizer_options = true;
|
update_rasterizer_options = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
m_error = GL_INVALID_ENUM;
|
RETURN_WITH_ERROR_IF(true, GL_INVALID_ENUM);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (update_rasterizer_options)
|
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);
|
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_disable, capability);
|
||||||
|
|
||||||
if (m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto rasterizer_options = m_rasterizer.options();
|
auto rasterizer_options = m_rasterizer.options();
|
||||||
bool update_rasterizer_options = false;
|
bool update_rasterizer_options = false;
|
||||||
|
@ -752,8 +675,7 @@ void SoftwareGLContext::gl_disable(GLenum capability)
|
||||||
update_rasterizer_options = false;
|
update_rasterizer_options = false;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
m_error = GL_INVALID_ENUM;
|
RETURN_WITH_ERROR_IF(true, GL_INVALID_ENUM);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (update_rasterizer_options)
|
if (update_rasterizer_options)
|
||||||
|
@ -762,15 +684,8 @@ void SoftwareGLContext::gl_disable(GLenum capability)
|
||||||
|
|
||||||
void SoftwareGLContext::gl_gen_textures(GLsizei n, GLuint* textures)
|
void SoftwareGLContext::gl_gen_textures(GLsizei n, GLuint* textures)
|
||||||
{
|
{
|
||||||
if (n < 0) {
|
RETURN_WITH_ERROR_IF(n < 0, GL_INVALID_VALUE);
|
||||||
m_error = GL_INVALID_VALUE;
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_in_draw_state) {
|
|
||||||
m_error = GL_INVALID_OPERATION;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_name_allocator.allocate(n, textures);
|
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)
|
void SoftwareGLContext::gl_delete_textures(GLsizei n, const GLuint* textures)
|
||||||
{
|
{
|
||||||
if (n < 0) {
|
RETURN_WITH_ERROR_IF(n < 0, GL_INVALID_VALUE);
|
||||||
m_error = GL_INVALID_VALUE;
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_in_draw_state) {
|
|
||||||
m_error = GL_INVALID_OPERATION;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_name_allocator.free(n, textures);
|
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)
|
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) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We only support GL_TEXTURE_2D for now
|
// We only support GL_TEXTURE_2D for now
|
||||||
if (target != GL_TEXTURE_2D) {
|
RETURN_WITH_ERROR_IF(target != GL_TEXTURE_2D, GL_INVALID_ENUM);
|
||||||
m_error = GL_INVALID_ENUM;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We only support symbolic constants for now
|
// We only support symbolic constants for now
|
||||||
if (!(internal_format == GL_RGB || internal_format == GL_RGBA)) {
|
RETURN_WITH_ERROR_IF(!(internal_format == GL_RGB || internal_format == GL_RGBA), GL_INVALID_ENUM);
|
||||||
m_error = GL_INVALID_VALUE;
|
RETURN_WITH_ERROR_IF(type != GL_UNSIGNED_BYTE, GL_INVALID_VALUE);
|
||||||
return;
|
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);
|
||||||
if (type != GL_UNSIGNED_BYTE) {
|
RETURN_WITH_ERROR_IF(border < 0 || border > 1, GL_INVALID_VALUE);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Load texture from the currently active texture unit
|
// TODO: Load texture from the currently active texture unit
|
||||||
// This is to test the functionality of texture data upload
|
// 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);
|
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_front_face, face);
|
||||||
|
|
||||||
if (face < GL_CW || face > GL_CCW) {
|
RETURN_WITH_ERROR_IF(face < GL_CW || face > GL_CCW, GL_INVALID_ENUM);
|
||||||
m_error = GL_INVALID_ENUM;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_front_face = face;
|
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);
|
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_cull_face, cull_mode);
|
||||||
|
|
||||||
if (cull_mode < GL_FRONT || cull_mode > GL_FRONT_AND_BACK) {
|
RETURN_WITH_ERROR_IF(cull_mode < GL_FRONT || cull_mode > GL_FRONT_AND_BACK, GL_INVALID_ENUM);
|
||||||
m_error = GL_INVALID_ENUM;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_culled_sides = cull_mode;
|
m_culled_sides = cull_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint SoftwareGLContext::gl_gen_lists(GLsizei range)
|
GLuint SoftwareGLContext::gl_gen_lists(GLsizei range)
|
||||||
{
|
{
|
||||||
if (range <= 0) {
|
RETURN_VALUE_WITH_ERROR_IF(range <= 0, GL_INVALID_VALUE, 0);
|
||||||
m_error = GL_INVALID_VALUE;
|
RETURN_VALUE_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION, 0);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (m_in_draw_state) {
|
|
||||||
m_error = GL_INVALID_OPERATION;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto initial_entry = m_listings.size();
|
auto initial_entry = m_listings.size();
|
||||||
m_listings.resize(range + initial_entry);
|
m_listings.resize(range + initial_entry);
|
||||||
|
@ -932,14 +799,8 @@ void SoftwareGLContext::gl_delete_lists(GLuint list, GLsizei range)
|
||||||
|
|
||||||
void SoftwareGLContext::gl_end_list()
|
void SoftwareGLContext::gl_end_list()
|
||||||
{
|
{
|
||||||
if (m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
RETURN_WITH_ERROR_IF(!m_current_listing_index.has_value(), GL_INVALID_OPERATION);
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!m_current_listing_index.has_value()) {
|
|
||||||
m_error = GL_INVALID_OPERATION;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_listings[m_current_listing_index->index] = move(m_current_listing_index->listing);
|
m_listings[m_current_listing_index->index] = move(m_current_listing_index->listing);
|
||||||
m_current_listing_index.clear();
|
m_current_listing_index.clear();
|
||||||
|
@ -947,22 +808,10 @@ void SoftwareGLContext::gl_end_list()
|
||||||
|
|
||||||
void SoftwareGLContext::gl_new_list(GLuint list, GLenum mode)
|
void SoftwareGLContext::gl_new_list(GLuint list, GLenum mode)
|
||||||
{
|
{
|
||||||
if (list == 0) {
|
RETURN_WITH_ERROR_IF(list == 0, GL_INVALID_VALUE);
|
||||||
m_error = GL_INVALID_VALUE;
|
RETURN_WITH_ERROR_IF(mode != GL_COMPILE && mode != GL_COMPILE_AND_EXECUTE, GL_INVALID_ENUM);
|
||||||
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);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_listings.size() < list)
|
if (m_listings.size() < list)
|
||||||
return;
|
return;
|
||||||
|
@ -972,20 +821,14 @@ void SoftwareGLContext::gl_new_list(GLuint list, GLenum mode)
|
||||||
|
|
||||||
void SoftwareGLContext::gl_flush()
|
void SoftwareGLContext::gl_flush()
|
||||||
{
|
{
|
||||||
if (m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No-op since SoftwareGLContext is completely synchronous at the moment
|
// No-op since SoftwareGLContext is completely synchronous at the moment
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftwareGLContext::gl_finish()
|
void SoftwareGLContext::gl_finish()
|
||||||
{
|
{
|
||||||
if (m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No-op since SoftwareGLContext is completely synchronous at the moment
|
// No-op since SoftwareGLContext is completely synchronous at the moment
|
||||||
}
|
}
|
||||||
|
@ -994,15 +837,12 @@ 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);
|
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_blend_func, src_factor, dst_factor);
|
||||||
|
|
||||||
if (m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: The list of allowed enums differs between API versions
|
// FIXME: The list of allowed enums differs between API versions
|
||||||
// This was taken from the 2.0 spec on https://docs.gl/gl2/glBlendFunc
|
// This was taken from the 2.0 spec on https://docs.gl/gl2/glBlendFunc
|
||||||
|
|
||||||
if (!(src_factor == GL_ZERO
|
RETURN_WITH_ERROR_IF(!(src_factor == GL_ZERO
|
||||||
|| src_factor == GL_ONE
|
|| src_factor == GL_ONE
|
||||||
|| src_factor == GL_SRC_COLOR
|
|| src_factor == GL_SRC_COLOR
|
||||||
|| src_factor == GL_ONE_MINUS_SRC_COLOR
|
|| src_factor == GL_ONE_MINUS_SRC_COLOR
|
||||||
|
@ -1016,12 +856,10 @@ void SoftwareGLContext::gl_blend_func(GLenum src_factor, GLenum dst_factor)
|
||||||
|| src_factor == GL_ONE_MINUS_CONSTANT_COLOR
|
|| src_factor == GL_ONE_MINUS_CONSTANT_COLOR
|
||||||
|| src_factor == GL_CONSTANT_ALPHA
|
|| src_factor == GL_CONSTANT_ALPHA
|
||||||
|| src_factor == GL_ONE_MINUS_CONSTANT_ALPHA
|
|| src_factor == GL_ONE_MINUS_CONSTANT_ALPHA
|
||||||
|| src_factor == GL_SRC_ALPHA_SATURATE)) {
|
|| src_factor == GL_SRC_ALPHA_SATURATE),
|
||||||
m_error = GL_INVALID_ENUM;
|
GL_INVALID_ENUM);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(dst_factor == GL_ZERO
|
RETURN_WITH_ERROR_IF(!(dst_factor == GL_ZERO
|
||||||
|| dst_factor == GL_ONE
|
|| dst_factor == GL_ONE
|
||||||
|| dst_factor == GL_SRC_COLOR
|
|| dst_factor == GL_SRC_COLOR
|
||||||
|| dst_factor == GL_ONE_MINUS_SRC_COLOR
|
|| dst_factor == GL_ONE_MINUS_SRC_COLOR
|
||||||
|
@ -1034,10 +872,8 @@ void SoftwareGLContext::gl_blend_func(GLenum src_factor, GLenum dst_factor)
|
||||||
|| dst_factor == GL_CONSTANT_COLOR
|
|| dst_factor == GL_CONSTANT_COLOR
|
||||||
|| dst_factor == GL_ONE_MINUS_CONSTANT_COLOR
|
|| dst_factor == GL_ONE_MINUS_CONSTANT_COLOR
|
||||||
|| dst_factor == GL_CONSTANT_ALPHA
|
|| dst_factor == GL_CONSTANT_ALPHA
|
||||||
|| dst_factor == GL_ONE_MINUS_CONSTANT_ALPHA)) {
|
|| dst_factor == GL_ONE_MINUS_CONSTANT_ALPHA),
|
||||||
m_error = GL_INVALID_ENUM;
|
GL_INVALID_ENUM);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_blend_source_factor = src_factor;
|
m_blend_source_factor = src_factor;
|
||||||
m_blend_destination_factor = dst_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);
|
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_shade_model, mode);
|
||||||
|
|
||||||
if (m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
RETURN_WITH_ERROR_IF(mode != GL_FLAT && mode != GL_SMOOTH, GL_INVALID_ENUM);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode != GL_FLAT && mode != GL_SMOOTH) {
|
|
||||||
m_error = GL_INVALID_ENUM;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto options = m_rasterizer.options();
|
auto options = m_rasterizer.options();
|
||||||
options.shade_smooth = (mode == GL_SMOOTH);
|
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);
|
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_alpha_func, func, ref);
|
||||||
|
|
||||||
if (m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
RETURN_WITH_ERROR_IF(func < GL_NEVER || func > GL_ALWAYS, GL_INVALID_ENUM);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (func < GL_NEVER || func > GL_ALWAYS) {
|
|
||||||
m_error = GL_INVALID_ENUM;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_alpha_test_func = func;
|
m_alpha_test_func = func;
|
||||||
m_alpha_test_ref_value = ref;
|
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);
|
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_hint, target, mode);
|
||||||
|
|
||||||
if (m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target != GL_PERSPECTIVE_CORRECTION_HINT
|
RETURN_WITH_ERROR_IF(target != GL_PERSPECTIVE_CORRECTION_HINT
|
||||||
&& target != GL_POINT_SMOOTH_HINT
|
&& target != GL_POINT_SMOOTH_HINT
|
||||||
&& target != GL_LINE_SMOOTH_HINT
|
&& target != GL_LINE_SMOOTH_HINT
|
||||||
&& target != GL_POLYGON_SMOOTH_HINT
|
&& target != GL_POLYGON_SMOOTH_HINT
|
||||||
&& target != GL_FOG_HINT
|
&& target != GL_FOG_HINT
|
||||||
&& target != GL_GENERATE_MIPMAP_HINT
|
&& target != GL_GENERATE_MIPMAP_HINT
|
||||||
&& target != GL_TEXTURE_COMPRESSION_HINT) {
|
&& target != GL_TEXTURE_COMPRESSION_HINT,
|
||||||
m_error = GL_INVALID_ENUM;
|
GL_INVALID_ENUM);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode != GL_DONT_CARE
|
RETURN_WITH_ERROR_IF(mode != GL_DONT_CARE
|
||||||
&& mode != GL_FASTEST
|
&& mode != GL_FASTEST
|
||||||
&& mode != GL_NICEST) {
|
&& mode != GL_NICEST,
|
||||||
m_error = GL_INVALID_ENUM;
|
GL_INVALID_ENUM);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// According to the spec implementors are free to ignore glHint. So we do.
|
// According to the spec implementors are free to ignore glHint. So we do.
|
||||||
}
|
}
|
||||||
|
@ -1124,53 +939,42 @@ void SoftwareGLContext::gl_read_buffer(GLenum mode)
|
||||||
{
|
{
|
||||||
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_read_buffer, mode);
|
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_read_buffer, mode);
|
||||||
|
|
||||||
if (m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: Also allow aux buffers GL_AUX0 through GL_AUX3 here
|
// FIXME: Also allow aux buffers GL_AUX0 through GL_AUX3 here
|
||||||
// plus any aux buffer between 0 and GL_AUX_BUFFERS
|
// plus any aux buffer between 0 and GL_AUX_BUFFERS
|
||||||
if (mode != GL_FRONT_LEFT
|
RETURN_WITH_ERROR_IF(mode != GL_FRONT_LEFT
|
||||||
&& mode != GL_FRONT_RIGHT
|
&& mode != GL_FRONT_RIGHT
|
||||||
&& mode != GL_BACK_LEFT
|
&& mode != GL_BACK_LEFT
|
||||||
&& mode != GL_BACK_RIGHT
|
&& mode != GL_BACK_RIGHT
|
||||||
&& mode != GL_FRONT
|
&& mode != GL_FRONT
|
||||||
&& mode != GL_BACK
|
&& mode != GL_BACK
|
||||||
&& mode != GL_LEFT
|
&& mode != GL_LEFT
|
||||||
&& mode != GL_RIGHT) {
|
&& mode != GL_RIGHT,
|
||||||
m_error = GL_INVALID_ENUM;
|
GL_INVALID_ENUM);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: We do not currently have aux buffers, so make it an invalid
|
// 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
|
// operation to select anything but front or back buffers. Also we do
|
||||||
// not allow selecting the stereoscopic RIGHT buffers since we do not
|
// not allow selecting the stereoscopic RIGHT buffers since we do not
|
||||||
// have them configured.
|
// have them configured.
|
||||||
if (mode != GL_FRONT_LEFT
|
RETURN_WITH_ERROR_IF(mode != GL_FRONT_LEFT
|
||||||
&& mode != GL_FRONT
|
&& mode != GL_FRONT
|
||||||
&& mode != GL_BACK_LEFT
|
&& mode != GL_BACK_LEFT
|
||||||
&& mode != GL_BACK
|
&& mode != GL_BACK
|
||||||
&& mode != GL_FRONT
|
&& mode != GL_FRONT
|
||||||
&& mode != GL_BACK
|
&& mode != GL_BACK
|
||||||
&& mode != GL_LEFT) {
|
&& mode != GL_LEFT,
|
||||||
m_error = GL_INVALID_OPERATION;
|
GL_INVALID_OPERATION);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_current_read_buffer = mode;
|
m_current_read_buffer = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftwareGLContext::gl_read_pixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
|
void SoftwareGLContext::gl_read_pixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
|
||||||
{
|
{
|
||||||
if (m_in_draw_state) {
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
m_error = GL_INVALID_OPERATION;
|
RETURN_WITH_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for negative width/height omitted because GLsizei is unsigned in our implementation
|
RETURN_WITH_ERROR_IF(format != GL_COLOR_INDEX
|
||||||
|
|
||||||
if (format != GL_COLOR_INDEX
|
|
||||||
&& format != GL_STENCIL_INDEX
|
&& format != GL_STENCIL_INDEX
|
||||||
&& format != GL_DEPTH_COMPONENT
|
&& format != GL_DEPTH_COMPONENT
|
||||||
&& format != GL_RED
|
&& format != GL_RED
|
||||||
|
@ -1180,12 +984,10 @@ void SoftwareGLContext::gl_read_pixels(GLint x, GLint y, GLsizei width, GLsizei
|
||||||
&& format != GL_RGB
|
&& format != GL_RGB
|
||||||
&& format != GL_RGBA
|
&& format != GL_RGBA
|
||||||
&& format != GL_LUMINANCE
|
&& format != GL_LUMINANCE
|
||||||
&& format != GL_LUMINANCE_ALPHA) {
|
&& format != GL_LUMINANCE_ALPHA,
|
||||||
m_error = GL_INVALID_ENUM;
|
GL_INVALID_ENUM);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type != GL_UNSIGNED_BYTE
|
RETURN_WITH_ERROR_IF(type != GL_UNSIGNED_BYTE
|
||||||
&& type != GL_BYTE
|
&& type != GL_BYTE
|
||||||
&& type != GL_BITMAP
|
&& type != GL_BITMAP
|
||||||
&& type != GL_UNSIGNED_SHORT
|
&& type != GL_UNSIGNED_SHORT
|
||||||
|
@ -1193,35 +995,26 @@ void SoftwareGLContext::gl_read_pixels(GLint x, GLint y, GLsizei width, GLsizei
|
||||||
&& type != GL_BLUE
|
&& type != GL_BLUE
|
||||||
&& type != GL_UNSIGNED_INT
|
&& type != GL_UNSIGNED_INT
|
||||||
&& type != GL_INT
|
&& type != GL_INT
|
||||||
&& type != GL_FLOAT) {
|
&& type != GL_FLOAT,
|
||||||
m_error = GL_INVALID_ENUM;
|
GL_INVALID_ENUM);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (format == GL_COLOR_INDEX) {
|
|
||||||
// FIXME: We only support RGBA buffers for now.
|
// FIXME: We only support RGBA buffers for now.
|
||||||
// Once we add support for indexed color modes do the correct check here
|
// Once we add support for indexed color modes do the correct check here
|
||||||
m_error = GL_INVALID_OPERATION;
|
RETURN_WITH_ERROR_IF(format == GL_COLOR_INDEX, GL_INVALID_OPERATION);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (format == GL_STENCIL_INDEX) {
|
|
||||||
// FIXME: We do not have stencil buffers yet
|
// FIXME: We do not have stencil buffers yet
|
||||||
// Once we add support for stencil buffers do the correct check here
|
// Once we add support for stencil buffers do the correct check here
|
||||||
m_error = GL_INVALID_OPERATION;
|
RETURN_WITH_ERROR_IF(format == GL_STENCIL_INDEX, GL_INVALID_OPERATION);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (format == GL_DEPTH_COMPONENT) {
|
if (format == GL_DEPTH_COMPONENT) {
|
||||||
// FIXME: This check needs to be a bit more sophisticated. Currently the buffers
|
// 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
|
// 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
|
// Error because only back buffer has a depth buffer
|
||||||
m_error = GL_INVALID_OPERATION;
|
RETURN_WITH_ERROR_IF(m_current_read_buffer == GL_FRONT
|
||||||
return;
|
|| 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
|
// Some helper functions for converting float values to integer types
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue