render: Make the GL backends cache and defer more state changes. SDL-ryan-batching-renderer
authorRyan C. Gordon <icculus@icculus.org>
Mon, 01 Oct 2018 22:53:45 -0400
branchSDL-ryan-batching-renderer
changeset 122822395434a074d
parent 12281 838c5562d05f
child 12283 6c108f3716d5
render: Make the GL backends cache and defer more state changes.
src/render/opengl/SDL_render_gl.c
src/render/opengles/SDL_render_gles.c
src/render/opengles2/SDL_render_gles2.c
     1.1 --- a/src/render/opengl/SDL_render_gl.c	Mon Oct 01 13:41:15 2018 -0400
     1.2 +++ b/src/render/opengl/SDL_render_gl.c	Mon Oct 01 22:53:45 2018 -0400
     1.3 @@ -62,11 +62,17 @@
     1.4  
     1.5  typedef struct
     1.6  {
     1.7 +    SDL_bool viewport_dirty;
     1.8      SDL_Rect viewport;
     1.9      SDL_Texture *texture;
    1.10 +    SDL_Texture *target;
    1.11 +    int drawablew;
    1.12 +    int drawableh;
    1.13      SDL_BlendMode blend;
    1.14      GL_Shader shader;
    1.15 +    SDL_bool cliprect_enabled_dirty;
    1.16      SDL_bool cliprect_enabled;
    1.17 +    SDL_bool cliprect_dirty;
    1.18      SDL_Rect cliprect;
    1.19      SDL_bool texturing;
    1.20      Uint32 color;
    1.21 @@ -934,6 +940,42 @@
    1.22  {
    1.23      const SDL_BlendMode blend = cmd->data.draw.blend;
    1.24  
    1.25 +    if (data->drawstate.viewport_dirty) {
    1.26 +        const SDL_bool istarget = data->drawstate.target != NULL;
    1.27 +        const SDL_Rect *viewport = &data->drawstate.viewport;
    1.28 +        data->glMatrixMode(GL_PROJECTION);
    1.29 +        data->glLoadIdentity();
    1.30 +        data->glViewport(viewport->x,
    1.31 +                         istarget ? viewport->y : (data->drawstate.drawableh - viewport->y - viewport->h),
    1.32 +                         viewport->w, viewport->h);
    1.33 +        if (viewport->w && viewport->h) {
    1.34 +            data->glOrtho((GLdouble) 0, (GLdouble) viewport->w,
    1.35 +                          (GLdouble) istarget ? 0 : viewport->h,
    1.36 +                          (GLdouble) istarget ? viewport->h : 0,
    1.37 +                          0.0, 1.0);
    1.38 +        }
    1.39 +        data->glMatrixMode(GL_MODELVIEW);
    1.40 +        data->drawstate.viewport_dirty = SDL_FALSE;
    1.41 +    }
    1.42 +
    1.43 +    if (data->drawstate.cliprect_enabled_dirty) {
    1.44 +        if (!data->drawstate.cliprect_enabled) {
    1.45 +            data->glDisable(GL_SCISSOR_TEST);
    1.46 +        } else {
    1.47 +            data->glEnable(GL_SCISSOR_TEST);
    1.48 +        }
    1.49 +        data->drawstate.cliprect_enabled_dirty = SDL_FALSE;
    1.50 +    }
    1.51 +
    1.52 +    if (data->drawstate.cliprect_enabled && data->drawstate.cliprect_dirty) {
    1.53 +        const SDL_Rect *viewport = &data->drawstate.viewport;
    1.54 +        const SDL_Rect *rect = &data->drawstate.cliprect;
    1.55 +        data->glScissor(viewport->x + rect->x,
    1.56 +                        data->drawstate.target ? viewport->y + rect->y : data->drawstate.drawableh - viewport->y - rect->y - rect->h,
    1.57 +                        rect->w, rect->h);
    1.58 +        data->drawstate.cliprect_dirty = SDL_FALSE;
    1.59 +    }
    1.60 +
    1.61      if (blend != data->drawstate.blend) {
    1.62          if (blend == SDL_BLENDMODE_NONE) {
    1.63              data->glDisable(GL_BLEND);
    1.64 @@ -1035,18 +1077,18 @@
    1.65  {
    1.66      /* !!! FIXME: it'd be nice to use a vertex buffer instead of immediate mode... */
    1.67      GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
    1.68 -    int drawablew = 0, drawableh = 0;
    1.69 -    const SDL_bool istarget = renderer->target != NULL;
    1.70      size_t i;
    1.71  
    1.72      if (GL_ActivateRenderer(renderer) < 0) {
    1.73          return -1;
    1.74      }
    1.75  
    1.76 -    if (!istarget) {
    1.77 -        SDL_GL_GetDrawableSize(renderer->window, &drawablew, &drawableh);
    1.78 +    data->drawstate.target = renderer->target;
    1.79 +    if (!data->drawstate.target) {
    1.80 +        SDL_GL_GetDrawableSize(renderer->window, &data->drawstate.drawablew, &data->drawstate.drawableh);
    1.81      }
    1.82  
    1.83 +
    1.84      while (cmd) {
    1.85          switch (cmd->command) {
    1.86              case SDL_RENDERCMD_SETDRAWCOLOR: {
    1.87 @@ -1069,18 +1111,7 @@
    1.88                  SDL_Rect *viewport = &data->drawstate.viewport;
    1.89                  if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)) != 0) {
    1.90                      SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect));
    1.91 -                    data->glMatrixMode(GL_PROJECTION);
    1.92 -                    data->glLoadIdentity();
    1.93 -                    data->glViewport(viewport->x,
    1.94 -                            istarget ? viewport->y : (drawableh - viewport->y - viewport->h),
    1.95 -                            viewport->w, viewport->h);
    1.96 -                    if (viewport->w && viewport->h) {
    1.97 -                        data->glOrtho((GLdouble) 0, (GLdouble) viewport->w,
    1.98 -                                      (GLdouble) istarget ? 0 : viewport->h,
    1.99 -                                      (GLdouble) istarget ? viewport->h : 0,
   1.100 -                                      0.0, 1.0);
   1.101 -                    }
   1.102 -                    data->glMatrixMode(GL_MODELVIEW);
   1.103 +                    data->drawstate.viewport_dirty = SDL_TRUE;
   1.104                  }
   1.105                  break;
   1.106              }
   1.107 @@ -1089,18 +1120,11 @@
   1.108                  const SDL_Rect *rect = &cmd->data.cliprect.rect;
   1.109                  if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) {
   1.110                      data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled;
   1.111 -                    if (!data->drawstate.cliprect_enabled) {
   1.112 -                        data->glDisable(GL_SCISSOR_TEST);
   1.113 -                    } else {
   1.114 -                        const SDL_Rect *viewport = &data->drawstate.viewport;
   1.115 -                        data->glEnable(GL_SCISSOR_TEST);
   1.116 -                        if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) {
   1.117 -                            data->glScissor(viewport->x + rect->x,
   1.118 -                                            istarget ? viewport->y + rect->y : drawableh - viewport->y - rect->y - rect->h,
   1.119 -                                            rect->w, rect->h);
   1.120 -                            SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect));
   1.121 -                        }
   1.122 -                    }
   1.123 +                    data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
   1.124 +                }
   1.125 +                if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) {
   1.126 +                    SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect));
   1.127 +                    data->drawstate.cliprect_dirty = SDL_TRUE;
   1.128                  }
   1.129                  break;
   1.130              }
   1.131 @@ -1122,13 +1146,11 @@
   1.132  
   1.133                  if (data->drawstate.cliprect_enabled) {
   1.134                      data->glDisable(GL_SCISSOR_TEST);
   1.135 +                    data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
   1.136                  }
   1.137  
   1.138                  data->glClear(GL_COLOR_BUFFER_BIT);
   1.139  
   1.140 -                if (data->drawstate.cliprect_enabled) {
   1.141 -                    data->glEnable(GL_SCISSOR_TEST);
   1.142 -                }
   1.143                  break;
   1.144              }
   1.145  
     2.1 --- a/src/render/opengles/SDL_render_gles.c	Mon Oct 01 13:41:15 2018 -0400
     2.2 +++ b/src/render/opengles/SDL_render_gles.c	Mon Oct 01 22:53:45 2018 -0400
     2.3 @@ -64,9 +64,15 @@
     2.4  typedef struct
     2.5  {
     2.6      SDL_Rect viewport;
     2.7 +    SDL_bool viewport_dirty;
     2.8      SDL_Texture *texture;
     2.9 +    SDL_Texture *target;
    2.10 +    int drawablew;
    2.11 +    int drawableh;
    2.12      SDL_BlendMode blend;
    2.13 +    SDL_bool cliprect_enabled_dirty;
    2.14      SDL_bool cliprect_enabled;
    2.15 +    SDL_bool cliprect_dirty;
    2.16      SDL_Rect cliprect;
    2.17      SDL_bool texturing;
    2.18      Uint32 color;
    2.19 @@ -692,6 +698,57 @@
    2.20  SetDrawState(GLES_RenderData *data, const SDL_RenderCommand *cmd)
    2.21  {
    2.22      const SDL_BlendMode blend = cmd->data.draw.blend;
    2.23 +    const Uint8 r = cmd->data.color.r;
    2.24 +    const Uint8 g = cmd->data.color.g;
    2.25 +    const Uint8 b = cmd->data.color.b;
    2.26 +    const Uint8 a = cmd->data.color.a;
    2.27 +    const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
    2.28 +
    2.29 +    if (color != data->drawstate.color) {
    2.30 +        const GLfloat fr = ((GLfloat) r) * inv255f;
    2.31 +        const GLfloat fg = ((GLfloat) g) * inv255f;
    2.32 +        const GLfloat fb = ((GLfloat) b) * inv255f;
    2.33 +        const GLfloat fa = ((GLfloat) a) * inv255f;
    2.34 +        data->glColor4f(fr, fg, fb, fa);
    2.35 +        data->drawstate.color = color;
    2.36 +    }
    2.37 +
    2.38 +    if (data->drawstate.viewport_dirty) {
    2.39 +        const SDL_Rect *viewport = &data->drawstate.viewport;
    2.40 +        const SDL_bool istarget = (data->drawstate.target != NULL);
    2.41 +        data->glMatrixMode(GL_PROJECTION);
    2.42 +        data->glLoadIdentity();
    2.43 +        data->glViewport(viewport->x,
    2.44 +                         istarget ? viewport->y : (data->drawstate.drawableh - viewport->y - viewport->h),
    2.45 +                         viewport->w, viewport->h);
    2.46 +        if (viewport->w && viewport->h) {
    2.47 +            data->glOrthof((GLfloat) 0, (GLfloat) viewport->w,
    2.48 +                           (GLfloat) istarget ? 0 : viewport->h,
    2.49 +                           (GLfloat) istarget ? viewport->h : 0,
    2.50 +                           0.0, 1.0);
    2.51 +        }
    2.52 +        data->glMatrixMode(GL_MODELVIEW);
    2.53 +        data->drawstate.viewport_dirty = SDL_FALSE;
    2.54 +    }
    2.55 +
    2.56 +    if (data->drawstate.cliprect_enabled_dirty) {
    2.57 +        if (data->drawstate.cliprect_enabled) {
    2.58 +            data->glEnable(GL_SCISSOR_TEST);
    2.59 +        } else {
    2.60 +            data->glDisable(GL_SCISSOR_TEST);
    2.61 +        }
    2.62 +        data->drawstate.cliprect_enabled_dirty = SDL_FALSE;
    2.63 +    }
    2.64 +
    2.65 +    if (data->drawstate.cliprect_enabled && data->drawstate.cliprect_dirty) {
    2.66 +        const SDL_Rect *viewport = &data->drawstate.viewport;
    2.67 +        const SDL_Rect *rect = &data->drawstate.cliprect;
    2.68 +        const SDL_bool istarget = (data->drawstate.target != NULL);
    2.69 +        data->glScissor(viewport->x + rect->x,
    2.70 +                        istarget ? viewport->y + rect->y : data->drawstate.drawableh - viewport->y - rect->y - rect->h,
    2.71 +                        rect->w, rect->h);
    2.72 +        data->drawstate.cliprect_dirty = SDL_FALSE;
    2.73 +    }
    2.74  
    2.75      if (blend != data->drawstate.blend) {
    2.76          if (blend == SDL_BLENDMODE_NONE) {
    2.77 @@ -747,52 +804,29 @@
    2.78  GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
    2.79  {
    2.80      GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
    2.81 -    int drawablew = 0, drawableh = 0;
    2.82 -    const SDL_bool istarget = renderer->target != NULL;
    2.83      size_t i;
    2.84  
    2.85      if (GLES_ActivateRenderer(renderer) < 0) {
    2.86          return -1;
    2.87      }
    2.88  
    2.89 -    if (!istarget) {
    2.90 -        SDL_GL_GetDrawableSize(renderer->window, &drawablew, &drawableh);
    2.91 +    data->drawstate.target = renderer->target;
    2.92 +
    2.93 +    if (!renderer->target) {
    2.94 +        SDL_GL_GetDrawableSize(renderer->window, &data->drawstate.drawablew, &data->drawstate.drawableh);
    2.95      }
    2.96  
    2.97      while (cmd) {
    2.98          switch (cmd->command) {
    2.99              case SDL_RENDERCMD_SETDRAWCOLOR: {
   2.100 -                const Uint8 r = cmd->data.color.r;
   2.101 -                const Uint8 g = cmd->data.color.g;
   2.102 -                const Uint8 b = cmd->data.color.b;
   2.103 -                const Uint8 a = cmd->data.color.a;
   2.104 -                const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
   2.105 -                if (color != data->drawstate.color) {
   2.106 -                    data->glColor4f((GLfloat) r * inv255f,
   2.107 -                                    (GLfloat) g * inv255f,
   2.108 -                                    (GLfloat) b * inv255f,
   2.109 -                                    (GLfloat) a * inv255f);
   2.110 -                    data->drawstate.color = color;
   2.111 -                }
   2.112 -                break;
   2.113 +                break;  /* not used in this render backend. */
   2.114              }
   2.115  
   2.116              case SDL_RENDERCMD_SETVIEWPORT: {
   2.117                  SDL_Rect *viewport = &data->drawstate.viewport;
   2.118                  if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)) != 0) {
   2.119                      SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect));
   2.120 -                    data->glMatrixMode(GL_PROJECTION);
   2.121 -                    data->glLoadIdentity();
   2.122 -                    data->glViewport(viewport->x,
   2.123 -                            istarget ? viewport->y : (drawableh - viewport->y - viewport->h),
   2.124 -                            viewport->w, viewport->h);
   2.125 -                    if (viewport->w && viewport->h) {
   2.126 -                        data->glOrthof((GLfloat) 0, (GLfloat) viewport->w,
   2.127 -                                      (GLfloat) istarget ? 0 : viewport->h,
   2.128 -                                      (GLfloat) istarget ? viewport->h : 0,
   2.129 -                                      0.0, 1.0);
   2.130 -                    }
   2.131 -                    data->glMatrixMode(GL_MODELVIEW);
   2.132 +                    data->drawstate.viewport_dirty = SDL_TRUE;
   2.133                  }
   2.134                  break;
   2.135              }
   2.136 @@ -801,18 +835,11 @@
   2.137                  const SDL_Rect *rect = &cmd->data.cliprect.rect;
   2.138                  if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) {
   2.139                      data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled;
   2.140 -                    if (!data->drawstate.cliprect_enabled) {
   2.141 -                        data->glDisable(GL_SCISSOR_TEST);
   2.142 -                    } else {
   2.143 -                        const SDL_Rect *viewport = &data->drawstate.viewport;
   2.144 -                        data->glEnable(GL_SCISSOR_TEST);
   2.145 -                        if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) {
   2.146 -                            data->glScissor(viewport->x + rect->x,
   2.147 -                                            istarget ? viewport->y + rect->y : drawableh - viewport->y - rect->y - rect->h,
   2.148 -                                            rect->w, rect->h);
   2.149 -                            SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect));
   2.150 -                        }
   2.151 -                    }
   2.152 +                    data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
   2.153 +                }
   2.154 +                if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) {
   2.155 +                    SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect));
   2.156 +                    data->drawstate.cliprect_dirty = SDL_TRUE;
   2.157                  }
   2.158                  break;
   2.159              }
   2.160 @@ -834,13 +861,11 @@
   2.161  
   2.162                  if (data->drawstate.cliprect_enabled) {
   2.163                      data->glDisable(GL_SCISSOR_TEST);
   2.164 +                    data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
   2.165                  }
   2.166  
   2.167                  data->glClear(GL_COLOR_BUFFER_BIT);
   2.168  
   2.169 -                if (data->drawstate.cliprect_enabled) {
   2.170 -                    data->glEnable(GL_SCISSOR_TEST);
   2.171 -                }
   2.172                  break;
   2.173              }
   2.174  
     3.1 --- a/src/render/opengles2/SDL_render_gles2.c	Mon Oct 01 13:41:15 2018 -0400
     3.2 +++ b/src/render/opengles2/SDL_render_gles2.c	Mon Oct 01 22:53:45 2018 -0400
     3.3 @@ -136,14 +136,20 @@
     3.4  typedef struct
     3.5  {
     3.6      SDL_Rect viewport;
     3.7 +    SDL_bool viewport_dirty;
     3.8      SDL_Texture *texture;
     3.9 +    SDL_Texture *target;
    3.10      SDL_BlendMode blend;
    3.11 +    SDL_bool cliprect_enabled_dirty;
    3.12      SDL_bool cliprect_enabled;
    3.13 +    SDL_bool cliprect_dirty;
    3.14      SDL_Rect cliprect;
    3.15      SDL_bool texturing;
    3.16      SDL_bool is_copy_ex;
    3.17      Uint32 color;
    3.18      Uint32 clear_color;
    3.19 +    int drawablew;
    3.20 +    int drawableh;
    3.21      GLES2_ProgramCacheEntry *program;
    3.22      GLfloat projection[4][4];
    3.23  } GLES2_DrawStateCache;
    3.24 @@ -944,6 +950,37 @@
    3.25  
    3.26      SDL_assert((texture != NULL) == (imgsrc != GLES2_IMAGESOURCE_SOLID));
    3.27  
    3.28 +    if (data->drawstate.viewport_dirty) {
    3.29 +        const SDL_Rect *viewport = &data->drawstate.viewport;
    3.30 +        data->glViewport(viewport->x,
    3.31 +                         data->drawstate.target ? viewport->y : (data->drawstate.drawableh - viewport->y - viewport->h),
    3.32 +                         viewport->w, viewport->h);
    3.33 +        if (viewport->w && viewport->h) {
    3.34 +            data->drawstate.projection[0][0] = 2.0f / viewport->w;
    3.35 +            data->drawstate.projection[1][1] = (data->drawstate.target ? 2.0f : -2.0f) / viewport->h;
    3.36 +            data->drawstate.projection[3][1] = data->drawstate.target ? -1.0f : 1.0f;
    3.37 +        }
    3.38 +        data->drawstate.viewport_dirty = SDL_FALSE;
    3.39 +    }
    3.40 +
    3.41 +    if (data->drawstate.cliprect_enabled_dirty) {
    3.42 +        if (!data->drawstate.cliprect_enabled) {
    3.43 +            data->glDisable(GL_SCISSOR_TEST);
    3.44 +        } else {
    3.45 +            data->glEnable(GL_SCISSOR_TEST);
    3.46 +        }
    3.47 +        data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
    3.48 +    }
    3.49 +
    3.50 +    if (data->drawstate.cliprect_enabled && data->drawstate.cliprect_dirty) {
    3.51 +        const SDL_Rect *viewport = &data->drawstate.viewport;
    3.52 +        const SDL_Rect *rect = &data->drawstate.cliprect;
    3.53 +        data->glScissor(viewport->x + rect->x,
    3.54 +                        data->drawstate.target ? viewport->y + rect->y : data->drawstate.drawableh - viewport->y - rect->y - rect->h,
    3.55 +                        rect->w, rect->h);
    3.56 +        SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect));
    3.57 +    }
    3.58 +
    3.59      if (texture != data->drawstate.texture) {
    3.60          if ((texture != NULL) != data->drawstate.texturing) {
    3.61              if (texture == NULL) {
    3.62 @@ -1157,16 +1194,15 @@
    3.63      const SDL_bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_ARGB8888 || renderer->target->format == SDL_PIXELFORMAT_RGB888));
    3.64      const int vboidx = data->current_vertex_buffer;
    3.65      const GLuint vbo = data->vertex_buffers[vboidx];
    3.66 -    int drawablew = 0, drawableh = 0;
    3.67 -    const SDL_bool istarget = renderer->target != NULL;
    3.68      size_t i;
    3.69  
    3.70      if (GLES2_ActivateRenderer(renderer) < 0) {
    3.71          return -1;
    3.72      }
    3.73  
    3.74 -    if (!istarget) {
    3.75 -        SDL_GL_GetDrawableSize(renderer->window, &drawablew, &drawableh);
    3.76 +    data->drawstate.target = renderer->target;
    3.77 +    if (!data->drawstate.target) {
    3.78 +        SDL_GL_GetDrawableSize(renderer->window, &data->drawstate.drawablew, &data->drawstate.drawableh);
    3.79      }
    3.80  
    3.81      /* upload the new VBO data for this set of commands. */
    3.82 @@ -1199,14 +1235,7 @@
    3.83                  SDL_Rect *viewport = &data->drawstate.viewport;
    3.84                  if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)) != 0) {
    3.85                      SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect));
    3.86 -                    data->glViewport(viewport->x,
    3.87 -                            istarget ? viewport->y : (drawableh - viewport->y - viewport->h),
    3.88 -                            viewport->w, viewport->h);
    3.89 -                    if (viewport->w && viewport->h) {
    3.90 -                        data->drawstate.projection[0][0] = 2.0f / viewport->w;
    3.91 -                        data->drawstate.projection[1][1] = (renderer->target ? 2.0f : -2.0f) / viewport->h;
    3.92 -                        data->drawstate.projection[3][1] = renderer->target ? -1.0f : 1.0f;
    3.93 -                    }
    3.94 +                    data->drawstate.viewport_dirty = SDL_TRUE;
    3.95                  }
    3.96                  break;
    3.97              }
    3.98 @@ -1215,32 +1244,26 @@
    3.99                  const SDL_Rect *rect = &cmd->data.cliprect.rect;
   3.100                  if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) {
   3.101                      data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled;
   3.102 -                    if (!data->drawstate.cliprect_enabled) {
   3.103 -                        data->glDisable(GL_SCISSOR_TEST);
   3.104 -                    } else {
   3.105 -                        const SDL_Rect *viewport = &data->drawstate.viewport;
   3.106 -                        data->glEnable(GL_SCISSOR_TEST);
   3.107 -                        if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) {
   3.108 -                            data->glScissor(viewport->x + rect->x,
   3.109 -                                            istarget ? viewport->y + rect->y : drawableh - viewport->y - rect->y - rect->h,
   3.110 -                                            rect->w, rect->h);
   3.111 -                            SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect));
   3.112 -                        }
   3.113 -                    }
   3.114 +                    data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
   3.115 +                }
   3.116 +
   3.117 +                if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) {
   3.118 +                    SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect));
   3.119 +                    data->drawstate.cliprect_dirty = SDL_TRUE;
   3.120                  }
   3.121                  break;
   3.122              }
   3.123  
   3.124              case SDL_RENDERCMD_CLEAR: {
   3.125 -                const Uint8 r = cmd->data.color.r;
   3.126 +                const Uint8 r = colorswap ? cmd->data.color.b : cmd->data.color.r;
   3.127                  const Uint8 g = cmd->data.color.g;
   3.128 -                const Uint8 b = cmd->data.color.b;
   3.129 +                const Uint8 b = colorswap ? cmd->data.color.r : cmd->data.color.b;
   3.130                  const Uint8 a = cmd->data.color.a;
   3.131                  const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
   3.132                  if (color != data->drawstate.clear_color) {
   3.133 -                    const GLfloat fr = ((GLfloat) colorswap ? b : r) * inv255f;
   3.134 +                    const GLfloat fr = ((GLfloat) r) * inv255f;
   3.135                      const GLfloat fg = ((GLfloat) g) * inv255f;
   3.136 -                    const GLfloat fb = ((GLfloat) colorswap ? r : b) * inv255f;
   3.137 +                    const GLfloat fb = ((GLfloat) b) * inv255f;
   3.138                      const GLfloat fa = ((GLfloat) a) * inv255f;
   3.139                      data->glClearColor(fr, fg, fb, fa);
   3.140                      data->drawstate.clear_color = color;
   3.141 @@ -1248,13 +1271,10 @@
   3.142  
   3.143                  if (data->drawstate.cliprect_enabled) {
   3.144                      data->glDisable(GL_SCISSOR_TEST);
   3.145 +                    data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
   3.146                  }
   3.147  
   3.148                  data->glClear(GL_COLOR_BUFFER_BIT);
   3.149 -
   3.150 -                if (data->drawstate.cliprect_enabled) {
   3.151 -                    data->glEnable(GL_SCISSOR_TEST);
   3.152 -                }
   3.153                  break;
   3.154              }
   3.155