diff --git a/src/render/vitagxm/SDL_render_vita_gxm.c b/src/render/vitagxm/SDL_render_vita_gxm.c index 9267b4e0e50ff..ee3586ca05a2c 100644 --- a/src/render/vitagxm/SDL_render_vita_gxm.c +++ b/src/render/vitagxm/SDL_render_vita_gxm.c @@ -826,6 +826,35 @@ static int VITA_GXM_RenderClear(SDL_Renderer *renderer, SDL_RenderCommand *cmd) return 0; } +static void ClampCliprectToViewport(SDL_Rect *clip, const SDL_Rect *viewport) +{ + int max_x_v, max_y_v, max_x_c, max_y_c; + + if (clip->x < 0) { + clip->w += clip->x; + clip->x = 0; + } + + if (clip->y < 0) { + clip->h += clip->y; + clip->y = 0; + } + + max_x_c = clip->x + clip->w; + max_y_c = clip->y + clip->h; + + max_x_v = viewport->x + viewport->w; + max_y_v = viewport->y + viewport->h; + + if (max_x_c > max_x_v) { + clip->w -= (max_x_v - max_x_c); + } + + if (max_y_c > max_y_v) { + clip->h -= (max_y_v - max_y_c); + } +} + static int SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd) { SDL_Texture *texture = cmd->data.draw.texture; @@ -868,9 +897,13 @@ static int SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd) data->drawstate.cliprect_enabled_dirty = SDL_FALSE; } - if (data->drawstate.cliprect_enabled && data->drawstate.cliprect_dirty) { - const SDL_Rect *rect = &data->drawstate.cliprect; - set_clip_rectangle(data, rect->x, rect->y, rect->x + rect->w, rect->y + rect->h); + if ((data->drawstate.cliprect_enabled || data->drawstate.viewport_is_set) && data->drawstate.cliprect_dirty) { + SDL_Rect rect; + SDL_copyp(&rect, &data->drawstate.cliprect); + if (data->drawstate.viewport_is_set) { + ClampCliprectToViewport(&rect, &data->drawstate.viewport); + } + set_clip_rectangle(data, rect.x, rect.y, rect.x + rect.w, rect.y + rect.h); data->drawstate.cliprect_dirty = SDL_FALSE; } @@ -925,20 +958,27 @@ static int SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd) static int VITA_GXM_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) { VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata; + int w, h; + StartDrawing(renderer); data->drawstate.target = renderer->target; if (!data->drawstate.target) { - int w, h; SDL_GL_GetDrawableSize(renderer->window, &w, &h); - if ((w != data->drawstate.drawablew) || (h != data->drawstate.drawableh)) { - data->drawstate.viewport_dirty = SDL_TRUE; // if the window dimensions changed, invalidate the current viewport, etc. - data->drawstate.cliprect_dirty = SDL_TRUE; - data->drawstate.drawablew = w; - data->drawstate.drawableh = h; + } else { + if (SDL_QueryTexture(renderer->target, NULL, NULL, &w, &h) < 0) { + w = data->drawstate.drawablew; + h = data->drawstate.drawableh; } } + if ((w != data->drawstate.drawablew) || (h != data->drawstate.drawableh)) { + data->drawstate.viewport_dirty = SDL_TRUE; // if the window dimensions changed, invalidate the current viewport, etc. + data->drawstate.cliprect_dirty = SDL_TRUE; + data->drawstate.drawablew = w; + data->drawstate.drawableh = h; + } + while (cmd) { switch (cmd->command) { @@ -949,6 +989,16 @@ static int VITA_GXM_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *c SDL_copyp(viewport, &cmd->data.viewport.rect); data->drawstate.viewport_dirty = SDL_TRUE; data->drawstate.cliprect_dirty = SDL_TRUE; + data->drawstate.viewport_is_set = viewport->x != 0 || viewport->y != 0 || viewport->w != data->drawstate.drawablew || viewport->h != data->drawstate.drawableh; + if (!data->drawstate.cliprect_enabled) { + if (data->drawstate.viewport_is_set) { + SDL_copyp(&data->drawstate.cliprect, viewport); + data->drawstate.cliprect.x = 0; + data->drawstate.cliprect.y = 0; + } else { + data->drawstate.cliprect_enabled_dirty = SDL_TRUE; + } + } } break; } @@ -956,9 +1006,15 @@ static int VITA_GXM_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *c case SDL_RENDERCMD_SETCLIPRECT: { const SDL_Rect *rect = &cmd->data.cliprect.rect; + const SDL_Rect *viewport = &data->drawstate.viewport; if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) { data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled; data->drawstate.cliprect_enabled_dirty = SDL_TRUE; + if (!data->drawstate.cliprect_enabled && data->drawstate.viewport_is_set) { + SDL_copyp(&data->drawstate.cliprect, viewport); + data->drawstate.cliprect.x = 0; + data->drawstate.cliprect.y = 0; + } } if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof(*rect)) != 0) { diff --git a/src/render/vitagxm/SDL_render_vita_gxm_types.h b/src/render/vitagxm/SDL_render_vita_gxm_types.h index c72c5eb10d234..d796403752716 100644 --- a/src/render/vitagxm/SDL_render_vita_gxm_types.h +++ b/src/render/vitagxm/SDL_render_vita_gxm_types.h @@ -106,6 +106,7 @@ typedef struct { SDL_Rect viewport; SDL_bool viewport_dirty; + SDL_bool viewport_is_set; SDL_Texture *texture; SDL_Texture *target; SDL_Color color;