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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
diff --git a/include/SDL_render.h b/include/SDL_render.h
index 77f706a..192e502 100644
--- a/include/SDL_render.h
+++ b/include/SDL_render.h
@@ -552,6 +552,16 @@ extern DECLSPEC void SDLCALL SDL_RenderGetClipRect(SDL_Renderer * renderer,
SDL_Rect * rect);
/**
+ * \brief Get wether clipping is enabled on the given renderer
+ *
+ * \param renderer The renderer from which clip state should be queried.
+ *
+ * \sa SDL_RenderGetClipRect()
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_RenderIsClipEnabled(SDL_Renderer * renderer);
+
+
+/**
* \brief Set the drawing scale for rendering on the current target.
*
* \param renderer The renderer for which the drawing scale should be set.
diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
index 5ae7927..f03f4b2 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -575,3 +575,4 @@
#define SDL_GetDefaultAssertionHandler SDL_GetDefaultAssertionHandler_REAL
#define SDL_GetAssertionHandler SDL_GetAssertionHandler_REAL
#define SDL_DXGIGetOutputInfo SDL_DXGIGetOutputInfo_REAL
+#define SDL_RenderIsClipEnabled SDL_RenderIsClipEnabled_REAL
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index ed0ea86..9c65205 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -606,3 +606,4 @@ SDL_DYNAPI_PROC(SDL_AssertionHandler,SDL_GetAssertionHandler,(void **a),(a),retu
#ifdef __WIN32__
SDL_DYNAPI_PROC(SDL_bool,SDL_DXGIGetOutputInfo,(int a,int *b, int *c),(a,b,c),return)
#endif
+SDL_DYNAPI_PROC(SDL_bool,SDL_RenderIsClipEnabled,(SDL_Renderer *a),(a),return)
diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c
index 2a5ea41..3aea6bc 100644
--- a/src/render/SDL_render.c
+++ b/src/render/SDL_render.c
@@ -1071,6 +1071,7 @@ SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
/* Make a backup of the viewport */
renderer->viewport_backup = renderer->viewport;
renderer->clip_rect_backup = renderer->clip_rect;
+ renderer->clipping_enabled_backup = renderer->clipping_enabled;
renderer->scale_backup = renderer->scale;
renderer->logical_w_backup = renderer->logical_w;
renderer->logical_h_backup = renderer->logical_h;
@@ -1093,6 +1094,7 @@ SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
} else {
renderer->viewport = renderer->viewport_backup;
renderer->clip_rect = renderer->clip_rect_backup;
+ renderer->clipping_enabled = renderer->clipping_enabled_backup;
renderer->scale = renderer->scale_backup;
renderer->logical_w = renderer->logical_w_backup;
renderer->logical_h = renderer->logical_h_backup;
@@ -1233,11 +1235,13 @@ SDL_RenderSetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect)
CHECK_RENDERER_MAGIC(renderer, -1)
if (rect) {
+ renderer->clipping_enabled = SDL_TRUE;
renderer->clip_rect.x = (int)SDL_floor(rect->x * renderer->scale.x);
renderer->clip_rect.y = (int)SDL_floor(rect->y * renderer->scale.y);
renderer->clip_rect.w = (int)SDL_ceil(rect->w * renderer->scale.x);
renderer->clip_rect.h = (int)SDL_ceil(rect->h * renderer->scale.y);
} else {
+ renderer->clipping_enabled = SDL_FALSE;
SDL_zero(renderer->clip_rect);
}
return renderer->UpdateClipRect(renderer);
@@ -1256,6 +1260,13 @@ SDL_RenderGetClipRect(SDL_Renderer * renderer, SDL_Rect * rect)
}
}
+SDL_bool
+SDL_RenderIsClipEnabled(SDL_Renderer * renderer)
+{
+ CHECK_RENDERER_MAGIC(renderer, SDL_FALSE)
+ return renderer->clipping_enabled;
+}
+
int
SDL_RenderSetScale(SDL_Renderer * renderer, float scaleX, float scaleY)
{
diff --git a/src/render/SDL_sysrender.h b/src/render/SDL_sysrender.h
index 5098d34..aba4bbb 100644
--- a/src/render/SDL_sysrender.h
+++ b/src/render/SDL_sysrender.h
@@ -143,6 +143,10 @@ struct SDL_Renderer
SDL_Rect clip_rect;
SDL_Rect clip_rect_backup;
+ /* Wether or not the clipping rectangle is used. */
+ SDL_bool clipping_enabled;
+ SDL_bool clipping_enabled_backup;
+
/* The render output coordinate scale */
SDL_FPoint scale;
SDL_FPoint scale_backup;
diff --git a/src/render/direct3d/SDL_render_d3d.c b/src/render/direct3d/SDL_render_d3d.c
index 2448281..d462ca8 100644
--- a/src/render/direct3d/SDL_render_d3d.c
+++ b/src/render/direct3d/SDL_render_d3d.c
@@ -1145,12 +1145,13 @@ D3D_UpdateViewport(SDL_Renderer * renderer)
static int
D3D_UpdateClipRect(SDL_Renderer * renderer)
{
- const SDL_Rect *rect = &renderer->clip_rect;
D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
- RECT r;
- HRESULT result;
- if (!SDL_RectEmpty(rect)) {
+ if (renderer->clipping_enabled) {
+ const SDL_Rect *rect = &renderer->clip_rect;
+ RECT r;
+ HRESULT result;
+
IDirect3DDevice9_SetRenderState(data->device, D3DRS_SCISSORTESTENABLE, TRUE);
r.left = rect->x;
r.top = rect->y;
diff --git a/src/render/direct3d11/SDL_render_d3d11.c b/src/render/direct3d11/SDL_render_d3d11.c
index 806846c..27ca61f 100644
--- a/src/render/direct3d11/SDL_render_d3d11.c
+++ b/src/render/direct3d11/SDL_render_d3d11.c
@@ -2232,13 +2232,12 @@ static int
D3D11_UpdateClipRect(SDL_Renderer * renderer)
{
D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
- const SDL_Rect *rect = &renderer->clip_rect;
- if (SDL_RectEmpty(rect)) {
+ if (!renderer->clipping_enabled) {
ID3D11DeviceContext_RSSetScissorRects(data->d3dContext, 0, NULL);
} else {
D3D11_RECT scissorRect;
- if (D3D11_GetViewportAlignedD3DRect(renderer, rect, &scissorRect) != 0) {
+ if (D3D11_GetViewportAlignedD3DRect(renderer, &renderer->clip_rect, &scissorRect) != 0) {
/* D3D11_GetViewportAlignedD3DRect will have set the SDL error */
return -1;
}
@@ -2366,7 +2365,7 @@ D3D11_RenderStartDrawOp(SDL_Renderer * renderer)
rendererData->currentRenderTargetView = renderTargetView;
}
- if (SDL_RectEmpty(&renderer->clip_rect)) {
+ if (!renderer->clipping_enabled) {
rasterizerState = rendererData->mainRasterizer;
} else {
rasterizerState = rendererData->clippedRasterizer;
diff --git a/src/render/opengl/SDL_render_gl.c b/src/render/opengl/SDL_render_gl.c
index 6962267..20a7f66 100644
--- a/src/render/opengl/SDL_render_gl.c
+++ b/src/render/opengl/SDL_render_gl.c
@@ -976,10 +976,10 @@ GL_UpdateViewport(SDL_Renderer * renderer)
static int
GL_UpdateClipRect(SDL_Renderer * renderer)
{
- const SDL_Rect *rect = &renderer->clip_rect;
GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
- if (!SDL_RectEmpty(rect)) {
+ if (renderer->clipping_enabled) {
+ const SDL_Rect *rect = &renderer->clip_rect;
data->glEnable(GL_SCISSOR_TEST);
data->glScissor(rect->x, renderer->viewport.h - rect->y - rect->h, rect->w, rect->h);
} else {
diff --git a/src/render/opengles/SDL_render_gles.c b/src/render/opengles/SDL_render_gles.c
index 43a07a4..dcfd41b 100644
--- a/src/render/opengles/SDL_render_gles.c
+++ b/src/render/opengles/SDL_render_gles.c
@@ -684,14 +684,14 @@ static int
GLES_UpdateClipRect(SDL_Renderer * renderer)
{
GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
- const SDL_Rect *rect = &renderer->clip_rect;
if (SDL_CurrentContext != data->context) {
/* We'll update the clip rect after we rebind the context */
return 0;
}
- if (!SDL_RectEmpty(rect)) {
+ if (renderer->clipping_enabled) {
+ const SDL_Rect *rect = &renderer->clip_rect;
data->glEnable(GL_SCISSOR_TEST);
data->glScissor(rect->x, renderer->viewport.h - rect->y - rect->h, rect->w, rect->h);
} else {
diff --git a/src/render/opengles2/SDL_render_gles2.c b/src/render/opengles2/SDL_render_gles2.c
index 4448478..2671973 100644
--- a/src/render/opengles2/SDL_render_gles2.c
+++ b/src/render/opengles2/SDL_render_gles2.c
@@ -362,14 +362,14 @@ static int
GLES2_UpdateClipRect(SDL_Renderer * renderer)
{
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
- const SDL_Rect *rect = &renderer->clip_rect;
if (SDL_CurrentContext != data->context) {
/* We'll update the clip rect after we rebind the context */
return 0;
}
- if (!SDL_RectEmpty(rect)) {
+ if (renderer->clipping_enabled) {
+ const SDL_Rect *rect = &renderer->clip_rect;
data->glEnable(GL_SCISSOR_TEST);
data->glScissor(rect->x, renderer->viewport.h - rect->y - rect->h, rect->w, rect->h);
} else {
diff --git a/src/render/software/SDL_render_sw.c b/src/render/software/SDL_render_sw.c
index f0eb768..29d331f 100644
--- a/src/render/software/SDL_render_sw.c
+++ b/src/render/software/SDL_render_sw.c
@@ -347,11 +347,9 @@ SW_UpdateClipRect(SDL_Renderer * renderer)
{
SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
SDL_Surface *surface = data->surface;
- const SDL_Rect *rect = &renderer->clip_rect;
-
if (surface) {
- if (!SDL_RectEmpty(rect)) {
- SDL_SetClipRect(surface, rect);
+ if (renderer->clipping_enabled) {
+ SDL_SetClipRect(surface, &renderer->clip_rect);
} else {
SDL_SetClipRect(surface, NULL);
}