Mercurial > sdl-ios-xcode
diff src/video/SDL_video.c @ 1670:eef792d31de8 SDL-1.3
Work in progress. :)
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Wed, 07 Jun 2006 16:10:28 +0000 |
parents | 9857d21967bb |
children | 8e754b82cecc |
line wrap: on
line diff
--- a/src/video/SDL_video.c Mon May 29 05:08:33 2006 +0000 +++ b/src/video/SDL_video.c Wed Jun 07 16:10:28 2006 +0000 @@ -231,7 +231,7 @@ } _this = video; _this->name = bootstrap[i]->name; - _this->next_window_id = 1; + _this->next_object_id = 1; /* Set some very sane GL defaults */ @@ -268,16 +268,6 @@ return (-1); } - /* Temporarily here for backwards compatibility */ - { - int bpp; - Uint32 Rmask, Gmask, Bmask, Amask; - - SDL_PixelFormatEnumToMasks(SDL_GetDesktopDisplayMode()->format, &bpp, - &Rmask, &Gmask, &Bmask, &Amask); - _this->info.vfmt = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask); - } - /* Sort the video modes */ for (i = 0; i < _this->num_displays; ++i) { SDL_qsort(_this->displays[i].display_modes, @@ -311,15 +301,6 @@ return _this; } -const SDL_VideoInfo * -SDL_GetVideoInfo(void) -{ - if (!_this) { - return NULL; - } - return &_this->info; -} - void SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode) { @@ -330,7 +311,6 @@ display.desktop_mode = *desktop_mode; } display.current_mode = display.desktop_mode; - display.max_windows = 1; SDL_AddVideoDisplay(&display); } @@ -378,14 +358,15 @@ } void -SDL_AddDisplayMode(int display, const SDL_DisplayMode * mode) +SDL_AddDisplayMode(int displayIndex, const SDL_DisplayMode * mode) { + SDL_VideoDisplay *display = &_this->displays[displayIndex]; SDL_DisplayMode *modes; int i, nmodes; /* Make sure we don't already have the mode in the list */ - modes = SDL_CurrentDisplay.display_modes; - nmodes = SDL_CurrentDisplay.num_display_modes; + modes = display->display_modes; + nmodes = display->num_display_modes; for (i = 0; i < nmodes; ++i) { if (SDL_memcmp(mode, &modes[i], sizeof(*mode)) == 0) { return; @@ -395,9 +376,9 @@ /* Go ahead and add the new mode */ modes = SDL_realloc(modes, (nmodes + 1) * sizeof(*mode)); if (modes) { - SDL_CurrentDisplay.display_modes = modes; + display->display_modes = modes; modes[nmodes] = *mode; - SDL_CurrentDisplay.num_display_modes++; + display->num_display_modes++; } } @@ -415,7 +396,7 @@ { if (index < 0 || index >= SDL_GetNumDisplayModes()) { SDL_SetError("index must be in the range of 0 - %d", - SDL_GetNumDisplayModes()); + SDL_GetNumDisplayModes() - 1); return NULL; } return &SDL_CurrentDisplay.display_modes[index]; @@ -568,19 +549,6 @@ return 0; } - /* Free any previous window surfaces */ - for (i = 0; i < display->num_windows; ++i) { - SDL_Window *window = &display->windows[i]; - if (window->shadow) { - SDL_FreeSurface(window->shadow); - window->shadow = NULL; - } - if (window->surface) { - SDL_FreeSurface(window->surface); - window->surface = NULL; - } - } - return _this->SetDisplayMode(_this, &display_mode); } @@ -605,7 +573,7 @@ } SDL_zero(window); - window.id = _this->next_window_id++; + window.id = _this->next_object_id++; window.title = title ? SDL_strdup(title) : NULL; window.x = x; window.y = y; @@ -653,7 +621,7 @@ } SDL_zero(window); - window.id = _this->next_window_id++; + window.id = _this->next_object_id++; if (!_this->CreateWindowFrom || _this->CreateWindowFrom(_this, &window, data) < 0) { @@ -701,28 +669,6 @@ return NULL; } -SDL_Window * -SDL_GetWindowFromSurface(SDL_Surface * surface) -{ - int i, j; - - if (!_this || !surface) { - return NULL; - } - - for (i = 0; i < _this->num_displays; ++i) { - SDL_VideoDisplay *display = &_this->displays[i]; - for (j = 0; j < display->num_windows; ++j) { - SDL_Window *window = &display->windows[j]; - if (surface == window->surface || surface == window->shadow) { - return window; - } - } - } - return NULL; -} - - Uint32 SDL_GetWindowFlags(SDL_WindowID windowID) { @@ -998,11 +944,8 @@ window->flags &= ~SDL_WINDOW_INPUT_GRABBED; _this->SetWindowGrab(_this, window); } - if (window->shadow) { - SDL_FreeSurface(window->shadow); - } - if (window->surface) { - SDL_FreeSurface(window->surface); + if (window->renderer) { + SDL_DestroyRenderer(window->id); } if (_this->DestroyWindow) { _this->DestroyWindow(_this, window); @@ -1024,371 +967,569 @@ } } -SDL_Surface * -SDL_CreateWindowSurface(SDL_WindowID windowID, Uint32 format, Uint32 flags) +void +SDL_AddRenderDriver(int displayIndex, const SDL_RenderDriver * driver) +{ + SDL_VideoDisplay *display = &_this->displays[displayIndex]; + SDL_RenderDriver *render_drivers; + + render_drivers = + SDL_realloc(display->render_drivers, + (display->num_render_drivers + + 1) * sizeof(*render_drivers)); + if (render_drivers) { + render_drivers[display->num_render_drivers] = *driver; + display->render_drivers = render_drivers; + display->num_render_drivers++; + } +} + +int +SDL_GetNumRenderers(void) +{ + if (_this) { + return SDL_CurrentDisplay.num_render_drivers; + } + return 0; +} + +int +SDL_GetRendererInfo(int index, SDL_RendererInfo * info) +{ + if (index < 0 || index >= SDL_GetNumRenderers()) { + SDL_SetError("index must be in the range of 0 - %d", + SDL_GetNumRenderers() - 1); + return -1; + } + *info = SDL_CurrentDisplay.render_drivers[index].info; + return 0; +} + +int +SDL_CreateRenderer(SDL_WindowID windowID, int index, Uint32 flags) +{ + SDL_Window *window = SDL_GetWindowFromID(windowID); + + if (!window) { + return 0; + } + + if (index < 0) { + int n = SDL_GetNumRenderers(); + for (index = 0; index < n; ++index) { + if ((SDL_CurrentDisplay.render_drivers[index].info. + flags & flags) == flags) { + break; + } + } + if (index == n) { + SDL_SetError("Couldn't find matching render driver"); + return -1; + } + } + + if (index >= SDL_GetNumRenderers()) { + SDL_SetError("index must be -1 or in the range of 0 - %d", + SDL_GetNumRenderers() - 1); + return -1; + } + + /* Free any existing renderer */ + SDL_DestroyRenderer(windowID); + + /* Create a new renderer instance */ + window->renderer = + SDL_CurrentDisplay.render_drivers[index].CreateRenderer(window, + flags); + if (!window->renderer) { + return -1; + } + SDL_CurrentDisplay.current_renderer = window->renderer; + + return 0; +} + +int +SDL_SelectRenderer(SDL_WindowID windowID) { SDL_Window *window = SDL_GetWindowFromID(windowID); - Uint32 black; - SDL_Surface *surface; + + if (!window || !window->renderer) { + return -1; + } + SDL_CurrentDisplay.current_renderer = window->renderer; + return 0; +} + +SDL_TextureID +SDL_CreateTexture(Uint32 format, int access, int w, int h) +{ + SDL_Renderer *renderer; + SDL_Texture *texture; + + if (!_this) { + return 0; + } + + renderer = SDL_CurrentDisplay.current_renderer; + if (!renderer || !renderer->CreateTexture) { + return 0; + } + + texture = (SDL_Texture *) SDL_malloc(sizeof(*texture)); + if (!texture) { + SDL_OutOfMemory(); + return 0; + } + + SDL_zerop(texture); + texture->id = _this->next_object_id++; + texture->format = format; + texture->access = access; + texture->w = w; + texture->h = h; + texture->renderer = renderer; - if (!window) { - return NULL; + if (renderer->CreateTexture(texture) < 0) { + SDL_free(texture); + return 0; + } +} + +SDL_TextureID +SDL_CreateTextureFromSurface(Uint32 format, int access, SDL_Surface * surface) +{ + SDL_TextureID textureID; + Uint32 surface_flags = surface->flags; + SDL_PixelFormat *fmt = surface->format; + Uint32 colorkey; + Uint8 alpha; + SDL_Rect bounds; + SDL_Surface dst; + int bpp; + Uint32 Rmask, Gmask, Bmask, Amask; + + if (!surface) { + SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface"); + return 0; + } + + if (format) { + if (!SDL_PixelFormatEnumToMasks + (format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { + SDL_SetError("Unknown pixel format"); + return 0; + } + } else { + bpp = fmt->BitsPerPixel; + Rmask = fmt->Rmask; + Gmask = fmt->Gmask; + Bmask = fmt->Bmask; + Amask = fmt->Amask; + format = SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask); + if (!format) { + SDL_SetError("Unknown pixel format"); + return 0; + } + } + + textureID = SDL_CreateTexture(format, access, surface->w, surface->h); + if (!textureID) { + return 0; } - if (!_this->CreateWindowSurface) { + /* Set up a destination surface for the texture update */ + SDL_zero(dst); + dst.format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask); + if (!dst.format) { + SDL_DestroyTexture(textureID); + return 0; + } + dst.w = surface->w; + dst.h = surface->h; + if (SDL_LockTexture(textureID, NULL, 1, &dst.pixels, &dst.pitch) == 0) { + dst.flags |= SDL_PREALLOC; + } else { + dst.pitch = SDL_CalculatePitch(&dst); + dst.pixels = SDL_malloc(dst.h * dst.pitch); + if (!dst.pixels) { + SDL_DestroyTexture(textureID); + SDL_FreeFormat(dst.format); + SDL_OutOfMemory(); + return 0; + } + } + + /* Copy the palette if any */ + if (fmt->palette && dst.format->palette) { + SDL_SetTexturePalette(textureID, fmt->palette->colors, 0, + fmt->palette->ncolors); + + SDL_memcpy(dst.format->palette->colors, + fmt->palette->colors, + fmt->palette->ncolors * sizeof(SDL_Color)); + dst.format->palette->ncolors = fmt->palette->ncolors; + } + + /* Make the texture transparent if the surface has colorkey */ + if (surface_flags & SDL_SRCCOLORKEY) { + int row; + int length = dst.w * dst.format->BytesPerPixel; + Uint8 *p = (Uint8 *) dst.pixels; + for (row = 0; row < dst.h; ++row) { + SDL_memset(p, 0, length); + p += dst.pitch; + } + } + + /* Copy over the alpha channel */ + if (surface_flags & SDL_SRCALPHA) { + if (fmt->Amask) { + surface->flags &= ~SDL_SRCALPHA; + } else { + /* FIXME: Need to make sure the texture has an alpha channel + * and copy 'alpha' into the texture alpha channel. + */ + alpha = surface->format->alpha; + SDL_SetAlpha(surface, 0, 0); + } + } + + /* Copy over the image data */ + bounds.x = 0; + bounds.y = 0; + bounds.w = surface->w; + bounds.h = surface->h; + SDL_LowerBlit(surface, &bounds, &dst, &bounds); + + /* Clean up the original surface */ + if ((surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) { + Uint32 cflags = surface_flags & (SDL_SRCCOLORKEY | SDL_RLEACCELOK); + SDL_SetColorKey(surface, cflags, colorkey); + } + if ((surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA) { + Uint32 aflags = surface_flags & (SDL_SRCALPHA | SDL_RLEACCELOK); + if (fmt->Amask) { + surface->flags |= SDL_SRCALPHA; + } else { + SDL_SetAlpha(surface, aflags, alpha); + } + } + + /* Update the texture */ + if (dst.flags & SDL_PREALLOC) { + SDL_UnlockTexture(textureID); + } else { + SDL_UpdateTexture(textureID, NULL, dst.pixels, dst.pitch); + SDL_free(dst.pixels); + } + SDL_FreeFormat(dst.format); + + return textureID; +} + +static __inline__ SDL_Texture * +SDL_GetTextureFromID(SDL_TextureID textureID) +{ + int hash; + SDL_Texture *texture; + + if (!_this) { return NULL; } - if (!window->surface) { - _this->CreateWindowSurface(_this, window, flags); - if (!window->surface) { - return NULL; - } - window->surface->flags |= SDL_SCREEN_SURFACE; - - /* If we have a palettized surface, create a default palette */ - if (window->surface->format->palette) { - SDL_Color colors[256]; - SDL_PixelFormat *vf = window->surface->format; - SDL_DitherColors(colors, vf->BitsPerPixel); - SDL_SetColors(window->surface, colors, 0, vf->palette->ncolors); + hash = (textureID % SDL_arraysize(SDL_CurrentDisplay.textures)); + for (texture = SDL_CurrentDisplay.textures[hash]; texture; + texture = texture->next) { + if (texture->id == textureID) { + return texture; } } - surface = window->surface; + return NULL; +} + +int +SDL_QueryTexture(SDL_TextureID textureID, Uint32 * format, int *access, + int *w, int *h) +{ + SDL_Texture *texture = SDL_GetTextureFromID(textureID); + + if (!texture) { + return -1; + } + + if (format) { + *format = texture->format; + } + if (access) { + *access = texture->access; + } + if (w) { + *w = texture->w; + } + if (h) { + *h = texture->h; + } + return 0; +} + +int +SDL_UpdateTexture(SDL_TextureID textureID, SDL_Rect * rect, + const void *pixels, int pitch) +{ + SDL_Texture *texture = SDL_GetTextureFromID(textureID); + SDL_Renderer *renderer; + + if (!texture) { + return -1; + } + + renderer = texture->renderer; + if (!renderer->UpdateTexture) { + return -1; + } + return renderer->UpdateTexture(texture, rect, pixels, pitch); +} + +int +SDL_LockTexture(SDL_TextureID textureID, SDL_Rect * rect, int markDirty, + void **pixels, int *pitch) +{ + SDL_Texture *texture = SDL_GetTextureFromID(textureID); + SDL_Renderer *renderer; + + if (!texture) { + return -1; + } - if (window->shadow) { - SDL_FreeSurface(window->shadow); - window->shadow = NULL; + renderer = texture->renderer; + if (!renderer->LockTexture) { + return -1; + } + return renderer->LockTexture(texture, rect, markDirty, pixels, pitch); +} + +void +SDL_UnlockTexture(SDL_TextureID textureID) +{ + SDL_Texture *texture = SDL_GetTextureFromID(textureID); + SDL_Renderer *renderer; + + if (!texture) { + return; + } + + renderer = texture->renderer; + if (!renderer->UnlockTexture) { + return; + } + return renderer->UnlockTexture(texture); +} + +void +SDL_DirtyTexture(SDL_TextureID textureID, int numrects, SDL_Rect * rects) +{ + SDL_Texture *texture = SDL_GetTextureFromID(textureID); + SDL_Renderer *renderer; + + if (!texture) { + return; + } + + renderer = texture->renderer; + if (!renderer->DirtyTexture) { + return; + } + renderer->DirtyTexture(texture, numrects, rects); +} + +void +SDL_SelectRenderTexture(SDL_TextureID textureID) +{ + SDL_Texture *texture = SDL_GetTextureFromID(textureID); + SDL_Renderer *renderer; + + if (!texture || texture->access != SDL_TextureAccess_Render) { + return; + } + renderer = texture->renderer; + if (!renderer->SelectRenderTexture) { + return; + } + renderer->SelectRenderTexture(texture); +} + +int +SDL_RenderFill(SDL_Rect * rect, Uint32 color) +{ + SDL_Renderer *renderer; + + if (!_this) { + return -1; + } + + renderer = SDL_CurrentDisplay.current_renderer; + if (!renderer || !renderer->RenderFill) { + return -1; } - /* Create a shadow surface if necessary */ - if ((!(flags & SDL_ANYFORMAT) - && (format != SDL_GetCurrentDisplayMode()->format)) - || ((flags & SDL_HWPALETTE) - && !(window->surface->flags & SDL_HWPALETTE))) { - int bpp; - Uint32 Rmask, Gmask, Bmask, Amask; + renderer->RenderFill(rect, color); +} + +int +SDL_RenderCopy(SDL_TextureID textureID, SDL_Rect * srcrect, + SDL_Rect * dstrect, int blendMode, int scaleMode) +{ + SDL_Texture *texture = SDL_GetTextureFromID(textureID); + SDL_Renderer *renderer; + + if (!texture || texture->renderer != SDL_CurrentDisplay.current_renderer) { + return; + } + + renderer = SDL_CurrentDisplay.current_renderer; + if (!renderer || !renderer->RenderCopy) { + return -1; + } + + return renderer->RenderCopy(texture, srcrect, dstrect, blendMode, + scaleMode); +} + +int +SDL_RenderReadPixels(SDL_Rect * rect, void *pixels, int pitch) +{ + SDL_Renderer *renderer; + + if (!_this) { + return -1; + } + + renderer = SDL_CurrentDisplay.current_renderer; + if (!renderer || !renderer->RenderReadPixels) { + return -1; + } + + return renderer->RenderReadPixels(rect, pixels, pitch); +} + +int +SDL_RenderWritePixels(SDL_Rect * rect, const void *pixels, int pitch) +{ + SDL_Renderer *renderer; + + if (!_this) { + return -1; + } + + renderer = SDL_CurrentDisplay.current_renderer; + if (!renderer || !renderer->RenderWritePixels) { + return -1; + } + + return renderer->RenderWritePixels(rect, pixels, pitch); +} + +void +SDL_RenderPresent(void) +{ + SDL_Renderer *renderer; + + if (!_this) { + return; + } + + renderer = SDL_CurrentDisplay.current_renderer; + if (!renderer || !renderer->RenderPresent) { + return; + } - SDL_PixelFormatEnumToMasks(format, &bpp, &Amask, &Gmask, &Bmask, - &Amask); - window->shadow = - SDL_CreateRGBSurface(SDL_SWSURFACE, surface->w, surface->h, bpp, - Rmask, Gmask, Bmask, Amask); - if (window->shadow == NULL) { - return NULL; + renderer->RenderPresent(); +} + +void +SDL_DestroyTexture(SDL_TextureID textureID) +{ + int hash; + SDL_Texture *prev, *texture; + SDL_Renderer *renderer; + + if (!_this) { + return; + } + + /* Look up the texture in the hash table */ + hash = (textureID % SDL_arraysize(SDL_CurrentDisplay.textures)); + prev = NULL; + for (texture = SDL_CurrentDisplay.textures[hash]; texture; + prev = texture, texture = texture->next) { + if (texture->id == textureID) { + break; } - window->shadow->flags |= SDL_SHADOW_SURFACE; + } + if (!texture) { + return; + } + + /* Unlink the texture from the list */ + if (prev) { + prev->next = texture->next; + } else { + SDL_CurrentDisplay.textures[hash] = texture->next; + } - surface = window->shadow; + /* Free the texture */ + renderer = texture->renderer; + renderer->DestroyTexture(texture); + SDL_free(texture); +} + +void +SDL_DestroyRenderer(SDL_WindowID windowID) +{ + SDL_Window *window = SDL_GetWindowFromID(windowID); + SDL_Renderer *renderer; + int i; + + if (!window) { + return; + } - /* 8-bit shadow surfaces report that they have exclusive palette */ - if (surface->format->palette) { - surface->flags |= SDL_HWPALETTE; - if (format == SDL_GetCurrentDisplayMode()->format) { - SDL_memcpy(surface->format->palette->colors, - window->surface->format->palette->colors, - window->surface->format->palette->ncolors * - sizeof(SDL_Color)); + renderer = window->renderer; + if (!renderer) { + return; + } + + /* Free existing textures for this renderer */ + for (i = 0; i < SDL_arraysize(SDL_CurrentDisplay.textures); ++i) { + SDL_Texture *texture; + SDL_Texture *prev = NULL; + SDL_Texture *next; + for (texture = SDL_CurrentDisplay.textures[i]; texture; + texture = next) { + next = texture->next; + if (texture->renderer == renderer) { + if (prev) { + prev->next = next; + } else { + SDL_CurrentDisplay.textures[i] = next; + } + renderer->DestroyTexture(texture); + SDL_free(texture); } else { - SDL_DitherColors(surface->format->palette->colors, bpp); + prev = texture; } } } - /* Clear the surface for display */ - { - Uint32 black = SDL_MapRGB(surface->format, 0, 0, 0); - SDL_FillRect(surface, NULL, black); - if (surface->flags & SDL_DOUBLEBUF) { - SDL_Flip(surface); - SDL_FillRect(surface, NULL, black); - } - SDL_Flip(surface); - } - - return surface; -} - -/* - * Convert a surface into the video pixel format. - */ -SDL_Surface * -SDL_DisplayFormat(SDL_Surface * surface) -{ - Uint32 flags; - - if (!SDL_PublicSurface) { - SDL_SetError("No video mode has been set"); - return (NULL); - } - /* Set the flags appropriate for copying to display surface */ - if (((SDL_PublicSurface->flags & SDL_HWSURFACE) == SDL_HWSURFACE) - && _this->info.blit_hw) - flags = SDL_HWSURFACE; - else - flags = SDL_SWSURFACE; -#ifdef AUTORLE_DISPLAYFORMAT - flags |= (surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA)); - flags |= SDL_RLEACCELOK; -#else - flags |= - surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA | SDL_RLEACCELOK); -#endif - return (SDL_ConvertSurface(surface, SDL_PublicSurface->format, flags)); -} - -/* - * Convert a surface into a format that's suitable for blitting to - * the screen, but including an alpha channel. - */ -SDL_Surface * -SDL_DisplayFormatAlpha(SDL_Surface * surface) -{ - SDL_PixelFormat *vf; - SDL_PixelFormat *format; - SDL_Surface *converted; - Uint32 flags; - /* default to ARGB8888 */ - Uint32 amask = 0xff000000; - Uint32 rmask = 0x00ff0000; - Uint32 gmask = 0x0000ff00; - Uint32 bmask = 0x000000ff; - - if (!SDL_PublicSurface) { - SDL_SetError("No video mode has been set"); - return (NULL); - } - vf = SDL_PublicSurface->format; - - switch (vf->BytesPerPixel) { - case 2: - /* For XGY5[56]5, use, AXGY8888, where {X, Y} = {R, B}. - For anything else (like ARGB4444) it doesn't matter - since we have no special code for it anyway */ - if ((vf->Rmask == 0x1f) && - (vf->Bmask == 0xf800 || vf->Bmask == 0x7c00)) { - rmask = 0xff; - bmask = 0xff0000; - } - break; - - case 3: - case 4: - /* Keep the video format, as long as the high 8 bits are - unused or alpha */ - if ((vf->Rmask == 0xff) && (vf->Bmask == 0xff0000)) { - rmask = 0xff; - bmask = 0xff0000; - } - break; - - default: - /* We have no other optimised formats right now. When/if a new - optimised alpha format is written, add the converter here */ - break; - } - format = SDL_AllocFormat(32, rmask, gmask, bmask, amask); - flags = SDL_PublicSurface->flags & SDL_HWSURFACE; - flags |= surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK); - converted = SDL_ConvertSurface(surface, format, flags); - SDL_FreeFormat(format); - return (converted); -} - -/* - * Update a specific portion of the physical screen - */ -void -SDL_UpdateRect(SDL_Surface * screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h) -{ - if (screen) { - SDL_Rect rect; - - /* Perform some checking */ - if (w == 0) - w = screen->w; - if (h == 0) - h = screen->h; - if ((int) (x + w) > screen->w) - return; - if ((int) (y + h) > screen->h) - return; - - /* Fill the rectangle */ - rect.x = (Sint16) x; - rect.y = (Sint16) y; - rect.w = (Uint16) w; - rect.h = (Uint16) h; - SDL_UpdateRects(screen, 1, &rect); - } -} -void -SDL_UpdateRects(SDL_Surface * screen, int numrects, SDL_Rect * rects) -{ - int i; - SDL_Window *window; - - /* Find the window corresponding to this surface */ - window = SDL_GetWindowFromSurface(screen); - if (!window) { - SDL_SetError("Couldn't find window associated with surface"); - return; - } + /* Free the renderer instance */ + renderer->DestroyRenderer(renderer); - if (screen->flags & SDL_SHADOW_SURFACE) { - if (SHOULD_DRAWCURSOR(SDL_cursorstate)) { - SDL_LockCursor(); - SDL_DrawCursor(screen); - for (i = 0; i < numrects; ++i) { - SDL_LowerBlit(screen, &rects[i], window->surface, &rects[i]); - } - SDL_EraseCursor(screen); - SDL_UnlockCursor(); - } else { - for (i = 0; i < numrects; ++i) { - SDL_LowerBlit(screen, &rects[i], window->surface, &rects[i]); - } - } - - /* Fall through to video surface update */ - screen = window->surface; - } - if ((screen->flags & SDL_SCREEN_SURFACE) && _this->UpdateWindowSurface) { - /* Update the video surface */ - if (screen->offset) { - int offset_y = screen->offset / screen->pitch; - int offset_x = screen->offset % screen->pitch; - for (i = 0; i < numrects; ++i) { - rects[i].x += offset_x; - rects[i].y += offset_y; - } - _this->UpdateWindowSurface(_this, window, numrects, rects); - for (i = 0; i < numrects; ++i) { - rects[i].x -= offset_x; - rects[i].y -= offset_y; - } - } else { - _this->UpdateWindowSurface(_this, window, numrects, rects); - } - } -} - -/* - * Performs hardware double buffering, if possible, or a full update if not. - */ -int -SDL_Flip(SDL_Surface * screen) -{ - SDL_Window *window; - - /* Find the window corresponding to this surface */ - window = SDL_GetWindowFromSurface(screen); - if (!window) { - SDL_SetError("Couldn't find window associated with surface"); - return; - } - - /* Copy the shadow surface to the video surface */ - if (screen->flags & SDL_SHADOW_SURFACE) { - SDL_Rect rect; - - rect.x = 0; - rect.y = 0; - rect.w = screen->w; - rect.h = screen->h; - if (SHOULD_DRAWCURSOR(SDL_cursorstate)) { - SDL_LockCursor(); - SDL_DrawCursor(screen); - SDL_LowerBlit(screen, &rect, window->surface, &rect); - SDL_EraseCursor(screen); - SDL_UnlockCursor(); - } else { - SDL_LowerBlit(screen, &rect, window->surface, &rect); - } - - /* Fall through to video surface update */ - screen = window->surface; + /* Clear references */ + window->renderer = NULL; + if (SDL_CurrentDisplay.current_renderer == renderer) { + SDL_CurrentDisplay.current_renderer = NULL; } - if (screen->flags & SDL_DOUBLEBUF) { - _this->FlipWindowSurface(_this, window); - } else { - SDL_UpdateRect(screen, 0, 0, 0, 0); - } - return (0); -} - -int -SDL_SetColors(SDL_Surface * screen, SDL_Color * colors, int firstcolor, - int ncolors) -{ - SDL_Window *window = NULL; - SDL_Palette *pal; - int gotall; - int palsize; - - /* Verify the parameters */ - pal = screen->format->palette; - if (!pal) { - return 0; /* not a palettized surface */ - } - gotall = 1; - palsize = 1 << screen->format->BitsPerPixel; - if (ncolors > (palsize - firstcolor)) { - ncolors = (palsize - firstcolor); - gotall = 0; - } - - if (colors != (pal->colors + firstcolor)) { - SDL_memcpy(pal->colors + firstcolor, colors, - ncolors * sizeof(*colors)); - } - SDL_FormatChanged(screen); - - if (screen->flags & (SDL_SHADOW_SURFACE | SDL_SCREEN_SURFACE)) { - window = SDL_GetWindowFromSurface(screen); - if (!window) { - return 0; - } - } - - if (screen->flags & SDL_SHADOW_SURFACE) { - SDL_Palette *vidpal; - - vidpal = window->surface->format->palette; - if (vidpal && vidpal->ncolors == pal->ncolors) { - /* This is a shadow surface, and the physical - * framebuffer is also indexed. Propagate the - * changes to its logical palette so that - * updates are always identity blits - */ - SDL_memcpy(vidpal->colors + firstcolor, colors, - ncolors * sizeof(*colors)); - } - if (window->surface->flags & SDL_HWPALETTE) { - /* Set the physical palette */ - screen = window->surface; - } else { - SDL_UpdateRect(screen, 0, 0, 0, 0); - } - } - - if (screen->flags & SDL_SCREEN_SURFACE) { - if (_this->SetWindowColors) { - gotall = - _this->SetWindowColors(_this, window, firstcolor, ncolors, - colors); - if (!gotall) { - /* The video flags shouldn't have SDL_HWPALETTE, and - the video driver is responsible for copying back the - correct colors into the video surface palette. - */ - ; - } - } - SDL_CursorPaletteChanged(); - } - - return gotall; } void @@ -1416,12 +1557,12 @@ SDL_free(display->windows); display->windows = NULL; } + SDL_free(display->info.vfmt); } _this->VideoQuit(_this); if (_this->displays) { SDL_free(_this->displays); } - SDL_free(_this->info.vfmt); _this->free(_this); _this = NULL; } @@ -1549,11 +1690,8 @@ void SDL_GL_SwapBuffers(void) { - if (SDL_VideoSurface->flags & SDL_INTERNALOPENGL) { - _this->GL_SwapBuffers(_this); - } else { - SDL_SetError("OpenGL video mode has not been set"); - } + // FIXME: Track the current window context - do we provide N contexts, and match them to M windows, or is there a one-to-one mapping? + _this->GL_SwapBuffers(_this); } #if 0 // FIXME