@@ -41,6 +41,10 @@ static void dealloc(Object *self) {
4141 SDL_EndGPURenderPass (this -> pass );
4242 }
4343
44+ if (this -> commands ) {
45+ this -> commands -> pass = NULL ;
46+ }
47+
4448 super (Object , self , dealloc );
4549}
4650
@@ -195,7 +199,18 @@ static void setBlendConstants(RenderPass *self, SDL_FColor blendConstants) {
195199static void setScissor (RenderPass * self , const SDL_Rect * scissor ) {
196200
197201 if (scissor ) {
198- self -> scissor = * scissor ;
202+ // Clamp to the render target bounds: a scissor that extends past the edge
203+ // (e.g. a view dragged partly offscreen) is invalid to SDL and would drop
204+ // the whole draw. Clamp each edge against the viewport, then subtract back
205+ // so w/h never exceed the space remaining from the clamped origin. A fully
206+ // offscreen scissor collapses to zero w/h, scissoring out the draw.
207+ // RenderPass does not yet capture the target dimensions, so the viewport
208+ // (which the caller is expected to have set) stands in for them.
209+ const int x = SDL_clamp (scissor -> x , 0 , (int ) self -> viewport .w );
210+ const int y = SDL_clamp (scissor -> y , 0 , (int ) self -> viewport .h );
211+ const int r = SDL_clamp (scissor -> x + scissor -> w , 0 , (int ) self -> viewport .w );
212+ const int b = SDL_clamp (scissor -> y + scissor -> h , 0 , (int ) self -> viewport .h );
213+ self -> scissor = (SDL_Rect ) { .x = x , .y = y , .w = r - x , .h = b - y };
199214 } else {
200215 // Reset to the full render target. RenderPass does not yet capture the
201216 // target dimensions, so fall back to the current viewport, which the
0 commit comments