Mercurial > sdl-ios-xcode
comparison src/video/SDL_video.c @ 2222:926294b2bb4e
Emphasized the separation between SDL_Surface and SDL_Texture
- SDL_Surface is a system memory representation of pixel data
- SDL_Texture is a video memory representation of pixel data
The concept of SDL_Surface with SDL_HWSURFACE is no longer used.
Separated SDL_Texture types by usage rather than memory type
- SDL_TEXTUREACCESS_STATIC is for rarely changed pixel data,
can be placed in video memory.
- SDL_TEXTUREACCESS_STREAMING is for frequently changing pixel
data, usually placed in system memory or AGP memory.
Optimized the SDL_compat usage of the OpenGL renderer by only
using one copy of the framebuffer instead of two.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 11 Aug 2007 20:54:31 +0000 |
parents | 3ee59c43d784 |
children | 989fb86ad1ec |
comparison
equal
deleted
inserted
replaced
2221:1d75c38e1e5c | 2222:926294b2bb4e |
---|---|
1530 | 1530 |
1531 return texture->id; | 1531 return texture->id; |
1532 } | 1532 } |
1533 | 1533 |
1534 SDL_TextureID | 1534 SDL_TextureID |
1535 SDL_CreateTextureFromSurface(Uint32 format, int access, SDL_Surface * surface) | 1535 SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface) |
1536 { | 1536 { |
1537 SDL_TextureID textureID; | 1537 SDL_TextureID textureID; |
1538 Uint32 surface_flags = surface->flags; | 1538 Uint32 surface_flags = surface->flags; |
1539 SDL_PixelFormat *fmt = surface->format; | 1539 SDL_PixelFormat *fmt = surface->format; |
1540 Uint8 alpha; | |
1541 SDL_Rect bounds; | |
1542 SDL_Surface dst; | |
1543 int bpp; | 1540 int bpp; |
1544 Uint32 Rmask, Gmask, Bmask, Amask; | 1541 Uint32 Rmask, Gmask, Bmask, Amask; |
1545 | 1542 |
1546 if (!surface) { | 1543 if (!surface) { |
1547 SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface"); | 1544 SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface"); |
1574 SDL_SetError("Unknown pixel format"); | 1571 SDL_SetError("Unknown pixel format"); |
1575 return 0; | 1572 return 0; |
1576 } | 1573 } |
1577 } | 1574 } |
1578 | 1575 |
1579 textureID = SDL_CreateTexture(format, access, surface->w, surface->h); | 1576 textureID = |
1577 SDL_CreateTexture(format, SDL_TEXTUREACCESS_STATIC, surface->w, | |
1578 surface->h); | |
1580 if (!textureID) { | 1579 if (!textureID) { |
1581 return 0; | 1580 return 0; |
1582 } | 1581 } |
1583 | 1582 |
1584 /* Set up a destination surface for the texture update */ | 1583 if (bpp == fmt->BitsPerPixel && Rmask == fmt->Rmask && Gmask == fmt->Gmask |
1585 SDL_zero(dst); | 1584 && Bmask == fmt->Bmask && Amask == fmt->Amask) { |
1586 dst.format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask); | 1585 if (SDL_MUSTLOCK(surface)) { |
1587 if (!dst.format) { | 1586 if (SDL_LockSurface(surface) < 0) { |
1588 SDL_DestroyTexture(textureID); | 1587 SDL_DestroyTexture(textureID); |
1589 return 0; | 1588 return 0; |
1590 } | 1589 } |
1591 dst.w = surface->w; | 1590 SDL_UpdateTexture(textureID, NULL, surface->pixels, |
1592 dst.h = surface->h; | 1591 surface->pitch); |
1593 if (SDL_LockTexture(textureID, NULL, 1, &dst.pixels, &dst.pitch) == 0) { | 1592 SDL_UnlockSurface(surface); |
1594 dst.flags |= SDL_PREALLOC; | 1593 } else { |
1594 SDL_UpdateTexture(textureID, NULL, surface->pixels, | |
1595 surface->pitch); | |
1596 } | |
1595 } else { | 1597 } else { |
1598 Uint8 alpha; | |
1599 SDL_Rect bounds; | |
1600 SDL_Surface dst; | |
1601 | |
1602 /* Set up a destination surface for the texture update */ | |
1603 SDL_zero(dst); | |
1604 dst.format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask); | |
1605 if (!dst.format) { | |
1606 SDL_DestroyTexture(textureID); | |
1607 return 0; | |
1608 } | |
1609 dst.w = surface->w; | |
1610 dst.h = surface->h; | |
1596 dst.pitch = SDL_CalculatePitch(&dst); | 1611 dst.pitch = SDL_CalculatePitch(&dst); |
1597 dst.pixels = SDL_malloc(dst.h * dst.pitch); | 1612 dst.pixels = SDL_malloc(dst.h * dst.pitch); |
1598 if (!dst.pixels) { | 1613 if (!dst.pixels) { |
1599 SDL_DestroyTexture(textureID); | 1614 SDL_DestroyTexture(textureID); |
1600 SDL_FreeFormat(dst.format); | 1615 SDL_FreeFormat(dst.format); |
1601 SDL_OutOfMemory(); | 1616 SDL_OutOfMemory(); |
1602 return 0; | 1617 return 0; |
1603 } | 1618 } |
1604 } | 1619 |
1605 | 1620 /* Copy the palette if any */ |
1606 /* Copy the palette if any */ | 1621 if (SDL_ISPIXELFORMAT_INDEXED(format)) { |
1607 if (SDL_ISPIXELFORMAT_INDEXED(format)) { | 1622 if (fmt->palette) { |
1608 if (fmt->palette) { | 1623 SDL_SetTexturePalette(textureID, fmt->palette->colors, 0, |
1609 SDL_SetTexturePalette(textureID, fmt->palette->colors, 0, | 1624 fmt->palette->ncolors); |
1610 fmt->palette->ncolors); | 1625 SDL_SetSurfacePalette(&dst, fmt->palette); |
1611 SDL_SetSurfacePalette(&dst, fmt->palette); | 1626 } else { |
1612 } else { | 1627 dst.format->palette = |
1613 dst.format->palette = | 1628 SDL_AllocPalette((1 << SDL_BITSPERPIXEL(format))); |
1614 SDL_AllocPalette((1 << SDL_BITSPERPIXEL(format))); | 1629 if (!dst.format->palette) { |
1615 if (!dst.format->palette) { | 1630 SDL_DestroyTexture(textureID); |
1616 SDL_DestroyTexture(textureID); | 1631 SDL_FreeFormat(dst.format); |
1617 SDL_FreeFormat(dst.format); | 1632 return 0; |
1618 return 0; | 1633 } |
1634 SDL_DitherColors(dst.format->palette->colors, | |
1635 SDL_BITSPERPIXEL(format)); | |
1619 } | 1636 } |
1620 SDL_DitherColors(dst.format->palette->colors, | 1637 } |
1621 SDL_BITSPERPIXEL(format)); | 1638 |
1622 } | 1639 /* Make the texture transparent if the surface has colorkey */ |
1623 } | 1640 if (surface_flags & SDL_SRCCOLORKEY) { |
1624 | 1641 int row; |
1625 /* Make the texture transparent if the surface has colorkey */ | 1642 int length = dst.w * dst.format->BytesPerPixel; |
1626 if (surface_flags & SDL_SRCCOLORKEY) { | 1643 Uint8 *p = (Uint8 *) dst.pixels; |
1627 int row; | 1644 for (row = 0; row < dst.h; ++row) { |
1628 int length = dst.w * dst.format->BytesPerPixel; | 1645 SDL_memset(p, 0, length); |
1629 Uint8 *p = (Uint8 *) dst.pixels; | 1646 p += dst.pitch; |
1630 for (row = 0; row < dst.h; ++row) { | 1647 } |
1631 SDL_memset(p, 0, length); | 1648 } |
1632 p += dst.pitch; | 1649 |
1633 } | 1650 /* Copy over the alpha channel */ |
1634 } | 1651 if (surface_flags & SDL_SRCALPHA) { |
1635 | 1652 if (fmt->Amask) { |
1636 /* Copy over the alpha channel */ | 1653 surface->flags &= ~SDL_SRCALPHA; |
1637 if (surface_flags & SDL_SRCALPHA) { | 1654 } else { |
1638 if (fmt->Amask) { | 1655 /* FIXME: Need to make sure the texture has an alpha channel |
1639 surface->flags &= ~SDL_SRCALPHA; | 1656 * and copy 'alpha' into the texture alpha channel. |
1640 } else { | 1657 */ |
1641 /* FIXME: Need to make sure the texture has an alpha channel | 1658 alpha = surface->format->alpha; |
1642 * and copy 'alpha' into the texture alpha channel. | 1659 SDL_SetAlpha(surface, 0, 0); |
1643 */ | 1660 } |
1644 alpha = surface->format->alpha; | 1661 } |
1645 SDL_SetAlpha(surface, 0, 0); | 1662 |
1646 } | 1663 /* Copy over the image data */ |
1647 } | 1664 bounds.x = 0; |
1648 | 1665 bounds.y = 0; |
1649 /* Copy over the image data */ | 1666 bounds.w = surface->w; |
1650 bounds.x = 0; | 1667 bounds.h = surface->h; |
1651 bounds.y = 0; | 1668 SDL_LowerBlit(surface, &bounds, &dst, &bounds); |
1652 bounds.w = surface->w; | 1669 |
1653 bounds.h = surface->h; | 1670 /* Clean up the original surface */ |
1654 SDL_LowerBlit(surface, &bounds, &dst, &bounds); | 1671 if ((surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA) { |
1655 | 1672 Uint32 aflags = surface_flags & (SDL_SRCALPHA | SDL_RLEACCELOK); |
1656 /* Clean up the original surface */ | 1673 if (fmt->Amask) { |
1657 if ((surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA) { | 1674 surface->flags |= SDL_SRCALPHA; |
1658 Uint32 aflags = surface_flags & (SDL_SRCALPHA | SDL_RLEACCELOK); | 1675 } else { |
1659 if (fmt->Amask) { | 1676 SDL_SetAlpha(surface, aflags, alpha); |
1660 surface->flags |= SDL_SRCALPHA; | 1677 } |
1661 } else { | 1678 } |
1662 SDL_SetAlpha(surface, aflags, alpha); | 1679 |
1663 } | 1680 /* Update the texture */ |
1664 } | |
1665 | |
1666 /* Update the texture */ | |
1667 if (dst.flags & SDL_PREALLOC) { | |
1668 SDL_UnlockTexture(textureID); | |
1669 } else { | |
1670 SDL_UpdateTexture(textureID, NULL, dst.pixels, dst.pitch); | 1681 SDL_UpdateTexture(textureID, NULL, dst.pixels, dst.pitch); |
1671 SDL_free(dst.pixels); | 1682 SDL_free(dst.pixels); |
1672 } | 1683 SDL_FreeFormat(dst.format); |
1673 SDL_FreeFormat(dst.format); | 1684 } |
1674 | 1685 |
1675 return textureID; | 1686 return textureID; |
1676 } | 1687 } |
1677 | 1688 |
1678 static __inline__ SDL_Texture * | 1689 static __inline__ SDL_Texture * |
1965 SDL_Rect full_rect; | 1976 SDL_Rect full_rect; |
1966 | 1977 |
1967 if (!texture) { | 1978 if (!texture) { |
1968 return -1; | 1979 return -1; |
1969 } | 1980 } |
1981 if (texture->access != SDL_TEXTUREACCESS_STREAMING) { | |
1982 SDL_SetError("SDL_LockTexture(): texture must be streaming"); | |
1983 return -1; | |
1984 } | |
1970 | 1985 |
1971 renderer = texture->renderer; | 1986 renderer = texture->renderer; |
1972 if (!renderer->LockTexture) { | 1987 if (!renderer->LockTexture) { |
1973 return -1; | 1988 return -1; |
1974 } | 1989 } |
1992 SDL_Renderer *renderer; | 2007 SDL_Renderer *renderer; |
1993 | 2008 |
1994 if (!texture) { | 2009 if (!texture) { |
1995 return; | 2010 return; |
1996 } | 2011 } |
2012 if (texture->access != SDL_TEXTUREACCESS_STREAMING) { | |
2013 return; | |
2014 } | |
1997 | 2015 |
1998 renderer = texture->renderer; | 2016 renderer = texture->renderer; |
1999 if (!renderer->UnlockTexture) { | 2017 if (!renderer->UnlockTexture) { |
2000 return; | 2018 return; |
2001 } | 2019 } |
2008 { | 2026 { |
2009 SDL_Texture *texture = SDL_GetTextureFromID(textureID); | 2027 SDL_Texture *texture = SDL_GetTextureFromID(textureID); |
2010 SDL_Renderer *renderer; | 2028 SDL_Renderer *renderer; |
2011 | 2029 |
2012 if (!texture) { | 2030 if (!texture) { |
2031 return; | |
2032 } | |
2033 if (texture->access != SDL_TEXTUREACCESS_STREAMING) { | |
2013 return; | 2034 return; |
2014 } | 2035 } |
2015 | 2036 |
2016 renderer = texture->renderer; | 2037 renderer = texture->renderer; |
2017 if (!renderer->DirtyTexture) { | 2038 if (!renderer->DirtyTexture) { |