Mercurial > sdl-ios-xcode
comparison src/SDL_compat.c @ 5172:ededa1ccf91c
Switched the SDL 1.2 compatibility to use the window surface, so it's fast even when there's no hardware acceleration available.
This means that the YUV overlay now uses software, but that's okay since fast YUV code should be using the textures now anyway.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Thu, 03 Feb 2011 21:13:55 -0800 |
parents | 88c656ffea44 |
children | 34e2d5115786 |
comparison
equal
deleted
inserted
replaced
5171:db487f28419e | 5172:ededa1ccf91c |
---|---|
26 #include "SDL.h" | 26 #include "SDL.h" |
27 #include "SDL_syswm.h" | 27 #include "SDL_syswm.h" |
28 | 28 |
29 #include "video/SDL_sysvideo.h" | 29 #include "video/SDL_sysvideo.h" |
30 #include "video/SDL_pixels_c.h" | 30 #include "video/SDL_pixels_c.h" |
31 #include "render/SDL_yuv_sw_c.h" | |
32 | |
31 | 33 |
32 static SDL_Window *SDL_VideoWindow = NULL; | 34 static SDL_Window *SDL_VideoWindow = NULL; |
33 static SDL_Renderer *SDL_VideoRenderer = NULL; | |
34 static SDL_Texture *SDL_VideoTexture = NULL; | |
35 static SDL_Surface *SDL_VideoSurface = NULL; | 35 static SDL_Surface *SDL_VideoSurface = NULL; |
36 static SDL_Surface *SDL_ShadowSurface = NULL; | 36 static SDL_Surface *SDL_ShadowSurface = NULL; |
37 static SDL_Surface *SDL_PublicSurface = NULL; | 37 static SDL_Surface *SDL_PublicSurface = NULL; |
38 static SDL_GLContext *SDL_VideoContext = NULL; | 38 static SDL_GLContext *SDL_VideoContext = NULL; |
39 static Uint32 SDL_VideoFlags = 0; | 39 static Uint32 SDL_VideoFlags = 0; |
40 static char *wm_title = NULL; | 40 static char *wm_title = NULL; |
41 static SDL_Surface *SDL_VideoIcon; | 41 static SDL_Surface *SDL_VideoIcon; |
42 static int SDL_enabled_UNICODE = 0; | 42 static int SDL_enabled_UNICODE = 0; |
43 | 43 |
44 char * | 44 const char * |
45 SDL_AudioDriverName(char *namebuf, int maxlen) | 45 SDL_AudioDriverName(char *namebuf, int maxlen) |
46 { | 46 { |
47 const char *name = SDL_GetCurrentAudioDriver(); | 47 const char *name = SDL_GetCurrentAudioDriver(); |
48 if (name) { | 48 if (name) { |
49 SDL_strlcpy(namebuf, name, maxlen); | 49 if (namebuf) { |
50 return namebuf; | 50 SDL_strlcpy(namebuf, name, maxlen); |
51 return namebuf; | |
52 } else { | |
53 return name; | |
54 } | |
51 } | 55 } |
52 return NULL; | 56 return NULL; |
53 } | 57 } |
54 | 58 |
55 char * | 59 const char * |
56 SDL_VideoDriverName(char *namebuf, int maxlen) | 60 SDL_VideoDriverName(char *namebuf, int maxlen) |
57 { | 61 { |
58 const char *name = SDL_GetCurrentVideoDriver(); | 62 const char *name = SDL_GetCurrentVideoDriver(); |
59 if (name) { | 63 if (name) { |
60 if (namebuf) { | 64 if (namebuf) { |
342 *x = (mode.w - w) / 2; | 346 *x = (mode.w - w) / 2; |
343 *y = (mode.h - h) / 2; | 347 *y = (mode.h - h) / 2; |
344 } | 348 } |
345 } | 349 } |
346 | 350 |
347 static SDL_Surface * | |
348 CreateVideoSurface(SDL_Texture * texture) | |
349 { | |
350 Uint32 format; | |
351 int w, h; | |
352 int bpp; | |
353 Uint32 Rmask, Gmask, Bmask, Amask; | |
354 | |
355 if (SDL_QueryTexture(texture, &format, NULL, &w, &h) < 0) { | |
356 return NULL; | |
357 } | |
358 | |
359 if (!SDL_PixelFormatEnumToMasks | |
360 (format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { | |
361 SDL_SetError("Unknown texture format"); | |
362 return NULL; | |
363 } | |
364 | |
365 return SDL_CreateRGBSurface(0, w, h, bpp, Rmask, Gmask, Bmask, Amask); | |
366 } | |
367 | |
368 static void | 351 static void |
369 ClearVideoSurface() | 352 ClearVideoSurface() |
370 { | 353 { |
371 Uint32 black; | 354 Uint32 black; |
372 | 355 |
432 SDL_VideoSurface->h = height; | 415 SDL_VideoSurface->h = height; |
433 return 0; | 416 return 0; |
434 } | 417 } |
435 | 418 |
436 /* Destroy the screen texture and recreate it */ | 419 /* Destroy the screen texture and recreate it */ |
437 SDL_QueryTexture(SDL_VideoTexture, &format, &access, &w, &h); | 420 SDL_VideoSurface = SDL_GetWindowSurface(SDL_VideoWindow); |
438 SDL_DestroyTexture(SDL_VideoTexture); | 421 if (!SDL_VideoSurface) { |
439 SDL_VideoTexture = SDL_CreateTexture(SDL_VideoRenderer, format, | |
440 access, width, height); | |
441 if (!SDL_VideoTexture) { | |
442 return -1; | 422 return -1; |
443 } | 423 } |
444 | |
445 SDL_VideoSurface->w = width; | |
446 SDL_VideoSurface->h = height; | |
447 SDL_CalculatePitch(SDL_VideoSurface); | |
448 SDL_VideoSurface->pixels = | |
449 SDL_realloc(SDL_VideoSurface->pixels, | |
450 SDL_VideoSurface->h * SDL_VideoSurface->pitch); | |
451 SDL_SetClipRect(SDL_VideoSurface, NULL); | |
452 SDL_InvalidateMap(SDL_VideoSurface->map); | |
453 | 424 |
454 if (SDL_ShadowSurface) { | 425 if (SDL_ShadowSurface) { |
455 SDL_ShadowSurface->w = width; | 426 SDL_ShadowSurface->w = width; |
456 SDL_ShadowSurface->h = height; | 427 SDL_ShadowSurface->h = height; |
457 SDL_ShadowSurface->pitch = SDL_CalculatePitch(SDL_ShadowSurface); | 428 SDL_ShadowSurface->pitch = SDL_CalculatePitch(SDL_ShadowSurface); |
458 SDL_ShadowSurface->pixels = | 429 SDL_ShadowSurface->pixels = |
459 SDL_realloc(SDL_ShadowSurface->pixels, | 430 SDL_realloc(SDL_ShadowSurface->pixels, |
460 SDL_ShadowSurface->h * SDL_ShadowSurface->pitch); | 431 SDL_ShadowSurface->h * SDL_ShadowSurface->pitch); |
461 SDL_SetClipRect(SDL_ShadowSurface, NULL); | 432 SDL_SetClipRect(SDL_ShadowSurface, NULL); |
462 SDL_InvalidateMap(SDL_ShadowSurface->map); | 433 SDL_InvalidateMap(SDL_ShadowSurface->map); |
434 } else { | |
435 SDL_PublicSurface = SDL_VideoSurface; | |
463 } | 436 } |
464 | 437 |
465 ClearVideoSurface(); | 438 ClearVideoSurface(); |
466 | 439 |
467 return 0; | 440 return 0; |
474 int window_x = SDL_WINDOWPOS_UNDEFINED; | 447 int window_x = SDL_WINDOWPOS_UNDEFINED; |
475 int window_y = SDL_WINDOWPOS_UNDEFINED; | 448 int window_y = SDL_WINDOWPOS_UNDEFINED; |
476 Uint32 window_flags; | 449 Uint32 window_flags; |
477 Uint32 surface_flags; | 450 Uint32 surface_flags; |
478 Uint32 i; | 451 Uint32 i; |
479 SDL_RendererInfo info; | |
480 Uint32 desired_format; | |
481 | 452 |
482 if (!SDL_GetVideoDevice()) { | 453 if (!SDL_GetVideoDevice()) { |
483 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) { | 454 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) { |
484 return NULL; | 455 return NULL; |
485 } | 456 } |
584 SDL_VideoSurface->flags |= surface_flags; | 555 SDL_VideoSurface->flags |= surface_flags; |
585 SDL_PublicSurface = SDL_VideoSurface; | 556 SDL_PublicSurface = SDL_VideoSurface; |
586 return SDL_PublicSurface; | 557 return SDL_PublicSurface; |
587 } | 558 } |
588 | 559 |
589 /* Create a renderer for the window */ | |
590 SDL_VideoRenderer = SDL_CreateRenderer(SDL_VideoWindow, -1, 0); | |
591 if (!SDL_VideoRenderer) { | |
592 return NULL; | |
593 } | |
594 | |
595 /* Create a texture for the screen surface */ | |
596 SDL_GetRendererInfo(SDL_VideoRenderer, &info); | |
597 desired_format = info.texture_formats[0]; | |
598 for (i = 0; i < info.num_texture_formats; ++i) { | |
599 if (!SDL_ISPIXELFORMAT_ALPHA(info.texture_formats[i])) { | |
600 desired_format = info.texture_formats[i]; | |
601 break; | |
602 } | |
603 } | |
604 SDL_VideoTexture = SDL_CreateTexture(SDL_VideoRenderer, desired_format, | |
605 SDL_TEXTUREACCESS_STREAMING, | |
606 width, height); | |
607 if (!SDL_VideoTexture) { | |
608 return NULL; | |
609 } | |
610 | |
611 /* Create the screen surface */ | 560 /* Create the screen surface */ |
612 SDL_VideoSurface = CreateVideoSurface(SDL_VideoTexture); | 561 SDL_VideoSurface = SDL_GetWindowSurface(SDL_VideoWindow); |
613 if (!SDL_VideoSurface) { | 562 if (!SDL_VideoSurface) { |
614 return NULL; | 563 return NULL; |
615 } | 564 } |
616 SDL_VideoSurface->flags |= surface_flags; | 565 SDL_VideoSurface->flags |= surface_flags; |
617 | 566 |
772 | 721 |
773 /* Fall through to video surface update */ | 722 /* Fall through to video surface update */ |
774 screen = SDL_VideoSurface; | 723 screen = SDL_VideoSurface; |
775 } | 724 } |
776 if (screen == SDL_VideoSurface) { | 725 if (screen == SDL_VideoSurface) { |
777 /* The surface memory needs to be copied to texture */ | 726 SDL_UpdateWindowSurfaceRects(SDL_VideoWindow, numrects, rects); |
778 int pitch = screen->pitch; | |
779 int psize = screen->format->BytesPerPixel; | |
780 for (i = 0; i < numrects; ++i) { | |
781 const SDL_Rect *rect = &rects[i]; | |
782 void *pixels = | |
783 (Uint8 *) screen->pixels + rect->y * pitch + | |
784 rect->x * psize; | |
785 SDL_UpdateTexture(SDL_VideoTexture, rect, pixels, pitch); | |
786 } | |
787 rect.x = 0; | |
788 rect.y = 0; | |
789 rect.w = screen->w; | |
790 rect.h = screen->h; | |
791 SDL_RenderCopy(SDL_VideoRenderer, SDL_VideoTexture, &rect, &rect); | |
792 SDL_RenderPresent(SDL_VideoRenderer); | |
793 } | 727 } |
794 } | 728 } |
795 | 729 |
796 void | 730 void |
797 SDL_WM_SetCaption(const char *title, const char *icon) | 731 SDL_WM_SetCaption(const char *title, const char *icon) |
1393 } | 1327 } |
1394 #endif | 1328 #endif |
1395 | 1329 |
1396 struct private_yuvhwdata | 1330 struct private_yuvhwdata |
1397 { | 1331 { |
1398 Uint16 pitches[3]; | 1332 SDL_SW_YUVTexture *texture; |
1399 Uint8 *planes[3]; | 1333 SDL_Surface *display; |
1400 | 1334 Uint32 display_format; |
1401 SDL_Texture *texture; | |
1402 Uint32 texture_format; | |
1403 }; | 1335 }; |
1404 | 1336 |
1405 SDL_Overlay * | 1337 SDL_Overlay * |
1406 SDL_CreateYUVOverlay(int w, int h, Uint32 format, SDL_Surface * display) | 1338 SDL_CreateYUVOverlay(int w, int h, Uint32 format, SDL_Surface * display) |
1407 { | 1339 { |
1408 SDL_Overlay *overlay; | 1340 SDL_Overlay *overlay; |
1409 Uint32 texture_format; | 1341 Uint32 texture_format; |
1342 SDL_SW_YUVTexture *texture; | |
1410 | 1343 |
1411 if ((display->flags & SDL_OPENGL) == SDL_OPENGL) { | 1344 if ((display->flags & SDL_OPENGL) == SDL_OPENGL) { |
1412 SDL_SetError("YUV overlays are not supported in OpenGL mode"); | 1345 SDL_SetError("YUV overlays are not supported in OpenGL mode"); |
1413 return NULL; | 1346 return NULL; |
1414 } | 1347 } |
1452 SDL_free(overlay); | 1385 SDL_free(overlay); |
1453 SDL_OutOfMemory(); | 1386 SDL_OutOfMemory(); |
1454 return NULL; | 1387 return NULL; |
1455 } | 1388 } |
1456 | 1389 |
1390 texture = SDL_SW_CreateYUVTexture(texture_format, w, h); | |
1391 if (!texture) { | |
1392 SDL_free(overlay->hwdata); | |
1393 SDL_free(overlay); | |
1394 return NULL; | |
1395 } | |
1396 overlay->hwdata->texture = texture; | |
1397 overlay->hwdata->display = NULL; | |
1398 overlay->hwdata->display_format = SDL_PIXELFORMAT_UNKNOWN; | |
1399 | |
1457 overlay->format = format; | 1400 overlay->format = format; |
1458 overlay->w = w; | 1401 overlay->w = w; |
1459 overlay->h = h; | 1402 overlay->h = h; |
1460 if (format == SDL_YV12_OVERLAY || format == SDL_IYUV_OVERLAY) { | 1403 if (format == SDL_YV12_OVERLAY || format == SDL_IYUV_OVERLAY) { |
1461 overlay->planes = 3; | 1404 overlay->planes = 3; |
1462 } else { | 1405 } else { |
1463 overlay->planes = 1; | 1406 overlay->planes = 1; |
1464 } | 1407 } |
1465 overlay->pitches = overlay->hwdata->pitches; | 1408 overlay->pitches = texture->pitches; |
1466 overlay->pixels = overlay->hwdata->planes; | 1409 overlay->pixels = texture->planes; |
1467 | |
1468 switch (format) { | |
1469 case SDL_YV12_OVERLAY: | |
1470 case SDL_IYUV_OVERLAY: | |
1471 overlay->pitches[0] = overlay->w; | |
1472 overlay->pitches[1] = overlay->w / 2; | |
1473 overlay->pitches[2] = overlay->w / 2; | |
1474 break; | |
1475 case SDL_YUY2_OVERLAY: | |
1476 case SDL_UYVY_OVERLAY: | |
1477 case SDL_YVYU_OVERLAY: | |
1478 overlay->pitches[0] = overlay->w * 2; | |
1479 break; | |
1480 } | |
1481 | |
1482 overlay->hwdata->texture = | |
1483 SDL_CreateTexture(SDL_VideoRenderer, texture_format, | |
1484 SDL_TEXTUREACCESS_STREAMING, w, h); | |
1485 if (!overlay->hwdata->texture) { | |
1486 SDL_FreeYUVOverlay(overlay); | |
1487 return NULL; | |
1488 } | |
1489 overlay->hwdata->texture_format = texture_format; | |
1490 | 1410 |
1491 return overlay; | 1411 return overlay; |
1492 } | 1412 } |
1493 | 1413 |
1494 int | 1414 int |
1495 SDL_LockYUVOverlay(SDL_Overlay * overlay) | 1415 SDL_LockYUVOverlay(SDL_Overlay * overlay) |
1496 { | 1416 { |
1417 SDL_Rect rect; | |
1497 void *pixels; | 1418 void *pixels; |
1498 int pitch; | 1419 int pitch; |
1499 | 1420 |
1500 if (!overlay) { | 1421 if (!overlay) { |
1501 SDL_SetError("Passed a NULL overlay"); | 1422 SDL_SetError("Passed a NULL overlay"); |
1502 return -1; | 1423 return -1; |
1503 } | 1424 } |
1504 if (SDL_LockTexture(overlay->hwdata->texture, NULL, &pixels, &pitch) < 0) { | 1425 |
1426 rect.x = 0; | |
1427 rect.y = 0; | |
1428 rect.w = overlay->w; | |
1429 rect.h = overlay->h; | |
1430 | |
1431 if (SDL_SW_LockYUVTexture(overlay->hwdata->texture, &rect, &pixels, &pitch) < 0) { | |
1505 return -1; | 1432 return -1; |
1506 } | 1433 } |
1434 | |
1507 overlay->pixels[0] = (Uint8 *) pixels; | 1435 overlay->pixels[0] = (Uint8 *) pixels; |
1508 overlay->pitches[0] = pitch; | 1436 overlay->pitches[0] = pitch; |
1509 switch (overlay->format) { | 1437 switch (overlay->format) { |
1510 case SDL_YV12_OVERLAY: | 1438 case SDL_YV12_OVERLAY: |
1511 case SDL_IYUV_OVERLAY: | 1439 case SDL_IYUV_OVERLAY: |
1528 SDL_UnlockYUVOverlay(SDL_Overlay * overlay) | 1456 SDL_UnlockYUVOverlay(SDL_Overlay * overlay) |
1529 { | 1457 { |
1530 if (!overlay) { | 1458 if (!overlay) { |
1531 return; | 1459 return; |
1532 } | 1460 } |
1533 SDL_UnlockTexture(overlay->hwdata->texture); | 1461 |
1462 SDL_SW_UnlockYUVTexture(overlay->hwdata->texture); | |
1534 } | 1463 } |
1535 | 1464 |
1536 int | 1465 int |
1537 SDL_DisplayYUVOverlay(SDL_Overlay * overlay, SDL_Rect * dstrect) | 1466 SDL_DisplayYUVOverlay(SDL_Overlay * overlay, SDL_Rect * dstrect) |
1538 { | 1467 { |
1468 SDL_Surface *display; | |
1469 SDL_Rect src_rect; | |
1470 SDL_Rect dst_rect; | |
1471 void *pixels; | |
1472 | |
1539 if (!overlay || !dstrect) { | 1473 if (!overlay || !dstrect) { |
1540 SDL_SetError("Passed a NULL overlay or dstrect"); | 1474 SDL_SetError("Passed a NULL overlay or dstrect"); |
1541 return -1; | 1475 return -1; |
1542 } | 1476 } |
1543 if (SDL_RenderCopy(SDL_VideoRenderer, overlay->hwdata->texture, NULL, dstrect) < 0) { | 1477 |
1478 display = overlay->hwdata->display; | |
1479 if (display != SDL_VideoSurface) { | |
1480 overlay->hwdata->display = display = SDL_VideoSurface; | |
1481 overlay->hwdata->display_format = SDL_MasksToPixelFormatEnum( | |
1482 display->format->BitsPerPixel, | |
1483 display->format->Rmask, | |
1484 display->format->Gmask, | |
1485 display->format->Bmask, | |
1486 display->format->Amask); | |
1487 } | |
1488 | |
1489 src_rect.x = 0; | |
1490 src_rect.y = 0; | |
1491 src_rect.w = overlay->w; | |
1492 src_rect.h = overlay->h; | |
1493 | |
1494 if (!SDL_IntersectRect(&display->clip_rect, dstrect, &dst_rect)) { | |
1495 return 0; | |
1496 } | |
1497 | |
1498 pixels = (void *)((Uint8 *)display->pixels + | |
1499 dst_rect.y * display->pitch + | |
1500 dst_rect.x * display->format->BytesPerPixel); | |
1501 | |
1502 if (SDL_SW_CopyYUVToRGB(overlay->hwdata->texture, &src_rect, | |
1503 overlay->hwdata->display_format, | |
1504 dst_rect.w, dst_rect.h, | |
1505 pixels, display->pitch) < 0) { | |
1544 return -1; | 1506 return -1; |
1545 } | 1507 } |
1546 SDL_RenderPresent(SDL_VideoRenderer); | 1508 SDL_UpdateWindowSurface(SDL_VideoWindow); |
1547 return 0; | 1509 return 0; |
1548 } | 1510 } |
1549 | 1511 |
1550 void | 1512 void |
1551 SDL_FreeYUVOverlay(SDL_Overlay * overlay) | 1513 SDL_FreeYUVOverlay(SDL_Overlay * overlay) |
1553 if (!overlay) { | 1515 if (!overlay) { |
1554 return; | 1516 return; |
1555 } | 1517 } |
1556 if (overlay->hwdata) { | 1518 if (overlay->hwdata) { |
1557 if (overlay->hwdata->texture) { | 1519 if (overlay->hwdata->texture) { |
1558 SDL_DestroyTexture(overlay->hwdata->texture); | 1520 SDL_SW_DestroyYUVTexture(overlay->hwdata->texture); |
1559 } | 1521 } |
1560 SDL_free(overlay->hwdata); | 1522 SDL_free(overlay->hwdata); |
1561 } | 1523 } |
1562 SDL_free(overlay); | 1524 SDL_free(overlay); |
1563 } | 1525 } |