Render: Allow empty cliprect.
authorJørgen P. Tjernø <jorgenpt@gmail.com>
Sat, 19 Apr 2014 13:15:41 -0700
changeset 8728c7174f961388
parent 8726 9a5a5808aa14
child 8729 94af945dbb57
Render: Allow empty cliprect.

This fixes an issue where an empty cliprect is treated the same as a NULL
cliprect, causing the render backends to disable clipping.

Also adds a new API, SDL_RenderIsClipEnabled(render) that allows you to
differentiate between:
- SDL_RenderSetClipRect(render, NULL)
- SDL_Rect r = {0,0,0,0}; SDL_RenderSetClipRect(render, &r);

Fixes https://bugzilla.libsdl.org/show_bug.cgi?id=2504
include/SDL_render.h
src/dynapi/SDL_dynapi_overrides.h
src/dynapi/SDL_dynapi_procs.h
src/render/SDL_render.c
src/render/SDL_sysrender.h
src/render/direct3d/SDL_render_d3d.c
src/render/direct3d11/SDL_render_d3d11.c
src/render/opengl/SDL_render_gl.c
src/render/opengles/SDL_render_gles.c
src/render/opengles2/SDL_render_gles2.c
src/render/software/SDL_render_sw.c
     1.1 --- a/include/SDL_render.h	Sat Apr 19 10:17:36 2014 -0700
     1.2 +++ b/include/SDL_render.h	Sat Apr 19 13:15:41 2014 -0700
     1.3 @@ -552,6 +552,16 @@
     1.4                                                     SDL_Rect * rect);
     1.5  
     1.6  /**
     1.7 + *  \brief Get wether clipping is enabled on the given renderer
     1.8 + *
     1.9 + *  \param renderer The renderer from which clip state should be queried.
    1.10 + *
    1.11 + *  \sa SDL_RenderGetClipRect()
    1.12 + */
    1.13 +extern DECLSPEC SDL_bool SDLCALL SDL_RenderIsClipEnabled(SDL_Renderer * renderer);
    1.14 +
    1.15 +
    1.16 +/**
    1.17   *  \brief Set the drawing scale for rendering on the current target.
    1.18   *
    1.19   *  \param renderer The renderer for which the drawing scale should be set.
     2.1 --- a/src/dynapi/SDL_dynapi_overrides.h	Sat Apr 19 10:17:36 2014 -0700
     2.2 +++ b/src/dynapi/SDL_dynapi_overrides.h	Sat Apr 19 13:15:41 2014 -0700
     2.3 @@ -575,3 +575,4 @@
     2.4  #define SDL_GetDefaultAssertionHandler SDL_GetDefaultAssertionHandler_REAL
     2.5  #define SDL_GetAssertionHandler SDL_GetAssertionHandler_REAL
     2.6  #define SDL_DXGIGetOutputInfo SDL_DXGIGetOutputInfo_REAL
     2.7 +#define SDL_RenderIsClipEnabled SDL_RenderIsClipEnabled_REAL
     3.1 --- a/src/dynapi/SDL_dynapi_procs.h	Sat Apr 19 10:17:36 2014 -0700
     3.2 +++ b/src/dynapi/SDL_dynapi_procs.h	Sat Apr 19 13:15:41 2014 -0700
     3.3 @@ -606,3 +606,4 @@
     3.4  #ifdef __WIN32__
     3.5  SDL_DYNAPI_PROC(SDL_bool,SDL_DXGIGetOutputInfo,(int a,int *b, int *c),(a,b,c),return)
     3.6  #endif
     3.7 +SDL_DYNAPI_PROC(SDL_bool,SDL_RenderIsClipEnabled,(SDL_Renderer *a),(a),return)
     4.1 --- a/src/render/SDL_render.c	Sat Apr 19 10:17:36 2014 -0700
     4.2 +++ b/src/render/SDL_render.c	Sat Apr 19 13:15:41 2014 -0700
     4.3 @@ -1071,6 +1071,7 @@
     4.4          /* Make a backup of the viewport */
     4.5          renderer->viewport_backup = renderer->viewport;
     4.6          renderer->clip_rect_backup = renderer->clip_rect;
     4.7 +        renderer->clipping_enabled_backup = renderer->clipping_enabled;
     4.8          renderer->scale_backup = renderer->scale;
     4.9          renderer->logical_w_backup = renderer->logical_w;
    4.10          renderer->logical_h_backup = renderer->logical_h;
    4.11 @@ -1093,6 +1094,7 @@
    4.12      } else {
    4.13          renderer->viewport = renderer->viewport_backup;
    4.14          renderer->clip_rect = renderer->clip_rect_backup;
    4.15 +        renderer->clipping_enabled = renderer->clipping_enabled_backup;
    4.16          renderer->scale = renderer->scale_backup;
    4.17          renderer->logical_w = renderer->logical_w_backup;
    4.18          renderer->logical_h = renderer->logical_h_backup;
    4.19 @@ -1233,11 +1235,13 @@
    4.20      CHECK_RENDERER_MAGIC(renderer, -1)
    4.21  
    4.22      if (rect) {
    4.23 +        renderer->clipping_enabled = SDL_TRUE;
    4.24          renderer->clip_rect.x = (int)SDL_floor(rect->x * renderer->scale.x);
    4.25          renderer->clip_rect.y = (int)SDL_floor(rect->y * renderer->scale.y);
    4.26          renderer->clip_rect.w = (int)SDL_ceil(rect->w * renderer->scale.x);
    4.27          renderer->clip_rect.h = (int)SDL_ceil(rect->h * renderer->scale.y);
    4.28      } else {
    4.29 +        renderer->clipping_enabled = SDL_FALSE;
    4.30          SDL_zero(renderer->clip_rect);
    4.31      }
    4.32      return renderer->UpdateClipRect(renderer);
    4.33 @@ -1256,6 +1260,13 @@
    4.34      }
    4.35  }
    4.36  
    4.37 +SDL_bool
    4.38 +SDL_RenderIsClipEnabled(SDL_Renderer * renderer)
    4.39 +{
    4.40 +    CHECK_RENDERER_MAGIC(renderer, SDL_FALSE)
    4.41 +    return renderer->clipping_enabled;
    4.42 +}
    4.43 +
    4.44  int
    4.45  SDL_RenderSetScale(SDL_Renderer * renderer, float scaleX, float scaleY)
    4.46  {
     5.1 --- a/src/render/SDL_sysrender.h	Sat Apr 19 10:17:36 2014 -0700
     5.2 +++ b/src/render/SDL_sysrender.h	Sat Apr 19 13:15:41 2014 -0700
     5.3 @@ -143,6 +143,10 @@
     5.4      SDL_Rect clip_rect;
     5.5      SDL_Rect clip_rect_backup;
     5.6  
     5.7 +    /* Wether or not the clipping rectangle is used. */
     5.8 +    SDL_bool clipping_enabled;
     5.9 +    SDL_bool clipping_enabled_backup;
    5.10 +
    5.11      /* The render output coordinate scale */
    5.12      SDL_FPoint scale;
    5.13      SDL_FPoint scale_backup;
     6.1 --- a/src/render/direct3d/SDL_render_d3d.c	Sat Apr 19 10:17:36 2014 -0700
     6.2 +++ b/src/render/direct3d/SDL_render_d3d.c	Sat Apr 19 13:15:41 2014 -0700
     6.3 @@ -1145,12 +1145,13 @@
     6.4  static int
     6.5  D3D_UpdateClipRect(SDL_Renderer * renderer)
     6.6  {
     6.7 -    const SDL_Rect *rect = &renderer->clip_rect;
     6.8      D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
     6.9 -    RECT r;
    6.10 -    HRESULT result;
    6.11  
    6.12 -    if (!SDL_RectEmpty(rect)) {
    6.13 +    if (renderer->clipping_enabled) {
    6.14 +        const SDL_Rect *rect = &renderer->clip_rect;
    6.15 +        RECT r;
    6.16 +        HRESULT result;
    6.17 +
    6.18          IDirect3DDevice9_SetRenderState(data->device, D3DRS_SCISSORTESTENABLE, TRUE);
    6.19          r.left = rect->x;
    6.20          r.top = rect->y;
     7.1 --- a/src/render/direct3d11/SDL_render_d3d11.c	Sat Apr 19 10:17:36 2014 -0700
     7.2 +++ b/src/render/direct3d11/SDL_render_d3d11.c	Sat Apr 19 13:15:41 2014 -0700
     7.3 @@ -2232,13 +2232,12 @@
     7.4  D3D11_UpdateClipRect(SDL_Renderer * renderer)
     7.5  {
     7.6      D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
     7.7 -    const SDL_Rect *rect = &renderer->clip_rect;
     7.8  
     7.9 -    if (SDL_RectEmpty(rect)) {
    7.10 +    if (!renderer->clipping_enabled) {
    7.11          ID3D11DeviceContext_RSSetScissorRects(data->d3dContext, 0, NULL);
    7.12      } else {
    7.13          D3D11_RECT scissorRect;
    7.14 -        if (D3D11_GetViewportAlignedD3DRect(renderer, rect, &scissorRect) != 0) {
    7.15 +        if (D3D11_GetViewportAlignedD3DRect(renderer, &renderer->clip_rect, &scissorRect) != 0) {
    7.16              /* D3D11_GetViewportAlignedD3DRect will have set the SDL error */
    7.17              return -1;
    7.18          }
    7.19 @@ -2366,7 +2365,7 @@
    7.20          rendererData->currentRenderTargetView = renderTargetView;
    7.21      }
    7.22  
    7.23 -    if (SDL_RectEmpty(&renderer->clip_rect)) {
    7.24 +    if (!renderer->clipping_enabled) {
    7.25          rasterizerState = rendererData->mainRasterizer;
    7.26      } else {
    7.27          rasterizerState = rendererData->clippedRasterizer;
     8.1 --- a/src/render/opengl/SDL_render_gl.c	Sat Apr 19 10:17:36 2014 -0700
     8.2 +++ b/src/render/opengl/SDL_render_gl.c	Sat Apr 19 13:15:41 2014 -0700
     8.3 @@ -976,10 +976,10 @@
     8.4  static int
     8.5  GL_UpdateClipRect(SDL_Renderer * renderer)
     8.6  {
     8.7 -    const SDL_Rect *rect = &renderer->clip_rect;
     8.8      GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
     8.9  
    8.10 -    if (!SDL_RectEmpty(rect)) {
    8.11 +    if (renderer->clipping_enabled) {
    8.12 +        const SDL_Rect *rect = &renderer->clip_rect;
    8.13          data->glEnable(GL_SCISSOR_TEST);
    8.14          data->glScissor(rect->x, renderer->viewport.h - rect->y - rect->h, rect->w, rect->h);
    8.15      } else {
     9.1 --- a/src/render/opengles/SDL_render_gles.c	Sat Apr 19 10:17:36 2014 -0700
     9.2 +++ b/src/render/opengles/SDL_render_gles.c	Sat Apr 19 13:15:41 2014 -0700
     9.3 @@ -684,14 +684,14 @@
     9.4  GLES_UpdateClipRect(SDL_Renderer * renderer)
     9.5  {
     9.6      GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
     9.7 -    const SDL_Rect *rect = &renderer->clip_rect;
     9.8  
     9.9      if (SDL_CurrentContext != data->context) {
    9.10          /* We'll update the clip rect after we rebind the context */
    9.11          return 0;
    9.12      }
    9.13  
    9.14 -    if (!SDL_RectEmpty(rect)) {
    9.15 +    if (renderer->clipping_enabled) {
    9.16 +        const SDL_Rect *rect = &renderer->clip_rect;
    9.17          data->glEnable(GL_SCISSOR_TEST);
    9.18          data->glScissor(rect->x, renderer->viewport.h - rect->y - rect->h, rect->w, rect->h);
    9.19      } else {
    10.1 --- a/src/render/opengles2/SDL_render_gles2.c	Sat Apr 19 10:17:36 2014 -0700
    10.2 +++ b/src/render/opengles2/SDL_render_gles2.c	Sat Apr 19 13:15:41 2014 -0700
    10.3 @@ -362,14 +362,14 @@
    10.4  GLES2_UpdateClipRect(SDL_Renderer * renderer)
    10.5  {
    10.6      GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
    10.7 -    const SDL_Rect *rect = &renderer->clip_rect;
    10.8  
    10.9      if (SDL_CurrentContext != data->context) {
   10.10          /* We'll update the clip rect after we rebind the context */
   10.11          return 0;
   10.12      }
   10.13  
   10.14 -    if (!SDL_RectEmpty(rect)) {
   10.15 +    if (renderer->clipping_enabled) {
   10.16 +        const SDL_Rect *rect = &renderer->clip_rect;
   10.17          data->glEnable(GL_SCISSOR_TEST);
   10.18          data->glScissor(rect->x, renderer->viewport.h - rect->y - rect->h, rect->w, rect->h);
   10.19      } else {
    11.1 --- a/src/render/software/SDL_render_sw.c	Sat Apr 19 10:17:36 2014 -0700
    11.2 +++ b/src/render/software/SDL_render_sw.c	Sat Apr 19 13:15:41 2014 -0700
    11.3 @@ -347,11 +347,9 @@
    11.4  {
    11.5      SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
    11.6      SDL_Surface *surface = data->surface;
    11.7 -    const SDL_Rect *rect = &renderer->clip_rect;
    11.8 -
    11.9      if (surface) {
   11.10 -        if (!SDL_RectEmpty(rect)) {
   11.11 -            SDL_SetClipRect(surface, rect);
   11.12 +        if (renderer->clipping_enabled) {
   11.13 +            SDL_SetClipRect(surface, &renderer->clip_rect);
   11.14          } else {
   11.15              SDL_SetClipRect(surface, NULL);
   11.16          }