@@ -76,6 +76,26 @@ typedef struct
7676 SDL_Texture * texture ;
7777} PSP_BlendState ;
7878
79+ typedef struct
80+ {
81+ SDL_Rect viewport ;
82+ SDL_bool viewport_dirty ;
83+ SDL_bool viewport_is_set ;
84+
85+ SDL_bool cliprect_enabled_dirty ;
86+ SDL_bool cliprect_enabled ;
87+ SDL_bool cliprect_dirty ;
88+ SDL_Rect cliprect ;
89+
90+ SDL_Texture * target ;
91+
92+ float draw_offset_x ;
93+ float draw_offset_y ;
94+
95+ int drawablew ;
96+ int drawableh ;
97+ } PSP_DrawstateCache ;
98+
7999typedef struct
80100{
81101 void * frontbuffer ; /**< main screen buffer */
@@ -91,6 +111,7 @@ typedef struct
91111 PSP_TextureData * most_recent_target ; /**< start of render target LRU double linked list */
92112 PSP_TextureData * least_recent_target ; /**< end of the LRU list */
93113
114+ PSP_DrawstateCache drawstate ;
94115 SDL_bool vblank_not_reached ; /**< whether vblank wasn't reached */
95116} PSP_RenderData ;
96117
@@ -1034,10 +1055,104 @@ static void PSP_SetBlendState(PSP_RenderData *data, PSP_BlendState *state)
10341055 * current = * state ;
10351056}
10361057
1058+ static void ClampCliprectToViewport (SDL_Rect * clip , const SDL_Rect * viewport )
1059+ {
1060+ int max_x_v , max_y_v , max_x_c , max_y_c ;
1061+
1062+ if (clip -> x < 0 ) {
1063+ clip -> w += clip -> x ;
1064+ clip -> x = 0 ;
1065+ }
1066+
1067+ if (clip -> y < 0 ) {
1068+ clip -> h += clip -> y ;
1069+ clip -> y = 0 ;
1070+ }
1071+
1072+ max_x_c = clip -> x + clip -> w ;
1073+ max_y_c = clip -> y + clip -> h ;
1074+
1075+ max_x_v = viewport -> x + viewport -> w ;
1076+ max_y_v = viewport -> y + viewport -> h ;
1077+
1078+ if (max_x_c > max_x_v ) {
1079+ clip -> w -= (max_x_v - max_x_c );
1080+ }
1081+
1082+ if (max_y_c > max_y_v ) {
1083+ clip -> h -= (max_y_v - max_y_c );
1084+ }
1085+ }
1086+
1087+ static void SetDrawState (PSP_RenderData * data )
1088+ {
1089+ if (data -> drawstate .viewport_dirty ) {
1090+ SDL_Rect * viewport = & data -> drawstate .viewport ;
1091+ /* FIXME: Find a genuine way to make viewport work (right now calling these functions here give no effect) */
1092+ /*
1093+ sceGuOffset(2048 - (480 >> 1) + viewport->x, 2048 - (272 >> 1) + viewport->y);
1094+ sceGuViewport(2048, 2048, viewport->w, viewport->h);
1095+ */
1096+ data -> drawstate .draw_offset_x = viewport -> x ;
1097+ data -> drawstate .draw_offset_y = viewport -> y ;
1098+ data -> drawstate .viewport_dirty = SDL_FALSE ;
1099+ }
1100+
1101+ if (data -> drawstate .cliprect_enabled_dirty ) {
1102+ if (!data -> drawstate .cliprect_enabled && !data -> drawstate .viewport_is_set ) {
1103+ sceGuDisable (GU_SCISSOR_TEST );
1104+ }
1105+ data -> drawstate .cliprect_enabled_dirty = SDL_FALSE ;
1106+ }
1107+
1108+ if ((data -> drawstate .cliprect_enabled || data -> drawstate .viewport_is_set ) && data -> drawstate .cliprect_dirty ) {
1109+ SDL_Rect rect ;
1110+ SDL_Rect * viewport = & data -> drawstate .viewport ;
1111+ SDL_copyp (& rect , & data -> drawstate .cliprect );
1112+ if (data -> drawstate .viewport_is_set ) {
1113+ ClampCliprectToViewport (& rect , viewport );
1114+ rect .x += viewport -> x ;
1115+ rect .y += viewport -> y ;
1116+ }
1117+ sceGuEnable (GU_SCISSOR_TEST );
1118+ sceGuScissor (rect .x , rect .y , rect .w , rect .h );
1119+ data -> drawstate .cliprect_dirty = SDL_FALSE ;
1120+ }
1121+ }
1122+
1123+ #define PSP_VERTICES_FUNK (FunkName , Type ) \
1124+ static const Type *FunkName(const PSP_DrawstateCache *drawstate, Uint8 *gpumem, SDL_RenderCommand *cmd, size_t count) \
1125+ { \
1126+ size_t i; \
1127+ float off_x, off_y; \
1128+ Type *verts = (Type *)(gpumem + cmd->data.draw.first); \
1129+ \
1130+ if (!drawstate->viewport_is_set) { \
1131+ return verts; \
1132+ } \
1133+ \
1134+ off_x = drawstate->draw_offset_x; \
1135+ off_y = drawstate->draw_offset_y; \
1136+ \
1137+ for (i = 0; i < count; ++i) { \
1138+ verts[i].x += off_x; \
1139+ verts[i].y += off_y; \
1140+ } \
1141+ \
1142+ return verts;\
1143+ }
1144+
1145+ PSP_VERTICES_FUNK (PSP_GetVertV , VertV )
1146+ PSP_VERTICES_FUNK (PSP_GetVertTV , VertTV )
1147+ PSP_VERTICES_FUNK (PSP_GetVertCV , VertCV )
1148+ PSP_VERTICES_FUNK (PSP_GetVertTCV , VertTCV )
1149+
10371150static int PSP_RunCommandQueue (SDL_Renderer * renderer , SDL_RenderCommand * cmd , void * vertices , size_t vertsize )
10381151{
10391152 PSP_RenderData * data = (PSP_RenderData * )renderer -> driverdata ;
10401153 Uint8 * gpumem = NULL ;
1154+ int w = 0 , h = 0 ;
1155+
10411156 StartDrawing (renderer );
10421157
10431158 /* note that before the renderer interface change, this would do extrememly small
@@ -1052,6 +1167,23 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
10521167 }
10531168 SDL_memcpy (gpumem , vertices , vertsize );
10541169
1170+ data -> drawstate .target = renderer -> target ;
1171+ if (!data -> drawstate .target ) {
1172+ SDL_GL_GetDrawableSize (renderer -> window , & w , & h );
1173+ } else {
1174+ if (SDL_QueryTexture (renderer -> target , NULL , NULL , & w , & h ) < 0 ) {
1175+ w = data -> drawstate .drawablew ;
1176+ h = data -> drawstate .drawableh ;
1177+ }
1178+ }
1179+
1180+ if ((w != data -> drawstate .drawablew ) || (h != data -> drawstate .drawableh )) {
1181+ data -> drawstate .viewport_dirty = SDL_TRUE ; /* if the window dimensions changed, invalidate the current viewport, etc. */
1182+ data -> drawstate .cliprect_dirty = SDL_TRUE ;
1183+ data -> drawstate .drawablew = w ;
1184+ data -> drawstate .drawableh = h ;
1185+ }
1186+
10551187 while (cmd ) {
10561188 switch (cmd -> command ) {
10571189 case SDL_RENDERCMD_SETDRAWCOLOR :
@@ -1061,22 +1193,42 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
10611193
10621194 case SDL_RENDERCMD_SETVIEWPORT :
10631195 {
1064- SDL_Rect * viewport = & cmd -> data .viewport .rect ;
1065- sceGuOffset (2048 - (viewport -> w >> 1 ), 2048 - (viewport -> h >> 1 ));
1066- sceGuViewport (2048 , 2048 , viewport -> w , viewport -> h );
1067- sceGuScissor (viewport -> x , viewport -> y , viewport -> w , viewport -> h );
1068- /* FIXME: We need to update the clip rect too, see https://github.com/libsdl-org/SDL/issues/9094 */
1196+ SDL_Rect * viewport = & data -> drawstate .viewport ;
1197+ if (SDL_memcmp (viewport , & cmd -> data .viewport .rect , sizeof (cmd -> data .viewport .rect )) != 0 ) {
1198+ SDL_copyp (viewport , & cmd -> data .viewport .rect );
1199+ data -> drawstate .viewport_dirty = SDL_TRUE ;
1200+ data -> drawstate .cliprect_dirty = SDL_TRUE ;
1201+ data -> drawstate .viewport_is_set = viewport -> x != 0 || viewport -> y != 0 || viewport -> w != data -> drawstate .drawablew || viewport -> h != data -> drawstate .drawableh ;
1202+ if (!data -> drawstate .cliprect_enabled ) {
1203+ if (data -> drawstate .viewport_is_set ) {
1204+ SDL_copyp (& data -> drawstate .cliprect , viewport );
1205+ data -> drawstate .cliprect .x = 0 ;
1206+ data -> drawstate .cliprect .y = 0 ;
1207+ } else {
1208+ data -> drawstate .cliprect_enabled_dirty = SDL_TRUE ;
1209+ }
1210+ }
1211+ }
10691212 break ;
10701213 }
10711214
10721215 case SDL_RENDERCMD_SETCLIPRECT :
10731216 {
10741217 const SDL_Rect * rect = & cmd -> data .cliprect .rect ;
1075- if (cmd -> data .cliprect .enabled ) {
1076- sceGuEnable (GU_SCISSOR_TEST );
1077- sceGuScissor (rect -> x , rect -> y , rect -> w , rect -> h );
1078- } else {
1079- sceGuDisable (GU_SCISSOR_TEST );
1218+ const SDL_Rect * viewport = & data -> drawstate .viewport ;
1219+ if (data -> drawstate .cliprect_enabled != cmd -> data .cliprect .enabled ) {
1220+ data -> drawstate .cliprect_enabled = cmd -> data .cliprect .enabled ;
1221+ data -> drawstate .cliprect_enabled_dirty = SDL_TRUE ;
1222+ if (!data -> drawstate .cliprect_enabled && data -> drawstate .viewport_is_set ) {
1223+ SDL_copyp (& data -> drawstate .cliprect , viewport );
1224+ data -> drawstate .cliprect .x = 0 ;
1225+ data -> drawstate .cliprect .y = 0 ;
1226+ }
1227+ }
1228+
1229+ if (SDL_memcmp (& data -> drawstate .cliprect , rect , sizeof (* rect )) != 0 ) {
1230+ SDL_copyp (& data -> drawstate .cliprect , rect );
1231+ data -> drawstate .cliprect_dirty = SDL_TRUE ;
10801232 }
10811233 break ;
10821234 }
@@ -1087,6 +1239,7 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
10871239 const Uint8 g = cmd -> data .color .g ;
10881240 const Uint8 b = cmd -> data .color .b ;
10891241 const Uint8 a = cmd -> data .color .a ;
1242+ SetDrawState (data );
10901243 sceGuClearColor (GU_RGBA (r , g , b , a ));
10911244 sceGuClearStencil (a );
10921245 sceGuClear (GU_COLOR_BUFFER_BIT | GU_STENCIL_BUFFER_BIT );
@@ -1096,7 +1249,7 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
10961249 case SDL_RENDERCMD_DRAW_POINTS :
10971250 {
10981251 const size_t count = cmd -> data .draw .count ;
1099- const VertV * verts = (VertV * )(gpumem + cmd -> data .draw .first );
1252+ const VertV * verts ; /* = (VertV *)(gpumem + cmd->data.draw.first);*/
11001253 const Uint8 r = cmd -> data .draw .r ;
11011254 const Uint8 g = cmd -> data .draw .g ;
11021255 const Uint8 b = cmd -> data .draw .b ;
@@ -1107,6 +1260,8 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
11071260 .mode = cmd -> data .draw .blend ,
11081261 .shadeModel = GU_FLAT
11091262 };
1263+ SetDrawState (data );
1264+ verts = PSP_GetVertV (& data -> drawstate , gpumem , cmd , count );
11101265 PSP_SetBlendState (data , & state );
11111266 sceGuDrawArray (GU_POINTS , GU_VERTEX_32BITF | GU_TRANSFORM_2D , count , 0 , verts );
11121267 break ;
@@ -1115,7 +1270,7 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
11151270 case SDL_RENDERCMD_DRAW_LINES :
11161271 {
11171272 const size_t count = cmd -> data .draw .count ;
1118- const VertV * verts = (VertV * )(gpumem + cmd -> data .draw .first );
1273+ const VertV * verts ; /* = (VertV *)(gpumem + cmd->data.draw.first);*/
11191274 const Uint8 r = cmd -> data .draw .r ;
11201275 const Uint8 g = cmd -> data .draw .g ;
11211276 const Uint8 b = cmd -> data .draw .b ;
@@ -1126,6 +1281,8 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
11261281 .mode = cmd -> data .draw .blend ,
11271282 .shadeModel = GU_FLAT
11281283 };
1284+ SetDrawState (data );
1285+ verts = PSP_GetVertV (& data -> drawstate , gpumem , cmd , count );
11291286 PSP_SetBlendState (data , & state );
11301287 sceGuDrawArray (GU_LINE_STRIP , GU_VERTEX_32BITF | GU_TRANSFORM_2D , count , 0 , verts );
11311288 break ;
@@ -1134,7 +1291,7 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
11341291 case SDL_RENDERCMD_FILL_RECTS :
11351292 {
11361293 const size_t count = cmd -> data .draw .count ;
1137- const VertV * verts = (VertV * )(gpumem + cmd -> data .draw .first );
1294+ const VertV * verts ; /* = (VertV *)(gpumem + cmd->data.draw.first);*/
11381295 const Uint8 r = cmd -> data .draw .r ;
11391296 const Uint8 g = cmd -> data .draw .g ;
11401297 const Uint8 b = cmd -> data .draw .b ;
@@ -1145,6 +1302,8 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
11451302 .mode = cmd -> data .draw .blend ,
11461303 .shadeModel = GU_FLAT
11471304 };
1305+ SetDrawState (data );
1306+ verts = PSP_GetVertV (& data -> drawstate , gpumem , cmd , 2 * count );
11481307 PSP_SetBlendState (data , & state );
11491308 sceGuDrawArray (GU_SPRITES , GU_VERTEX_32BITF | GU_TRANSFORM_2D , 2 * count , 0 , verts );
11501309 break ;
@@ -1153,7 +1312,7 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
11531312 case SDL_RENDERCMD_COPY :
11541313 {
11551314 const size_t count = cmd -> data .draw .count ;
1156- const VertTV * verts = (VertTV * )(gpumem + cmd -> data .draw .first );
1315+ const VertTV * verts ; /* = (VertTV *)(gpumem + cmd->data.draw.first);*/
11571316 const Uint8 a = cmd -> data .draw .a ;
11581317 const Uint8 r = cmd -> data .draw .r ;
11591318 const Uint8 g = cmd -> data .draw .g ;
@@ -1164,6 +1323,8 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
11641323 .mode = cmd -> data .draw .blend ,
11651324 .shadeModel = GU_SMOOTH
11661325 };
1326+ SetDrawState (data );
1327+ verts = PSP_GetVertTV (& data -> drawstate , gpumem , cmd , 2 * count );
11671328 PSP_SetBlendState (data , & state );
11681329 sceGuDrawArray (GU_SPRITES , GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D , 2 * count , 0 , verts );
11691330 break ;
@@ -1182,6 +1343,8 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
11821343 .mode = cmd -> data .draw .blend ,
11831344 .shadeModel = GU_SMOOTH
11841345 };
1346+ SetDrawState (data );
1347+ verts = PSP_GetVertTV (& data -> drawstate , gpumem , cmd , 4 );
11851348 PSP_SetBlendState (data , & state );
11861349 sceGuDrawArray (GU_TRIANGLE_FAN , GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D , 4 , 0 , verts );
11871350 break ;
@@ -1190,14 +1353,15 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
11901353 case SDL_RENDERCMD_GEOMETRY :
11911354 {
11921355 const size_t count = cmd -> data .draw .count ;
1356+ SetDrawState (data );
11931357 if (!cmd -> data .draw .texture ) {
1194- const VertCV * verts = ( VertCV * )( gpumem + cmd -> data . draw . first );
1358+ const VertCV * verts = PSP_GetVertCV ( & data -> drawstate , gpumem , cmd , count );
11951359 sceGuDisable (GU_TEXTURE_2D );
11961360 /* In GU_SMOOTH mode */
11971361 sceGuDrawArray (GU_TRIANGLES , GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_2D , count , 0 , verts );
11981362 sceGuEnable (GU_TEXTURE_2D );
11991363 } else {
1200- const VertTCV * verts = (VertTCV * )(gpumem + cmd -> data .draw .first );
1364+ const VertTCV * verts ; /* = (VertTCV *)(gpumem + cmd->data.draw.first);*/
12011365 const Uint8 a = cmd -> data .draw .a ;
12021366 const Uint8 r = cmd -> data .draw .r ;
12031367 const Uint8 g = cmd -> data .draw .g ;
@@ -1208,6 +1372,7 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
12081372 .mode = cmd -> data .draw .blend ,
12091373 .shadeModel = GU_FLAT
12101374 };
1375+ verts = PSP_GetVertTCV (& data -> drawstate , gpumem , cmd , count );
12111376 TextureActivate (cmd -> data .draw .texture );
12121377 PSP_SetBlendState (data , & state );
12131378 sceGuDrawArray (GU_TRIANGLES , GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_2D , count , 0 , verts );
0 commit comments