trunk/src/osd/sdl/draw13.c
| r242695 | r242696 | |
| 43 | 43 | |
| 44 | 44 | |
| 45 | 45 | //============================================================ |
| 46 | | // MACROS |
| 46 | // Inline functions |
| 47 | 47 | //============================================================ |
| 48 | 48 | |
| 49 | | #define IS_OPAQUE(a) (a >= 1.0f) |
| 50 | | #define IS_TRANSPARENT(a) (a < 0.0001f) |
| 49 | static inline bool is_opaque(const float &a) |
| 50 | { |
| 51 | return (a >= 1.0f); |
| 52 | } |
| 51 | 53 | |
| 52 | | #define MAX4(a, b, c, d) MAX(a, MAX(b, MAX(c, d))) |
| 53 | | #define MIN4(a, b, c, d) MIN(a, MIN(b, MIN(c, d))) |
| 54 | static inline bool is_transparent(const float &a) |
| 55 | { |
| 56 | return (a < 0.0001f); |
| 57 | } |
| 54 | 58 | |
| 55 | | |
| 56 | 59 | //============================================================ |
| 57 | 60 | // TYPES |
| 58 | 61 | //============================================================ |
| r242695 | r242696 | |
| 64 | 67 | : dudx(0), dvdx(0), dudy(0), dvdy(0), startu(0), startv(0), |
| 65 | 68 | rotwidth(0), rotheight(0) |
| 66 | 69 | {} |
| 70 | void compute(const render_primitive &prim); |
| 71 | |
| 67 | 72 | INT32 dudx, dvdx, dudy, dvdy; |
| 68 | 73 | INT32 startu, startv; |
| 69 | 74 | INT32 rotwidth, rotheight; |
| 70 | 75 | }; |
| 71 | 76 | |
| 72 | | struct texture_info; |
| 77 | class texture_info; |
| 73 | 78 | |
| 74 | | typedef void (*texture_copy_func)(texture_info *texture, const render_texinfo *texsource); |
| 79 | typedef void (*texture_copy_func)(const texture_info *texture, const render_texinfo *texsource); |
| 75 | 80 | |
| 76 | | struct copy_info { |
| 81 | struct copy_info_t { |
| 77 | 82 | int src_fmt; |
| 78 | 83 | Uint32 dst_fmt; |
| 79 | 84 | int dst_bpp; |
| r242695 | r242696 | |
| 88 | 93 | int samples; |
| 89 | 94 | int perf; |
| 90 | 95 | /* list */ |
| 91 | | copy_info *next; |
| 96 | copy_info_t *next; |
| 92 | 97 | }; |
| 93 | 98 | |
| 99 | //============================================================ |
| 100 | // Textures |
| 101 | //============================================================ |
| 102 | |
| 103 | struct sdl_info; |
| 104 | |
| 94 | 105 | /* texture_info holds information about a texture */ |
| 95 | | struct texture_info |
| 106 | class texture_info |
| 96 | 107 | { |
| 97 | | texture_info() |
| 98 | | : next(NULL), hash(0), flags(0), rawwidth(0), rawheight(0), format(0), |
| 99 | | pixels(NULL), pitch(0), pixels_own(0), texture_id(NULL), copyinfo(NULL), |
| 100 | | sdl_access(0), sdl_blendmode(SDL_BLENDMODE_NONE), is_rotated(0), last_access(0) |
| 101 | | { |
| 102 | | } |
| 103 | | texture_info * next; // next texture in the list |
| 108 | friend class simple_list<texture_info>; |
| 109 | public: |
| 110 | texture_info(SDL_Renderer *renderer, const render_texinfo &texsource, const quad_setup_data &setup, const UINT32 flags); |
| 111 | ~texture_info(); |
| 104 | 112 | |
| 105 | | HashT hash; // hash value for the texture (must be >= pointer size) |
| 106 | | UINT32 flags; // rendering flags |
| 107 | | render_texinfo texinfo; // copy of the texture info |
| 113 | void set_data(const render_texinfo &texsource, const UINT32 flags); |
| 114 | void render_quad(const render_primitive *prim, const int x, const int y); |
| 115 | bool matches(const render_primitive &prim, const quad_setup_data &setup); |
| 108 | 116 | |
| 109 | | int rawwidth, rawheight;// raw width/height of the texture |
| 117 | copy_info_t *compute_size_type(); |
| 110 | 118 | |
| 111 | | int format; // texture format |
| 112 | | void *pixels; // pixels for the texture |
| 113 | | int pitch; |
| 114 | | int pixels_own; // do we own / allocated it ? |
| 119 | void *m_pixels; // pixels for the texture |
| 120 | int m_pitch; |
| 115 | 121 | |
| 116 | | SDL_Texture *texture_id; |
| 122 | copy_info_t *m_copyinfo; |
| 123 | quad_setup_data m_setup; |
| 117 | 124 | |
| 118 | | copy_info *copyinfo; |
| 119 | | Uint32 sdl_access; |
| 120 | | SDL_BlendMode sdl_blendmode; |
| 121 | | quad_setup_data setup; |
| 122 | | int is_rotated; |
| 125 | osd_ticks_t m_last_access; |
| 123 | 126 | |
| 124 | | osd_ticks_t last_access; |
| 127 | int raw_width() const { return m_texinfo.width; } |
| 128 | int raw_height() const { return m_texinfo.height; } |
| 129 | |
| 130 | texture_info *next() { return m_next; } |
| 131 | const render_texinfo &texinfo() const { return m_texinfo; } |
| 132 | render_texinfo &texinfo() { return m_texinfo; } |
| 133 | |
| 134 | const HashT hash() const { return m_hash; } |
| 135 | const UINT32 flags() const { return m_flags; } |
| 136 | const bool is_pixels_owned() const { // do we own / allocated it ? |
| 137 | return m_sdl_access == SDL_TEXTUREACCESS_STATIC |
| 138 | && m_copyinfo->func != NULL ; |
| 139 | } |
| 140 | |
| 141 | private: |
| 142 | SDL_Renderer * m_renderer; |
| 143 | render_texinfo m_texinfo; // copy of the texture info |
| 144 | HashT m_hash; // hash value for the texture (must be >= pointer size) |
| 145 | UINT32 m_flags; // rendering flags |
| 146 | |
| 147 | SDL_Texture * m_texture_id; |
| 148 | int m_is_rotated; |
| 149 | |
| 150 | int m_format; // texture format |
| 151 | SDL_BlendMode m_sdl_blendmode; |
| 152 | Uint32 m_sdl_access; |
| 153 | |
| 154 | texture_info * m_next; // next texture in the list |
| 125 | 155 | }; |
| 126 | 156 | |
| 127 | 157 | /* sdl_info is the information about SDL for the current screen */ |
| 128 | 158 | struct sdl_info |
| 129 | 159 | { |
| 130 | 160 | sdl_info() |
| 131 | | : blittimer(0), extra_flags(0), sdl_renderer(NULL), texlist(NULL), |
| 132 | | texture_max_width(0), texture_max_height(0), last_hofs(0), last_vofs(0), |
| 133 | | resize_pending(0), resize_width(0), resize_height(0), |
| 134 | | last_blit_time(0), last_blit_pixels(0) |
| 161 | : m_blittimer(0), m_renderer(NULL), |
| 162 | m_hofs(0), m_vofs(0), |
| 163 | m_resize_pending(0), m_resize_width(0), m_resize_height(0), |
| 164 | m_last_blit_time(0), m_last_blit_pixels(0) |
| 135 | 165 | {} |
| 136 | | INT32 blittimer; |
| 137 | | UINT32 extra_flags; |
| 138 | 166 | |
| 139 | | SDL_Renderer *sdl_renderer; |
| 140 | | texture_info * texlist; // list of active textures |
| 141 | | INT32 texture_max_width; // texture maximum width |
| 142 | | INT32 texture_max_height; // texture maximum height |
| 167 | void render_quad(texture_info *texture, const render_primitive *prim, const int x, const int y); |
| 143 | 168 | |
| 144 | | float last_hofs; |
| 145 | | float last_vofs; |
| 169 | texture_info *texture_find(const render_primitive &prim, const quad_setup_data &setup); |
| 170 | texture_info *texture_update(const render_primitive &prim); |
| 146 | 171 | |
| 172 | INT32 m_blittimer; |
| 173 | |
| 174 | SDL_Renderer * m_renderer; |
| 175 | simple_list<texture_info> m_texlist; // list of active textures |
| 176 | |
| 177 | float m_hofs; |
| 178 | float m_vofs; |
| 179 | |
| 147 | 180 | // resize information |
| 148 | 181 | |
| 149 | | UINT8 resize_pending; |
| 150 | | UINT32 resize_width; |
| 151 | | UINT32 resize_height; |
| 182 | UINT8 m_resize_pending; |
| 183 | UINT32 m_resize_width; |
| 184 | UINT32 m_resize_height; |
| 152 | 185 | |
| 153 | 186 | // Stats |
| 154 | | INT64 last_blit_time; |
| 155 | | INT64 last_blit_pixels; |
| 187 | INT64 m_last_blit_time; |
| 188 | INT64 m_last_blit_pixels; |
| 156 | 189 | }; |
| 157 | 190 | |
| 158 | 191 | //============================================================ |
| r242695 | r242696 | |
| 171 | 204 | static void drawsdl2_destroy_all_textures(sdl_window_info *window); |
| 172 | 205 | static void drawsdl2_window_clear(sdl_window_info *window); |
| 173 | 206 | static int drawsdl2_xy_to_render_target(sdl_window_info *window, int x, int y, int *xt, int *yt); |
| 174 | | static void drawsdl2_destroy_texture(sdl_info *sdl, texture_info *texture); |
| 175 | 207 | |
| 176 | 208 | //============================================================ |
| 177 | | // Textures |
| 178 | | //============================================================ |
| 179 | | |
| 180 | | static void texture_set_data(sdl_info *sdl, texture_info *texture, const render_texinfo *texsource, UINT32 flags); |
| 181 | | static texture_info *texture_create(sdl_window_info *window, const render_texinfo *texsource, quad_setup_data *setup, UINT32 flags); |
| 182 | | static texture_info *texture_find(sdl_info *sdl, const render_primitive *prim, quad_setup_data *setup); |
| 183 | | static texture_info * texture_update(sdl_window_info *window, const render_primitive *prim); |
| 184 | | |
| 185 | | |
| 186 | | //============================================================ |
| 187 | 209 | // TEXCOPY FUNCS |
| 188 | 210 | //============================================================ |
| 189 | 211 | |
| r242695 | r242696 | |
| 202 | 224 | #define ENTRY_BM(a,b,c,d,f,bm) { SDL_TEXFORMAT_ ## a, SDL_PIXELFORMAT_ ## b, c, d, texcopy_ ## f, bm, #a, #b, 0, 0, 0, 0} |
| 203 | 225 | #define ENTRY_LR(a,b,c,d,f) { SDL_TEXFORMAT_ ## a, SDL_PIXELFORMAT_ ## b, c, d, texcopy_ ## f, BM_ALL, #a, #b, 0, 0, 0, -1} |
| 204 | 226 | |
| 205 | | static copy_info blit_info_default[] = |
| 227 | static copy_info_t blit_info_default[] = |
| 206 | 228 | { |
| 207 | 229 | /* no rotation */ |
| 208 | 230 | ENTRY(ARGB32, ARGB8888, 4, 0, NULL), |
| 209 | 231 | ENTRY_LR(ARGB32, RGB888, 4, 0, argb32_rgb32), |
| 210 | | /* Entry for primarily for directfb */ |
| 232 | /* Entry primarily for directfb */ |
| 211 | 233 | ENTRY_BM(ARGB32, RGB888, 4, 0, argb32_rgb32, SDL_BLENDMODE_ADD), |
| 212 | 234 | ENTRY_BM(ARGB32, RGB888, 4, 0, argb32_rgb32, SDL_BLENDMODE_MOD), |
| 213 | 235 | ENTRY_BM(ARGB32, RGB888, 4, 0, argb32_rgb32, SDL_BLENDMODE_NONE), |
| r242695 | r242696 | |
| 247 | 269 | /* rotation */ |
| 248 | 270 | ENTRY(ARGB32, ARGB8888, 4, 1, rot_argb32_argb32), |
| 249 | 271 | ENTRY_LR(ARGB32, RGB888, 4, 1, rot_argb32_rgb32), |
| 250 | | /* Entry for primarily for directfb */ |
| 272 | /* Entry primarily for directfb */ |
| 251 | 273 | ENTRY_BM(ARGB32, RGB888, 4, 1, rot_argb32_rgb32, SDL_BLENDMODE_ADD), |
| 252 | 274 | ENTRY_BM(ARGB32, RGB888, 4, 1, rot_argb32_rgb32, SDL_BLENDMODE_MOD), |
| 253 | 275 | ENTRY_BM(ARGB32, RGB888, 4, 1, rot_argb32_rgb32, SDL_BLENDMODE_NONE), |
| r242695 | r242696 | |
| 281 | 303 | { -1 }, |
| 282 | 304 | }; |
| 283 | 305 | |
| 284 | | static copy_info *blit_info[SDL_TEXFORMAT_LAST+1]; |
| 306 | static copy_info_t *blit_info[SDL_TEXFORMAT_LAST+1]; |
| 285 | 307 | |
| 286 | 308 | static struct |
| 287 | 309 | { |
| r242695 | r242696 | |
| 300 | 322 | return floor(f + 0.5f); |
| 301 | 323 | } |
| 302 | 324 | |
| 303 | | INLINE HashT texture_compute_hash(const render_texinfo *texture, UINT32 flags) |
| 325 | INLINE HashT texture_compute_hash(const render_texinfo &texture, const UINT32 flags) |
| 304 | 326 | { |
| 305 | | return (HashT)texture->base ^ (flags & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)); |
| 327 | return (HashT)texture.base ^ (flags & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)); |
| 306 | 328 | } |
| 307 | 329 | |
| 308 | | INLINE SDL_BlendMode map_blendmode(int blendmode) |
| 330 | INLINE SDL_BlendMode map_blendmode(const int blendmode) |
| 309 | 331 | { |
| 310 | 332 | switch (blendmode) |
| 311 | 333 | { |
| r242695 | r242696 | |
| 331 | 353 | UINT32 sa = (UINT32)(255.0f * color->a); |
| 332 | 354 | |
| 333 | 355 | |
| 334 | | if (color->r >= 1.0f && color->g >= 1.0f && color->b >= 1.0f && IS_OPAQUE(color->a)) |
| 356 | if (color->r >= 1.0f && color->g >= 1.0f && color->b >= 1.0f && is_opaque(color->a)) |
| 335 | 357 | { |
| 336 | 358 | SDL_SetTextureColorMod(texture_id, 0xFF, 0xFF, 0xFF); |
| 337 | 359 | SDL_SetTextureAlphaMod(texture_id, 0xFF); |
| 338 | 360 | } |
| 339 | 361 | /* coloring-only case */ |
| 340 | | else if (IS_OPAQUE(color->a)) |
| 362 | else if (is_opaque(color->a)) |
| 341 | 363 | { |
| 342 | 364 | SDL_SetTextureColorMod(texture_id, sr, sg, sb); |
| 343 | 365 | SDL_SetTextureAlphaMod(texture_id, 0xFF); |
| 344 | 366 | } |
| 345 | 367 | /* alpha and/or coloring case */ |
| 346 | | else if (!IS_TRANSPARENT(color->a)) |
| 368 | else if (!is_transparent(color->a)) |
| 347 | 369 | { |
| 348 | 370 | SDL_SetTextureColorMod(texture_id, sr, sg, sb); |
| 349 | 371 | SDL_SetTextureAlphaMod(texture_id, sa); |
| r242695 | r242696 | |
| 355 | 377 | } |
| 356 | 378 | } |
| 357 | 379 | |
| 358 | | INLINE void render_quad(sdl_info *sdl, texture_info *texture, render_primitive *prim, int x, int y) |
| 380 | void texture_info::render_quad(const render_primitive *prim, const int x, const int y) |
| 359 | 381 | { |
| 360 | | SDL_Texture *texture_id; |
| 361 | 382 | SDL_Rect target_rect; |
| 362 | 383 | |
| 363 | 384 | target_rect.x = x; |
| r242695 | r242696 | |
| 365 | 386 | target_rect.w = round_nearest(prim->bounds.x1 - prim->bounds.x0); |
| 366 | 387 | target_rect.h = round_nearest(prim->bounds.y1 - prim->bounds.y0); |
| 367 | 388 | |
| 368 | | if (texture) |
| 369 | | { |
| 370 | | texture_id = texture->texture_id; |
| 371 | | |
| 372 | | texture->copyinfo->time -= osd_ticks(); |
| 373 | 389 | #if 0 |
| 374 | | if ((PRIMFLAG_GET_SCREENTEX(prim->flags)) && video_config.filter) |
| 375 | | { |
| 376 | | SDL_SetTextureScaleMode(texture->texture_id, DRAW2_SCALEMODE_BEST); |
| 377 | | } |
| 378 | | else |
| 379 | | { |
| 380 | | SDL_SetTextureScaleMode(texture->texture_id, DRAW2_SCALEMODE_NEAREST); |
| 381 | | } |
| 390 | // no longer supported in SDL2 |
| 391 | if ((PRIMFLAG_GET_SCREENTEX(prim->m_flags)) && video_config.filter) |
| 392 | { |
| 393 | SDL_SetTextureScaleMode(texture->m_texture_id, DRAW2_SCALEMODE_BEST); |
| 394 | } |
| 395 | else |
| 396 | { |
| 397 | SDL_SetTextureScaleMode(texture->m_texture_id, DRAW2_SCALEMODE_NEAREST); |
| 398 | } |
| 382 | 399 | #endif |
| 383 | | SDL_SetTextureBlendMode(texture_id, texture->sdl_blendmode); |
| 384 | | set_coloralphamode(texture_id, &prim->color); |
| 385 | | SDL_RenderCopy(sdl->sdl_renderer, texture_id, NULL, &target_rect); |
| 386 | | texture->copyinfo->time += osd_ticks(); |
| 387 | | |
| 388 | | texture->copyinfo->pixel_count += MAX(STAT_PIXEL_THRESHOLD , (texture->rawwidth * texture->rawheight)); |
| 389 | | if (sdl->last_blit_pixels) |
| 390 | | { |
| 391 | | texture->copyinfo->time += (sdl->last_blit_time * (INT64) (texture->rawwidth * texture->rawheight)) / (INT64) sdl->last_blit_pixels; |
| 392 | | } |
| 393 | | texture->copyinfo->samples++; |
| 394 | | texture->copyinfo->perf = ( texture->copyinfo->pixel_count * (osd_ticks_per_second()/1000)) / texture->copyinfo->time; |
| 395 | | } |
| 396 | | else |
| 397 | | { |
| 398 | | UINT32 sr = (UINT32)(255.0f * prim->color.r); |
| 399 | | UINT32 sg = (UINT32)(255.0f * prim->color.g); |
| 400 | | UINT32 sb = (UINT32)(255.0f * prim->color.b); |
| 401 | | UINT32 sa = (UINT32)(255.0f * prim->color.a); |
| 402 | | |
| 403 | | SDL_SetRenderDrawBlendMode(sdl->sdl_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim->flags))); |
| 404 | | SDL_SetRenderDrawColor(sdl->sdl_renderer, sr, sg, sb, sa); |
| 405 | | SDL_RenderFillRect(sdl->sdl_renderer, &target_rect); |
| 406 | | } |
| 400 | SDL_SetTextureBlendMode(m_texture_id, m_sdl_blendmode); |
| 401 | set_coloralphamode(m_texture_id, &prim->color); |
| 402 | SDL_RenderCopy(m_renderer, m_texture_id, NULL, &target_rect); |
| 407 | 403 | } |
| 408 | 404 | |
| 409 | | #if 0 |
| 410 | | static int RendererSupportsFormat(Uint32 format, Uint32 access, const char *sformat) |
| 405 | void sdl_info::render_quad(texture_info *texture, const render_primitive *prim, const int x, const int y) |
| 411 | 406 | { |
| 412 | | struct SDL_RendererInfo render_info; |
| 413 | | int i; |
| 407 | SDL_Rect target_rect; |
| 414 | 408 | |
| 415 | | SDL_GetRendererInfo(&render_info); |
| 409 | target_rect.x = x; |
| 410 | target_rect.y = y; |
| 411 | target_rect.w = round_nearest(prim->bounds.x1 - prim->bounds.x0); |
| 412 | target_rect.h = round_nearest(prim->bounds.y1 - prim->bounds.y0); |
| 416 | 413 | |
| 417 | | for (i=0; i < render_info.num_texture_formats; i++) |
| 418 | | { |
| 419 | | if (format == render_info.texture_formats[i]) |
| 420 | | return 1; |
| 421 | | } |
| 422 | | osd_printf_verbose("Pixelformat <%s> not supported\n", sformat); |
| 423 | | return 0; |
| 414 | if (texture) |
| 415 | { |
| 416 | copy_info_t *copyinfo = texture->m_copyinfo; |
| 417 | copyinfo->time -= osd_ticks(); |
| 418 | texture->render_quad(prim, x, y); |
| 419 | copyinfo->time += osd_ticks(); |
| 420 | |
| 421 | copyinfo->pixel_count += MAX(STAT_PIXEL_THRESHOLD , (texture->raw_width() * texture->raw_height())); |
| 422 | if (m_last_blit_pixels) |
| 423 | { |
| 424 | copyinfo->time += (m_last_blit_time * (INT64) (texture->raw_width() * texture->raw_height())) / (INT64) m_last_blit_pixels; |
| 425 | } |
| 426 | copyinfo->samples++; |
| 427 | copyinfo->perf = ( texture->m_copyinfo->pixel_count * (osd_ticks_per_second()/1000)) / texture->m_copyinfo->time; |
| 428 | } |
| 429 | else |
| 430 | { |
| 431 | UINT32 sr = (UINT32)(255.0f * prim->color.r); |
| 432 | UINT32 sg = (UINT32)(255.0f * prim->color.g); |
| 433 | UINT32 sb = (UINT32)(255.0f * prim->color.b); |
| 434 | UINT32 sa = (UINT32)(255.0f * prim->color.a); |
| 435 | |
| 436 | SDL_SetRenderDrawBlendMode(m_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim->flags))); |
| 437 | SDL_SetRenderDrawColor(m_renderer, sr, sg, sb, sa); |
| 438 | SDL_RenderFillRect(m_renderer, &target_rect); |
| 439 | } |
| 424 | 440 | } |
| 425 | | #else |
| 441 | |
| 426 | 442 | static int RendererSupportsFormat(SDL_Renderer *renderer, Uint32 format, Uint32 access, const char *sformat) |
| 427 | 443 | { |
| 428 | 444 | int i; |
| r242695 | r242696 | |
| 449 | 465 | fmt_support[i].status = 0; |
| 450 | 466 | return 0; |
| 451 | 467 | } |
| 452 | | #endif |
| 453 | 468 | |
| 454 | 469 | //============================================================ |
| 455 | 470 | // drawsdl2_init |
| 456 | 471 | //============================================================ |
| 457 | 472 | |
| 458 | | static void add_list(copy_info **head, copy_info *element, Uint32 bm) |
| 473 | static void add_list(copy_info_t **head, copy_info_t *element, Uint32 bm) |
| 459 | 474 | { |
| 460 | | copy_info *newci = global_alloc(copy_info); |
| 475 | copy_info_t *newci = global_alloc(copy_info_t); |
| 461 | 476 | *newci = *element; |
| 462 | 477 | |
| 463 | 478 | newci->bm_mask = bm; |
| r242695 | r242696 | |
| 465 | 480 | *head = newci; |
| 466 | 481 | } |
| 467 | 482 | |
| 468 | | static void expand_copy_info(copy_info *list) |
| 483 | static void expand_copy_info(copy_info_t *list) |
| 469 | 484 | { |
| 470 | | copy_info *bi; |
| 485 | copy_info_t *bi; |
| 471 | 486 | |
| 472 | 487 | for (bi = list; bi->src_fmt != -1; bi++) |
| 473 | 488 | { |
| r242695 | r242696 | |
| 506 | 521 | |
| 507 | 522 | // No fatalerror here since not all video drivers support GL ! |
| 508 | 523 | if (SDL_GL_LoadLibrary(stemp) != 0) // Load library (default for e==NULL |
| 509 | | osd_printf_verbose("Warning: Unable to load opengl library: %s\n", stemp ? stemp : "<default>"); |
| 524 | osd_printf_warning("Warning: Unable to load opengl library: %s\n", stemp ? stemp : "<default>"); |
| 510 | 525 | else |
| 511 | 526 | osd_printf_verbose("Loaded opengl shared library: %s\n", stemp ? stemp : "<default>"); |
| 512 | 527 | |
| r242695 | r242696 | |
| 521 | 536 | static void drawsdl2_exit(void) |
| 522 | 537 | { |
| 523 | 538 | int i; |
| 524 | | copy_info *bi, *freeme; |
| 539 | copy_info_t *bi, *freeme; |
| 525 | 540 | for (i = 0; i <= SDL_TEXFORMAT_LAST; i++) |
| 526 | 541 | for (bi = blit_info[i]; bi != NULL; ) |
| 527 | 542 | { |
| r242695 | r242696 | |
| 565 | 580 | |
| 566 | 581 | window->dxdata = sdl; |
| 567 | 582 | |
| 568 | | sdl->extra_flags = (window->fullscreen() ? |
| 583 | UINT32 extra_flags = (window->fullscreen() ? |
| 569 | 584 | SDL_WINDOW_BORDERLESS | SDL_WINDOW_INPUT_FOCUS | SDL_WINDOW_FULLSCREEN : SDL_WINDOW_RESIZABLE); |
| 570 | 585 | |
| 571 | 586 | // create the SDL window |
| 572 | 587 | window->sdl_window = SDL_CreateWindow(window->title, window->monitor()->monitor_x, 0, |
| 573 | | width, height, sdl->extra_flags); |
| 588 | width, height, extra_flags); |
| 574 | 589 | |
| 575 | 590 | if (window->fullscreen() && video_config.switchres) |
| 576 | 591 | { |
| r242695 | r242696 | |
| 608 | 623 | // create renderer |
| 609 | 624 | |
| 610 | 625 | if (video_config.waitvsync) |
| 611 | | sdl->sdl_renderer = SDL_CreateRenderer(window->sdl_window, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED); |
| 626 | sdl->m_renderer = SDL_CreateRenderer(window->sdl_window, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED); |
| 612 | 627 | else |
| 613 | | sdl->sdl_renderer = SDL_CreateRenderer(window->sdl_window, -1, SDL_RENDERER_ACCELERATED); |
| 628 | sdl->m_renderer = SDL_CreateRenderer(window->sdl_window, -1, SDL_RENDERER_ACCELERATED); |
| 614 | 629 | |
| 615 | | if (!sdl->sdl_renderer) |
| 630 | if (!sdl->m_renderer) |
| 616 | 631 | { |
| 617 | 632 | fatalerror("Error on creating renderer: %s\n", SDL_GetError()); |
| 618 | 633 | } |
| r242695 | r242696 | |
| 625 | 640 | SDL_GetWindowSize(window->sdl_window, &window->width, &window->height); |
| 626 | 641 | |
| 627 | 642 | |
| 628 | | sdl->blittimer = 3; |
| 643 | sdl->m_blittimer = 3; |
| 629 | 644 | |
| 630 | | // in case any textures try to come up before these are validated, |
| 631 | | // OpenGL guarantees all implementations can handle something this size. |
| 632 | | sdl->texture_max_width = 64; |
| 633 | | sdl->texture_max_height = 64; |
| 634 | | |
| 635 | | SDL_RenderPresent(sdl->sdl_renderer); |
| 645 | SDL_RenderPresent(sdl->m_renderer); |
| 636 | 646 | osd_printf_verbose("Leave drawsdl2_window_create\n"); |
| 637 | 647 | return 0; |
| 638 | 648 | } |
| r242695 | r242696 | |
| 645 | 655 | { |
| 646 | 656 | sdl_info *sdl = (sdl_info *) window->dxdata; |
| 647 | 657 | |
| 648 | | sdl->resize_pending = 1; |
| 649 | | sdl->resize_height = height; |
| 650 | | sdl->resize_width = width; |
| 658 | sdl->m_resize_pending = 1; |
| 659 | sdl->m_resize_height = height; |
| 660 | sdl->m_resize_width = width; |
| 651 | 661 | |
| 652 | 662 | window->width = width; |
| 653 | 663 | window->height = height; |
| 654 | 664 | |
| 655 | | sdl->blittimer = 3; |
| 665 | sdl->m_blittimer = 3; |
| 656 | 666 | |
| 657 | 667 | } |
| 658 | 668 | |
| r242695 | r242696 | |
| 664 | 674 | { |
| 665 | 675 | sdl_info *sdl = (sdl_info *) window->dxdata; |
| 666 | 676 | |
| 667 | | *xt = x - sdl->last_hofs; |
| 668 | | *yt = y - sdl->last_vofs; |
| 677 | *xt = x - sdl->m_hofs; |
| 678 | *yt = y - sdl->m_vofs; |
| 669 | 679 | if (*xt<0 || *xt >= window->blitwidth) |
| 670 | 680 | return 0; |
| 671 | 681 | if (*yt<0 || *yt >= window->blitheight) |
| r242695 | r242696 | |
| 708 | 718 | return 0; |
| 709 | 719 | } |
| 710 | 720 | |
| 711 | | if (sdl->resize_pending) |
| 721 | if (sdl->m_resize_pending) |
| 712 | 722 | { |
| 713 | | SDL_SetWindowSize(window->sdl_window, sdl->resize_width, sdl->resize_height); |
| 723 | SDL_SetWindowSize(window->sdl_window, sdl->m_resize_width, sdl->m_resize_height); |
| 714 | 724 | SDL_GetWindowSize(window->sdl_window, &window->width, &window->height); |
| 715 | | sdl->resize_pending = 0; |
| 716 | | SDL_RenderSetViewport(sdl->sdl_renderer, NULL); |
| 725 | sdl->m_resize_pending = 0; |
| 726 | SDL_RenderSetViewport(sdl->m_renderer, NULL); |
| 717 | 727 | } |
| 718 | 728 | |
| 719 | 729 | //SDL_SelectRenderer(window->sdl_window); |
| 720 | 730 | |
| 721 | | if (sdl->blittimer > 0) |
| 731 | if (sdl->m_blittimer > 0) |
| 722 | 732 | { |
| 723 | 733 | /* SDL Underlays need alpha = 0 ! */ |
| 724 | | SDL_SetRenderDrawBlendMode(sdl->sdl_renderer, SDL_BLENDMODE_NONE); |
| 734 | SDL_SetRenderDrawBlendMode(sdl->m_renderer, SDL_BLENDMODE_NONE); |
| 725 | 735 | //SDL_SetRenderDrawColor(0,0,0,255); |
| 726 | | SDL_SetRenderDrawColor(sdl->sdl_renderer, 0,0,0,0); |
| 727 | | SDL_RenderFillRect(sdl->sdl_renderer, NULL); |
| 728 | | sdl->blittimer--; |
| 736 | SDL_SetRenderDrawColor(sdl->m_renderer, 0,0,0,0); |
| 737 | SDL_RenderFillRect(sdl->m_renderer, NULL); |
| 738 | sdl->m_blittimer--; |
| 729 | 739 | } |
| 730 | 740 | |
| 731 | 741 | // compute centering parameters |
| r242695 | r242696 | |
| 756 | 766 | } |
| 757 | 767 | } |
| 758 | 768 | |
| 759 | | sdl->last_hofs = hofs; |
| 760 | | sdl->last_vofs = vofs; |
| 769 | sdl->m_hofs = hofs; |
| 770 | sdl->m_vofs = vofs; |
| 761 | 771 | |
| 762 | 772 | window->primlist->acquire_lock(); |
| 763 | 773 | |
| r242695 | r242696 | |
| 774 | 784 | sb = (int)(255.0f * prim->color.b); |
| 775 | 785 | sa = (int)(255.0f * prim->color.a); |
| 776 | 786 | |
| 777 | | SDL_SetRenderDrawBlendMode(sdl->sdl_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim->flags))); |
| 778 | | SDL_SetRenderDrawColor(sdl->sdl_renderer, sr, sg, sb, sa); |
| 779 | | SDL_RenderDrawLine(sdl->sdl_renderer, prim->bounds.x0 + hofs, prim->bounds.y0 + vofs, |
| 787 | SDL_SetRenderDrawBlendMode(sdl->m_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim->flags))); |
| 788 | SDL_SetRenderDrawColor(sdl->m_renderer, sr, sg, sb, sa); |
| 789 | SDL_RenderDrawLine(sdl->m_renderer, prim->bounds.x0 + hofs, prim->bounds.y0 + vofs, |
| 780 | 790 | prim->bounds.x1 + hofs, prim->bounds.y1 + vofs); |
| 781 | 791 | break; |
| 782 | 792 | case render_primitive::QUAD: |
| 783 | | texture = texture_update(window, prim); |
| 793 | texture = sdl->texture_update(*prim); |
| 784 | 794 | if (texture) |
| 785 | | blit_pixels += (texture->rawheight * texture->rawwidth); |
| 786 | | render_quad(sdl, texture, prim, |
| 795 | blit_pixels += (texture->raw_height() * texture->raw_width()); |
| 796 | sdl->render_quad(texture, prim, |
| 787 | 797 | round_nearest(hofs + prim->bounds.x0), |
| 788 | 798 | round_nearest(vofs + prim->bounds.y0)); |
| 789 | 799 | break; |
| r242695 | r242696 | |
| 794 | 804 | |
| 795 | 805 | window->primlist->release_lock(); |
| 796 | 806 | |
| 797 | | sdl->last_blit_pixels = blit_pixels; |
| 798 | | sdl->last_blit_time = -osd_ticks(); |
| 799 | | SDL_RenderPresent(sdl->sdl_renderer); |
| 800 | | sdl->last_blit_time += osd_ticks(); |
| 807 | sdl->m_last_blit_pixels = blit_pixels; |
| 808 | sdl->m_last_blit_time = -osd_ticks(); |
| 809 | SDL_RenderPresent(sdl->m_renderer); |
| 810 | sdl->m_last_blit_time += osd_ticks(); |
| 801 | 811 | |
| 802 | 812 | return 0; |
| 803 | 813 | } |
| r242695 | r242696 | |
| 811 | 821 | { |
| 812 | 822 | sdl_info *sdl = (sdl_info *) window->dxdata; |
| 813 | 823 | |
| 814 | | sdl->blittimer = 2; |
| 824 | sdl->m_blittimer = 2; |
| 815 | 825 | } |
| 816 | 826 | |
| 817 | 827 | |
| r242695 | r242696 | |
| 845 | 855 | // texture_compute_size and type |
| 846 | 856 | //============================================================ |
| 847 | 857 | |
| 848 | | static copy_info *texture_compute_size_type(SDL_Renderer *renderer, const render_texinfo *texsource, texture_info *texture, UINT32 flags) |
| 858 | copy_info_t *texture_info::compute_size_type() |
| 849 | 859 | { |
| 850 | | copy_info *bi; |
| 851 | | copy_info *result = NULL; |
| 860 | copy_info_t *bi; |
| 861 | copy_info_t *result = NULL; |
| 852 | 862 | int maxperf = 0; |
| 853 | | //int bm = PRIMFLAG_GET_BLENDMODE(flags); |
| 854 | 863 | |
| 855 | | for (bi = blit_info[texture->format]; bi != NULL; bi = bi->next) |
| 864 | for (bi = blit_info[m_format]; bi != NULL; bi = bi->next) |
| 856 | 865 | { |
| 857 | | if ((texture->is_rotated == bi->rotate) |
| 858 | | && (texture->sdl_blendmode == bi->bm_mask)) |
| 866 | if ((m_is_rotated == bi->rotate) |
| 867 | && (m_sdl_blendmode == bi->bm_mask)) |
| 859 | 868 | { |
| 860 | | if (RendererSupportsFormat(renderer, bi->dst_fmt, texture->sdl_access, bi->dstname)) |
| 869 | if (RendererSupportsFormat(m_renderer, bi->dst_fmt, m_sdl_access, bi->dstname)) |
| 861 | 870 | { |
| 862 | | if (bi->perf == 0) |
| 871 | int perf = bi->perf; |
| 872 | if (perf == 0) |
| 863 | 873 | return bi; |
| 864 | | else if (bi->perf > (maxperf * 102) / 100) |
| 874 | else if (perf > (maxperf * 102) / 100) |
| 865 | 875 | { |
| 866 | 876 | result = bi; |
| 867 | | maxperf = bi->perf; |
| 877 | maxperf = perf; |
| 868 | 878 | } |
| 869 | 879 | } |
| 870 | 880 | } |
| r242695 | r242696 | |
| 872 | 882 | if (result) |
| 873 | 883 | return result; |
| 874 | 884 | /* try last resort handlers */ |
| 875 | | for (bi = blit_info[texture->format]; bi != NULL; bi = bi->next) |
| 885 | for (bi = blit_info[m_format]; bi != NULL; bi = bi->next) |
| 876 | 886 | { |
| 877 | | if ((texture->is_rotated == bi->rotate) |
| 878 | | && (texture->sdl_blendmode == bi->bm_mask)) |
| 879 | | if (RendererSupportsFormat(renderer, bi->dst_fmt, texture->sdl_access, bi->dstname)) |
| 887 | if ((m_is_rotated == bi->rotate) |
| 888 | && (m_sdl_blendmode == bi->bm_mask)) |
| 889 | if (RendererSupportsFormat(m_renderer, bi->dst_fmt, m_sdl_access, bi->dstname)) |
| 880 | 890 | return bi; |
| 881 | 891 | } |
| 882 | 892 | //FIXME: crash implement a -do nothing handler */ |
| r242695 | r242696 | |
| 884 | 894 | } |
| 885 | 895 | |
| 886 | 896 | //============================================================ |
| 887 | | // texture_create |
| 897 | // texture_info::matches |
| 888 | 898 | //============================================================ |
| 889 | 899 | |
| 890 | | static texture_info *texture_create(sdl_window_info *window, const render_texinfo *texsource, quad_setup_data *setup, UINT32 flags) |
| 900 | bool texture_info::matches(const render_primitive &prim, const quad_setup_data &setup) |
| 891 | 901 | { |
| 892 | | sdl_info *sdl = (sdl_info *) window->dxdata; |
| 893 | | texture_info *texture; |
| 902 | return texinfo().base == prim.texture.base && |
| 903 | texinfo().width == prim.texture.width && |
| 904 | texinfo().height == prim.texture.height && |
| 905 | texinfo().rowpixels == prim.texture.rowpixels && |
| 906 | m_setup.dudx == setup.dudx && |
| 907 | m_setup.dvdx == setup.dvdx && |
| 908 | m_setup.dudy == setup.dudy && |
| 909 | m_setup.dvdy == setup.dvdy && |
| 910 | ((flags() ^ prim.flags) & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) == 0; |
| 911 | } |
| 894 | 912 | |
| 895 | | // allocate a new texture |
| 896 | | texture = global_alloc(texture_info); |
| 913 | //============================================================ |
| 914 | // texture_create |
| 915 | //============================================================ |
| 897 | 916 | |
| 917 | texture_info::texture_info(SDL_Renderer *renderer, const render_texinfo &texsource, const quad_setup_data &setup, UINT32 flags) |
| 918 | { |
| 919 | |
| 898 | 920 | // fill in the core data |
| 899 | | texture->hash = texture_compute_hash(texsource, flags); |
| 900 | | texture->flags = flags; |
| 901 | | texture->texinfo = *texsource; |
| 902 | | texture->texinfo.seqid = -1; // force set data |
| 903 | | texture->is_rotated = FALSE; |
| 904 | | texture->setup = *setup; |
| 905 | | texture->sdl_blendmode = map_blendmode(PRIMFLAG_GET_BLENDMODE(flags)); |
| 921 | m_renderer = renderer; |
| 922 | m_hash = texture_compute_hash(texsource, flags); |
| 923 | m_flags = flags; |
| 924 | m_texinfo = texsource; |
| 925 | m_texinfo.seqid = -1; // force set data |
| 926 | m_is_rotated = FALSE; |
| 927 | m_setup = setup; |
| 928 | m_sdl_blendmode = map_blendmode(PRIMFLAG_GET_BLENDMODE(flags)); |
| 929 | m_pitch = 0; |
| 906 | 930 | |
| 907 | 931 | switch (PRIMFLAG_GET_TEXFORMAT(flags)) |
| 908 | 932 | { |
| 909 | 933 | case TEXFORMAT_ARGB32: |
| 910 | | texture->format = SDL_TEXFORMAT_ARGB32; |
| 934 | m_format = SDL_TEXFORMAT_ARGB32; |
| 911 | 935 | break; |
| 912 | 936 | case TEXFORMAT_RGB32: |
| 913 | | texture->format = texsource->palette() ? SDL_TEXFORMAT_RGB32_PALETTED : SDL_TEXFORMAT_RGB32; |
| 937 | m_format = texsource.palette() ? SDL_TEXFORMAT_RGB32_PALETTED : SDL_TEXFORMAT_RGB32; |
| 914 | 938 | break; |
| 915 | 939 | case TEXFORMAT_PALETTE16: |
| 916 | | texture->format = SDL_TEXFORMAT_PALETTE16; |
| 940 | m_format = SDL_TEXFORMAT_PALETTE16; |
| 917 | 941 | break; |
| 918 | 942 | case TEXFORMAT_PALETTEA16: |
| 919 | | texture->format = SDL_TEXFORMAT_PALETTE16A; |
| 943 | m_format = SDL_TEXFORMAT_PALETTE16A; |
| 920 | 944 | break; |
| 921 | 945 | case TEXFORMAT_YUY16: |
| 922 | | texture->format = texsource->palette() ? SDL_TEXFORMAT_YUY16_PALETTED : SDL_TEXFORMAT_YUY16; |
| 946 | m_format = texsource.palette() ? SDL_TEXFORMAT_YUY16_PALETTED : SDL_TEXFORMAT_YUY16; |
| 923 | 947 | break; |
| 924 | 948 | |
| 925 | 949 | default: |
| 926 | 950 | osd_printf_error("Unknown textureformat %d\n", PRIMFLAG_GET_TEXFORMAT(flags)); |
| 927 | 951 | } |
| 928 | 952 | |
| 929 | | texture->rawwidth = texsource->width; |
| 930 | | texture->rawheight = texsource->height; |
| 931 | | if (setup->rotwidth != texture->rawwidth || setup->rotheight != texture->rawheight |
| 932 | | || setup->dudx < 0 ) |
| 933 | | texture->is_rotated = TRUE; |
| 953 | if (setup.rotwidth != m_texinfo.width || setup.rotheight != m_texinfo.height |
| 954 | || setup.dudx < 0 || setup.dvdy < 0) |
| 955 | m_is_rotated = TRUE; |
| 934 | 956 | else |
| 935 | | texture->is_rotated = FALSE; |
| 957 | m_is_rotated = FALSE; |
| 936 | 958 | |
| 937 | | //texture->sdl_access = SDL_TEXTUREACCESS_STATIC; |
| 938 | | texture->sdl_access = SDL_TEXTUREACCESS_STREAMING; |
| 959 | //m_sdl_access = SDL_TEXTUREACCESS_STATIC; |
| 960 | m_sdl_access = SDL_TEXTUREACCESS_STREAMING; |
| 939 | 961 | |
| 940 | 962 | // Watch out for 0x0 textures ... |
| 941 | | if (!texture->setup.rotwidth || !texture->setup.rotheight) |
| 963 | if (!m_setup.rotwidth || !m_setup.rotheight) |
| 942 | 964 | osd_printf_warning("Trying to create texture with zero dim\n"); |
| 943 | 965 | |
| 944 | | // compute the size |
| 945 | | texture->copyinfo = texture_compute_size_type(sdl->sdl_renderer, texsource, texture, flags); |
| 966 | // set copy_info |
| 946 | 967 | |
| 947 | | texture->texture_id = SDL_CreateTexture(sdl->sdl_renderer, texture->copyinfo->dst_fmt, texture->sdl_access, |
| 948 | | texture->setup.rotwidth, texture->setup.rotheight); |
| 968 | m_copyinfo = compute_size_type(); |
| 949 | 969 | |
| 950 | | if (!texture->texture_id) |
| 951 | | osd_printf_error("Error creating texture: %d x %d, pixelformat %s error: %s\n", texture->setup.rotwidth, texture->setup.rotheight, |
| 952 | | texture->copyinfo->dstname, SDL_GetError()); |
| 970 | m_texture_id = SDL_CreateTexture(m_renderer, m_copyinfo->dst_fmt, m_sdl_access, |
| 971 | m_setup.rotwidth, m_setup.rotheight); |
| 953 | 972 | |
| 954 | | if ( (texture->copyinfo->func != NULL) && (texture->sdl_access == SDL_TEXTUREACCESS_STATIC)) |
| 973 | if (!m_texture_id) |
| 974 | osd_printf_error("Error creating texture: %d x %d, pixelformat %s error: %s\n", m_setup.rotwidth, m_setup.rotheight, |
| 975 | m_copyinfo->dstname, SDL_GetError()); |
| 976 | |
| 977 | if (m_sdl_access == SDL_TEXTUREACCESS_STATIC) |
| 955 | 978 | { |
| 956 | | texture->pixels = malloc(texture->setup.rotwidth * texture->setup.rotheight * texture->copyinfo->dst_bpp); |
| 957 | | texture->pixels_own=TRUE; |
| 979 | if (m_copyinfo->func != NULL) |
| 980 | m_pixels = malloc(m_setup.rotwidth * m_setup.rotheight * m_copyinfo->dst_bpp); |
| 981 | else |
| 982 | m_pixels = NULL; |
| 958 | 983 | } |
| 959 | | /* add us to the texture list */ |
| 960 | | texture->next = sdl->texlist; |
| 961 | | sdl->texlist = texture; |
| 984 | m_last_access = osd_ticks(); |
| 962 | 985 | |
| 963 | | texture->last_access = osd_ticks(); |
| 986 | } |
| 964 | 987 | |
| 965 | | return texture; |
| 988 | texture_info::~texture_info() |
| 989 | { |
| 990 | SDL_DestroyTexture(m_texture_id); |
| 991 | if ( is_pixels_owned() && m_pixels != NULL ) |
| 992 | free(m_pixels); |
| 966 | 993 | } |
| 967 | 994 | |
| 968 | 995 | //============================================================ |
| 969 | 996 | // texture_set_data |
| 970 | 997 | //============================================================ |
| 971 | 998 | |
| 972 | | static void texture_set_data(sdl_info *sdl, texture_info *texture, const render_texinfo *texsource, UINT32 flags) |
| 999 | void texture_info::set_data(const render_texinfo &texsource, const UINT32 flags) |
| 973 | 1000 | { |
| 974 | | texture->copyinfo->time -= osd_ticks(); |
| 975 | | if (texture->sdl_access == SDL_TEXTUREACCESS_STATIC) |
| 1001 | m_copyinfo->time -= osd_ticks(); |
| 1002 | if (m_sdl_access == SDL_TEXTUREACCESS_STATIC) |
| 976 | 1003 | { |
| 977 | | if ( texture->copyinfo->func ) |
| 1004 | if ( m_copyinfo->func ) |
| 978 | 1005 | { |
| 979 | | texture->pitch = texture->setup.rotwidth * texture->copyinfo->dst_bpp; |
| 980 | | texture->copyinfo->func(texture, texsource); |
| 1006 | m_pitch = m_setup.rotwidth * m_copyinfo->dst_bpp; |
| 1007 | m_copyinfo->func(this, &texsource); |
| 981 | 1008 | } |
| 982 | 1009 | else |
| 983 | 1010 | { |
| 984 | | texture->pixels = texsource->base; |
| 985 | | texture->pitch = texture->texinfo.rowpixels * texture->copyinfo->dst_bpp; |
| 1011 | m_pixels = texsource.base; |
| 1012 | m_pitch = m_texinfo.rowpixels * m_copyinfo->dst_bpp; |
| 986 | 1013 | } |
| 987 | | SDL_UpdateTexture(texture->texture_id, NULL, texture->pixels, texture->pitch); |
| 1014 | SDL_UpdateTexture(m_texture_id, NULL, m_pixels, m_pitch); |
| 988 | 1015 | } |
| 989 | 1016 | else |
| 990 | 1017 | { |
| 991 | | SDL_LockTexture(texture->texture_id, NULL, (void **) &texture->pixels, &texture->pitch); |
| 992 | | if ( texture->copyinfo->func ) |
| 993 | | texture->copyinfo->func(texture, texsource); |
| 1018 | SDL_LockTexture(m_texture_id, NULL, (void **) &m_pixels, &m_pitch); |
| 1019 | if ( m_copyinfo->func ) |
| 1020 | m_copyinfo->func(this, &texsource); |
| 994 | 1021 | else |
| 995 | 1022 | { |
| 996 | | UINT8 *src = (UINT8 *) texsource->base; |
| 997 | | UINT8 *dst = (UINT8 *) texture->pixels; |
| 998 | | int spitch = texsource->rowpixels * texture->copyinfo->dst_bpp; |
| 999 | | int num = texsource->width * texture->copyinfo->dst_bpp; |
| 1000 | | int h = texsource->height; |
| 1023 | UINT8 *src = (UINT8 *) texsource.base; |
| 1024 | UINT8 *dst = (UINT8 *) m_pixels; |
| 1025 | int spitch = texsource.rowpixels * m_copyinfo->dst_bpp; |
| 1026 | int num = texsource.width * m_copyinfo->dst_bpp; |
| 1027 | int h = texsource.height; |
| 1001 | 1028 | while (h--) { |
| 1002 | 1029 | memcpy(dst, src, num); |
| 1003 | 1030 | src += spitch; |
| 1004 | | dst += texture->pitch; |
| 1031 | dst += m_pitch; |
| 1005 | 1032 | } |
| 1006 | 1033 | } |
| 1007 | | SDL_UnlockTexture(texture->texture_id); |
| 1034 | SDL_UnlockTexture(m_texture_id); |
| 1008 | 1035 | } |
| 1009 | | texture->copyinfo->time += osd_ticks(); |
| 1036 | m_copyinfo->time += osd_ticks(); |
| 1010 | 1037 | } |
| 1011 | 1038 | |
| 1012 | 1039 | //============================================================ |
| 1013 | 1040 | // compute rotation setup |
| 1014 | 1041 | //============================================================ |
| 1015 | 1042 | |
| 1016 | | static void compute_setup(sdl_info *sdl, const render_primitive *prim, quad_setup_data *setup, int flags) |
| 1043 | void quad_setup_data::compute(const render_primitive &prim) |
| 1017 | 1044 | { |
| 1018 | | const render_quad_texuv *texcoords = &prim->texcoords; |
| 1019 | | int texwidth = prim->texture.width; |
| 1020 | | int texheight = prim->texture.height; |
| 1045 | const render_quad_texuv *texcoords = &prim.texcoords; |
| 1046 | int texwidth = prim.texture.width; |
| 1047 | int texheight = prim.texture.height; |
| 1021 | 1048 | float fdudx, fdvdx, fdudy, fdvdy; |
| 1022 | 1049 | float width, height; |
| 1023 | 1050 | float fscale; |
| 1024 | 1051 | /* determine U/V deltas */ |
| 1025 | | if ((PRIMFLAG_GET_SCREENTEX(flags))) |
| 1052 | if ((PRIMFLAG_GET_SCREENTEX(prim.flags))) |
| 1026 | 1053 | fscale = (float) video_config.prescale; |
| 1027 | 1054 | else |
| 1028 | 1055 | fscale = 1.0f; |
| r242695 | r242696 | |
| 1032 | 1059 | fdudy = (texcoords->bl.u - texcoords->tl.u) / fscale; // b a12 |
| 1033 | 1060 | fdvdy = (texcoords->bl.v - texcoords->tl.v) / fscale; // d a22 |
| 1034 | 1061 | |
| 1062 | #if 0 |
| 1063 | printf("tl.u %f tl.v %f\n", texcoords->tl.u, texcoords->tl.v); |
| 1064 | printf("tr.u %f tr.v %f\n", texcoords->tr.u, texcoords->tr.v); |
| 1065 | printf("bl.u %f bl.v %f\n", texcoords->bl.u, texcoords->bl.v); |
| 1066 | printf("br.u %f br.v %f\n", texcoords->br.u, texcoords->br.v); |
| 1035 | 1067 | /* compute start and delta U,V coordinates now */ |
| 1068 | #endif |
| 1036 | 1069 | |
| 1037 | | setup->dudx = round_nearest(65536.0f * fdudx); |
| 1038 | | setup->dvdx = round_nearest(65536.0f * fdvdx); |
| 1039 | | setup->dudy = round_nearest(65536.0f * fdudy); |
| 1040 | | setup->dvdy = round_nearest(65536.0f * fdvdy); |
| 1041 | | setup->startu = round_nearest(65536.0f * (float) texwidth * texcoords->tl.u); |
| 1042 | | setup->startv = round_nearest(65536.0f * (float) texheight * texcoords->tl.v); |
| 1070 | dudx = round_nearest(65536.0f * fdudx); |
| 1071 | dvdx = round_nearest(65536.0f * fdvdx); |
| 1072 | dudy = round_nearest(65536.0f * fdudy); |
| 1073 | dvdy = round_nearest(65536.0f * fdvdy); |
| 1074 | startu = round_nearest(65536.0f * (float) texwidth * texcoords->tl.u); |
| 1075 | startv = round_nearest(65536.0f * (float) texheight * texcoords->tl.v); |
| 1043 | 1076 | |
| 1044 | 1077 | /* clamp to integers */ |
| 1045 | 1078 | |
| 1046 | 1079 | width = fabs((fdudx * (float) (texwidth) + fdvdx * (float) (texheight)) * fscale * fscale); |
| 1047 | 1080 | height = fabs((fdudy * (float)(texwidth) + fdvdy * (float) (texheight)) * fscale * fscale); |
| 1048 | 1081 | |
| 1049 | | setup->rotwidth = width; |
| 1050 | | setup->rotheight = height; |
| 1082 | rotwidth = width; |
| 1083 | rotheight = height; |
| 1051 | 1084 | |
| 1052 | | setup->startu += (setup->dudx + setup->dudy) / 2; |
| 1053 | | setup->startv += (setup->dvdx + setup->dvdy) / 2; |
| 1085 | startu += (dudx + dudy) / 2; |
| 1086 | startv += (dvdx + dvdy) / 2; |
| 1054 | 1087 | |
| 1055 | 1088 | } |
| 1056 | 1089 | |
| r242695 | r242696 | |
| 1058 | 1091 | // texture_find |
| 1059 | 1092 | //============================================================ |
| 1060 | 1093 | |
| 1061 | | static texture_info *texture_find(sdl_info *sdl, const render_primitive *prim, quad_setup_data *setup) |
| 1094 | texture_info *sdl_info::texture_find(const render_primitive &prim, const quad_setup_data &setup) |
| 1062 | 1095 | { |
| 1063 | | HashT texhash = texture_compute_hash(&prim->texture, prim->flags); |
| 1096 | HashT texhash = texture_compute_hash(prim.texture, prim.flags); |
| 1064 | 1097 | texture_info *texture; |
| 1065 | 1098 | osd_ticks_t now = osd_ticks(); |
| 1066 | 1099 | |
| 1067 | 1100 | // find a match |
| 1068 | | for (texture = sdl->texlist; texture != NULL; ) |
| 1069 | | if (texture->hash == texhash && |
| 1070 | | texture->texinfo.base == prim->texture.base && |
| 1071 | | texture->texinfo.width == prim->texture.width && |
| 1072 | | texture->texinfo.height == prim->texture.height && |
| 1073 | | texture->texinfo.rowpixels == prim->texture.rowpixels && |
| 1074 | | texture->setup.dudx == setup->dudx && |
| 1075 | | texture->setup.dvdx == setup->dvdx && |
| 1076 | | texture->setup.dudy == setup->dudy && |
| 1077 | | texture->setup.dvdy == setup->dvdy && |
| 1078 | | ((texture->flags ^ prim->flags) & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) == 0) |
| 1101 | for (texture = m_texlist.first(); texture != NULL; ) |
| 1102 | if (texture->hash() == texhash && |
| 1103 | texture->matches(prim, setup)) |
| 1079 | 1104 | { |
| 1080 | | /* would we choose another blitter ? */ |
| 1081 | | if ((texture->copyinfo->samples & 0x1f) == 0x1f) |
| 1105 | /* would we choose another blitter based on performance ? */ |
| 1106 | if ((texture->m_copyinfo->samples & 0x7f) == 0x7f) |
| 1082 | 1107 | { |
| 1083 | | if (texture->copyinfo != texture_compute_size_type(sdl->sdl_renderer, &texture->texinfo, texture, prim->flags)) |
| 1108 | if (texture->m_copyinfo != texture->compute_size_type()) |
| 1084 | 1109 | return NULL; |
| 1085 | | #if 0 |
| 1086 | | else |
| 1087 | | { |
| 1088 | | /* reset stats */ |
| 1089 | | texture->copyinfo->samples = 0; |
| 1090 | | texture->copyinfo->time = 0; |
| 1091 | | texture->copyinfo->pixel_count = 0; |
| 1092 | | } |
| 1093 | | #endif |
| 1094 | 1110 | } |
| 1095 | | texture->last_access = now; |
| 1111 | texture->m_last_access = now; |
| 1096 | 1112 | return texture; |
| 1097 | 1113 | } |
| 1098 | 1114 | else |
| 1099 | 1115 | { |
| 1100 | 1116 | /* free resources not needed any longer? */ |
| 1101 | 1117 | texture_info *expire = texture; |
| 1102 | | texture = texture->next; |
| 1103 | | if (now - expire->last_access > osd_ticks_per_second()) |
| 1104 | | drawsdl2_destroy_texture(sdl, expire); |
| 1118 | texture = texture->next(); |
| 1119 | if (now - expire->m_last_access > osd_ticks_per_second()) |
| 1120 | m_texlist.remove(*expire); |
| 1105 | 1121 | } |
| 1106 | 1122 | |
| 1107 | 1123 | // nothing found |
| r242695 | r242696 | |
| 1112 | 1128 | // texture_update |
| 1113 | 1129 | //============================================================ |
| 1114 | 1130 | |
| 1115 | | static texture_info * texture_update(sdl_window_info *window, const render_primitive *prim) |
| 1131 | texture_info * sdl_info::texture_update(const render_primitive &prim) |
| 1116 | 1132 | { |
| 1117 | | sdl_info *sdl = (sdl_info *) window->dxdata; |
| 1118 | 1133 | quad_setup_data setup; |
| 1119 | 1134 | texture_info *texture; |
| 1120 | 1135 | |
| 1121 | | compute_setup(sdl, prim, &setup, prim->flags); |
| 1136 | setup.compute(prim); |
| 1122 | 1137 | |
| 1123 | | texture = texture_find(sdl, prim, &setup); |
| 1138 | texture = texture_find(prim, setup); |
| 1124 | 1139 | |
| 1125 | 1140 | // if we didn't find one, create a new texture |
| 1126 | | if (texture == NULL && prim->texture.base != NULL) |
| 1141 | if (texture == NULL && prim.texture.base != NULL) |
| 1127 | 1142 | { |
| 1128 | | texture = texture_create(window, &prim->texture, &setup, prim->flags); |
| 1143 | texture = global_alloc(texture_info(m_renderer, prim.texture, setup, prim.flags)); |
| 1144 | /* add us to the texture list */ |
| 1145 | m_texlist.prepend(*texture); |
| 1146 | |
| 1129 | 1147 | } |
| 1130 | 1148 | |
| 1131 | 1149 | if (texture != NULL) |
| 1132 | 1150 | { |
| 1133 | | if (prim->texture.base != NULL && texture->texinfo.seqid != prim->texture.seqid) |
| 1151 | if (prim.texture.base != NULL && texture->texinfo().seqid != prim.texture.seqid) |
| 1134 | 1152 | { |
| 1135 | | texture->texinfo.seqid = prim->texture.seqid; |
| 1153 | texture->texinfo().seqid = prim.texture.seqid; |
| 1136 | 1154 | // if we found it, but with a different seqid, copy the data |
| 1137 | | texture_set_data(sdl, texture, &prim->texture, prim->flags); |
| 1155 | texture->set_data(prim.texture, prim.flags); |
| 1138 | 1156 | } |
| 1139 | 1157 | |
| 1140 | 1158 | } |
| 1141 | 1159 | return texture; |
| 1142 | 1160 | } |
| 1143 | 1161 | |
| 1144 | | static void drawsdl2_destroy_texture(sdl_info *sdl, texture_info *texture) |
| 1145 | | { |
| 1146 | | texture_info *p; |
| 1147 | 1162 | |
| 1148 | | SDL_DestroyTexture(texture->texture_id); |
| 1149 | | if ( texture->pixels_own ) |
| 1150 | | { |
| 1151 | | free(texture->pixels); |
| 1152 | | texture->pixels=NULL; |
| 1153 | | texture->pixels_own=FALSE; |
| 1154 | | } |
| 1155 | | |
| 1156 | | for (p=sdl->texlist; p != NULL; p = p->next) |
| 1157 | | if (p->next == texture) |
| 1158 | | break; |
| 1159 | | if (p == NULL) |
| 1160 | | sdl->texlist = NULL; |
| 1161 | | else |
| 1162 | | p->next = texture->next; |
| 1163 | | global_free(texture); |
| 1164 | | } |
| 1165 | | |
| 1166 | 1163 | static void drawsdl2_destroy_all_textures(sdl_window_info *window) |
| 1167 | 1164 | { |
| 1168 | 1165 | sdl_info *sdl = (sdl_info *) window->dxdata; |
| 1169 | | texture_info *next_texture=NULL, *texture = NULL; |
| 1170 | | int lock=FALSE; |
| 1171 | 1166 | |
| 1172 | 1167 | if (sdl == NULL) |
| 1173 | 1168 | return; |
| 1174 | 1169 | |
| 1175 | 1170 | if(window->primlist) |
| 1176 | 1171 | { |
| 1177 | | lock=TRUE; |
| 1178 | 1172 | window->primlist->acquire_lock(); |
| 1173 | sdl->m_texlist.reset(); |
| 1174 | window->primlist->release_lock(); |
| 1179 | 1175 | } |
| 1180 | | |
| 1181 | | texture = sdl->texlist; |
| 1182 | | |
| 1183 | | while (texture) |
| 1184 | | { |
| 1185 | | next_texture = texture->next; |
| 1186 | | drawsdl2_destroy_texture(sdl, texture); |
| 1187 | | texture = next_texture; |
| 1188 | | } |
| 1189 | | |
| 1190 | | if (lock) |
| 1191 | | window->primlist->release_lock(); |
| 1176 | else |
| 1177 | sdl->m_texlist.reset(); |
| 1192 | 1178 | } |