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) {