src/video/SDL_renderer_sw.c
author Sam Lantinga <slouken@libsdl.org>
Tue, 01 Feb 2011 19:19:43 -0800
changeset 5147 ad50b3db78bd
parent 5142 c8e049de174c
child 5148 5429daf5e3f9
permissions -rw-r--r--
The rendering functions take a context so it's clear what window they're drawing to. This also potentially opens to the door to multi-threaded rendering in the future.
slouken@1895
     1
/*
slouken@1895
     2
    SDL - Simple DirectMedia Layer
slouken@3697
     3
    Copyright (C) 1997-2010 Sam Lantinga
slouken@1895
     4
slouken@1895
     5
    This library is free software; you can redistribute it and/or
slouken@1895
     6
    modify it under the terms of the GNU Lesser General Public
slouken@1895
     7
    License as published by the Free Software Foundation; either
slouken@1895
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@1895
     9
slouken@1895
    10
    This library is distributed in the hope that it will be useful,
slouken@1895
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@1895
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1895
    13
    Lesser General Public License for more details.
slouken@1895
    14
slouken@1895
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1895
    16
    License along with this library; if not, write to the Free Software
slouken@1895
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@1895
    18
slouken@1895
    19
    Sam Lantinga
slouken@1895
    20
    slouken@libsdl.org
slouken@1895
    21
*/
slouken@1895
    22
#include "SDL_config.h"
slouken@1895
    23
slouken@1895
    24
#include "SDL_video.h"
slouken@1895
    25
#include "SDL_sysvideo.h"
slouken@1907
    26
#include "SDL_pixels_c.h"
slouken@1895
    27
#include "SDL_rect_c.h"
slouken@1895
    28
#include "SDL_yuv_sw_c.h"
slouken@4472
    29
#include "SDL_renderer_sw.h"
slouken@1895
    30
slouken@1895
    31
slouken@1895
    32
/* SDL surface based renderer implementation */
slouken@1895
    33
slouken@1918
    34
static SDL_Renderer *SW_CreateRenderer(SDL_Window * window, Uint32 flags);
slouken@5147
    35
static void SW_WindowEvent(SDL_Renderer * renderer,
slouken@5147
    36
                           const SDL_WindowEvent *event);
slouken@1918
    37
static int SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
slouken@1918
    38
static int SW_QueryTexturePixels(SDL_Renderer * renderer,
slouken@1918
    39
                                 SDL_Texture * texture, void **pixels,
slouken@1918
    40
                                 int *pitch);
slouken@1918
    41
static int SW_SetTexturePalette(SDL_Renderer * renderer,
slouken@1918
    42
                                SDL_Texture * texture,
slouken@1918
    43
                                const SDL_Color * colors, int firstcolor,
slouken@1918
    44
                                int ncolors);
slouken@1918
    45
static int SW_GetTexturePalette(SDL_Renderer * renderer,
slouken@1918
    46
                                SDL_Texture * texture, SDL_Color * colors,
slouken@1918
    47
                                int firstcolor, int ncolors);
slouken@1985
    48
static int SW_SetTextureColorMod(SDL_Renderer * renderer,
slouken@1985
    49
                                 SDL_Texture * texture);
slouken@1985
    50
static int SW_SetTextureAlphaMod(SDL_Renderer * renderer,
slouken@1985
    51
                                 SDL_Texture * texture);
slouken@5141
    52
static int SW_SetTextureBlendMode(SDL_Renderer * renderer,
slouken@5141
    53
                                  SDL_Texture * texture);
slouken@1985
    54
static int SW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@1985
    55
                            const SDL_Rect * rect, const void *pixels,
slouken@1985
    56
                            int pitch);
slouken@1918
    57
static int SW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@1985
    58
                          const SDL_Rect * rect, int markDirty, void **pixels,
slouken@1985
    59
                          int *pitch);
slouken@1918
    60
static void SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
slouken@3596
    61
static int SW_RenderDrawPoints(SDL_Renderer * renderer,
slouken@3596
    62
                               const SDL_Point * points, int count);
slouken@3596
    63
static int SW_RenderDrawLines(SDL_Renderer * renderer,
slouken@3596
    64
                              const SDL_Point * points, int count);
slouken@3596
    65
static int SW_RenderDrawRects(SDL_Renderer * renderer,
slouken@3596
    66
                              const SDL_Rect ** rects, int count);
slouken@3596
    67
static int SW_RenderFillRects(SDL_Renderer * renderer,
slouken@3596
    68
                              const SDL_Rect ** rects, int count);
slouken@1918
    69
static int SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@1985
    70
                         const SDL_Rect * srcrect, const SDL_Rect * dstrect);
slouken@3427
    71
static int SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
slouken@3435
    72
                               Uint32 format, void * pixels, int pitch);
slouken@3427
    73
static int SW_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
slouken@3435
    74
                                Uint32 format, const void * pixels, int pitch);
slouken@1918
    75
static void SW_RenderPresent(SDL_Renderer * renderer);
slouken@1918
    76
static void SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture);
slouken@1918
    77
static void SW_DestroyRenderer(SDL_Renderer * renderer);
slouken@1895
    78
slouken@1895
    79
slouken@1918
    80
SDL_RenderDriver SW_RenderDriver = {
slouken@1918
    81
    SW_CreateRenderer,
slouken@1895
    82
    {
slouken@1895
    83
     "software",
slouken@5142
    84
     (SDL_RENDERER_PRESENTVSYNC),
slouken@2811
    85
     14,
slouken@1895
    86
     {
slouken@1965
    87
      SDL_PIXELFORMAT_INDEX8,
slouken@1965
    88
      SDL_PIXELFORMAT_RGB555,
slouken@1965
    89
      SDL_PIXELFORMAT_RGB565,
slouken@1965
    90
      SDL_PIXELFORMAT_RGB888,
slouken@1965
    91
      SDL_PIXELFORMAT_BGR888,
slouken@1965
    92
      SDL_PIXELFORMAT_ARGB8888,
slouken@1965
    93
      SDL_PIXELFORMAT_RGBA8888,
slouken@1965
    94
      SDL_PIXELFORMAT_ABGR8888,
slouken@1965
    95
      SDL_PIXELFORMAT_BGRA8888,
slouken@2811
    96
      SDL_PIXELFORMAT_YV12,
slouken@2811
    97
      SDL_PIXELFORMAT_IYUV,
slouken@1965
    98
      SDL_PIXELFORMAT_YUY2,
slouken@2810
    99
      SDL_PIXELFORMAT_UYVY,
slouken@2810
   100
      SDL_PIXELFORMAT_YVYU},
slouken@1895
   101
     0,
slouken@1895
   102
     0}
slouken@1895
   103
};
slouken@1895
   104
slouken@1895
   105
typedef struct
slouken@1895
   106
{
slouken@1907
   107
    Uint32 format;
slouken@1972
   108
    SDL_bool updateSize;
slouken@5142
   109
    SDL_Texture *texture;
slouken@1907
   110
    SDL_Surface surface;
slouken@1895
   111
    SDL_Renderer *renderer;
slouken@1895
   112
    SDL_DirtyRectList dirty;
slouken@1918
   113
} SW_RenderData;
slouken@1895
   114
slouken@1907
   115
static SDL_Texture *
slouken@1907
   116
CreateTexture(SDL_Renderer * renderer, Uint32 format, int w, int h)
slouken@1907
   117
{
slouken@1907
   118
    SDL_Texture *texture;
slouken@1907
   119
slouken@1920
   120
    texture = (SDL_Texture *) SDL_calloc(1, sizeof(*texture));
slouken@1907
   121
    if (!texture) {
slouken@1907
   122
        SDL_OutOfMemory();
slouken@1907
   123
        return NULL;
slouken@1907
   124
    }
slouken@1907
   125
slouken@1907
   126
    texture->format = format;
slouken@2222
   127
    texture->access = SDL_TEXTUREACCESS_STREAMING;
slouken@1907
   128
    texture->w = w;
slouken@1907
   129
    texture->h = h;
slouken@1907
   130
    texture->renderer = renderer;
slouken@1907
   131
slouken@1907
   132
    if (renderer->CreateTexture(renderer, texture) < 0) {
slouken@1907
   133
        SDL_free(texture);
slouken@1907
   134
        return NULL;
slouken@1907
   135
    }
slouken@1907
   136
    return texture;
slouken@1907
   137
}
slouken@1907
   138
slouken@1907
   139
static void
slouken@1907
   140
DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
slouken@1907
   141
{
slouken@1907
   142
    renderer->DestroyTexture(renderer, texture);
slouken@1907
   143
    SDL_free(texture);
slouken@1907
   144
}
slouken@1907
   145
slouken@1907
   146
static int
slouken@1907
   147
DisplayPaletteChanged(void *userdata, SDL_Palette * palette)
slouken@1907
   148
{
slouken@1918
   149
    SW_RenderData *data = (SW_RenderData *) userdata;
slouken@1907
   150
slouken@5142
   151
    if (data->renderer->SetTexturePalette) {
slouken@5142
   152
        data->renderer->SetTexturePalette(data->renderer, data->texture,
slouken@5142
   153
                                          palette->colors, 0,
slouken@5142
   154
                                          palette->ncolors);
slouken@1907
   155
    }
slouken@1907
   156
    return 0;
slouken@1907
   157
}
slouken@1907
   158
slouken@2227
   159
void
slouken@2227
   160
Setup_SoftwareRenderer(SDL_Renderer * renderer)
slouken@2227
   161
{
slouken@2227
   162
    renderer->CreateTexture = SW_CreateTexture;
slouken@2227
   163
    renderer->QueryTexturePixels = SW_QueryTexturePixels;
slouken@2227
   164
    renderer->SetTexturePalette = SW_SetTexturePalette;
slouken@2227
   165
    renderer->GetTexturePalette = SW_GetTexturePalette;
slouken@2227
   166
    renderer->SetTextureColorMod = SW_SetTextureColorMod;
slouken@2227
   167
    renderer->SetTextureAlphaMod = SW_SetTextureAlphaMod;
slouken@5141
   168
    renderer->SetTextureBlendMode = SW_SetTextureBlendMode;
slouken@2227
   169
    renderer->UpdateTexture = SW_UpdateTexture;
slouken@2227
   170
    renderer->LockTexture = SW_LockTexture;
slouken@2227
   171
    renderer->UnlockTexture = SW_UnlockTexture;
slouken@2227
   172
    renderer->DestroyTexture = SW_DestroyTexture;
slouken@2227
   173
slouken@2227
   174
    renderer->info.num_texture_formats =
slouken@2227
   175
        SW_RenderDriver.info.num_texture_formats;
slouken@2227
   176
    SDL_memcpy(renderer->info.texture_formats,
slouken@2227
   177
               SW_RenderDriver.info.texture_formats,
slouken@2227
   178
               sizeof(renderer->info.texture_formats));;
slouken@2227
   179
    renderer->info.max_texture_width = SW_RenderDriver.info.max_texture_width;
slouken@2227
   180
    renderer->info.max_texture_height =
slouken@2227
   181
        SW_RenderDriver.info.max_texture_height;
slouken@2227
   182
}
slouken@2227
   183
slouken@1895
   184
SDL_Renderer *
slouken@1918
   185
SW_CreateRenderer(SDL_Window * window, Uint32 flags)
slouken@1895
   186
{
slouken@3685
   187
    SDL_VideoDisplay *display = window->display;
slouken@1895
   188
    SDL_DisplayMode *displayMode = &display->current_mode;
slouken@1895
   189
    SDL_Renderer *renderer;
slouken@1918
   190
    SW_RenderData *data;
slouken@1895
   191
    int i, n;
slouken@1895
   192
    int bpp;
slouken@1895
   193
    Uint32 Rmask, Gmask, Bmask, Amask;
slouken@1907
   194
    Uint32 renderer_flags;
slouken@1929
   195
    const char *desired_driver;
slouken@1895
   196
slouken@1895
   197
    if (!SDL_PixelFormatEnumToMasks
slouken@1895
   198
        (displayMode->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
slouken@1895
   199
        SDL_SetError("Unknown display format");
slouken@1895
   200
        return NULL;
slouken@1895
   201
    }
slouken@1895
   202
slouken@1895
   203
    renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
slouken@1895
   204
    if (!renderer) {
slouken@1895
   205
        SDL_OutOfMemory();
slouken@1895
   206
        return NULL;
slouken@1895
   207
    }
slouken@1895
   208
slouken@1920
   209
    data = (SW_RenderData *) SDL_calloc(1, sizeof(*data));
slouken@1895
   210
    if (!data) {
slouken@1918
   211
        SW_DestroyRenderer(renderer);
slouken@1895
   212
        SDL_OutOfMemory();
slouken@1895
   213
        return NULL;
slouken@1895
   214
    }
slouken@5147
   215
    renderer->WindowEvent = SW_WindowEvent;
slouken@2884
   216
slouken@3596
   217
    renderer->RenderDrawPoints = SW_RenderDrawPoints;
slouken@3596
   218
    renderer->RenderDrawLines = SW_RenderDrawLines;
slouken@3596
   219
    renderer->RenderDrawRects = SW_RenderDrawRects;
slouken@3596
   220
    renderer->RenderFillRects = SW_RenderFillRects;
slouken@1918
   221
    renderer->RenderCopy = SW_RenderCopy;
slouken@3427
   222
    renderer->RenderReadPixels = SW_RenderReadPixels;
slouken@3427
   223
    renderer->RenderWritePixels = SW_RenderWritePixels;
slouken@1918
   224
    renderer->RenderPresent = SW_RenderPresent;
slouken@1918
   225
    renderer->DestroyRenderer = SW_DestroyRenderer;
slouken@2227
   226
    renderer->info.name = SW_RenderDriver.info.name;
slouken@2227
   227
    renderer->info.flags = 0;
slouken@3685
   228
    renderer->window = window;
slouken@1895
   229
    renderer->driverdata = data;
slouken@2227
   230
    Setup_SoftwareRenderer(renderer);
slouken@1895
   231
slouken@5142
   232
    n = 1;
slouken@1907
   233
    data->format = displayMode->format;
slouken@1895
   234
slouken@1895
   235
    /* Find a render driver that we can use to display data */
slouken@5142
   236
    renderer_flags = 0;
slouken@1965
   237
    if (flags & SDL_RENDERER_PRESENTVSYNC) {
slouken@1965
   238
        renderer_flags |= SDL_RENDERER_PRESENTVSYNC;
slouken@1907
   239
    }
slouken@1929
   240
    desired_driver = SDL_getenv("SDL_VIDEO_RENDERER_SWDRIVER");
slouken@1895
   241
    for (i = 0; i < display->num_render_drivers; ++i) {
slouken@1895
   242
        SDL_RenderDriver *driver = &display->render_drivers[i];
slouken@1929
   243
        if (driver->info.name == SW_RenderDriver.info.name) {
slouken@1929
   244
            continue;
slouken@1929
   245
        }
slouken@1929
   246
        if (desired_driver
slouken@1929
   247
            && SDL_strcasecmp(desired_driver, driver->info.name) != 0) {
slouken@1929
   248
            continue;
slouken@1929
   249
        }
slouken@1929
   250
        data->renderer = driver->CreateRenderer(window, renderer_flags);
slouken@1929
   251
        if (data->renderer) {
slouken@1929
   252
            break;
slouken@1895
   253
        }
slouken@1895
   254
    }
slouken@1895
   255
    if (i == display->num_render_drivers) {
slouken@1918
   256
        SW_DestroyRenderer(renderer);
slouken@1895
   257
        SDL_SetError("Couldn't find display render driver");
slouken@1895
   258
        return NULL;
slouken@1895
   259
    }
slouken@1965
   260
    if (data->renderer->info.flags & SDL_RENDERER_PRESENTVSYNC) {
slouken@1965
   261
        renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
slouken@1907
   262
    }
slouken@1907
   263
slouken@1907
   264
    /* Create the textures we'll use for display */
slouken@5142
   265
    data->texture =
slouken@5142
   266
        CreateTexture(data->renderer, data->format, window->w, window->h);
slouken@5142
   267
    if (!data->texture) {
slouken@5142
   268
        SW_DestroyRenderer(renderer);
slouken@5142
   269
        return NULL;
slouken@1907
   270
    }
slouken@1907
   271
slouken@1907
   272
    /* Create a surface we'll use for rendering */
slouken@1907
   273
    data->surface.flags = SDL_PREALLOC;
slouken@1907
   274
    data->surface.format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
slouken@1907
   275
    if (!data->surface.format) {
slouken@1918
   276
        SW_DestroyRenderer(renderer);
slouken@1907
   277
        return NULL;
slouken@1907
   278
    }
slouken@1907
   279
    SDL_SetSurfacePalette(&data->surface, display->palette);
slouken@1907
   280
slouken@1907
   281
    /* Set up a palette watch on the display palette */
slouken@1907
   282
    if (display->palette) {
slouken@1907
   283
        SDL_AddPaletteWatch(display->palette, DisplayPaletteChanged, data);
slouken@1907
   284
    }
slouken@1907
   285
slouken@1895
   286
    return renderer;
slouken@1895
   287
}
slouken@1895
   288
slouken@5147
   289
static SDL_Texture *
slouken@1970
   290
SW_ActivateRenderer(SDL_Renderer * renderer)
slouken@1970
   291
{
slouken@1970
   292
    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
slouken@3685
   293
    SDL_Window *window = renderer->window;
slouken@1970
   294
slouken@1972
   295
    if (data->updateSize) {
slouken@1972
   296
        /* Recreate the textures for the new window size */
slouken@5142
   297
        if (data->texture) {
slouken@5142
   298
            DestroyTexture(data->renderer, data->texture);
slouken@1972
   299
        }
slouken@5142
   300
        data->texture = CreateTexture(data->renderer, data->format,
slouken@5142
   301
                                      window->w, window->h);
slouken@5147
   302
        if (data->texture) {
slouken@5147
   303
            data->updateSize = SDL_FALSE;
slouken@1972
   304
        }
slouken@1972
   305
    }
slouken@5147
   306
    return data->texture;
slouken@1970
   307
}
slouken@1970
   308
slouken@5147
   309
static void
slouken@5147
   310
SW_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
slouken@1970
   311
{
slouken@1970
   312
    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
slouken@1970
   313
slouken@5147
   314
    if (event->event == SDL_WINDOWEVENT_RESIZED) {
slouken@5147
   315
        data->updateSize = SDL_TRUE;
slouken@1970
   316
    }
slouken@1970
   317
}
slouken@1970
   318
slouken@1970
   319
static int
slouken@1918
   320
SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
slouken@1895
   321
{
slouken@1895
   322
    if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
slouken@2786
   323
        texture->driverdata =
slouken@2786
   324
            SDL_SW_CreateYUVTexture(texture->format, texture->w, texture->h);
slouken@1895
   325
    } else {
slouken@1895
   326
        int bpp;
slouken@1895
   327
        Uint32 Rmask, Gmask, Bmask, Amask;
slouken@1895
   328
slouken@1895
   329
        if (!SDL_PixelFormatEnumToMasks
slouken@1895
   330
            (texture->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
slouken@1895
   331
            SDL_SetError("Unknown texture format");
slouken@1895
   332
            return -1;
slouken@1895
   333
        }
slouken@1895
   334
slouken@1895
   335
        texture->driverdata =
slouken@1895
   336
            SDL_CreateRGBSurface(0, texture->w, texture->h, bpp, Rmask, Gmask,
slouken@1895
   337
                                 Bmask, Amask);
slouken@3053
   338
        SDL_SetSurfaceColorMod(texture->driverdata, texture->r, texture->g,
slouken@3053
   339
                               texture->b);
slouken@3053
   340
        SDL_SetSurfaceAlphaMod(texture->driverdata, texture->a);
slouken@3053
   341
        SDL_SetSurfaceBlendMode(texture->driverdata, texture->blendMode);
slouken@3053
   342
slouken@2802
   343
        if (texture->access == SDL_TEXTUREACCESS_STATIC) {
slouken@2802
   344
            SDL_SetSurfaceRLE(texture->driverdata, 1);
slouken@2802
   345
        }
slouken@1895
   346
    }
slouken@1895
   347
slouken@1895
   348
    if (!texture->driverdata) {
slouken@1895
   349
        return -1;
slouken@1895
   350
    }
slouken@1895
   351
    return 0;
slouken@1895
   352
}
slouken@1895
   353
slouken@1895
   354
static int
slouken@1918
   355
SW_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@1918
   356
                      void **pixels, int *pitch)
slouken@1895
   357
{
slouken@1895
   358
    if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
slouken@2735
   359
        return SDL_SW_QueryYUVTexturePixels((SDL_SW_YUVTexture *)
slouken@2735
   360
                                            texture->driverdata, pixels,
slouken@2735
   361
                                            pitch);
slouken@1895
   362
    } else {
slouken@1895
   363
        SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
slouken@1895
   364
slouken@1895
   365
        *pixels = surface->pixels;
slouken@1895
   366
        *pitch = surface->pitch;
slouken@1895
   367
        return 0;
slouken@1895
   368
    }
slouken@1895
   369
}
slouken@1895
   370
slouken@1895
   371
static int
slouken@1918
   372
SW_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@1918
   373
                     const SDL_Color * colors, int firstcolor, int ncolors)
slouken@1895
   374
{
slouken@1895
   375
    if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
slouken@1895
   376
        SDL_SetError("YUV textures don't have a palette");
slouken@1895
   377
        return -1;
slouken@1895
   378
    } else {
slouken@1895
   379
        SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
slouken@1895
   380
slouken@1895
   381
        return SDL_SetPaletteColors(surface->format->palette, colors,
slouken@1895
   382
                                    firstcolor, ncolors);
slouken@1895
   383
    }
slouken@1895
   384
}
slouken@1895
   385
slouken@1895
   386
static int
slouken@1918
   387
SW_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@1918
   388
                     SDL_Color * colors, int firstcolor, int ncolors)
slouken@1895
   389
{
slouken@1895
   390
    if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
slouken@1895
   391
        SDL_SetError("YUV textures don't have a palette");
slouken@1895
   392
        return -1;
slouken@1895
   393
    } else {
slouken@1895
   394
        SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
slouken@1895
   395
slouken@1895
   396
        SDL_memcpy(colors, &surface->format->palette->colors[firstcolor],
slouken@1895
   397
                   ncolors * sizeof(*colors));
slouken@1895
   398
        return 0;
slouken@1895
   399
    }
slouken@1895
   400
}
slouken@1895
   401
slouken@1985
   402
static int
slouken@1985
   403
SW_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture)
slouken@1985
   404
{
slouken@2267
   405
    SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
slouken@2267
   406
    return SDL_SetSurfaceColorMod(surface, texture->r, texture->g,
slouken@2267
   407
                                  texture->b);
slouken@1985
   408
}
slouken@1985
   409
slouken@1985
   410
static int
slouken@1985
   411
SW_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture)
slouken@1985
   412
{
slouken@2267
   413
    SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
slouken@2267
   414
    return SDL_SetSurfaceAlphaMod(surface, texture->a);
slouken@1985
   415
}
slouken@1985
   416
slouken@1985
   417
static int
slouken@1985
   418
SW_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture)
slouken@1985
   419
{
slouken@2267
   420
    SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
slouken@2267
   421
    return SDL_SetSurfaceBlendMode(surface, texture->blendMode);
slouken@1985
   422
}
slouken@1985
   423
slouken@1985
   424
static int
slouken@1918
   425
SW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@1918
   426
                 const SDL_Rect * rect, const void *pixels, int pitch)
slouken@1895
   427
{
slouken@1895
   428
    if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
slouken@2735
   429
        return SDL_SW_UpdateYUVTexture((SDL_SW_YUVTexture *)
slouken@2735
   430
                                       texture->driverdata, rect, pixels,
slouken@2735
   431
                                       pitch);
slouken@1895
   432
    } else {
slouken@1895
   433
        SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
slouken@1895
   434
        Uint8 *src, *dst;
slouken@1895
   435
        int row;
slouken@1895
   436
        size_t length;
slouken@1895
   437
slouken@1895
   438
        src = (Uint8 *) pixels;
slouken@1895
   439
        dst =
slouken@1895
   440
            (Uint8 *) surface->pixels + rect->y * surface->pitch +
slouken@1895
   441
            rect->x * surface->format->BytesPerPixel;
slouken@1895
   442
        length = rect->w * surface->format->BytesPerPixel;
slouken@1895
   443
        for (row = 0; row < rect->h; ++row) {
slouken@1895
   444
            SDL_memcpy(dst, src, length);
slouken@1895
   445
            src += pitch;
slouken@1895
   446
            dst += surface->pitch;
slouken@1895
   447
        }
slouken@1895
   448
        return 0;
slouken@1895
   449
    }
slouken@1895
   450
}
slouken@1895
   451
slouken@1895
   452
static int
slouken@1918
   453
SW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@1918
   454
               const SDL_Rect * rect, int markDirty, void **pixels,
slouken@1918
   455
               int *pitch)
slouken@1895
   456
{
slouken@1895
   457
    if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
slouken@2735
   458
        return SDL_SW_LockYUVTexture((SDL_SW_YUVTexture *)
slouken@2735
   459
                                     texture->driverdata, rect, markDirty,
slouken@2735
   460
                                     pixels, pitch);
slouken@1895
   461
    } else {
slouken@1895
   462
        SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
slouken@1895
   463
slouken@1895
   464
        *pixels =
slouken@1895
   465
            (void *) ((Uint8 *) surface->pixels + rect->y * surface->pitch +
slouken@1895
   466
                      rect->x * surface->format->BytesPerPixel);
slouken@1895
   467
        *pitch = surface->pitch;
slouken@1895
   468
        return 0;
slouken@1895
   469
    }
slouken@1895
   470
}
slouken@1895
   471
slouken@1895
   472
static void
slouken@1918
   473
SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
slouken@1895
   474
{
slouken@1895
   475
    if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
slouken@1895
   476
        SDL_SW_UnlockYUVTexture((SDL_SW_YUVTexture *) texture->driverdata);
slouken@1895
   477
    }
slouken@1895
   478
}
slouken@1895
   479
slouken@1895
   480
static int
slouken@3596
   481
SW_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
slouken@3596
   482
                    int count)
slouken@2901
   483
{
slouken@2901
   484
    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
slouken@5147
   485
    SDL_Texture *texture = SW_ActivateRenderer(renderer);
slouken@2904
   486
    SDL_Rect rect;
slouken@3536
   487
    int i;
slouken@3536
   488
    int x, y;
slouken@3536
   489
    int status = 0;
slouken@2901
   490
slouken@5147
   491
    if (!texture) {
slouken@5147
   492
        return -1;
slouken@5147
   493
    }
slouken@5147
   494
slouken@3536
   495
    /* Get the smallest rectangle that contains everything */
slouken@3536
   496
    rect.x = 0;
slouken@3536
   497
    rect.y = 0;
slouken@3536
   498
    rect.w = texture->w;
slouken@3536
   499
    rect.h = texture->h;
slouken@3536
   500
    if (!SDL_EnclosePoints(points, count, &rect, &rect)) {
slouken@3536
   501
        /* Nothing to draw */
slouken@3536
   502
        return 0;
slouken@2904
   503
    }
slouken@2904
   504
slouken@3536
   505
    if (data->renderer->LockTexture(data->renderer, texture, &rect, 1,
slouken@2891
   506
                                    &data->surface.pixels,
slouken@2888
   507
                                    &data->surface.pitch) < 0) {
slouken@2888
   508
        return -1;
slouken@2888
   509
    }
slouken@2888
   510
slouken@3536
   511
    data->surface.clip_rect.w = data->surface.w = rect.w;
slouken@3536
   512
    data->surface.clip_rect.h = data->surface.h = rect.h;
slouken@2904
   513
slouken@3536
   514
    /* Draw the points! */
slouken@5140
   515
    if (renderer->blendMode == SDL_BLENDMODE_NONE) {
slouken@3536
   516
        Uint32 color = SDL_MapRGBA(data->surface.format,
slouken@3536
   517
                                   renderer->r, renderer->g, renderer->b,
slouken@3536
   518
                                   renderer->a);
slouken@2888
   519
slouken@3536
   520
        for (i = 0; i < count; ++i) {
slouken@3536
   521
            x = points[i].x - rect.x;
slouken@3536
   522
            y = points[i].y - rect.y;
slouken@3536
   523
slouken@3536
   524
            status = SDL_DrawPoint(&data->surface, x, y, color);
slouken@3536
   525
        }
slouken@2888
   526
    } else {
slouken@3536
   527
        for (i = 0; i < count; ++i) {
slouken@3536
   528
            x = points[i].x - rect.x;
slouken@3536
   529
            y = points[i].y - rect.y;
slouken@3536
   530
slouken@3536
   531
            status = SDL_BlendPoint(&data->surface, x, y,
slouken@3536
   532
                                    renderer->blendMode,
slouken@3536
   533
                                    renderer->r, renderer->g, renderer->b,
slouken@3536
   534
                                    renderer->a);
slouken@3536
   535
        }
slouken@2888
   536
    }
slouken@2888
   537
slouken@3536
   538
    data->renderer->UnlockTexture(data->renderer, texture);
slouken@3536
   539
slouken@2888
   540
    return status;
slouken@2888
   541
}
slouken@2888
   542
slouken@2888
   543
static int
slouken@3596
   544
SW_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
slouken@3596
   545
                   int count)
slouken@1895
   546
{
slouken@1918
   547
    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
slouken@5147
   548
    SDL_Texture *texture = SW_ActivateRenderer(renderer);
slouken@3536
   549
    SDL_Rect clip, rect;
slouken@3536
   550
    int i;
slouken@3536
   551
    int x1, y1, x2, y2;
slouken@3536
   552
    int status = 0;
slouken@3536
   553
slouken@5147
   554
    if (!texture) {
slouken@5147
   555
        return -1;
slouken@5147
   556
    }
slouken@5147
   557
slouken@3536
   558
    /* Get the smallest rectangle that contains everything */
slouken@3536
   559
    clip.x = 0;
slouken@3536
   560
    clip.y = 0;
slouken@3536
   561
    clip.w = texture->w;
slouken@3536
   562
    clip.h = texture->h;
slouken@3536
   563
    SDL_EnclosePoints(points, count, NULL, &rect);
slouken@3536
   564
    if (!SDL_IntersectRect(&rect, &clip, &rect)) {
slouken@3536
   565
        /* Nothing to draw */
slouken@3536
   566
        return 0;
slouken@3536
   567
    }
slouken@1895
   568
slouken@3536
   569
    if (data->renderer->LockTexture(data->renderer, texture, &rect, 1,
slouken@3536
   570
                                    &data->surface.pixels,
slouken@2735
   571
                                    &data->surface.pitch) < 0) {
slouken@1907
   572
        return -1;
slouken@1907
   573
    }
slouken@2888
   574
slouken@3536
   575
    data->surface.clip_rect.w = data->surface.w = rect.w;
slouken@3536
   576
    data->surface.clip_rect.h = data->surface.h = rect.h;
slouken@1907
   577
slouken@3536
   578
    /* Draw the points! */
slouken@5140
   579
    if (renderer->blendMode == SDL_BLENDMODE_NONE) {
slouken@3536
   580
        Uint32 color = SDL_MapRGBA(data->surface.format,
slouken@3536
   581
                                   renderer->r, renderer->g, renderer->b,
slouken@3536
   582
                                   renderer->a);
slouken@2888
   583
slouken@3536
   584
        for (i = 1; i < count; ++i) {
slouken@3536
   585
            x1 = points[i-1].x - rect.x;
slouken@3536
   586
            y1 = points[i-1].y - rect.y;
slouken@3536
   587
            x2 = points[i].x - rect.x;
slouken@3536
   588
            y2 = points[i].y - rect.y;
slouken@3536
   589
slouken@3536
   590
            status = SDL_DrawLine(&data->surface, x1, y1, x2, y2, color);
slouken@3536
   591
        }
slouken@2888
   592
    } else {
slouken@3536
   593
        for (i = 1; i < count; ++i) {
slouken@3536
   594
            x1 = points[i-1].x - rect.x;
slouken@3536
   595
            y1 = points[i-1].y - rect.y;
slouken@3536
   596
            x2 = points[i].x - rect.x;
slouken@3536
   597
            y2 = points[i].y - rect.y;
slouken@3536
   598
slouken@3536
   599
            status = SDL_BlendLine(&data->surface, x1, y1, x2, y2,
slouken@3536
   600
                                   renderer->blendMode,
slouken@3536
   601
                                   renderer->r, renderer->g, renderer->b,
slouken@3536
   602
                                   renderer->a);
slouken@3536
   603
        }
slouken@2888
   604
    }
slouken@1907
   605
slouken@3536
   606
    data->renderer->UnlockTexture(data->renderer, texture);
slouken@3536
   607
slouken@3536
   608
    return status;
slouken@3536
   609
}
slouken@3536
   610
slouken@3536
   611
static int
slouken@3596
   612
SW_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
slouken@3596
   613
                   int count)
slouken@3596
   614
{
slouken@3596
   615
    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
slouken@5147
   616
    SDL_Texture *texture = SW_ActivateRenderer(renderer);
slouken@3596
   617
    SDL_Rect clip, rect;
slouken@3596
   618
    Uint32 color = 0;
slouken@3596
   619
    int i;
slouken@3596
   620
    int status = 0;
slouken@3596
   621
slouken@5147
   622
    if (!texture) {
slouken@5147
   623
        return -1;
slouken@5147
   624
    }
slouken@5147
   625
slouken@3596
   626
    clip.x = 0;
slouken@3596
   627
    clip.y = 0;
slouken@3596
   628
    clip.w = texture->w;
slouken@3596
   629
    clip.h = texture->h;
slouken@3596
   630
slouken@5140
   631
    if (renderer->blendMode == SDL_BLENDMODE_NONE) {
slouken@3596
   632
        color = SDL_MapRGBA(data->surface.format,
slouken@3596
   633
                            renderer->r, renderer->g, renderer->b,
slouken@3596
   634
                            renderer->a);
slouken@3596
   635
    }
slouken@3596
   636
slouken@3596
   637
    for (i = 0; i < count; ++i) {
slouken@3599
   638
        /* FIXME: We don't want to draw clipped edges */
slouken@3596
   639
        if (!SDL_IntersectRect(rects[i], &clip, &rect)) {
slouken@3596
   640
            /* Nothing to draw */
slouken@3596
   641
            continue;
slouken@3596
   642
        }
slouken@3596
   643
slouken@3596
   644
        if (data->renderer->LockTexture(data->renderer, texture, &rect, 1,
slouken@3596
   645
                                        &data->surface.pixels,
slouken@3596
   646
                                        &data->surface.pitch) < 0) {
slouken@3596
   647
            return -1;
slouken@3596
   648
        }
slouken@3596
   649
slouken@3596
   650
        data->surface.clip_rect.w = data->surface.w = rect.w;
slouken@3596
   651
        data->surface.clip_rect.h = data->surface.h = rect.h;
slouken@3596
   652
slouken@5140
   653
        if (renderer->blendMode == SDL_BLENDMODE_NONE) {
slouken@3596
   654
            status = SDL_DrawRect(&data->surface, NULL, color);
slouken@3596
   655
        } else {
slouken@3596
   656
            status = SDL_BlendRect(&data->surface, NULL,
slouken@3596
   657
                                   renderer->blendMode,
slouken@3596
   658
                                   renderer->r, renderer->g, renderer->b,
slouken@3596
   659
                                   renderer->a);
slouken@3596
   660
        }
slouken@3596
   661
slouken@3596
   662
        data->renderer->UnlockTexture(data->renderer, texture);
slouken@3596
   663
    }
slouken@3596
   664
    return status;
slouken@3596
   665
}
slouken@3596
   666
slouken@3596
   667
static int
slouken@3596
   668
SW_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
slouken@3596
   669
                   int count)
slouken@3536
   670
{
slouken@3536
   671
    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
slouken@5147
   672
    SDL_Texture *texture = SW_ActivateRenderer(renderer);
slouken@3536
   673
    SDL_Rect clip, rect;
slouken@3536
   674
    Uint32 color = 0;
slouken@3536
   675
    int i;
slouken@3536
   676
    int status = 0;
slouken@3536
   677
slouken@5147
   678
    if (!texture) {
slouken@5147
   679
        return -1;
slouken@5147
   680
    }
slouken@5147
   681
slouken@3536
   682
    clip.x = 0;
slouken@3536
   683
    clip.y = 0;
slouken@3536
   684
    clip.w = texture->w;
slouken@3536
   685
    clip.h = texture->h;
slouken@3536
   686
slouken@5140
   687
    if (renderer->blendMode == SDL_BLENDMODE_NONE) {
slouken@3536
   688
        color = SDL_MapRGBA(data->surface.format,
slouken@3536
   689
                            renderer->r, renderer->g, renderer->b,
slouken@3536
   690
                            renderer->a);
slouken@3536
   691
    }
slouken@3536
   692
slouken@3536
   693
    for (i = 0; i < count; ++i) {
slouken@3536
   694
        if (!SDL_IntersectRect(rects[i], &clip, &rect)) {
slouken@3536
   695
            /* Nothing to draw */
slouken@3536
   696
            continue;
slouken@3536
   697
        }
slouken@3536
   698
slouken@3536
   699
        if (data->renderer->LockTexture(data->renderer, texture, &rect, 1,
slouken@3536
   700
                                        &data->surface.pixels,
slouken@3536
   701
                                        &data->surface.pitch) < 0) {
slouken@3536
   702
            return -1;
slouken@3536
   703
        }
slouken@3536
   704
slouken@3536
   705
        data->surface.clip_rect.w = data->surface.w = rect.w;
slouken@3536
   706
        data->surface.clip_rect.h = data->surface.h = rect.h;
slouken@3536
   707
slouken@5140
   708
        if (renderer->blendMode == SDL_BLENDMODE_NONE) {
slouken@3536
   709
            status = SDL_FillRect(&data->surface, NULL, color);
slouken@3536
   710
        } else {
slouken@3596
   711
            status = SDL_BlendFillRect(&data->surface, NULL,
slouken@3596
   712
                                       renderer->blendMode,
slouken@3596
   713
                                       renderer->r, renderer->g, renderer->b,
slouken@3596
   714
                                       renderer->a);
slouken@3536
   715
        }
slouken@3536
   716
slouken@3536
   717
        data->renderer->UnlockTexture(data->renderer, texture);
slouken@3536
   718
    }
slouken@1907
   719
    return status;
slouken@1895
   720
}
slouken@1895
   721
slouken@1895
   722
static int
slouken@1918
   723
SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@1985
   724
              const SDL_Rect * srcrect, const SDL_Rect * dstrect)
slouken@1895
   725
{
slouken@1918
   726
    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
slouken@1907
   727
    int status;
slouken@1895
   728
slouken@5147
   729
    if (!SW_ActivateRenderer(renderer)) {
slouken@5147
   730
        return -1;
slouken@5147
   731
    }
slouken@5147
   732
slouken@5142
   733
    if (data->renderer->LockTexture(data->renderer, data->texture,
slouken@2735
   734
                                    dstrect, 1, &data->surface.pixels,
slouken@2735
   735
                                    &data->surface.pitch) < 0) {
slouken@1907
   736
        return -1;
slouken@1907
   737
    }
slouken@1907
   738
slouken@1895
   739
    if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
slouken@1907
   740
        status =
slouken@1907
   741
            SDL_SW_CopyYUVToRGB((SDL_SW_YUVTexture *) texture->driverdata,
slouken@1907
   742
                                srcrect, data->format, dstrect->w, dstrect->h,
slouken@1907
   743
                                data->surface.pixels, data->surface.pitch);
slouken@1895
   744
    } else {
slouken@1895
   745
        SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
slouken@2267
   746
        SDL_Rect real_srcrect = *srcrect;
slouken@2267
   747
        SDL_Rect real_dstrect;
slouken@1907
   748
slouken@2267
   749
        data->surface.w = dstrect->w;
slouken@2267
   750
        data->surface.h = dstrect->h;
slouken@2267
   751
        data->surface.clip_rect.w = dstrect->w;
slouken@2267
   752
        data->surface.clip_rect.h = dstrect->h;
slouken@2267
   753
        real_dstrect = data->surface.clip_rect;
slouken@1895
   754
slouken@2267
   755
        status =
slouken@2267
   756
            SDL_LowerBlit(surface, &real_srcrect, &data->surface,
slouken@2267
   757
                          &real_dstrect);
slouken@1895
   758
    }
slouken@5142
   759
    data->renderer->UnlockTexture(data->renderer, data->texture);
slouken@1907
   760
    return status;
slouken@1895
   761
}
slouken@1895
   762
slouken@3427
   763
static int
slouken@3427
   764
SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
slouken@3435
   765
                    Uint32 format, void * pixels, int pitch)
slouken@3427
   766
{
slouken@3427
   767
    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
slouken@3427
   768
slouken@5147
   769
    if (!SW_ActivateRenderer(renderer)) {
slouken@5147
   770
        return -1;
slouken@5147
   771
    }
slouken@5147
   772
slouken@5142
   773
    if (data->renderer->LockTexture(data->renderer, data->texture,
slouken@3427
   774
                                    rect, 0, &data->surface.pixels,
slouken@3427
   775
                                    &data->surface.pitch) < 0) {
slouken@3427
   776
        return -1;
slouken@3427
   777
    }
slouken@3427
   778
slouken@3435
   779
    SDL_ConvertPixels(rect->w, rect->h,
slouken@3435
   780
                      data->format, data->surface.pixels, data->surface.pitch,
slouken@3435
   781
                      format, pixels, pitch);
slouken@3427
   782
slouken@5142
   783
    data->renderer->UnlockTexture(data->renderer, data->texture);
slouken@3427
   784
    return 0;
slouken@3427
   785
}
slouken@3427
   786
slouken@3427
   787
static int
slouken@3427
   788
SW_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
slouken@3435
   789
                     Uint32 format, const void * pixels, int pitch)
slouken@3427
   790
{
slouken@3427
   791
    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
slouken@3427
   792
slouken@5147
   793
    if (!SW_ActivateRenderer(renderer)) {
slouken@5147
   794
        return -1;
slouken@5147
   795
    }
slouken@5147
   796
slouken@5142
   797
    if (data->renderer->LockTexture(data->renderer, data->texture,
slouken@3427
   798
                                    rect, 1, &data->surface.pixels,
slouken@3427
   799
                                    &data->surface.pitch) < 0) {
slouken@3427
   800
        return -1;
slouken@3427
   801
    }
slouken@3427
   802
slouken@3435
   803
    SDL_ConvertPixels(rect->w, rect->h, format, pixels, pitch,
slouken@3435
   804
                      data->format, data->surface.pixels, data->surface.pitch);
slouken@3427
   805
slouken@5142
   806
    data->renderer->UnlockTexture(data->renderer, data->texture);
slouken@3427
   807
    return 0;
slouken@3427
   808
}
slouken@3427
   809
slouken@1895
   810
static void
slouken@1918
   811
SW_RenderPresent(SDL_Renderer * renderer)
slouken@1895
   812
{
slouken@1918
   813
    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
slouken@5147
   814
    SDL_Texture *texture = SW_ActivateRenderer(renderer);
slouken@5142
   815
    SDL_Rect rect;
slouken@1895
   816
slouken@5147
   817
    if (!texture) {
slouken@5147
   818
        return;
slouken@5147
   819
    }
slouken@5147
   820
slouken@1895
   821
    /* Send the data to the display */
slouken@5142
   822
    rect.x = 0;
slouken@5142
   823
    rect.y = 0;
slouken@5142
   824
    rect.w = texture->w;
slouken@5142
   825
    rect.h = texture->h;
slouken@5142
   826
    data->renderer->RenderCopy(data->renderer, texture, &rect, &rect);
slouken@1895
   827
    data->renderer->RenderPresent(data->renderer);
slouken@1895
   828
}
slouken@1895
   829
slouken@1895
   830
static void
slouken@1918
   831
SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
slouken@1895
   832
{
slouken@1895
   833
    if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
slouken@1895
   834
        SDL_SW_DestroyYUVTexture((SDL_SW_YUVTexture *) texture->driverdata);
slouken@1895
   835
    } else {
slouken@1895
   836
        SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
slouken@1895
   837
slouken@1895
   838
        SDL_FreeSurface(surface);
slouken@1895
   839
    }
slouken@1895
   840
}
slouken@1895
   841
slouken@1895
   842
static void
slouken@1918
   843
SW_DestroyRenderer(SDL_Renderer * renderer)
slouken@1895
   844
{
slouken@1918
   845
    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
slouken@3685
   846
    SDL_Window *window = renderer->window;
slouken@3685
   847
    SDL_VideoDisplay *display = window->display;
slouken@1895
   848
    int i;
slouken@1895
   849
slouken@1895
   850
    if (data) {
slouken@5142
   851
        if (data->texture) {
slouken@5142
   852
            DestroyTexture(data->renderer, data->texture);
slouken@1895
   853
        }
slouken@1907
   854
        if (data->surface.format) {
slouken@1907
   855
            SDL_SetSurfacePalette(&data->surface, NULL);
slouken@1907
   856
            SDL_FreeFormat(data->surface.format);
slouken@1907
   857
        }
slouken@1907
   858
        if (display->palette) {
slouken@1907
   859
            SDL_DelPaletteWatch(display->palette, DisplayPaletteChanged,
slouken@1907
   860
                                data);
slouken@1907
   861
        }
slouken@1907
   862
        if (data->renderer) {
slouken@1907
   863
            data->renderer->DestroyRenderer(data->renderer);
slouken@1907
   864
        }
slouken@1895
   865
        SDL_FreeDirtyRects(&data->dirty);
slouken@1895
   866
        SDL_free(data);
slouken@1895
   867
    }
slouken@1895
   868
    SDL_free(renderer);
slouken@1895
   869
}
slouken@1895
   870
slouken@1895
   871
/* vi: set ts=4 sw=4 expandtab: */