From 1289fdded2010e23c08912422b1683002e9a9295 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Fri, 29 May 2026 13:44:46 -0700
Subject: [PATCH] render: an empty clip rect should clip all drawing
Added a test to validate this and fixed the Metal renderer
Fixes https://github.com/libsdl-org/SDL/issues/15434
(cherry picked from commit e04bfb4c6edeb709e0c40da8e8a50d7df258ce9a)
---
src/render/metal/SDL_render_metal.m | 16 ++++++++--------
test/testautomation_render.c | 14 ++++++++++++++
2 files changed, 22 insertions(+), 8 deletions(-)
diff --git a/src/render/metal/SDL_render_metal.m b/src/render/metal/SDL_render_metal.m
index d5edfc2200444..c8a4579182297 100644
--- a/src/render/metal/SDL_render_metal.m
+++ b/src/render/metal/SDL_render_metal.m
@@ -1538,14 +1538,14 @@ static bool SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, c
METAL_GetOutputSize(renderer, &output.w, &output.h);
}
- if (SDL_GetRectIntersection(&output, &clip, &clip)) {
- MTLScissorRect mtlrect;
- mtlrect.x = clip.x;
- mtlrect.y = clip.y;
- mtlrect.width = clip.w;
- mtlrect.height = clip.h;
- [data.mtlcmdencoder setScissorRect:mtlrect];
- }
+ SDL_GetRectIntersection(&output, &clip, &clip);
+
+ MTLScissorRect mtlrect;
+ mtlrect.x = clip.x;
+ mtlrect.y = clip.y;
+ mtlrect.width = clip.w;
+ mtlrect.height = clip.h;
+ [data.mtlcmdencoder setScissorRect:mtlrect];
statecache->cliprect_dirty = false;
}
diff --git a/test/testautomation_render.c b/test/testautomation_render.c
index c88a3df7eabaa..071ae5db164ae 100644
--- a/test/testautomation_render.c
+++ b/test/testautomation_render.c
@@ -1361,6 +1361,20 @@ static int SDLCALL render_testClipRect(void *arg)
/* Check to see if final image matches. */
compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE);
+ /*
+ * Verify that empty cliprect clips all drawing
+ */
+
+ /* Set the cliprect and do a fill operation */
+ cliprect.h = 0;
+ CHECK_FUNC(SDL_SetRenderClipRect, (renderer, &cliprect))
+ CHECK_FUNC(SDL_SetRenderDrawColor, (renderer, 255, 0, 0, SDL_ALPHA_OPAQUE))
+ CHECK_FUNC(SDL_RenderFillRect, (renderer, NULL))
+ CHECK_FUNC(SDL_SetRenderClipRect, (renderer, NULL))
+
+ /* Check to see if final image matches. */
+ compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE);
+
/*
* Verify that clear ignores the cliprect
*/