changeset 5198:bb45ecd958d8

Renamed files for consistency
author Sam Lantinga <slouken@libsdl.org>
date Sat, 05 Feb 2011 12:01:11 -0800
parents 69f47f2c1856
children 06837416f969
files src/render/SDL_render.c src/render/direct3d/SDL_d3drender.c src/render/direct3d/SDL_render_d3d.c src/render/opengl/SDL_render_gl.c src/render/opengl/SDL_renderer_gl.c src/render/opengles/SDL_render_gles.c src/render/opengles/SDL_renderer_gles.c src/render/software/SDL_render_sw.c src/render/software/SDL_render_sw_c.h src/render/software/SDL_renderer_sw.c src/render/software/SDL_renderer_sw_c.h
diffstat 11 files changed, 3066 insertions(+), 3066 deletions(-) [+]
line wrap: on
line diff
--- a/src/render/SDL_render.c	Sat Feb 05 11:54:46 2011 -0800
+++ b/src/render/SDL_render.c	Sat Feb 05 12:01:11 2011 -0800
@@ -27,7 +27,7 @@
 #include "SDL_render.h"
 #include "SDL_sysrender.h"
 #include "../video/SDL_pixels_c.h"
-#include "software/SDL_renderer_sw_c.h"
+#include "software/SDL_render_sw_c.h"
 
 
 #define CHECK_RENDERER_MAGIC(renderer, retval) \
--- a/src/render/direct3d/SDL_d3drender.c	Sat Feb 05 11:54:46 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1048 +0,0 @@
-/*
-    SDL - Simple DirectMedia Layer
-    Copyright (C) 1997-2010 Sam Lantinga
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    Sam Lantinga
-    slouken@libsdl.org
-*/
-#include "SDL_config.h"
-
-#if SDL_VIDEO_RENDER_D3D
-
-#include "../../core/windows/SDL_windows.h"
-
-#include "SDL_loadso.h"
-#include "SDL_syswm.h"
-#include "../SDL_sysrender.h"
-
-#if SDL_VIDEO_RENDER_D3D
-#define D3D_DEBUG_INFO
-#include <d3d9.h>
-#endif
-
-#ifdef ASSEMBLE_SHADER
-///////////////////////////////////////////////////////////////////////////
-// ID3DXBuffer:
-// ------------
-// The buffer object is used by D3DX to return arbitrary size data.
-//
-// GetBufferPointer -
-//    Returns a pointer to the beginning of the buffer.
-//
-// GetBufferSize -
-//    Returns the size of the buffer, in bytes.
-///////////////////////////////////////////////////////////////////////////
-
-typedef interface ID3DXBuffer ID3DXBuffer;
-typedef interface ID3DXBuffer *LPD3DXBUFFER;
-
-// {8BA5FB08-5195-40e2-AC58-0D989C3A0102}
-DEFINE_GUID(IID_ID3DXBuffer, 
-0x8ba5fb08, 0x5195, 0x40e2, 0xac, 0x58, 0xd, 0x98, 0x9c, 0x3a, 0x1, 0x2);
-
-#undef INTERFACE
-#define INTERFACE ID3DXBuffer
-
-typedef interface ID3DXBuffer {
-    const struct ID3DXBufferVtbl FAR* lpVtbl;
-} ID3DXBuffer;
-typedef const struct ID3DXBufferVtbl ID3DXBufferVtbl;
-const struct ID3DXBufferVtbl
-{
-    // IUnknown
-    STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE;
-    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
-    STDMETHOD_(ULONG, Release)(THIS) PURE;
-
-    // ID3DXBuffer
-    STDMETHOD_(LPVOID, GetBufferPointer)(THIS) PURE;
-    STDMETHOD_(DWORD, GetBufferSize)(THIS) PURE;
-};
-
-HRESULT WINAPI
-    D3DXAssembleShader(
-        LPCSTR                          pSrcData,
-        UINT                            SrcDataLen,
-        CONST LPVOID*                   pDefines,
-        LPVOID                          pInclude,
-        DWORD                           Flags,
-        LPD3DXBUFFER*                   ppShader,
-        LPD3DXBUFFER*                   ppErrorMsgs);
-
-#endif /* ASSEMBLE_SHADER */
-
-
-/* Direct3D renderer implementation */
-
-static SDL_Renderer *D3D_CreateRenderer(SDL_Window * window, Uint32 flags);
-static int D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
-static int D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
-                             const SDL_Rect * rect, const void *pixels,
-                             int pitch);
-static int D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
-                           const SDL_Rect * rect, void **pixels, int *pitch);
-static void D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
-static int D3D_RenderDrawPoints(SDL_Renderer * renderer,
-                                const SDL_Point * points, int count);
-static int D3D_RenderDrawLines(SDL_Renderer * renderer,
-                               const SDL_Point * points, int count);
-static int D3D_RenderFillRects(SDL_Renderer * renderer,
-                               const SDL_Rect ** rects, int count);
-static int D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
-                          const SDL_Rect * srcrect, const SDL_Rect * dstrect);
-static int D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
-                                Uint32 format, void * pixels, int pitch);
-static void D3D_RenderPresent(SDL_Renderer * renderer);
-static void D3D_DestroyTexture(SDL_Renderer * renderer,
-                               SDL_Texture * texture);
-static void D3D_DestroyRenderer(SDL_Renderer * renderer);
-
-
-SDL_RenderDriver D3D_RenderDriver = {
-    D3D_CreateRenderer,
-    {
-     "direct3d",
-     (SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED),
-     1,
-     {SDL_PIXELFORMAT_ARGB8888},
-     0,
-     0}
-};
-
-typedef struct
-{
-    void* d3dDLL;
-    IDirect3D9 *d3d;
-    IDirect3DDevice9 *device;
-    UINT adapter;
-    D3DPRESENT_PARAMETERS pparams;
-    SDL_bool beginScene;
-} D3D_RenderData;
-
-typedef struct
-{
-    IDirect3DTexture9 *texture;
-} D3D_TextureData;
-
-typedef struct
-{
-    float x, y, z;
-    float rhw;
-    DWORD color;
-    float u, v;
-} Vertex;
-
-static void
-D3D_SetError(const char *prefix, HRESULT result)
-{
-    const char *error;
-
-    switch (result) {
-    case D3DERR_WRONGTEXTUREFORMAT:
-        error = "WRONGTEXTUREFORMAT";
-        break;
-    case D3DERR_UNSUPPORTEDCOLOROPERATION:
-        error = "UNSUPPORTEDCOLOROPERATION";
-        break;
-    case D3DERR_UNSUPPORTEDCOLORARG:
-        error = "UNSUPPORTEDCOLORARG";
-        break;
-    case D3DERR_UNSUPPORTEDALPHAOPERATION:
-        error = "UNSUPPORTEDALPHAOPERATION";
-        break;
-    case D3DERR_UNSUPPORTEDALPHAARG:
-        error = "UNSUPPORTEDALPHAARG";
-        break;
-    case D3DERR_TOOMANYOPERATIONS:
-        error = "TOOMANYOPERATIONS";
-        break;
-    case D3DERR_CONFLICTINGTEXTUREFILTER:
-        error = "CONFLICTINGTEXTUREFILTER";
-        break;
-    case D3DERR_UNSUPPORTEDFACTORVALUE:
-        error = "UNSUPPORTEDFACTORVALUE";
-        break;
-    case D3DERR_CONFLICTINGRENDERSTATE:
-        error = "CONFLICTINGRENDERSTATE";
-        break;
-    case D3DERR_UNSUPPORTEDTEXTUREFILTER:
-        error = "UNSUPPORTEDTEXTUREFILTER";
-        break;
-    case D3DERR_CONFLICTINGTEXTUREPALETTE:
-        error = "CONFLICTINGTEXTUREPALETTE";
-        break;
-    case D3DERR_DRIVERINTERNALERROR:
-        error = "DRIVERINTERNALERROR";
-        break;
-    case D3DERR_NOTFOUND:
-        error = "NOTFOUND";
-        break;
-    case D3DERR_MOREDATA:
-        error = "MOREDATA";
-        break;
-    case D3DERR_DEVICELOST:
-        error = "DEVICELOST";
-        break;
-    case D3DERR_DEVICENOTRESET:
-        error = "DEVICENOTRESET";
-        break;
-    case D3DERR_NOTAVAILABLE:
-        error = "NOTAVAILABLE";
-        break;
-    case D3DERR_OUTOFVIDEOMEMORY:
-        error = "OUTOFVIDEOMEMORY";
-        break;
-    case D3DERR_INVALIDDEVICE:
-        error = "INVALIDDEVICE";
-        break;
-    case D3DERR_INVALIDCALL:
-        error = "INVALIDCALL";
-        break;
-    case D3DERR_DRIVERINVALIDCALL:
-        error = "DRIVERINVALIDCALL";
-        break;
-    case D3DERR_WASSTILLDRAWING:
-        error = "WASSTILLDRAWING";
-        break;
-    default:
-        error = "UNKNOWN";
-        break;
-    }
-    SDL_SetError("%s: %s", prefix, error);
-}
-
-static D3DFORMAT
-PixelFormatToD3DFMT(Uint32 format)
-{
-    switch (format) {
-    case SDL_PIXELFORMAT_RGB565:
-        return D3DFMT_R5G6B5;
-    case SDL_PIXELFORMAT_RGB888:
-        return D3DFMT_X8R8G8B8;
-    case SDL_PIXELFORMAT_ARGB8888:
-        return D3DFMT_A8R8G8B8;
-    default:
-        return D3DFMT_UNKNOWN;
-    }
-}
-
-static Uint32
-D3DFMTToPixelFormat(D3DFORMAT format)
-{
-    switch (format) {
-    case D3DFMT_R5G6B5:
-        return SDL_PIXELFORMAT_RGB565;
-    case D3DFMT_X8R8G8B8:
-        return SDL_PIXELFORMAT_RGB888;
-    case D3DFMT_A8R8G8B8:
-        return SDL_PIXELFORMAT_ARGB8888;
-    default:
-        return SDL_PIXELFORMAT_UNKNOWN;
-    }
-}
-
-SDL_Renderer *
-D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
-{
-    SDL_Renderer *renderer;
-    D3D_RenderData *data;
-    SDL_SysWMinfo windowinfo;
-    HRESULT result;
-    D3DPRESENT_PARAMETERS pparams;
-    IDirect3DSwapChain9 *chain;
-    D3DCAPS9 caps;
-    Uint32 window_flags;
-    int w, h;
-    SDL_DisplayMode fullscreen_mode;
-
-    renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
-    if (!renderer) {
-        SDL_OutOfMemory();
-        return NULL;
-    }
-
-    data = (D3D_RenderData *) SDL_calloc(1, sizeof(*data));
-    if (!data) {
-        SDL_free(renderer);
-        SDL_OutOfMemory();
-        return NULL;
-    }
-
-    data->d3dDLL = SDL_LoadObject("D3D9.DLL");
-    if (data->d3dDLL) {
-        IDirect3D9 *(WINAPI * D3DCreate) (UINT SDKVersion);
-
-        D3DCreate =
-            (IDirect3D9 * (WINAPI *) (UINT)) SDL_LoadFunction(data->d3dDLL,
-                                                            "Direct3DCreate9");
-        if (D3DCreate) {
-            data->d3d = D3DCreate(D3D_SDK_VERSION);
-        }
-        if (!data->d3d) {
-            SDL_UnloadObject(data->d3dDLL);
-            data->d3dDLL = NULL;
-        }
-    }
-    if (!data->d3d) {
-        SDL_free(renderer);
-        SDL_free(data);
-        SDL_SetError("Unable to create Direct3D interface");
-        return NULL;
-    }
-
-    renderer->CreateTexture = D3D_CreateTexture;
-    renderer->UpdateTexture = D3D_UpdateTexture;
-    renderer->LockTexture = D3D_LockTexture;
-    renderer->UnlockTexture = D3D_UnlockTexture;
-    renderer->RenderDrawPoints = D3D_RenderDrawPoints;
-    renderer->RenderDrawLines = D3D_RenderDrawLines;
-    renderer->RenderFillRects = D3D_RenderFillRects;
-    renderer->RenderCopy = D3D_RenderCopy;
-    renderer->RenderReadPixels = D3D_RenderReadPixels;
-    renderer->RenderPresent = D3D_RenderPresent;
-    renderer->DestroyTexture = D3D_DestroyTexture;
-    renderer->DestroyRenderer = D3D_DestroyRenderer;
-    renderer->info = D3D_RenderDriver.info;
-    renderer->driverdata = data;
-
-    renderer->info.flags = SDL_RENDERER_ACCELERATED;
-
-    SDL_VERSION(&windowinfo.version);
-    SDL_GetWindowWMInfo(window, &windowinfo);
-
-    window_flags = SDL_GetWindowFlags(window);
-    SDL_GetWindowSize(window, &w, &h);
-    SDL_GetWindowDisplayMode(window, &fullscreen_mode);
-
-    SDL_zero(pparams);
-    pparams.hDeviceWindow = windowinfo.info.win.window;
-    pparams.BackBufferWidth = w;
-    pparams.BackBufferHeight = h;
-    if (window_flags & SDL_WINDOW_FULLSCREEN) {
-        pparams.BackBufferFormat =
-            PixelFormatToD3DFMT(fullscreen_mode.format);
-    } else {
-        pparams.BackBufferFormat = D3DFMT_UNKNOWN;
-    }
-    pparams.BackBufferCount = 1;
-    pparams.SwapEffect = D3DSWAPEFFECT_DISCARD;
-
-    if (window_flags & SDL_WINDOW_FULLSCREEN) {
-        pparams.Windowed = FALSE;
-        pparams.FullScreen_RefreshRateInHz =
-            fullscreen_mode.refresh_rate;
-    } else {
-        pparams.Windowed = TRUE;
-        pparams.FullScreen_RefreshRateInHz = 0;
-    }
-    if (flags & SDL_RENDERER_PRESENTVSYNC) {
-        pparams.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
-    } else {
-        pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
-    }
-
-    /* FIXME: Which adapter? */
-    data->adapter = D3DADAPTER_DEFAULT;
-    IDirect3D9_GetDeviceCaps(data->d3d, data->adapter, D3DDEVTYPE_HAL, &caps);
-
-    result = IDirect3D9_CreateDevice(data->d3d, data->adapter,
-                                     D3DDEVTYPE_HAL,
-                                     pparams.hDeviceWindow,
-                                     (caps.
-                                      DevCaps &
-                                      D3DDEVCAPS_HWTRANSFORMANDLIGHT) ?
-                                     D3DCREATE_HARDWARE_VERTEXPROCESSING :
-                                     D3DCREATE_SOFTWARE_VERTEXPROCESSING,
-                                     &pparams, &data->device);
-    if (FAILED(result)) {
-        D3D_DestroyRenderer(renderer);
-        D3D_SetError("CreateDevice()", result);
-        return NULL;
-    }
-    data->beginScene = SDL_TRUE;
-
-    /* Get presentation parameters to fill info */
-    result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain);
-    if (FAILED(result)) {
-        D3D_DestroyRenderer(renderer);
-        D3D_SetError("GetSwapChain()", result);
-        return NULL;
-    }
-    result = IDirect3DSwapChain9_GetPresentParameters(chain, &pparams);
-    if (FAILED(result)) {
-        IDirect3DSwapChain9_Release(chain);
-        D3D_DestroyRenderer(renderer);
-        D3D_SetError("GetPresentParameters()", result);
-        return NULL;
-    }
-    IDirect3DSwapChain9_Release(chain);
-    if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) {
-        renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
-    }
-    data->pparams = pparams;
-
-    IDirect3DDevice9_GetDeviceCaps(data->device, &caps);
-    renderer->info.max_texture_width = caps.MaxTextureWidth;
-    renderer->info.max_texture_height = caps.MaxTextureHeight;
-
-    /* Set up parameters for rendering */
-    IDirect3DDevice9_SetVertexShader(data->device, NULL);
-    IDirect3DDevice9_SetFVF(data->device,
-                            D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
-    IDirect3DDevice9_SetRenderState(data->device, D3DRS_ZENABLE, D3DZB_FALSE);
-    IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE,
-                                    D3DCULL_NONE);
-    IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE);
-    /* Enable color modulation by diffuse color */
-    IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLOROP,
-                                          D3DTOP_MODULATE);
-    IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG1,
-                                          D3DTA_TEXTURE);
-    IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG2,
-                                          D3DTA_DIFFUSE);
-    /* Enable alpha modulation by diffuse alpha */
-    IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAOP,
-                                          D3DTOP_MODULATE);
-    IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG1,
-                                          D3DTA_TEXTURE);
-    IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG2,
-                                          D3DTA_DIFFUSE);
-    /* Disable second texture stage, since we're done */
-    IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_COLOROP,
-                                          D3DTOP_DISABLE);
-    IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_ALPHAOP,
-                                          D3DTOP_DISABLE);
-
-    return renderer;
-}
-
-static int
-D3D_Reset(SDL_Renderer * renderer)
-{
-    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
-    HRESULT result;
-
-    result = IDirect3DDevice9_Reset(data->device, &data->pparams);
-    if (FAILED(result)) {
-        if (result == D3DERR_DEVICELOST) {
-            /* Don't worry about it, we'll reset later... */
-            return 0;
-        } else {
-            D3D_SetError("Reset()", result);
-            return -1;
-        }
-    }
-    IDirect3DDevice9_SetVertexShader(data->device, NULL);
-    IDirect3DDevice9_SetFVF(data->device,
-                            D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
-    IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE,
-                                    D3DCULL_NONE);
-    IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE);
-    return 0;
-}
-
-/* FIXME: This needs to be called... when? */
-#if 0
-static int
-D3D_DisplayModeChanged(SDL_Renderer * renderer)
-{
-    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
-    SDL_Window *window = renderer->window;
-    SDL_VideoDisplay *display = window->display;
-
-    data->pparams.BackBufferWidth = window->w;
-    data->pparams.BackBufferHeight = window->h;
-    if (window->flags & SDL_WINDOW_FULLSCREEN) {
-        data->pparams.BackBufferFormat =
-            PixelFormatToD3DFMT(window->fullscreen_mode.format);
-    } else {
-        data->pparams.BackBufferFormat = D3DFMT_UNKNOWN;
-    }
-    return D3D_Reset(renderer);
-}
-#endif
-
-static int
-D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
-{
-    D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata;
-    SDL_Window *window = renderer->window;
-    D3DFORMAT display_format = renderdata->pparams.BackBufferFormat;
-    D3D_TextureData *data;
-    D3DPOOL pool;
-    DWORD usage;
-    HRESULT result;
-
-    data = (D3D_TextureData *) SDL_calloc(1, sizeof(*data));
-    if (!data) {
-        SDL_OutOfMemory();
-        return -1;
-    }
-
-    texture->driverdata = data;
-
-#ifdef USE_DYNAMIC_TEXTURE
-    if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
-        pool = D3DPOOL_DEFAULT;
-        usage = D3DUSAGE_DYNAMIC;
-    } else
-#endif
-    {
-        pool = D3DPOOL_MANAGED;
-        usage = 0;
-    }
-
-    result =
-        IDirect3DDevice9_CreateTexture(renderdata->device, texture->w,
-                                       texture->h, 1, usage,
-                                       PixelFormatToD3DFMT(texture->format),
-                                       pool, &data->texture, NULL);
-    if (FAILED(result)) {
-        D3D_SetError("CreateTexture()", result);
-        return -1;
-    }
-
-    return 0;
-}
-
-static int
-D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
-                  const SDL_Rect * rect, const void *pixels, int pitch)
-{
-    D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
-    D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata;
-    RECT d3drect;
-    D3DLOCKED_RECT locked;
-    const Uint8 *src;
-    Uint8 *dst;
-    int row, length;
-    HRESULT result;
-
-#ifdef USE_DYNAMIC_TEXTURE
-    if (texture->access == SDL_TEXTUREACCESS_STREAMING &&
-        rect->x == 0 && rect->y == 0 &&
-        rect->w == texture->w && rect->h == texture->h) {
-        result = IDirect3DTexture9_LockRect(data->texture, 0, &locked, NULL, D3DLOCK_DISCARD);
-    } else
-#endif
-    {
-        d3drect.left = rect->x;
-        d3drect.right = rect->x + rect->w;
-        d3drect.top = rect->y;
-        d3drect.bottom = rect->y + rect->h;
-        result = IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect, 0);
-    }
-
-    if (FAILED(result)) {
-        D3D_SetError("LockRect()", result);
-        return -1;
-    }
-
-    src = pixels;
-    dst = locked.pBits;
-    length = rect->w * SDL_BYTESPERPIXEL(texture->format);
-    if (length == pitch && length == locked.Pitch) {
-        SDL_memcpy(dst, src, length*rect->h);
-    } else {
-        for (row = 0; row < rect->h; ++row) {
-            SDL_memcpy(dst, src, length);
-            src += pitch;
-            dst += locked.Pitch;
-        }
-    }
-    IDirect3DTexture9_UnlockRect(data->texture, 0);
-
-    return 0;
-}
-
-static int
-D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
-                const SDL_Rect * rect, void **pixels, int *pitch)
-{
-    D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
-    RECT d3drect;
-    D3DLOCKED_RECT locked;
-    HRESULT result;
-
-    d3drect.left = rect->x;
-    d3drect.right = rect->x + rect->w;
-    d3drect.top = rect->y;
-    d3drect.bottom = rect->y + rect->h;
-
-    result = IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect, 0);
-    if (FAILED(result)) {
-        D3D_SetError("LockRect()", result);
-        return -1;
-    }
-    *pixels = locked.pBits;
-    *pitch = locked.Pitch;
-    return 0;
-}
-
-static void
-D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
-{
-    D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
-
-    IDirect3DTexture9_UnlockRect(data->texture, 0);
-}
-
-static void
-D3D_SetBlendMode(D3D_RenderData * data, int blendMode)
-{
-    switch (blendMode) {
-    case SDL_BLENDMODE_NONE:
-        IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE,
-                                        FALSE);
-        break;
-    case SDL_BLENDMODE_BLEND:
-        IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE,
-                                        TRUE);
-        IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLEND,
-                                        D3DBLEND_SRCALPHA);
-        IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
-                                        D3DBLEND_INVSRCALPHA);
-        break;
-    case SDL_BLENDMODE_ADD:
-        IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE,
-                                        TRUE);
-        IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLEND,
-                                        D3DBLEND_SRCALPHA);
-        IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
-                                        D3DBLEND_ONE);
-        break;
-    case SDL_BLENDMODE_MOD:
-        IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE,
-                                        TRUE);
-        IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLEND,
-                                        D3DBLEND_ZERO);
-        IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
-                                        D3DBLEND_SRCCOLOR);
-        break;
-    }
-}
-
-static int
-D3D_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
-                     int count)
-{
-    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
-    DWORD color;
-    Vertex *vertices;
-    int i;
-    HRESULT result;
-
-    if (data->beginScene) {
-        IDirect3DDevice9_BeginScene(data->device);
-        data->beginScene = SDL_FALSE;
-    }
-
-    D3D_SetBlendMode(data, renderer->blendMode);
-
-    result =
-        IDirect3DDevice9_SetTexture(data->device, 0,
-                                    (IDirect3DBaseTexture9 *) 0);
-    if (FAILED(result)) {
-        D3D_SetError("SetTexture()", result);
-        return -1;
-    }
-
-    color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b);
-
-    vertices = SDL_stack_alloc(Vertex, count);
-    for (i = 0; i < count; ++i) {
-        vertices[i].x = (float) points[i].x;
-        vertices[i].y = (float) points[i].y;
-        vertices[i].z = 0.0f;
-        vertices[i].rhw = 1.0f;
-        vertices[i].color = color;
-        vertices[i].u = 0.0f;
-        vertices[i].v = 0.0f;
-    }
-    result =
-        IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_POINTLIST, count,
-                                         vertices, sizeof(*vertices));
-    SDL_stack_free(vertices);
-    if (FAILED(result)) {
-        D3D_SetError("DrawPrimitiveUP()", result);
-        return -1;
-    }
-    return 0;
-}
-
-static int
-D3D_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
-                    int count)
-{
-    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
-    DWORD color;
-    Vertex *vertices;
-    int i;
-    HRESULT result;
-
-    if (data->beginScene) {
-        IDirect3DDevice9_BeginScene(data->device);
-        data->beginScene = SDL_FALSE;
-    }
-
-    D3D_SetBlendMode(data, renderer->blendMode);
-
-    result =
-        IDirect3DDevice9_SetTexture(data->device, 0,
-                                    (IDirect3DBaseTexture9 *) 0);
-    if (FAILED(result)) {
-        D3D_SetError("SetTexture()", result);
-        return -1;
-    }
-
-    color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b);
-
-    vertices = SDL_stack_alloc(Vertex, count);
-    for (i = 0; i < count; ++i) {
-        vertices[i].x = (float) points[i].x;
-        vertices[i].y = (float) points[i].y;
-        vertices[i].z = 0.0f;
-        vertices[i].rhw = 1.0f;
-        vertices[i].color = color;
-        vertices[i].u = 0.0f;
-        vertices[i].v = 0.0f;
-    }
-    result =
-        IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_LINESTRIP, count-1,
-                                         vertices, sizeof(*vertices));
-
-    /* DirectX 9 has the same line rasterization semantics as GDI,
-       so we need to close the endpoint of the line */
-    if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) {
-        vertices[0].x = (float) points[count-1].x;
-        vertices[0].y = (float) points[count-1].y;
-        result = IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_POINTLIST, 1, vertices, sizeof(*vertices));
-    }
-
-    SDL_stack_free(vertices);
-    if (FAILED(result)) {
-        D3D_SetError("DrawPrimitiveUP()", result);
-        return -1;
-    }
-    return 0;
-}
-
-static int
-D3D_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
-                    int count)
-{
-    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
-    DWORD color;
-    int i;
-    float minx, miny, maxx, maxy;
-    Vertex vertices[4];
-    HRESULT result;
-
-    if (data->beginScene) {
-        IDirect3DDevice9_BeginScene(data->device);
-        data->beginScene = SDL_FALSE;
-    }
-
-    D3D_SetBlendMode(data, renderer->blendMode);
-
-    result =
-        IDirect3DDevice9_SetTexture(data->device, 0,
-                                    (IDirect3DBaseTexture9 *) 0);
-    if (FAILED(result)) {
-        D3D_SetError("SetTexture()", result);
-        return -1;
-    }
-
-    color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b);
-
-    for (i = 0; i < count; ++i) {
-        const SDL_Rect *rect = rects[i];
-
-        minx = (float) rect->x;
-        miny = (float) rect->y;
-        maxx = (float) rect->x + rect->w;
-        maxy = (float) rect->y + rect->h;
-
-        vertices[0].x = minx;
-        vertices[0].y = miny;
-        vertices[0].z = 0.0f;
-        vertices[0].rhw = 1.0f;
-        vertices[0].color = color;
-        vertices[0].u = 0.0f;
-        vertices[0].v = 0.0f;
-
-        vertices[1].x = maxx;
-        vertices[1].y = miny;
-        vertices[1].z = 0.0f;
-        vertices[1].rhw = 1.0f;
-        vertices[1].color = color;
-        vertices[1].u = 0.0f;
-        vertices[1].v = 0.0f;
-
-        vertices[2].x = maxx;
-        vertices[2].y = maxy;
-        vertices[2].z = 0.0f;
-        vertices[2].rhw = 1.0f;
-        vertices[2].color = color;
-        vertices[2].u = 0.0f;
-        vertices[2].v = 0.0f;
-
-        vertices[3].x = minx;
-        vertices[3].y = maxy;
-        vertices[3].z = 0.0f;
-        vertices[3].rhw = 1.0f;
-        vertices[3].color = color;
-        vertices[3].u = 0.0f;
-        vertices[3].v = 0.0f;
-
-        result =
-            IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN,
-                                             2, vertices, sizeof(*vertices));
-        if (FAILED(result)) {
-            D3D_SetError("DrawPrimitiveUP()", result);
-            return -1;
-        }
-    }
-    return 0;
-}
-
-static int
-D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
-               const SDL_Rect * srcrect, const SDL_Rect * dstrect)
-{
-    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
-    D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata;
-    LPDIRECT3DPIXELSHADER9 shader = NULL;
-    float minx, miny, maxx, maxy;
-    float minu, maxu, minv, maxv;
-    DWORD color;
-    Vertex vertices[4];
-    HRESULT result;
-
-    if (data->beginScene) {
-        IDirect3DDevice9_BeginScene(data->device);
-        data->beginScene = SDL_FALSE;
-    }
-
-    minx = (float) dstrect->x - 0.5f;
-    miny = (float) dstrect->y - 0.5f;
-    maxx = (float) dstrect->x + dstrect->w - 0.5f;
-    maxy = (float) dstrect->y + dstrect->h - 0.5f;
-
-    minu = (float) srcrect->x / texture->w;
-    maxu = (float) (srcrect->x + srcrect->w) / texture->w;
-    minv = (float) srcrect->y / texture->h;
-    maxv = (float) (srcrect->y + srcrect->h) / texture->h;
-
-    color = D3DCOLOR_ARGB(texture->a, texture->r, texture->g, texture->b);
-
-    vertices[0].x = minx;
-    vertices[0].y = miny;
-    vertices[0].z = 0.0f;
-    vertices[0].rhw = 1.0f;
-    vertices[0].color = color;
-    vertices[0].u = minu;
-    vertices[0].v = minv;
-
-    vertices[1].x = maxx;
-    vertices[1].y = miny;
-    vertices[1].z = 0.0f;
-    vertices[1].rhw = 1.0f;
-    vertices[1].color = color;
-    vertices[1].u = maxu;
-    vertices[1].v = minv;
-
-    vertices[2].x = maxx;
-    vertices[2].y = maxy;
-    vertices[2].z = 0.0f;
-    vertices[2].rhw = 1.0f;
-    vertices[2].color = color;
-    vertices[2].u = maxu;
-    vertices[2].v = maxv;
-
-    vertices[3].x = minx;
-    vertices[3].y = maxy;
-    vertices[3].z = 0.0f;
-    vertices[3].rhw = 1.0f;
-    vertices[3].color = color;
-    vertices[3].u = minu;
-    vertices[3].v = maxv;
-
-    D3D_SetBlendMode(data, texture->blendMode);
-
-    IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MINFILTER,
-                                     D3DTEXF_LINEAR);
-    IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MAGFILTER,
-                                     D3DTEXF_LINEAR);
-
-    result =
-        IDirect3DDevice9_SetTexture(data->device, 0, (IDirect3DBaseTexture9 *)
-                                    texturedata->texture);
-    if (FAILED(result)) {
-        D3D_SetError("SetTexture()", result);
-        return -1;
-    }
-    if (shader) {
-        result = IDirect3DDevice9_SetPixelShader(data->device, shader);
-        if (FAILED(result)) {
-            D3D_SetError("SetShader()", result);
-            return -1;
-        }
-    }
-    result =
-        IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2,
-                                         vertices, sizeof(*vertices));
-    if (FAILED(result)) {
-        D3D_SetError("DrawPrimitiveUP()", result);
-        return -1;
-    }
-    if (shader) {
-        result = IDirect3DDevice9_SetPixelShader(data->device, NULL);
-        if (FAILED(result)) {
-            D3D_SetError("SetShader()", result);
-            return -1;
-        }
-    }
-    return 0;
-}
-
-static int
-D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
-                     Uint32 format, void * pixels, int pitch)
-{
-    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
-    D3DSURFACE_DESC desc;
-    LPDIRECT3DSURFACE9 backBuffer;
-    LPDIRECT3DSURFACE9 surface;
-    RECT d3drect;
-    D3DLOCKED_RECT locked;
-    HRESULT result;
-
-    result = IDirect3DDevice9_GetBackBuffer(data->device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer);
-    if (FAILED(result)) {
-        D3D_SetError("GetBackBuffer()", result);
-        return -1;
-    }
-
-    result = IDirect3DSurface9_GetDesc(backBuffer, &desc);
-    if (FAILED(result)) {
-        D3D_SetError("GetDesc()", result);
-        IDirect3DSurface9_Release(backBuffer);
-        return -1;
-    }
-
-    result = IDirect3DDevice9_CreateOffscreenPlainSurface(data->device, desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surface, NULL);
-    if (FAILED(result)) {
-        D3D_SetError("CreateOffscreenPlainSurface()", result);
-        IDirect3DSurface9_Release(backBuffer);
-        return -1;
-    }
-
-    result = IDirect3DDevice9_GetRenderTargetData(data->device, backBuffer, surface);
-    if (FAILED(result)) {
-        D3D_SetError("GetRenderTargetData()", result);
-        IDirect3DSurface9_Release(surface);
-        IDirect3DSurface9_Release(backBuffer);
-        return -1;
-    }
-
-    d3drect.left = rect->x;
-    d3drect.right = rect->x + rect->w;
-    d3drect.top = rect->y;
-    d3drect.bottom = rect->y + rect->h;
-
-    result = IDirect3DSurface9_LockRect(surface, &locked, &d3drect, D3DLOCK_READONLY);
-    if (FAILED(result)) {
-        D3D_SetError("LockRect()", result);
-        IDirect3DSurface9_Release(surface);
-        IDirect3DSurface9_Release(backBuffer);
-        return -1;
-    }
-
-    SDL_ConvertPixels(rect->w, rect->h,
-                      D3DFMTToPixelFormat(desc.Format), locked.pBits, locked.Pitch,
-                      format, pixels, pitch);
-
-    IDirect3DSurface9_UnlockRect(surface);
-
-    IDirect3DSurface9_Release(surface);
-    IDirect3DSurface9_Release(backBuffer);
-
-    return 0;
-}
-
-static void
-D3D_RenderPresent(SDL_Renderer * renderer)
-{
-    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
-    HRESULT result;
-
-    if (!data->beginScene) {
-        IDirect3DDevice9_EndScene(data->device);
-        data->beginScene = SDL_TRUE;
-    }
-
-    result = IDirect3DDevice9_TestCooperativeLevel(data->device);
-    if (result == D3DERR_DEVICELOST) {
-        /* We'll reset later */
-        return;
-    }
-    if (result == D3DERR_DEVICENOTRESET) {
-        D3D_Reset(renderer);
-    }
-    result = IDirect3DDevice9_Present(data->device, NULL, NULL, NULL, NULL);
-    if (FAILED(result)) {
-        D3D_SetError("Present()", result);
-    }
-}
-
-static void
-D3D_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
-{
-    D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
-
-    if (!data) {
-        return;
-    }
-    if (data->texture) {
-        IDirect3DTexture9_Release(data->texture);
-    }
-    SDL_free(data);
-    texture->driverdata = NULL;
-}
-
-static void
-D3D_DestroyRenderer(SDL_Renderer * renderer)
-{
-    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
-
-    if (data) {
-        if (data->device) {
-            IDirect3DDevice9_Release(data->device);
-        }
-        if (data->d3d) {
-            IDirect3D9_Release(data->d3d);
-            SDL_UnloadObject(data->d3dDLL);
-        }
-        SDL_free(data);
-    }
-    SDL_free(renderer);
-}
-
-#endif /* SDL_VIDEO_RENDER_D3D */
-
-/* vi: set ts=4 sw=4 expandtab: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/render/direct3d/SDL_render_d3d.c	Sat Feb 05 12:01:11 2011 -0800
@@ -0,0 +1,1048 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2010 Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+#if SDL_VIDEO_RENDER_D3D
+
+#include "../../core/windows/SDL_windows.h"
+
+#include "SDL_loadso.h"
+#include "SDL_syswm.h"
+#include "../SDL_sysrender.h"
+
+#if SDL_VIDEO_RENDER_D3D
+#define D3D_DEBUG_INFO
+#include <d3d9.h>
+#endif
+
+#ifdef ASSEMBLE_SHADER
+///////////////////////////////////////////////////////////////////////////
+// ID3DXBuffer:
+// ------------
+// The buffer object is used by D3DX to return arbitrary size data.
+//
+// GetBufferPointer -
+//    Returns a pointer to the beginning of the buffer.
+//
+// GetBufferSize -
+//    Returns the size of the buffer, in bytes.
+///////////////////////////////////////////////////////////////////////////
+
+typedef interface ID3DXBuffer ID3DXBuffer;
+typedef interface ID3DXBuffer *LPD3DXBUFFER;
+
+// {8BA5FB08-5195-40e2-AC58-0D989C3A0102}
+DEFINE_GUID(IID_ID3DXBuffer, 
+0x8ba5fb08, 0x5195, 0x40e2, 0xac, 0x58, 0xd, 0x98, 0x9c, 0x3a, 0x1, 0x2);
+
+#undef INTERFACE
+#define INTERFACE ID3DXBuffer
+
+typedef interface ID3DXBuffer {
+    const struct ID3DXBufferVtbl FAR* lpVtbl;
+} ID3DXBuffer;
+typedef const struct ID3DXBufferVtbl ID3DXBufferVtbl;
+const struct ID3DXBufferVtbl
+{
+    // IUnknown
+    STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+
+    // ID3DXBuffer
+    STDMETHOD_(LPVOID, GetBufferPointer)(THIS) PURE;
+    STDMETHOD_(DWORD, GetBufferSize)(THIS) PURE;
+};
+
+HRESULT WINAPI
+    D3DXAssembleShader(
+        LPCSTR                          pSrcData,
+        UINT                            SrcDataLen,
+        CONST LPVOID*                   pDefines,
+        LPVOID                          pInclude,
+        DWORD                           Flags,
+        LPD3DXBUFFER*                   ppShader,
+        LPD3DXBUFFER*                   ppErrorMsgs);
+
+#endif /* ASSEMBLE_SHADER */
+
+
+/* Direct3D renderer implementation */
+
+static SDL_Renderer *D3D_CreateRenderer(SDL_Window * window, Uint32 flags);
+static int D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
+static int D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+                             const SDL_Rect * rect, const void *pixels,
+                             int pitch);
+static int D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+                           const SDL_Rect * rect, void **pixels, int *pitch);
+static void D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
+static int D3D_RenderDrawPoints(SDL_Renderer * renderer,
+                                const SDL_Point * points, int count);
+static int D3D_RenderDrawLines(SDL_Renderer * renderer,
+                               const SDL_Point * points, int count);
+static int D3D_RenderFillRects(SDL_Renderer * renderer,
+                               const SDL_Rect ** rects, int count);
+static int D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
+                          const SDL_Rect * srcrect, const SDL_Rect * dstrect);
+static int D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+                                Uint32 format, void * pixels, int pitch);
+static void D3D_RenderPresent(SDL_Renderer * renderer);
+static void D3D_DestroyTexture(SDL_Renderer * renderer,
+                               SDL_Texture * texture);
+static void D3D_DestroyRenderer(SDL_Renderer * renderer);
+
+
+SDL_RenderDriver D3D_RenderDriver = {
+    D3D_CreateRenderer,
+    {
+     "direct3d",
+     (SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED),
+     1,
+     {SDL_PIXELFORMAT_ARGB8888},
+     0,
+     0}
+};
+
+typedef struct
+{
+    void* d3dDLL;
+    IDirect3D9 *d3d;
+    IDirect3DDevice9 *device;
+    UINT adapter;
+    D3DPRESENT_PARAMETERS pparams;
+    SDL_bool beginScene;
+} D3D_RenderData;
+
+typedef struct
+{
+    IDirect3DTexture9 *texture;
+} D3D_TextureData;
+
+typedef struct
+{
+    float x, y, z;
+    float rhw;
+    DWORD color;
+    float u, v;
+} Vertex;
+
+static void
+D3D_SetError(const char *prefix, HRESULT result)
+{
+    const char *error;
+
+    switch (result) {
+    case D3DERR_WRONGTEXTUREFORMAT:
+        error = "WRONGTEXTUREFORMAT";
+        break;
+    case D3DERR_UNSUPPORTEDCOLOROPERATION:
+        error = "UNSUPPORTEDCOLOROPERATION";
+        break;
+    case D3DERR_UNSUPPORTEDCOLORARG:
+        error = "UNSUPPORTEDCOLORARG";
+        break;
+    case D3DERR_UNSUPPORTEDALPHAOPERATION:
+        error = "UNSUPPORTEDALPHAOPERATION";
+        break;
+    case D3DERR_UNSUPPORTEDALPHAARG:
+        error = "UNSUPPORTEDALPHAARG";
+        break;
+    case D3DERR_TOOMANYOPERATIONS:
+        error = "TOOMANYOPERATIONS";
+        break;
+    case D3DERR_CONFLICTINGTEXTUREFILTER:
+        error = "CONFLICTINGTEXTUREFILTER";
+        break;
+    case D3DERR_UNSUPPORTEDFACTORVALUE:
+        error = "UNSUPPORTEDFACTORVALUE";
+        break;
+    case D3DERR_CONFLICTINGRENDERSTATE:
+        error = "CONFLICTINGRENDERSTATE";
+        break;
+    case D3DERR_UNSUPPORTEDTEXTUREFILTER:
+        error = "UNSUPPORTEDTEXTUREFILTER";
+        break;
+    case D3DERR_CONFLICTINGTEXTUREPALETTE:
+        error = "CONFLICTINGTEXTUREPALETTE";
+        break;
+    case D3DERR_DRIVERINTERNALERROR:
+        error = "DRIVERINTERNALERROR";
+        break;
+    case D3DERR_NOTFOUND:
+        error = "NOTFOUND";
+        break;
+    case D3DERR_MOREDATA:
+        error = "MOREDATA";
+        break;
+    case D3DERR_DEVICELOST:
+        error = "DEVICELOST";
+        break;
+    case D3DERR_DEVICENOTRESET:
+        error = "DEVICENOTRESET";
+        break;
+    case D3DERR_NOTAVAILABLE:
+        error = "NOTAVAILABLE";
+        break;
+    case D3DERR_OUTOFVIDEOMEMORY:
+        error = "OUTOFVIDEOMEMORY";
+        break;
+    case D3DERR_INVALIDDEVICE:
+        error = "INVALIDDEVICE";
+        break;
+    case D3DERR_INVALIDCALL:
+        error = "INVALIDCALL";
+        break;
+    case D3DERR_DRIVERINVALIDCALL:
+        error = "DRIVERINVALIDCALL";
+        break;
+    case D3DERR_WASSTILLDRAWING:
+        error = "WASSTILLDRAWING";
+        break;
+    default:
+        error = "UNKNOWN";
+        break;
+    }
+    SDL_SetError("%s: %s", prefix, error);
+}
+
+static D3DFORMAT
+PixelFormatToD3DFMT(Uint32 format)
+{
+    switch (format) {
+    case SDL_PIXELFORMAT_RGB565:
+        return D3DFMT_R5G6B5;
+    case SDL_PIXELFORMAT_RGB888:
+        return D3DFMT_X8R8G8B8;
+    case SDL_PIXELFORMAT_ARGB8888:
+        return D3DFMT_A8R8G8B8;
+    default:
+        return D3DFMT_UNKNOWN;
+    }
+}
+
+static Uint32
+D3DFMTToPixelFormat(D3DFORMAT format)
+{
+    switch (format) {
+    case D3DFMT_R5G6B5:
+        return SDL_PIXELFORMAT_RGB565;
+    case D3DFMT_X8R8G8B8:
+        return SDL_PIXELFORMAT_RGB888;
+    case D3DFMT_A8R8G8B8:
+        return SDL_PIXELFORMAT_ARGB8888;
+    default:
+        return SDL_PIXELFORMAT_UNKNOWN;
+    }
+}
+
+SDL_Renderer *
+D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
+{
+    SDL_Renderer *renderer;
+    D3D_RenderData *data;
+    SDL_SysWMinfo windowinfo;
+    HRESULT result;
+    D3DPRESENT_PARAMETERS pparams;
+    IDirect3DSwapChain9 *chain;
+    D3DCAPS9 caps;
+    Uint32 window_flags;
+    int w, h;
+    SDL_DisplayMode fullscreen_mode;
+
+    renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
+    if (!renderer) {
+        SDL_OutOfMemory();
+        return NULL;
+    }
+
+    data = (D3D_RenderData *) SDL_calloc(1, sizeof(*data));
+    if (!data) {
+        SDL_free(renderer);
+        SDL_OutOfMemory();
+        return NULL;
+    }
+
+    data->d3dDLL = SDL_LoadObject("D3D9.DLL");
+    if (data->d3dDLL) {
+        IDirect3D9 *(WINAPI * D3DCreate) (UINT SDKVersion);
+
+        D3DCreate =
+            (IDirect3D9 * (WINAPI *) (UINT)) SDL_LoadFunction(data->d3dDLL,
+                                                            "Direct3DCreate9");
+        if (D3DCreate) {
+            data->d3d = D3DCreate(D3D_SDK_VERSION);
+        }
+        if (!data->d3d) {
+            SDL_UnloadObject(data->d3dDLL);
+            data->d3dDLL = NULL;
+        }
+    }
+    if (!data->d3d) {
+        SDL_free(renderer);
+        SDL_free(data);
+        SDL_SetError("Unable to create Direct3D interface");
+        return NULL;
+    }
+
+    renderer->CreateTexture = D3D_CreateTexture;
+    renderer->UpdateTexture = D3D_UpdateTexture;
+    renderer->LockTexture = D3D_LockTexture;
+    renderer->UnlockTexture = D3D_UnlockTexture;
+    renderer->RenderDrawPoints = D3D_RenderDrawPoints;
+    renderer->RenderDrawLines = D3D_RenderDrawLines;
+    renderer->RenderFillRects = D3D_RenderFillRects;
+    renderer->RenderCopy = D3D_RenderCopy;
+    renderer->RenderReadPixels = D3D_RenderReadPixels;
+    renderer->RenderPresent = D3D_RenderPresent;
+    renderer->DestroyTexture = D3D_DestroyTexture;
+    renderer->DestroyRenderer = D3D_DestroyRenderer;
+    renderer->info = D3D_RenderDriver.info;
+    renderer->driverdata = data;
+
+    renderer->info.flags = SDL_RENDERER_ACCELERATED;
+
+    SDL_VERSION(&windowinfo.version);
+    SDL_GetWindowWMInfo(window, &windowinfo);
+
+    window_flags = SDL_GetWindowFlags(window);
+    SDL_GetWindowSize(window, &w, &h);
+    SDL_GetWindowDisplayMode(window, &fullscreen_mode);
+
+    SDL_zero(pparams);
+    pparams.hDeviceWindow = windowinfo.info.win.window;
+    pparams.BackBufferWidth = w;
+    pparams.BackBufferHeight = h;
+    if (window_flags & SDL_WINDOW_FULLSCREEN) {
+        pparams.BackBufferFormat =
+            PixelFormatToD3DFMT(fullscreen_mode.format);
+    } else {
+        pparams.BackBufferFormat = D3DFMT_UNKNOWN;
+    }
+    pparams.BackBufferCount = 1;
+    pparams.SwapEffect = D3DSWAPEFFECT_DISCARD;
+
+    if (window_flags & SDL_WINDOW_FULLSCREEN) {
+        pparams.Windowed = FALSE;
+        pparams.FullScreen_RefreshRateInHz =
+            fullscreen_mode.refresh_rate;
+    } else {
+        pparams.Windowed = TRUE;
+        pparams.FullScreen_RefreshRateInHz = 0;
+    }
+    if (flags & SDL_RENDERER_PRESENTVSYNC) {
+        pparams.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
+    } else {
+        pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
+    }
+
+    /* FIXME: Which adapter? */
+    data->adapter = D3DADAPTER_DEFAULT;
+    IDirect3D9_GetDeviceCaps(data->d3d, data->adapter, D3DDEVTYPE_HAL, &caps);
+
+    result = IDirect3D9_CreateDevice(data->d3d, data->adapter,
+                                     D3DDEVTYPE_HAL,
+                                     pparams.hDeviceWindow,
+                                     (caps.
+                                      DevCaps &
+                                      D3DDEVCAPS_HWTRANSFORMANDLIGHT) ?
+                                     D3DCREATE_HARDWARE_VERTEXPROCESSING :
+                                     D3DCREATE_SOFTWARE_VERTEXPROCESSING,
+                                     &pparams, &data->device);
+    if (FAILED(result)) {
+        D3D_DestroyRenderer(renderer);
+        D3D_SetError("CreateDevice()", result);
+        return NULL;
+    }
+    data->beginScene = SDL_TRUE;
+
+    /* Get presentation parameters to fill info */
+    result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain);
+    if (FAILED(result)) {
+        D3D_DestroyRenderer(renderer);
+        D3D_SetError("GetSwapChain()", result);
+        return NULL;
+    }
+    result = IDirect3DSwapChain9_GetPresentParameters(chain, &pparams);
+    if (FAILED(result)) {
+        IDirect3DSwapChain9_Release(chain);
+        D3D_DestroyRenderer(renderer);
+        D3D_SetError("GetPresentParameters()", result);
+        return NULL;
+    }
+    IDirect3DSwapChain9_Release(chain);
+    if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) {
+        renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
+    }
+    data->pparams = pparams;
+
+    IDirect3DDevice9_GetDeviceCaps(data->device, &caps);
+    renderer->info.max_texture_width = caps.MaxTextureWidth;
+    renderer->info.max_texture_height = caps.MaxTextureHeight;
+
+    /* Set up parameters for rendering */
+    IDirect3DDevice9_SetVertexShader(data->device, NULL);
+    IDirect3DDevice9_SetFVF(data->device,
+                            D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
+    IDirect3DDevice9_SetRenderState(data->device, D3DRS_ZENABLE, D3DZB_FALSE);
+    IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE,
+                                    D3DCULL_NONE);
+    IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE);
+    /* Enable color modulation by diffuse color */
+    IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLOROP,
+                                          D3DTOP_MODULATE);
+    IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG1,
+                                          D3DTA_TEXTURE);
+    IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG2,
+                                          D3DTA_DIFFUSE);
+    /* Enable alpha modulation by diffuse alpha */
+    IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAOP,
+                                          D3DTOP_MODULATE);
+    IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG1,
+                                          D3DTA_TEXTURE);
+    IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG2,
+                                          D3DTA_DIFFUSE);
+    /* Disable second texture stage, since we're done */
+    IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_COLOROP,
+                                          D3DTOP_DISABLE);
+    IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_ALPHAOP,
+                                          D3DTOP_DISABLE);
+
+    return renderer;
+}
+
+static int
+D3D_Reset(SDL_Renderer * renderer)
+{
+    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
+    HRESULT result;
+
+    result = IDirect3DDevice9_Reset(data->device, &data->pparams);
+    if (FAILED(result)) {
+        if (result == D3DERR_DEVICELOST) {
+            /* Don't worry about it, we'll reset later... */
+            return 0;
+        } else {
+            D3D_SetError("Reset()", result);
+            return -1;
+        }
+    }
+    IDirect3DDevice9_SetVertexShader(data->device, NULL);
+    IDirect3DDevice9_SetFVF(data->device,
+                            D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
+    IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE,
+                                    D3DCULL_NONE);
+    IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE);
+    return 0;
+}
+
+/* FIXME: This needs to be called... when? */
+#if 0
+static int
+D3D_DisplayModeChanged(SDL_Renderer * renderer)
+{
+    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
+    SDL_Window *window = renderer->window;
+    SDL_VideoDisplay *display = window->display;
+
+    data->pparams.BackBufferWidth = window->w;
+    data->pparams.BackBufferHeight = window->h;
+    if (window->flags & SDL_WINDOW_FULLSCREEN) {
+        data->pparams.BackBufferFormat =
+            PixelFormatToD3DFMT(window->fullscreen_mode.format);
+    } else {
+        data->pparams.BackBufferFormat = D3DFMT_UNKNOWN;
+    }
+    return D3D_Reset(renderer);
+}
+#endif
+
+static int
+D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+    D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata;
+    SDL_Window *window = renderer->window;
+    D3DFORMAT display_format = renderdata->pparams.BackBufferFormat;
+    D3D_TextureData *data;
+    D3DPOOL pool;
+    DWORD usage;
+    HRESULT result;
+
+    data = (D3D_TextureData *) SDL_calloc(1, sizeof(*data));
+    if (!data) {
+        SDL_OutOfMemory();
+        return -1;
+    }
+
+    texture->driverdata = data;
+
+#ifdef USE_DYNAMIC_TEXTURE
+    if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
+        pool = D3DPOOL_DEFAULT;
+        usage = D3DUSAGE_DYNAMIC;
+    } else
+#endif
+    {
+        pool = D3DPOOL_MANAGED;
+        usage = 0;
+    }
+
+    result =
+        IDirect3DDevice9_CreateTexture(renderdata->device, texture->w,
+                                       texture->h, 1, usage,
+                                       PixelFormatToD3DFMT(texture->format),
+                                       pool, &data->texture, NULL);
+    if (FAILED(result)) {
+        D3D_SetError("CreateTexture()", result);
+        return -1;
+    }
+
+    return 0;
+}
+
+static int
+D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+                  const SDL_Rect * rect, const void *pixels, int pitch)
+{
+    D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
+    D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata;
+    RECT d3drect;
+    D3DLOCKED_RECT locked;
+    const Uint8 *src;
+    Uint8 *dst;
+    int row, length;
+    HRESULT result;
+
+#ifdef USE_DYNAMIC_TEXTURE
+    if (texture->access == SDL_TEXTUREACCESS_STREAMING &&
+        rect->x == 0 && rect->y == 0 &&
+        rect->w == texture->w && rect->h == texture->h) {
+        result = IDirect3DTexture9_LockRect(data->texture, 0, &locked, NULL, D3DLOCK_DISCARD);
+    } else
+#endif
+    {
+        d3drect.left = rect->x;
+        d3drect.right = rect->x + rect->w;
+        d3drect.top = rect->y;
+        d3drect.bottom = rect->y + rect->h;
+        result = IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect, 0);
+    }
+
+    if (FAILED(result)) {
+        D3D_SetError("LockRect()", result);
+        return -1;
+    }
+
+    src = pixels;
+    dst = locked.pBits;
+    length = rect->w * SDL_BYTESPERPIXEL(texture->format);
+    if (length == pitch && length == locked.Pitch) {
+        SDL_memcpy(dst, src, length*rect->h);
+    } else {
+        for (row = 0; row < rect->h; ++row) {
+            SDL_memcpy(dst, src, length);
+            src += pitch;
+            dst += locked.Pitch;
+        }
+    }
+    IDirect3DTexture9_UnlockRect(data->texture, 0);
+
+    return 0;
+}
+
+static int
+D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+                const SDL_Rect * rect, void **pixels, int *pitch)
+{
+    D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
+    RECT d3drect;
+    D3DLOCKED_RECT locked;
+    HRESULT result;
+
+    d3drect.left = rect->x;
+    d3drect.right = rect->x + rect->w;
+    d3drect.top = rect->y;
+    d3drect.bottom = rect->y + rect->h;
+
+    result = IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect, 0);
+    if (FAILED(result)) {
+        D3D_SetError("LockRect()", result);
+        return -1;
+    }
+    *pixels = locked.pBits;
+    *pitch = locked.Pitch;
+    return 0;
+}
+
+static void
+D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+    D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
+
+    IDirect3DTexture9_UnlockRect(data->texture, 0);
+}
+
+static void
+D3D_SetBlendMode(D3D_RenderData * data, int blendMode)
+{
+    switch (blendMode) {
+    case SDL_BLENDMODE_NONE:
+        IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE,
+                                        FALSE);
+        break;
+    case SDL_BLENDMODE_BLEND:
+        IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE,
+                                        TRUE);
+        IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLEND,
+                                        D3DBLEND_SRCALPHA);
+        IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
+                                        D3DBLEND_INVSRCALPHA);
+        break;
+    case SDL_BLENDMODE_ADD:
+        IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE,
+                                        TRUE);
+        IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLEND,
+                                        D3DBLEND_SRCALPHA);
+        IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
+                                        D3DBLEND_ONE);
+        break;
+    case SDL_BLENDMODE_MOD:
+        IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE,
+                                        TRUE);
+        IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLEND,
+                                        D3DBLEND_ZERO);
+        IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
+                                        D3DBLEND_SRCCOLOR);
+        break;
+    }
+}
+
+static int
+D3D_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
+                     int count)
+{
+    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
+    DWORD color;
+    Vertex *vertices;
+    int i;
+    HRESULT result;
+
+    if (data->beginScene) {
+        IDirect3DDevice9_BeginScene(data->device);
+        data->beginScene = SDL_FALSE;
+    }
+
+    D3D_SetBlendMode(data, renderer->blendMode);
+
+    result =
+        IDirect3DDevice9_SetTexture(data->device, 0,
+                                    (IDirect3DBaseTexture9 *) 0);
+    if (FAILED(result)) {
+        D3D_SetError("SetTexture()", result);
+        return -1;
+    }
+
+    color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b);
+
+    vertices = SDL_stack_alloc(Vertex, count);
+    for (i = 0; i < count; ++i) {
+        vertices[i].x = (float) points[i].x;
+        vertices[i].y = (float) points[i].y;
+        vertices[i].z = 0.0f;
+        vertices[i].rhw = 1.0f;
+        vertices[i].color = color;
+        vertices[i].u = 0.0f;
+        vertices[i].v = 0.0f;
+    }
+    result =
+        IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_POINTLIST, count,
+                                         vertices, sizeof(*vertices));
+    SDL_stack_free(vertices);
+    if (FAILED(result)) {
+        D3D_SetError("DrawPrimitiveUP()", result);
+        return -1;
+    }
+    return 0;
+}
+
+static int
+D3D_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
+                    int count)
+{
+    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
+    DWORD color;
+    Vertex *vertices;
+    int i;
+    HRESULT result;
+
+    if (data->beginScene) {
+        IDirect3DDevice9_BeginScene(data->device);
+        data->beginScene = SDL_FALSE;
+    }
+
+    D3D_SetBlendMode(data, renderer->blendMode);
+
+    result =
+        IDirect3DDevice9_SetTexture(data->device, 0,
+                                    (IDirect3DBaseTexture9 *) 0);
+    if (FAILED(result)) {
+        D3D_SetError("SetTexture()", result);
+        return -1;
+    }
+
+    color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b);
+
+    vertices = SDL_stack_alloc(Vertex, count);
+    for (i = 0; i < count; ++i) {
+        vertices[i].x = (float) points[i].x;
+        vertices[i].y = (float) points[i].y;
+        vertices[i].z = 0.0f;
+        vertices[i].rhw = 1.0f;
+        vertices[i].color = color;
+        vertices[i].u = 0.0f;
+        vertices[i].v = 0.0f;
+    }
+    result =
+        IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_LINESTRIP, count-1,
+                                         vertices, sizeof(*vertices));
+
+    /* DirectX 9 has the same line rasterization semantics as GDI,
+       so we need to close the endpoint of the line */
+    if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) {
+        vertices[0].x = (float) points[count-1].x;
+        vertices[0].y = (float) points[count-1].y;
+        result = IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_POINTLIST, 1, vertices, sizeof(*vertices));
+    }
+
+    SDL_stack_free(vertices);
+    if (FAILED(result)) {
+        D3D_SetError("DrawPrimitiveUP()", result);
+        return -1;
+    }
+    return 0;
+}
+
+static int
+D3D_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
+                    int count)
+{
+    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
+    DWORD color;
+    int i;
+    float minx, miny, maxx, maxy;
+    Vertex vertices[4];
+    HRESULT result;
+
+    if (data->beginScene) {
+        IDirect3DDevice9_BeginScene(data->device);
+        data->beginScene = SDL_FALSE;
+    }
+
+    D3D_SetBlendMode(data, renderer->blendMode);
+
+    result =
+        IDirect3DDevice9_SetTexture(data->device, 0,
+                                    (IDirect3DBaseTexture9 *) 0);
+    if (FAILED(result)) {
+        D3D_SetError("SetTexture()", result);
+        return -1;
+    }
+
+    color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b);
+
+    for (i = 0; i < count; ++i) {
+        const SDL_Rect *rect = rects[i];
+
+        minx = (float) rect->x;
+        miny = (float) rect->y;
+        maxx = (float) rect->x + rect->w;
+        maxy = (float) rect->y + rect->h;
+
+        vertices[0].x = minx;
+        vertices[0].y = miny;
+        vertices[0].z = 0.0f;
+        vertices[0].rhw = 1.0f;
+        vertices[0].color = color;
+        vertices[0].u = 0.0f;
+        vertices[0].v = 0.0f;
+
+        vertices[1].x = maxx;
+        vertices[1].y = miny;
+        vertices[1].z = 0.0f;
+        vertices[1].rhw = 1.0f;
+        vertices[1].color = color;
+        vertices[1].u = 0.0f;
+        vertices[1].v = 0.0f;
+
+        vertices[2].x = maxx;
+        vertices[2].y = maxy;
+        vertices[2].z = 0.0f;
+        vertices[2].rhw = 1.0f;
+        vertices[2].color = color;
+        vertices[2].u = 0.0f;
+        vertices[2].v = 0.0f;
+
+        vertices[3].x = minx;
+        vertices[3].y = maxy;
+        vertices[3].z = 0.0f;
+        vertices[3].rhw = 1.0f;
+        vertices[3].color = color;
+        vertices[3].u = 0.0f;
+        vertices[3].v = 0.0f;
+
+        result =
+            IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN,
+                                             2, vertices, sizeof(*vertices));
+        if (FAILED(result)) {
+            D3D_SetError("DrawPrimitiveUP()", result);
+            return -1;
+        }
+    }
+    return 0;
+}
+
+static int
+D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
+               const SDL_Rect * srcrect, const SDL_Rect * dstrect)
+{
+    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
+    D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata;
+    LPDIRECT3DPIXELSHADER9 shader = NULL;
+    float minx, miny, maxx, maxy;
+    float minu, maxu, minv, maxv;
+    DWORD color;
+    Vertex vertices[4];
+    HRESULT result;
+
+    if (data->beginScene) {
+        IDirect3DDevice9_BeginScene(data->device);
+        data->beginScene = SDL_FALSE;
+    }
+
+    minx = (float) dstrect->x - 0.5f;
+    miny = (float) dstrect->y - 0.5f;
+    maxx = (float) dstrect->x + dstrect->w - 0.5f;
+    maxy = (float) dstrect->y + dstrect->h - 0.5f;
+
+    minu = (float) srcrect->x / texture->w;
+    maxu = (float) (srcrect->x + srcrect->w) / texture->w;
+    minv = (float) srcrect->y / texture->h;
+    maxv = (float) (srcrect->y + srcrect->h) / texture->h;
+
+    color = D3DCOLOR_ARGB(texture->a, texture->r, texture->g, texture->b);
+
+    vertices[0].x = minx;
+    vertices[0].y = miny;
+    vertices[0].z = 0.0f;
+    vertices[0].rhw = 1.0f;
+    vertices[0].color = color;
+    vertices[0].u = minu;
+    vertices[0].v = minv;
+
+    vertices[1].x = maxx;
+    vertices[1].y = miny;
+    vertices[1].z = 0.0f;
+    vertices[1].rhw = 1.0f;
+    vertices[1].color = color;
+    vertices[1].u = maxu;
+    vertices[1].v = minv;
+
+    vertices[2].x = maxx;
+    vertices[2].y = maxy;
+    vertices[2].z = 0.0f;
+    vertices[2].rhw = 1.0f;
+    vertices[2].color = color;
+    vertices[2].u = maxu;
+    vertices[2].v = maxv;
+
+    vertices[3].x = minx;
+    vertices[3].y = maxy;
+    vertices[3].z = 0.0f;
+    vertices[3].rhw = 1.0f;
+    vertices[3].color = color;
+    vertices[3].u = minu;
+    vertices[3].v = maxv;
+
+    D3D_SetBlendMode(data, texture->blendMode);
+
+    IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MINFILTER,
+                                     D3DTEXF_LINEAR);
+    IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MAGFILTER,
+                                     D3DTEXF_LINEAR);
+
+    result =
+        IDirect3DDevice9_SetTexture(data->device, 0, (IDirect3DBaseTexture9 *)
+                                    texturedata->texture);
+    if (FAILED(result)) {
+        D3D_SetError("SetTexture()", result);
+        return -1;
+    }
+    if (shader) {
+        result = IDirect3DDevice9_SetPixelShader(data->device, shader);
+        if (FAILED(result)) {
+            D3D_SetError("SetShader()", result);
+            return -1;
+        }
+    }
+    result =
+        IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2,
+                                         vertices, sizeof(*vertices));
+    if (FAILED(result)) {
+        D3D_SetError("DrawPrimitiveUP()", result);
+        return -1;
+    }
+    if (shader) {
+        result = IDirect3DDevice9_SetPixelShader(data->device, NULL);
+        if (FAILED(result)) {
+            D3D_SetError("SetShader()", result);
+            return -1;
+        }
+    }
+    return 0;
+}
+
+static int
+D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+                     Uint32 format, void * pixels, int pitch)
+{
+    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
+    D3DSURFACE_DESC desc;
+    LPDIRECT3DSURFACE9 backBuffer;
+    LPDIRECT3DSURFACE9 surface;
+    RECT d3drect;
+    D3DLOCKED_RECT locked;
+    HRESULT result;
+
+    result = IDirect3DDevice9_GetBackBuffer(data->device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer);
+    if (FAILED(result)) {
+        D3D_SetError("GetBackBuffer()", result);
+        return -1;
+    }
+
+    result = IDirect3DSurface9_GetDesc(backBuffer, &desc);
+    if (FAILED(result)) {
+        D3D_SetError("GetDesc()", result);
+        IDirect3DSurface9_Release(backBuffer);
+        return -1;
+    }
+
+    result = IDirect3DDevice9_CreateOffscreenPlainSurface(data->device, desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surface, NULL);
+    if (FAILED(result)) {
+        D3D_SetError("CreateOffscreenPlainSurface()", result);
+        IDirect3DSurface9_Release(backBuffer);
+        return -1;
+    }
+
+    result = IDirect3DDevice9_GetRenderTargetData(data->device, backBuffer, surface);
+    if (FAILED(result)) {
+        D3D_SetError("GetRenderTargetData()", result);
+        IDirect3DSurface9_Release(surface);
+        IDirect3DSurface9_Release(backBuffer);
+        return -1;
+    }
+
+    d3drect.left = rect->x;
+    d3drect.right = rect->x + rect->w;
+    d3drect.top = rect->y;
+    d3drect.bottom = rect->y + rect->h;
+
+    result = IDirect3DSurface9_LockRect(surface, &locked, &d3drect, D3DLOCK_READONLY);
+    if (FAILED(result)) {
+        D3D_SetError("LockRect()", result);
+        IDirect3DSurface9_Release(surface);
+        IDirect3DSurface9_Release(backBuffer);
+        return -1;
+    }
+
+    SDL_ConvertPixels(rect->w, rect->h,
+                      D3DFMTToPixelFormat(desc.Format), locked.pBits, locked.Pitch,
+                      format, pixels, pitch);
+
+    IDirect3DSurface9_UnlockRect(surface);
+
+    IDirect3DSurface9_Release(surface);
+    IDirect3DSurface9_Release(backBuffer);
+
+    return 0;
+}
+
+static void
+D3D_RenderPresent(SDL_Renderer * renderer)
+{
+    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
+    HRESULT result;
+
+    if (!data->beginScene) {
+        IDirect3DDevice9_EndScene(data->device);
+        data->beginScene = SDL_TRUE;
+    }
+
+    result = IDirect3DDevice9_TestCooperativeLevel(data->device);
+    if (result == D3DERR_DEVICELOST) {
+        /* We'll reset later */
+        return;
+    }
+    if (result == D3DERR_DEVICENOTRESET) {
+        D3D_Reset(renderer);
+    }
+    result = IDirect3DDevice9_Present(data->device, NULL, NULL, NULL, NULL);
+    if (FAILED(result)) {
+        D3D_SetError("Present()", result);
+    }
+}
+
+static void
+D3D_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+    D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
+
+    if (!data) {
+        return;
+    }
+    if (data->texture) {
+        IDirect3DTexture9_Release(data->texture);
+    }
+    SDL_free(data);
+    texture->driverdata = NULL;
+}
+
+static void
+D3D_DestroyRenderer(SDL_Renderer * renderer)
+{
+    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
+
+    if (data) {
+        if (data->device) {
+            IDirect3DDevice9_Release(data->device);
+        }
+        if (data->d3d) {
+            IDirect3D9_Release(data->d3d);
+            SDL_UnloadObject(data->d3dDLL);
+        }
+        SDL_free(data);
+    }
+    SDL_free(renderer);
+}
+
+#endif /* SDL_VIDEO_RENDER_D3D */
+
+/* vi: set ts=4 sw=4 expandtab: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/render/opengl/SDL_render_gl.c	Sat Feb 05 12:01:11 2011 -0800
@@ -0,0 +1,826 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2010 Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+#if SDL_VIDEO_RENDER_OGL
+
+#include "SDL_opengl.h"
+#include "../SDL_sysrender.h"
+
+#ifdef __MACOSX__
+#include <OpenGL/OpenGL.h>
+#endif
+
+
+/* OpenGL renderer implementation */
+
+/* Details on optimizing the texture path on Mac OS X:
+   http://developer.apple.com/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_texturedata/chapter_10_section_2.html
+*/
+
+/* Used to re-create the window with OpenGL capability */
+extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags);
+
+static const float inv255f = 1.0f / 255.0f;
+
+static SDL_Renderer *GL_CreateRenderer(SDL_Window * window, Uint32 flags);
+static void GL_WindowEvent(SDL_Renderer * renderer,
+                           const SDL_WindowEvent *event);
+static int GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
+static int GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+                            const SDL_Rect * rect, const void *pixels,
+                            int pitch);
+static int GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+                          const SDL_Rect * rect, void **pixels, int *pitch);
+static void GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
+static int GL_RenderClear(SDL_Renderer * renderer);
+static int GL_RenderDrawPoints(SDL_Renderer * renderer,
+                               const SDL_Point * points, int count);
+static int GL_RenderDrawLines(SDL_Renderer * renderer,
+                              const SDL_Point * points, int count);
+static int GL_RenderFillRects(SDL_Renderer * renderer,
+                              const SDL_Rect ** rects, int count);
+static int GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
+                         const SDL_Rect * srcrect, const SDL_Rect * dstrect);
+static int GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+                               Uint32 pixel_format, void * pixels, int pitch);
+static void GL_RenderPresent(SDL_Renderer * renderer);
+static void GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture);
+static void GL_DestroyRenderer(SDL_Renderer * renderer);
+
+
+SDL_RenderDriver GL_RenderDriver = {
+    GL_CreateRenderer,
+    {
+     "opengl",
+     (SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED),
+     1,
+     {SDL_PIXELFORMAT_ARGB8888},
+     0,
+     0}
+};
+
+typedef struct
+{
+    SDL_GLContext context;
+    SDL_bool updateSize;
+    SDL_bool GL_ARB_texture_rectangle_supported;
+    int blendMode;
+
+    /* OpenGL functions */
+#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
+#include "../../video/SDL_glfuncs.h"
+#undef SDL_PROC
+
+    void (*glTextureRangeAPPLE) (GLenum target, GLsizei length,
+                                 const GLvoid * pointer);
+} GL_RenderData;
+
+typedef struct
+{
+    GLuint texture;
+    GLenum type;
+    GLfloat texw;
+    GLfloat texh;
+    GLenum format;
+    GLenum formattype;
+    void *pixels;
+    int pitch;
+} GL_TextureData;
+
+
+static void
+GL_SetError(const char *prefix, GLenum result)
+{
+    const char *error;
+
+    switch (result) {
+    case GL_NO_ERROR:
+        error = "GL_NO_ERROR";
+        break;
+    case GL_INVALID_ENUM:
+        error = "GL_INVALID_ENUM";
+        break;
+    case GL_INVALID_VALUE:
+        error = "GL_INVALID_VALUE";
+        break;
+    case GL_INVALID_OPERATION:
+        error = "GL_INVALID_OPERATION";
+        break;
+    case GL_STACK_OVERFLOW:
+        error = "GL_STACK_OVERFLOW";
+        break;
+    case GL_STACK_UNDERFLOW:
+        error = "GL_STACK_UNDERFLOW";
+        break;
+    case GL_OUT_OF_MEMORY:
+        error = "GL_OUT_OF_MEMORY";
+        break;
+    case GL_TABLE_TOO_LARGE:
+        error = "GL_TABLE_TOO_LARGE";
+        break;
+    default:
+        error = "UNKNOWN";
+        break;
+    }
+    SDL_SetError("%s: %s", prefix, error);
+}
+
+static int
+GL_LoadFunctions(GL_RenderData * data)
+{
+#ifdef __SDL_NOGETPROCADDR__
+#define SDL_PROC(ret,func,params) data->func=func;
+#else
+#define SDL_PROC(ret,func,params) \
+    do { \
+        data->func = SDL_GL_GetProcAddress(#func); \
+        if ( ! data->func ) { \
+            SDL_SetError("Couldn't load GL function %s: %s\n", #func, SDL_GetError()); \
+            return -1; \
+        } \
+    } while ( 0 );
+#endif /* __SDL_NOGETPROCADDR__ */
+
+#include "../../video/SDL_glfuncs.h"
+#undef SDL_PROC
+    return 0;
+}
+
+SDL_Renderer *
+GL_CreateRenderer(SDL_Window * window, Uint32 flags)
+{
+    SDL_Renderer *renderer;
+    GL_RenderData *data;
+    GLint value;
+    Uint32 window_flags;
+
+    window_flags = SDL_GetWindowFlags(window);
+    if (!(window_flags & SDL_WINDOW_OPENGL)) {
+        if (SDL_RecreateWindow(window, window_flags | SDL_WINDOW_OPENGL) < 0) {
+            return NULL;
+        }
+    }
+
+    renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
+    if (!renderer) {
+        SDL_OutOfMemory();
+        return NULL;
+    }
+
+    data = (GL_RenderData *) SDL_calloc(1, sizeof(*data));
+    if (!data) {
+        GL_DestroyRenderer(renderer);
+        SDL_OutOfMemory();
+        return NULL;
+    }
+
+    renderer->WindowEvent = GL_WindowEvent;
+    renderer->CreateTexture = GL_CreateTexture;
+    renderer->UpdateTexture = GL_UpdateTexture;
+    renderer->LockTexture = GL_LockTexture;
+    renderer->UnlockTexture = GL_UnlockTexture;
+    renderer->RenderClear = GL_RenderClear;
+    renderer->RenderDrawPoints = GL_RenderDrawPoints;
+    renderer->RenderDrawLines = GL_RenderDrawLines;
+    renderer->RenderFillRects = GL_RenderFillRects;
+    renderer->RenderCopy = GL_RenderCopy;
+    renderer->RenderReadPixels = GL_RenderReadPixels;
+    renderer->RenderPresent = GL_RenderPresent;
+    renderer->DestroyTexture = GL_DestroyTexture;
+    renderer->DestroyRenderer = GL_DestroyRenderer;
+    renderer->info = GL_RenderDriver.info;
+    renderer->driverdata = data;
+
+    renderer->info.flags = SDL_RENDERER_ACCELERATED;
+
+    if (GL_LoadFunctions(data) < 0) {
+        GL_DestroyRenderer(renderer);
+        return NULL;
+    }
+
+    data->context = SDL_GL_CreateContext(window);
+    if (!data->context) {
+        GL_DestroyRenderer(renderer);
+        return NULL;
+    }
+    if (SDL_GL_MakeCurrent(window, data->context) < 0) {
+        GL_DestroyRenderer(renderer);
+        return NULL;
+    }
+#ifdef __MACOSX__
+    /* Enable multi-threaded rendering */
+    /* Disabled until Ryan finishes his VBO/PBO code...
+       CGLEnable(CGLGetCurrentContext(), kCGLCEMPEngine);
+     */
+#endif
+
+    if (flags & SDL_RENDERER_PRESENTVSYNC) {
+        SDL_GL_SetSwapInterval(1);
+    } else {
+        SDL_GL_SetSwapInterval(0);
+    }
+    if (SDL_GL_GetSwapInterval() > 0) {
+        renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
+    }
+
+    data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
+    renderer->info.max_texture_width = value;
+    data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
+    renderer->info.max_texture_height = value;
+
+    if (SDL_GL_ExtensionSupported("GL_ARB_texture_rectangle")
+        || SDL_GL_ExtensionSupported("GL_EXT_texture_rectangle")) {
+        data->GL_ARB_texture_rectangle_supported = SDL_TRUE;
+    }
+    if (SDL_GL_ExtensionSupported("GL_APPLE_texture_range")) {
+        data->glTextureRangeAPPLE =
+            (void (*)(GLenum, GLsizei, const GLvoid *))
+            SDL_GL_GetProcAddress("glTextureRangeAPPLE");
+    }
+
+    /* Set up parameters for rendering */
+    data->blendMode = -1;
+    data->glDisable(GL_DEPTH_TEST);
+    data->glDisable(GL_CULL_FACE);
+    /* This ended up causing video discrepancies between OpenGL and Direct3D */
+    /*data->glEnable(GL_LINE_SMOOTH);*/
+    if (data->GL_ARB_texture_rectangle_supported) {
+        data->glEnable(GL_TEXTURE_RECTANGLE_ARB);
+    } else {
+        data->glEnable(GL_TEXTURE_2D);
+    }
+    data->updateSize = SDL_TRUE;
+
+    return renderer;
+}
+
+static SDL_GLContext SDL_CurrentContext = NULL;
+
+static int
+GL_ActivateRenderer(SDL_Renderer * renderer)
+{
+    GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+    SDL_Window *window = renderer->window;
+
+    if (SDL_CurrentContext != data->context) {
+        if (SDL_GL_MakeCurrent(window, data->context) < 0) {
+            return -1;
+        }
+        SDL_CurrentContext = data->context;
+    }
+    if (data->updateSize) {
+        int w, h;
+
+        SDL_GetWindowSize(window, &w, &h);
+        data->glMatrixMode(GL_PROJECTION);
+        data->glLoadIdentity();
+        data->glMatrixMode(GL_MODELVIEW);
+        data->glLoadIdentity();
+        data->glViewport(0, 0, w, h);
+        data->glOrtho(0.0, (GLdouble) w, (GLdouble) h, 0.0, 0.0, 1.0);
+        data->updateSize = SDL_FALSE;
+    }
+    return 0;
+}
+
+static void
+GL_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
+{
+    GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+
+    if (event->event == SDL_WINDOWEVENT_RESIZED) {
+        /* Rebind the context to the window area and update matrices */
+        SDL_CurrentContext = NULL;
+        data->updateSize = SDL_TRUE;
+    }
+}
+
+static __inline__ int
+power_of_2(int input)
+{
+    int value = 1;
+
+    while (value < input) {
+        value <<= 1;
+    }
+    return value;
+}
+
+static __inline__ SDL_bool
+convert_format(GL_RenderData *renderdata, Uint32 pixel_format,
+               GLint* internalFormat, GLenum* format, GLenum* type)
+{
+    switch (pixel_format) {
+    case SDL_PIXELFORMAT_RGB888:
+    case SDL_PIXELFORMAT_ARGB8888:
+        *internalFormat = GL_RGBA8;
+        *format = GL_BGRA;
+        *type = GL_UNSIGNED_INT_8_8_8_8_REV;
+        break;
+    default:
+        return SDL_FALSE;
+    }
+    return SDL_TRUE;
+}
+
+static int
+GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+    GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
+    GL_TextureData *data;
+    GLint internalFormat;
+    GLenum format, type;
+    int texture_w, texture_h;
+    GLenum result;
+
+    GL_ActivateRenderer(renderer);
+
+    if (!convert_format(renderdata, texture->format, &internalFormat,
+                        &format, &type)) {
+        SDL_SetError("Texture format %s not supported by OpenGL",
+                     SDL_GetPixelFormatName(texture->format));
+        return -1;
+    }
+
+    data = (GL_TextureData *) SDL_calloc(1, sizeof(*data));
+    if (!data) {
+        SDL_OutOfMemory();
+        return -1;
+    }
+
+    if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
+        data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
+        data->pixels = SDL_malloc(texture->h * data->pitch);
+        if (!data->pixels) {
+            SDL_OutOfMemory();
+            SDL_free(data);
+            return -1;
+        }
+    }
+
+    texture->driverdata = data;
+
+    renderdata->glGetError();
+    renderdata->glGenTextures(1, &data->texture);
+    if (renderdata->GL_ARB_texture_rectangle_supported) {
+        data->type = GL_TEXTURE_RECTANGLE_ARB;
+        texture_w = texture->w;
+        texture_h = texture->h;
+        data->texw = (GLfloat) texture_w;
+        data->texh = (GLfloat) texture_h;
+    } else {
+        data->type = GL_TEXTURE_2D;
+        texture_w = power_of_2(texture->w);
+        texture_h = power_of_2(texture->h);
+        data->texw = (GLfloat) (texture->w) / texture_w;
+        data->texh = (GLfloat) texture->h / texture_h;
+    }
+
+    data->format = format;
+    data->formattype = type;
+    renderdata->glEnable(data->type);
+    renderdata->glBindTexture(data->type, data->texture);
+    renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER,
+                                GL_LINEAR);
+    renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER,
+                                GL_LINEAR);
+    renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
+                                GL_CLAMP_TO_EDGE);
+    renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
+                                GL_CLAMP_TO_EDGE);
+#ifdef __MACOSX__
+#ifndef GL_TEXTURE_STORAGE_HINT_APPLE
+#define GL_TEXTURE_STORAGE_HINT_APPLE       0x85BC
+#endif
+#ifndef STORAGE_CACHED_APPLE
+#define STORAGE_CACHED_APPLE                0x85BE
+#endif
+#ifndef STORAGE_SHARED_APPLE
+#define STORAGE_SHARED_APPLE                0x85BF
+#endif
+    if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
+        renderdata->glTexParameteri(data->type, GL_TEXTURE_STORAGE_HINT_APPLE,
+                                    GL_STORAGE_SHARED_APPLE);
+    } else {
+        renderdata->glTexParameteri(data->type, GL_TEXTURE_STORAGE_HINT_APPLE,
+                                    GL_STORAGE_CACHED_APPLE);
+    }
+    if (texture->access == SDL_TEXTUREACCESS_STREAMING
+        && texture->format == SDL_PIXELFORMAT_ARGB8888) {
+        renderdata->glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
+        renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
+                                 texture_h, 0, format, type, data->pixels);
+    }
+    else
+#endif
+    {
+        renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
+                                 texture_h, 0, format, type, NULL);
+    }
+    renderdata->glDisable(data->type);
+    result = renderdata->glGetError();
+    if (result != GL_NO_ERROR) {
+        GL_SetError("glTexImage2D()", result);
+        return -1;
+    }
+    return 0;
+}
+
+static void
+SetupTextureUpdate(GL_RenderData * renderdata, SDL_Texture * texture,
+                   int pitch)
+{
+    renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH,
+                              (pitch / SDL_BYTESPERPIXEL(texture->format)));
+}
+
+static int
+GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+                 const SDL_Rect * rect, const void *pixels, int pitch)
+{
+    GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
+    GL_TextureData *data = (GL_TextureData *) texture->driverdata;
+    GLenum result;
+
+    GL_ActivateRenderer(renderer);
+
+    renderdata->glGetError();
+    SetupTextureUpdate(renderdata, texture, pitch);
+    renderdata->glEnable(data->type);
+    renderdata->glBindTexture(data->type, data->texture);
+    renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w,
+                                rect->h, data->format, data->formattype,
+                                pixels);
+    renderdata->glDisable(data->type);
+    result = renderdata->glGetError();
+    if (result != GL_NO_ERROR) {
+        GL_SetError("glTexSubImage2D()", result);
+        return -1;
+    }
+    return 0;
+}
+
+static int
+GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+               const SDL_Rect * rect, void **pixels, int *pitch)
+{
+    GL_TextureData *data = (GL_TextureData *) texture->driverdata;
+
+    *pixels =
+        (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
+                  rect->x * SDL_BYTESPERPIXEL(texture->format));
+    *pitch = data->pitch;
+    return 0;
+}
+
+static void
+GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+    GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
+    GL_TextureData *data = (GL_TextureData *) texture->driverdata;
+
+    GL_ActivateRenderer(renderer);
+
+    SetupTextureUpdate(renderdata, texture, data->pitch);
+    renderdata->glEnable(data->type);
+    renderdata->glBindTexture(data->type, data->texture);
+    renderdata->glTexSubImage2D(data->type, 0, 0, 0, texture->w, texture->h,
+                                data->format, data->formattype, data->pixels);
+    renderdata->glDisable(data->type);
+}
+
+static void
+GL_SetBlendMode(GL_RenderData * data, int blendMode)
+{
+    if (blendMode != data->blendMode) {
+        switch (blendMode) {
+        case SDL_BLENDMODE_NONE:
+            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+            data->glDisable(GL_BLEND);
+            break;
+        case SDL_BLENDMODE_BLEND:
+            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+            data->glEnable(GL_BLEND);
+            data->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+            break;
+        case SDL_BLENDMODE_ADD:
+            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+            data->glEnable(GL_BLEND);
+            data->glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+            break;
+        case SDL_BLENDMODE_MOD:
+            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+            data->glEnable(GL_BLEND);
+            data->glBlendFunc(GL_ZERO, GL_SRC_COLOR);
+            break;
+        }
+        data->blendMode = blendMode;
+    }
+}
+
+static int
+GL_RenderClear(SDL_Renderer * renderer)
+{
+    GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+
+    GL_ActivateRenderer(renderer);
+
+    data->glClearColor((GLfloat) renderer->r * inv255f,
+                       (GLfloat) renderer->g * inv255f,
+                       (GLfloat) renderer->b * inv255f,
+                       (GLfloat) renderer->a * inv255f);
+
+    data->glClear(GL_COLOR_BUFFER_BIT);
+
+    return 0;
+}
+
+static int
+GL_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
+                    int count)
+{
+    GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+    int i;
+
+    GL_ActivateRenderer(renderer);
+
+    GL_SetBlendMode(data, renderer->blendMode);
+
+    data->glColor4f((GLfloat) renderer->r * inv255f,
+                    (GLfloat) renderer->g * inv255f,
+                    (GLfloat) renderer->b * inv255f,
+                    (GLfloat) renderer->a * inv255f);
+
+    data->glBegin(GL_POINTS);
+    for (i = 0; i < count; ++i) {
+        data->glVertex2f(0.5f + points[i].x, 0.5f + points[i].y);
+    }
+    data->glEnd();
+
+    return 0;
+}
+
+static int
+GL_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
+                   int count)
+{
+    GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+    int i;
+
+    GL_ActivateRenderer(renderer);
+
+    GL_SetBlendMode(data, renderer->blendMode);
+
+    data->glColor4f((GLfloat) renderer->r * inv255f,
+                    (GLfloat) renderer->g * inv255f,
+                    (GLfloat) renderer->b * inv255f,
+                    (GLfloat) renderer->a * inv255f);
+
+    if (count > 2 && 
+        points[0].x == points[count-1].x && points[0].y == points[count-1].y) {
+        data->glBegin(GL_LINE_LOOP);
+        /* GL_LINE_LOOP takes care of the final segment */
+        --count;
+        for (i = 0; i < count; ++i) {
+            data->glVertex2f(0.5f + points[i].x, 0.5f + points[i].y);
+        }
+        data->glEnd();
+    } else {
+#if defined(__APPLE__) || defined(__WIN32__)
+#else
+        int x1, y1, x2, y2;
+#endif
+
+        data->glBegin(GL_LINE_STRIP);
+        for (i = 0; i < count; ++i) {
+            data->glVertex2f(0.5f + points[i].x, 0.5f + points[i].y);
+        }
+        data->glEnd();
+
+        /* The line is half open, so we need one more point to complete it.
+         * http://www.opengl.org/documentation/specs/version1.1/glspec1.1/node47.html
+         * If we have to, we can use vertical line and horizontal line textures
+         * for vertical and horizontal lines, and then create custom textures
+         * for diagonal lines and software render those.  It's terrible, but at
+         * least it would be pixel perfect.
+         */
+        data->glBegin(GL_POINTS);
+#if defined(__APPLE__) || defined(__WIN32__)
+        /* Mac OS X and Windows seem to always leave the second point open */
+        data->glVertex2f(0.5f + points[count-1].x, 0.5f + points[count-1].y);
+#else
+        /* Linux seems to leave the right-most or bottom-most point open */
+        x1 = points[0].x;
+        y1 = points[0].y;
+        x2 = points[count-1].x;
+        y2 = points[count-1].y;
+
+        if (x1 > x2) {
+            data->glVertex2f(0.5f + x1, 0.5f + y1);
+        } else if (x2 > x1) {
+            data->glVertex2f(0.5f + x2, 0.5f + y2);
+        } else if (y1 > y2) {
+            data->glVertex2f(0.5f + x1, 0.5f + y1);
+        } else if (y2 > y1) {
+            data->glVertex2f(0.5f + x2, 0.5f + y2);
+        }
+#endif
+        data->glEnd();
+    }
+
+    return 0;
+}
+
+static int
+GL_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
+{
+    GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+    int i;
+
+    GL_ActivateRenderer(renderer);
+
+    GL_SetBlendMode(data, renderer->blendMode);
+
+    data->glColor4f((GLfloat) renderer->r * inv255f,
+                    (GLfloat) renderer->g * inv255f,
+                    (GLfloat) renderer->b * inv255f,
+                    (GLfloat) renderer->a * inv255f);
+
+    for (i = 0; i < count; ++i) {
+        const SDL_Rect *rect = rects[i];
+
+        data->glRecti(rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
+    }
+
+    return 0;
+}
+
+static int
+GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
+              const SDL_Rect * srcrect, const SDL_Rect * dstrect)
+{
+    GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+    GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
+    int minx, miny, maxx, maxy;
+    GLfloat minu, maxu, minv, maxv;
+
+    GL_ActivateRenderer(renderer);
+
+    minx = dstrect->x;
+    miny = dstrect->y;
+    maxx = dstrect->x + dstrect->w;
+    maxy = dstrect->y + dstrect->h;
+
+    minu = (GLfloat) srcrect->x / texture->w;
+    minu *= texturedata->texw;
+    maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w;
+    maxu *= texturedata->texw;
+    minv = (GLfloat) srcrect->y / texture->h;
+    minv *= texturedata->texh;
+    maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
+    maxv *= texturedata->texh;
+
+    data->glEnable(texturedata->type);
+    data->glBindTexture(texturedata->type, texturedata->texture);
+
+    if (texture->modMode) {
+        data->glColor4f((GLfloat) texture->r * inv255f,
+                        (GLfloat) texture->g * inv255f,
+                        (GLfloat) texture->b * inv255f,
+                        (GLfloat) texture->a * inv255f);
+    } else {
+        data->glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+    }
+
+    GL_SetBlendMode(data, texture->blendMode);
+
+    data->glBegin(GL_TRIANGLE_STRIP);
+    data->glTexCoord2f(minu, minv);
+    data->glVertex2f((GLfloat) minx, (GLfloat) miny);
+    data->glTexCoord2f(maxu, minv);
+    data->glVertex2f((GLfloat) maxx, (GLfloat) miny);
+    data->glTexCoord2f(minu, maxv);
+    data->glVertex2f((GLfloat) minx, (GLfloat) maxy);
+    data->glTexCoord2f(maxu, maxv);
+    data->glVertex2f((GLfloat) maxx, (GLfloat) maxy);
+    data->glEnd();
+
+    data->glDisable(texturedata->type);
+
+    return 0;
+}
+
+static int
+GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+                    Uint32 pixel_format, void * pixels, int pitch)
+{
+    GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+    SDL_Window *window = renderer->window;
+    GLint internalFormat;
+    GLenum format, type;
+    Uint8 *src, *dst, *tmp;
+    int w, h, length, rows;
+
+    GL_ActivateRenderer(renderer);
+
+    if (!convert_format(data, pixel_format, &internalFormat, &format, &type)) {
+        /* FIXME: Do a temp copy to a format that is supported */
+        SDL_SetError("Unsupported pixel format");
+        return -1;
+    }
+
+    SDL_GetWindowSize(window, &w, &h);
+
+    data->glPixelStorei(GL_PACK_ALIGNMENT, 1);
+    data->glPixelStorei(GL_PACK_ROW_LENGTH,
+                        (pitch / SDL_BYTESPERPIXEL(pixel_format)));
+
+    data->glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h,
+                       format, type, pixels);
+
+    /* Flip the rows to be top-down */
+    length = rect->w * SDL_BYTESPERPIXEL(pixel_format);
+    src = (Uint8*)pixels + (rect->h-1)*pitch;
+    dst = (Uint8*)pixels;
+    tmp = SDL_stack_alloc(Uint8, length);
+    rows = rect->h / 2;
+    while (rows--) {
+        SDL_memcpy(tmp, dst, length);
+        SDL_memcpy(dst, src, length);
+        SDL_memcpy(src, tmp, length);
+        dst += pitch;
+        src -= pitch;
+    }
+    SDL_stack_free(tmp);
+
+    return 0;
+}
+
+static void
+GL_RenderPresent(SDL_Renderer * renderer)
+{
+    GL_ActivateRenderer(renderer);
+
+    SDL_GL_SwapWindow(renderer->window);
+}
+
+static void
+GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+    GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
+    GL_TextureData *data = (GL_TextureData *) texture->driverdata;
+
+    GL_ActivateRenderer(renderer);
+
+    if (!data) {
+        return;
+    }
+    if (data->texture) {
+        renderdata->glDeleteTextures(1, &data->texture);
+    }
+    if (data->pixels) {
+        SDL_free(data->pixels);
+    }
+    SDL_free(data);
+    texture->driverdata = NULL;
+}
+
+static void
+GL_DestroyRenderer(SDL_Renderer * renderer)
+{
+    GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+
+    if (data) {
+        if (data->context) {
+            /* SDL_GL_MakeCurrent(0, NULL); *//* doesn't do anything */
+            SDL_GL_DeleteContext(data->context);
+        }
+        SDL_free(data);
+    }
+    SDL_free(renderer);
+}
+
+#endif /* SDL_VIDEO_RENDER_OGL */
+
+/* vi: set ts=4 sw=4 expandtab: */
--- a/src/render/opengl/SDL_renderer_gl.c	Sat Feb 05 11:54:46 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,826 +0,0 @@
-/*
-    SDL - Simple DirectMedia Layer
-    Copyright (C) 1997-2010 Sam Lantinga
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    Sam Lantinga
-    slouken@libsdl.org
-*/
-#include "SDL_config.h"
-
-#if SDL_VIDEO_RENDER_OGL
-
-#include "SDL_opengl.h"
-#include "../SDL_sysrender.h"
-
-#ifdef __MACOSX__
-#include <OpenGL/OpenGL.h>
-#endif
-
-
-/* OpenGL renderer implementation */
-
-/* Details on optimizing the texture path on Mac OS X:
-   http://developer.apple.com/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_texturedata/chapter_10_section_2.html
-*/
-
-/* Used to re-create the window with OpenGL capability */
-extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags);
-
-static const float inv255f = 1.0f / 255.0f;
-
-static SDL_Renderer *GL_CreateRenderer(SDL_Window * window, Uint32 flags);
-static void GL_WindowEvent(SDL_Renderer * renderer,
-                           const SDL_WindowEvent *event);
-static int GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
-static int GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
-                            const SDL_Rect * rect, const void *pixels,
-                            int pitch);
-static int GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
-                          const SDL_Rect * rect, void **pixels, int *pitch);
-static void GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
-static int GL_RenderClear(SDL_Renderer * renderer);
-static int GL_RenderDrawPoints(SDL_Renderer * renderer,
-                               const SDL_Point * points, int count);
-static int GL_RenderDrawLines(SDL_Renderer * renderer,
-                              const SDL_Point * points, int count);
-static int GL_RenderFillRects(SDL_Renderer * renderer,
-                              const SDL_Rect ** rects, int count);
-static int GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
-                         const SDL_Rect * srcrect, const SDL_Rect * dstrect);
-static int GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
-                               Uint32 pixel_format, void * pixels, int pitch);
-static void GL_RenderPresent(SDL_Renderer * renderer);
-static void GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture);
-static void GL_DestroyRenderer(SDL_Renderer * renderer);
-
-
-SDL_RenderDriver GL_RenderDriver = {
-    GL_CreateRenderer,
-    {
-     "opengl",
-     (SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED),
-     1,
-     {SDL_PIXELFORMAT_ARGB8888},
-     0,
-     0}
-};
-
-typedef struct
-{
-    SDL_GLContext context;
-    SDL_bool updateSize;
-    SDL_bool GL_ARB_texture_rectangle_supported;
-    int blendMode;
-
-    /* OpenGL functions */
-#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
-#include "../../video/SDL_glfuncs.h"
-#undef SDL_PROC
-
-    void (*glTextureRangeAPPLE) (GLenum target, GLsizei length,
-                                 const GLvoid * pointer);
-} GL_RenderData;
-
-typedef struct
-{
-    GLuint texture;
-    GLenum type;
-    GLfloat texw;
-    GLfloat texh;
-    GLenum format;
-    GLenum formattype;
-    void *pixels;
-    int pitch;
-} GL_TextureData;
-
-
-static void
-GL_SetError(const char *prefix, GLenum result)
-{
-    const char *error;
-
-    switch (result) {
-    case GL_NO_ERROR:
-        error = "GL_NO_ERROR";
-        break;
-    case GL_INVALID_ENUM:
-        error = "GL_INVALID_ENUM";
-        break;
-    case GL_INVALID_VALUE:
-        error = "GL_INVALID_VALUE";
-        break;
-    case GL_INVALID_OPERATION:
-        error = "GL_INVALID_OPERATION";
-        break;
-    case GL_STACK_OVERFLOW:
-        error = "GL_STACK_OVERFLOW";
-        break;
-    case GL_STACK_UNDERFLOW:
-        error = "GL_STACK_UNDERFLOW";
-        break;
-    case GL_OUT_OF_MEMORY:
-        error = "GL_OUT_OF_MEMORY";
-        break;
-    case GL_TABLE_TOO_LARGE:
-        error = "GL_TABLE_TOO_LARGE";
-        break;
-    default:
-        error = "UNKNOWN";
-        break;
-    }
-    SDL_SetError("%s: %s", prefix, error);
-}
-
-static int
-GL_LoadFunctions(GL_RenderData * data)
-{
-#ifdef __SDL_NOGETPROCADDR__
-#define SDL_PROC(ret,func,params) data->func=func;
-#else
-#define SDL_PROC(ret,func,params) \
-    do { \
-        data->func = SDL_GL_GetProcAddress(#func); \
-        if ( ! data->func ) { \
-            SDL_SetError("Couldn't load GL function %s: %s\n", #func, SDL_GetError()); \
-            return -1; \
-        } \
-    } while ( 0 );
-#endif /* __SDL_NOGETPROCADDR__ */
-
-#include "../../video/SDL_glfuncs.h"
-#undef SDL_PROC
-    return 0;
-}
-
-SDL_Renderer *
-GL_CreateRenderer(SDL_Window * window, Uint32 flags)
-{
-    SDL_Renderer *renderer;
-    GL_RenderData *data;
-    GLint value;
-    Uint32 window_flags;
-
-    window_flags = SDL_GetWindowFlags(window);
-    if (!(window_flags & SDL_WINDOW_OPENGL)) {
-        if (SDL_RecreateWindow(window, window_flags | SDL_WINDOW_OPENGL) < 0) {
-            return NULL;
-        }
-    }
-
-    renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
-    if (!renderer) {
-        SDL_OutOfMemory();
-        return NULL;
-    }
-
-    data = (GL_RenderData *) SDL_calloc(1, sizeof(*data));
-    if (!data) {
-        GL_DestroyRenderer(renderer);
-        SDL_OutOfMemory();
-        return NULL;
-    }
-
-    renderer->WindowEvent = GL_WindowEvent;
-    renderer->CreateTexture = GL_CreateTexture;
-    renderer->UpdateTexture = GL_UpdateTexture;
-    renderer->LockTexture = GL_LockTexture;
-    renderer->UnlockTexture = GL_UnlockTexture;
-    renderer->RenderClear = GL_RenderClear;
-    renderer->RenderDrawPoints = GL_RenderDrawPoints;
-    renderer->RenderDrawLines = GL_RenderDrawLines;
-    renderer->RenderFillRects = GL_RenderFillRects;
-    renderer->RenderCopy = GL_RenderCopy;
-    renderer->RenderReadPixels = GL_RenderReadPixels;
-    renderer->RenderPresent = GL_RenderPresent;
-    renderer->DestroyTexture = GL_DestroyTexture;
-    renderer->DestroyRenderer = GL_DestroyRenderer;
-    renderer->info = GL_RenderDriver.info;
-    renderer->driverdata = data;
-
-    renderer->info.flags = SDL_RENDERER_ACCELERATED;
-
-    if (GL_LoadFunctions(data) < 0) {
-        GL_DestroyRenderer(renderer);
-        return NULL;
-    }
-
-    data->context = SDL_GL_CreateContext(window);
-    if (!data->context) {
-        GL_DestroyRenderer(renderer);
-        return NULL;
-    }
-    if (SDL_GL_MakeCurrent(window, data->context) < 0) {
-        GL_DestroyRenderer(renderer);
-        return NULL;
-    }
-#ifdef __MACOSX__
-    /* Enable multi-threaded rendering */
-    /* Disabled until Ryan finishes his VBO/PBO code...
-       CGLEnable(CGLGetCurrentContext(), kCGLCEMPEngine);
-     */
-#endif
-
-    if (flags & SDL_RENDERER_PRESENTVSYNC) {
-        SDL_GL_SetSwapInterval(1);
-    } else {
-        SDL_GL_SetSwapInterval(0);
-    }
-    if (SDL_GL_GetSwapInterval() > 0) {
-        renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
-    }
-
-    data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
-    renderer->info.max_texture_width = value;
-    data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
-    renderer->info.max_texture_height = value;
-
-    if (SDL_GL_ExtensionSupported("GL_ARB_texture_rectangle")
-        || SDL_GL_ExtensionSupported("GL_EXT_texture_rectangle")) {
-        data->GL_ARB_texture_rectangle_supported = SDL_TRUE;
-    }
-    if (SDL_GL_ExtensionSupported("GL_APPLE_texture_range")) {
-        data->glTextureRangeAPPLE =
-            (void (*)(GLenum, GLsizei, const GLvoid *))
-            SDL_GL_GetProcAddress("glTextureRangeAPPLE");
-    }
-
-    /* Set up parameters for rendering */
-    data->blendMode = -1;
-    data->glDisable(GL_DEPTH_TEST);
-    data->glDisable(GL_CULL_FACE);
-    /* This ended up causing video discrepancies between OpenGL and Direct3D */
-    /*data->glEnable(GL_LINE_SMOOTH);*/
-    if (data->GL_ARB_texture_rectangle_supported) {
-        data->glEnable(GL_TEXTURE_RECTANGLE_ARB);
-    } else {
-        data->glEnable(GL_TEXTURE_2D);
-    }
-    data->updateSize = SDL_TRUE;
-
-    return renderer;
-}
-
-static SDL_GLContext SDL_CurrentContext = NULL;
-
-static int
-GL_ActivateRenderer(SDL_Renderer * renderer)
-{
-    GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
-    SDL_Window *window = renderer->window;
-
-    if (SDL_CurrentContext != data->context) {
-        if (SDL_GL_MakeCurrent(window, data->context) < 0) {
-            return -1;
-        }
-        SDL_CurrentContext = data->context;
-    }
-    if (data->updateSize) {
-        int w, h;
-
-        SDL_GetWindowSize(window, &w, &h);
-        data->glMatrixMode(GL_PROJECTION);
-        data->glLoadIdentity();
-        data->glMatrixMode(GL_MODELVIEW);
-        data->glLoadIdentity();
-        data->glViewport(0, 0, w, h);
-        data->glOrtho(0.0, (GLdouble) w, (GLdouble) h, 0.0, 0.0, 1.0);
-        data->updateSize = SDL_FALSE;
-    }
-    return 0;
-}
-
-static void
-GL_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
-{
-    GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
-
-    if (event->event == SDL_WINDOWEVENT_RESIZED) {
-        /* Rebind the context to the window area and update matrices */
-        SDL_CurrentContext = NULL;
-        data->updateSize = SDL_TRUE;
-    }
-}
-
-static __inline__ int
-power_of_2(int input)
-{
-    int value = 1;
-
-    while (value < input) {
-        value <<= 1;
-    }
-    return value;
-}
-
-static __inline__ SDL_bool
-convert_format(GL_RenderData *renderdata, Uint32 pixel_format,
-               GLint* internalFormat, GLenum* format, GLenum* type)
-{
-    switch (pixel_format) {
-    case SDL_PIXELFORMAT_RGB888:
-    case SDL_PIXELFORMAT_ARGB8888:
-        *internalFormat = GL_RGBA8;
-        *format = GL_BGRA;
-        *type = GL_UNSIGNED_INT_8_8_8_8_REV;
-        break;
-    default:
-        return SDL_FALSE;
-    }
-    return SDL_TRUE;
-}
-
-static int
-GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
-{
-    GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
-    GL_TextureData *data;
-    GLint internalFormat;
-    GLenum format, type;
-    int texture_w, texture_h;
-    GLenum result;
-
-    GL_ActivateRenderer(renderer);
-
-    if (!convert_format(renderdata, texture->format, &internalFormat,
-                        &format, &type)) {
-        SDL_SetError("Texture format %s not supported by OpenGL",
-                     SDL_GetPixelFormatName(texture->format));
-        return -1;
-    }
-
-    data = (GL_TextureData *) SDL_calloc(1, sizeof(*data));
-    if (!data) {
-        SDL_OutOfMemory();
-        return -1;
-    }
-
-    if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
-        data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
-        data->pixels = SDL_malloc(texture->h * data->pitch);
-        if (!data->pixels) {
-            SDL_OutOfMemory();
-            SDL_free(data);
-            return -1;
-        }
-    }
-
-    texture->driverdata = data;
-
-    renderdata->glGetError();
-    renderdata->glGenTextures(1, &data->texture);
-    if (renderdata->GL_ARB_texture_rectangle_supported) {
-        data->type = GL_TEXTURE_RECTANGLE_ARB;
-        texture_w = texture->w;
-        texture_h = texture->h;
-        data->texw = (GLfloat) texture_w;
-        data->texh = (GLfloat) texture_h;
-    } else {
-        data->type = GL_TEXTURE_2D;
-        texture_w = power_of_2(texture->w);
-        texture_h = power_of_2(texture->h);
-        data->texw = (GLfloat) (texture->w) / texture_w;
-        data->texh = (GLfloat) texture->h / texture_h;
-    }
-
-    data->format = format;
-    data->formattype = type;
-    renderdata->glEnable(data->type);
-    renderdata->glBindTexture(data->type, data->texture);
-    renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER,
-                                GL_LINEAR);
-    renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER,
-                                GL_LINEAR);
-    renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
-                                GL_CLAMP_TO_EDGE);
-    renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
-                                GL_CLAMP_TO_EDGE);
-#ifdef __MACOSX__
-#ifndef GL_TEXTURE_STORAGE_HINT_APPLE
-#define GL_TEXTURE_STORAGE_HINT_APPLE       0x85BC
-#endif
-#ifndef STORAGE_CACHED_APPLE
-#define STORAGE_CACHED_APPLE                0x85BE
-#endif
-#ifndef STORAGE_SHARED_APPLE
-#define STORAGE_SHARED_APPLE                0x85BF
-#endif
-    if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
-        renderdata->glTexParameteri(data->type, GL_TEXTURE_STORAGE_HINT_APPLE,
-                                    GL_STORAGE_SHARED_APPLE);
-    } else {
-        renderdata->glTexParameteri(data->type, GL_TEXTURE_STORAGE_HINT_APPLE,
-                                    GL_STORAGE_CACHED_APPLE);
-    }
-    if (texture->access == SDL_TEXTUREACCESS_STREAMING
-        && texture->format == SDL_PIXELFORMAT_ARGB8888) {
-        renderdata->glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
-        renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
-                                 texture_h, 0, format, type, data->pixels);
-    }
-    else
-#endif
-    {
-        renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
-                                 texture_h, 0, format, type, NULL);
-    }
-    renderdata->glDisable(data->type);
-    result = renderdata->glGetError();
-    if (result != GL_NO_ERROR) {
-        GL_SetError("glTexImage2D()", result);
-        return -1;
-    }
-    return 0;
-}
-
-static void
-SetupTextureUpdate(GL_RenderData * renderdata, SDL_Texture * texture,
-                   int pitch)
-{
-    renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-    renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH,
-                              (pitch / SDL_BYTESPERPIXEL(texture->format)));
-}
-
-static int
-GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
-                 const SDL_Rect * rect, const void *pixels, int pitch)
-{
-    GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
-    GL_TextureData *data = (GL_TextureData *) texture->driverdata;
-    GLenum result;
-
-    GL_ActivateRenderer(renderer);
-
-    renderdata->glGetError();
-    SetupTextureUpdate(renderdata, texture, pitch);
-    renderdata->glEnable(data->type);
-    renderdata->glBindTexture(data->type, data->texture);
-    renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w,
-                                rect->h, data->format, data->formattype,
-                                pixels);
-    renderdata->glDisable(data->type);
-    result = renderdata->glGetError();
-    if (result != GL_NO_ERROR) {
-        GL_SetError("glTexSubImage2D()", result);
-        return -1;
-    }
-    return 0;
-}
-
-static int
-GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
-               const SDL_Rect * rect, void **pixels, int *pitch)
-{
-    GL_TextureData *data = (GL_TextureData *) texture->driverdata;
-
-    *pixels =
-        (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
-                  rect->x * SDL_BYTESPERPIXEL(texture->format));
-    *pitch = data->pitch;
-    return 0;
-}
-
-static void
-GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
-{
-    GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
-    GL_TextureData *data = (GL_TextureData *) texture->driverdata;
-
-    GL_ActivateRenderer(renderer);
-
-    SetupTextureUpdate(renderdata, texture, data->pitch);
-    renderdata->glEnable(data->type);
-    renderdata->glBindTexture(data->type, data->texture);
-    renderdata->glTexSubImage2D(data->type, 0, 0, 0, texture->w, texture->h,
-                                data->format, data->formattype, data->pixels);
-    renderdata->glDisable(data->type);
-}
-
-static void
-GL_SetBlendMode(GL_RenderData * data, int blendMode)
-{
-    if (blendMode != data->blendMode) {
-        switch (blendMode) {
-        case SDL_BLENDMODE_NONE:
-            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-            data->glDisable(GL_BLEND);
-            break;
-        case SDL_BLENDMODE_BLEND:
-            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-            data->glEnable(GL_BLEND);
-            data->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-            break;
-        case SDL_BLENDMODE_ADD:
-            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-            data->glEnable(GL_BLEND);
-            data->glBlendFunc(GL_SRC_ALPHA, GL_ONE);
-            break;
-        case SDL_BLENDMODE_MOD:
-            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-            data->glEnable(GL_BLEND);
-            data->glBlendFunc(GL_ZERO, GL_SRC_COLOR);
-            break;
-        }
-        data->blendMode = blendMode;
-    }
-}
-
-static int
-GL_RenderClear(SDL_Renderer * renderer)
-{
-    GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
-
-    GL_ActivateRenderer(renderer);
-
-    data->glClearColor((GLfloat) renderer->r * inv255f,
-                       (GLfloat) renderer->g * inv255f,
-                       (GLfloat) renderer->b * inv255f,
-                       (GLfloat) renderer->a * inv255f);
-
-    data->glClear(GL_COLOR_BUFFER_BIT);
-
-    return 0;
-}
-
-static int
-GL_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
-                    int count)
-{
-    GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
-    int i;
-
-    GL_ActivateRenderer(renderer);
-
-    GL_SetBlendMode(data, renderer->blendMode);
-
-    data->glColor4f((GLfloat) renderer->r * inv255f,
-                    (GLfloat) renderer->g * inv255f,
-                    (GLfloat) renderer->b * inv255f,
-                    (GLfloat) renderer->a * inv255f);
-
-    data->glBegin(GL_POINTS);
-    for (i = 0; i < count; ++i) {
-        data->glVertex2f(0.5f + points[i].x, 0.5f + points[i].y);
-    }
-    data->glEnd();
-
-    return 0;
-}
-
-static int
-GL_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
-                   int count)
-{
-    GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
-    int i;
-
-    GL_ActivateRenderer(renderer);
-
-    GL_SetBlendMode(data, renderer->blendMode);
-
-    data->glColor4f((GLfloat) renderer->r * inv255f,
-                    (GLfloat) renderer->g * inv255f,
-                    (GLfloat) renderer->b * inv255f,
-                    (GLfloat) renderer->a * inv255f);
-
-    if (count > 2 && 
-        points[0].x == points[count-1].x && points[0].y == points[count-1].y) {
-        data->glBegin(GL_LINE_LOOP);
-        /* GL_LINE_LOOP takes care of the final segment */
-        --count;
-        for (i = 0; i < count; ++i) {
-            data->glVertex2f(0.5f + points[i].x, 0.5f + points[i].y);
-        }
-        data->glEnd();
-    } else {
-#if defined(__APPLE__) || defined(__WIN32__)
-#else
-        int x1, y1, x2, y2;
-#endif
-
-        data->glBegin(GL_LINE_STRIP);
-        for (i = 0; i < count; ++i) {
-            data->glVertex2f(0.5f + points[i].x, 0.5f + points[i].y);
-        }
-        data->glEnd();
-
-        /* The line is half open, so we need one more point to complete it.
-         * http://www.opengl.org/documentation/specs/version1.1/glspec1.1/node47.html
-         * If we have to, we can use vertical line and horizontal line textures
-         * for vertical and horizontal lines, and then create custom textures
-         * for diagonal lines and software render those.  It's terrible, but at
-         * least it would be pixel perfect.
-         */
-        data->glBegin(GL_POINTS);
-#if defined(__APPLE__) || defined(__WIN32__)
-        /* Mac OS X and Windows seem to always leave the second point open */
-        data->glVertex2f(0.5f + points[count-1].x, 0.5f + points[count-1].y);
-#else
-        /* Linux seems to leave the right-most or bottom-most point open */
-        x1 = points[0].x;
-        y1 = points[0].y;
-        x2 = points[count-1].x;
-        y2 = points[count-1].y;
-
-        if (x1 > x2) {
-            data->glVertex2f(0.5f + x1, 0.5f + y1);
-        } else if (x2 > x1) {
-            data->glVertex2f(0.5f + x2, 0.5f + y2);
-        } else if (y1 > y2) {
-            data->glVertex2f(0.5f + x1, 0.5f + y1);
-        } else if (y2 > y1) {
-            data->glVertex2f(0.5f + x2, 0.5f + y2);
-        }
-#endif
-        data->glEnd();
-    }
-
-    return 0;
-}
-
-static int
-GL_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
-{
-    GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
-    int i;
-
-    GL_ActivateRenderer(renderer);
-
-    GL_SetBlendMode(data, renderer->blendMode);
-
-    data->glColor4f((GLfloat) renderer->r * inv255f,
-                    (GLfloat) renderer->g * inv255f,
-                    (GLfloat) renderer->b * inv255f,
-                    (GLfloat) renderer->a * inv255f);
-
-    for (i = 0; i < count; ++i) {
-        const SDL_Rect *rect = rects[i];
-
-        data->glRecti(rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
-    }
-
-    return 0;
-}
-
-static int
-GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
-              const SDL_Rect * srcrect, const SDL_Rect * dstrect)
-{
-    GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
-    GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
-    int minx, miny, maxx, maxy;
-    GLfloat minu, maxu, minv, maxv;
-
-    GL_ActivateRenderer(renderer);
-
-    minx = dstrect->x;
-    miny = dstrect->y;
-    maxx = dstrect->x + dstrect->w;
-    maxy = dstrect->y + dstrect->h;
-
-    minu = (GLfloat) srcrect->x / texture->w;
-    minu *= texturedata->texw;
-    maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w;
-    maxu *= texturedata->texw;
-    minv = (GLfloat) srcrect->y / texture->h;
-    minv *= texturedata->texh;
-    maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
-    maxv *= texturedata->texh;
-
-    data->glEnable(texturedata->type);
-    data->glBindTexture(texturedata->type, texturedata->texture);
-
-    if (texture->modMode) {
-        data->glColor4f((GLfloat) texture->r * inv255f,
-                        (GLfloat) texture->g * inv255f,
-                        (GLfloat) texture->b * inv255f,
-                        (GLfloat) texture->a * inv255f);
-    } else {
-        data->glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
-    }
-
-    GL_SetBlendMode(data, texture->blendMode);
-
-    data->glBegin(GL_TRIANGLE_STRIP);
-    data->glTexCoord2f(minu, minv);
-    data->glVertex2f((GLfloat) minx, (GLfloat) miny);
-    data->glTexCoord2f(maxu, minv);
-    data->glVertex2f((GLfloat) maxx, (GLfloat) miny);
-    data->glTexCoord2f(minu, maxv);
-    data->glVertex2f((GLfloat) minx, (GLfloat) maxy);
-    data->glTexCoord2f(maxu, maxv);
-    data->glVertex2f((GLfloat) maxx, (GLfloat) maxy);
-    data->glEnd();
-
-    data->glDisable(texturedata->type);
-
-    return 0;
-}
-
-static int
-GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
-                    Uint32 pixel_format, void * pixels, int pitch)
-{
-    GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
-    SDL_Window *window = renderer->window;
-    GLint internalFormat;
-    GLenum format, type;
-    Uint8 *src, *dst, *tmp;
-    int w, h, length, rows;
-
-    GL_ActivateRenderer(renderer);
-
-    if (!convert_format(data, pixel_format, &internalFormat, &format, &type)) {
-        /* FIXME: Do a temp copy to a format that is supported */
-        SDL_SetError("Unsupported pixel format");
-        return -1;
-    }
-
-    SDL_GetWindowSize(window, &w, &h);
-
-    data->glPixelStorei(GL_PACK_ALIGNMENT, 1);
-    data->glPixelStorei(GL_PACK_ROW_LENGTH,
-                        (pitch / SDL_BYTESPERPIXEL(pixel_format)));
-
-    data->glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h,
-                       format, type, pixels);
-
-    /* Flip the rows to be top-down */
-    length = rect->w * SDL_BYTESPERPIXEL(pixel_format);
-    src = (Uint8*)pixels + (rect->h-1)*pitch;
-    dst = (Uint8*)pixels;
-    tmp = SDL_stack_alloc(Uint8, length);
-    rows = rect->h / 2;
-    while (rows--) {
-        SDL_memcpy(tmp, dst, length);
-        SDL_memcpy(dst, src, length);
-        SDL_memcpy(src, tmp, length);
-        dst += pitch;
-        src -= pitch;
-    }
-    SDL_stack_free(tmp);
-
-    return 0;
-}
-
-static void
-GL_RenderPresent(SDL_Renderer * renderer)
-{
-    GL_ActivateRenderer(renderer);
-
-    SDL_GL_SwapWindow(renderer->window);
-}
-
-static void
-GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
-{
-    GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
-    GL_TextureData *data = (GL_TextureData *) texture->driverdata;
-
-    GL_ActivateRenderer(renderer);
-
-    if (!data) {
-        return;
-    }
-    if (data->texture) {
-        renderdata->glDeleteTextures(1, &data->texture);
-    }
-    if (data->pixels) {
-        SDL_free(data->pixels);
-    }
-    SDL_free(data);
-    texture->driverdata = NULL;
-}
-
-static void
-GL_DestroyRenderer(SDL_Renderer * renderer)
-{
-    GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
-
-    if (data) {
-        if (data->context) {
-            /* SDL_GL_MakeCurrent(0, NULL); *//* doesn't do anything */
-            SDL_GL_DeleteContext(data->context);
-        }
-        SDL_free(data);
-    }
-    SDL_free(renderer);
-}
-
-#endif /* SDL_VIDEO_RENDER_OGL */
-
-/* vi: set ts=4 sw=4 expandtab: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/render/opengles/SDL_render_gles.c	Sat Feb 05 12:01:11 2011 -0800
@@ -0,0 +1,748 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2010 Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+#if SDL_VIDEO_RENDER_OGL_ES
+
+#include "SDL_opengles.h"
+#include "../SDL_sysrender.h"
+
+#if defined(SDL_VIDEO_DRIVER_PANDORA)
+
+/* Empty function stub to get OpenGL ES 1.x support without  */
+/* OpenGL ES extension GL_OES_draw_texture supported         */
+GL_API void GL_APIENTRY
+glDrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)
+{
+    return;
+}
+
+#endif /* PANDORA */
+
+/* OpenGL ES 1.1 renderer implementation, based on the OpenGL renderer */
+
+/* Used to re-create the window with OpenGL capability */
+extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags);
+
+static const float inv255f = 1.0f / 255.0f;
+
+static SDL_Renderer *GLES_CreateRenderer(SDL_Window * window, Uint32 flags);
+static void GLES_WindowEvent(SDL_Renderer * renderer,
+                             const SDL_WindowEvent *event);
+static int GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
+static int GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+                              const SDL_Rect * rect, const void *pixels,
+                              int pitch);
+static int GLES_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+                            const SDL_Rect * rect, void **pixels, int *pitch);
+static void GLES_UnlockTexture(SDL_Renderer * renderer,
+                               SDL_Texture * texture);
+static int GLES_RenderDrawPoints(SDL_Renderer * renderer,
+                                 const SDL_Point * points, int count);
+static int GLES_RenderDrawLines(SDL_Renderer * renderer,
+                                const SDL_Point * points, int count);
+static int GLES_RenderFillRects(SDL_Renderer * renderer,
+                                const SDL_Rect ** rects, int count);
+static int GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
+                           const SDL_Rect * srcrect,
+                           const SDL_Rect * dstrect);
+static void GLES_RenderPresent(SDL_Renderer * renderer);
+static void GLES_DestroyTexture(SDL_Renderer * renderer,
+                                SDL_Texture * texture);
+static void GLES_DestroyRenderer(SDL_Renderer * renderer);
+
+
+SDL_RenderDriver GL_ES_RenderDriver = {
+    GLES_CreateRenderer,
+    {
+     "opengl_es",
+     (SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED),
+     1,
+     {SDL_PIXELFORMAT_ABGR8888},
+     0,
+     0}
+};
+
+typedef struct
+{
+    SDL_GLContext context;
+    SDL_bool updateSize;
+    int blendMode;
+
+#ifndef APIENTRY
+#define APIENTRY
+#endif
+
+    SDL_bool useDrawTexture;
+    SDL_bool GL_OES_draw_texture_supported;
+
+    /* OpenGL ES functions */
+#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
+#include "../../video/SDL_glesfuncs.h"
+#undef SDL_PROC
+
+} GLES_RenderData;
+
+typedef struct
+{
+    GLuint texture;
+    GLenum type;
+    GLfloat texw;
+    GLfloat texh;
+    GLenum format;
+    GLenum formattype;
+    void *pixels;
+    int pitch;
+} GLES_TextureData;
+
+static void
+GLES_SetError(const char *prefix, GLenum result)
+{
+    const char *error;
+
+    switch (result) {
+    case GL_NO_ERROR:
+        error = "GL_NO_ERROR";
+        break;
+    case GL_INVALID_ENUM:
+        error = "GL_INVALID_ENUM";
+        break;
+    case GL_INVALID_VALUE:
+        error = "GL_INVALID_VALUE";
+        break;
+    case GL_INVALID_OPERATION:
+        error = "GL_INVALID_OPERATION";
+        break;
+    case GL_STACK_OVERFLOW:
+        error = "GL_STACK_OVERFLOW";
+        break;
+    case GL_STACK_UNDERFLOW:
+        error = "GL_STACK_UNDERFLOW";
+        break;
+    case GL_OUT_OF_MEMORY:
+        error = "GL_OUT_OF_MEMORY";
+        break;
+    default:
+        error = "UNKNOWN";
+        break;
+    }
+    SDL_SetError("%s: %s", prefix, error);
+}
+
+static int
+GLES_LoadFunctions(GLES_RenderData * data)
+{
+
+#define SDL_PROC(ret,func,params) \
+    data->func = func;
+#include "../../video/SDL_glesfuncs.h"
+#undef SDL_PROC
+
+    return 0;
+}
+
+SDL_Renderer *
+GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
+{
+
+    SDL_Renderer *renderer;
+    GLES_RenderData *data;
+    GLint value;
+    Uint32 window_flags;
+
+    window_flags = SDL_GetWindowFlags(window);
+    if (!(window_flags & SDL_WINDOW_OPENGL)) {
+        if (SDL_RecreateWindow(window, window_flags | SDL_WINDOW_OPENGL) < 0) {
+            return NULL;
+        }
+    }
+
+    renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
+    if (!renderer) {
+        SDL_OutOfMemory();
+        return NULL;
+    }
+
+    data = (GLES_RenderData *) SDL_calloc(1, sizeof(*data));
+    if (!data) {
+        GLES_DestroyRenderer(renderer);
+        SDL_OutOfMemory();
+        return NULL;
+    }
+
+    renderer->WindowEvent = GLES_WindowEvent;
+    renderer->CreateTexture = GLES_CreateTexture;
+    renderer->UpdateTexture = GLES_UpdateTexture;
+    renderer->LockTexture = GLES_LockTexture;
+    renderer->UnlockTexture = GLES_UnlockTexture;
+    renderer->RenderDrawPoints = GLES_RenderDrawPoints;
+    renderer->RenderDrawLines = GLES_RenderDrawLines;
+    renderer->RenderFillRects = GLES_RenderFillRects;
+    renderer->RenderCopy = GLES_RenderCopy;
+    renderer->RenderPresent = GLES_RenderPresent;
+    renderer->DestroyTexture = GLES_DestroyTexture;
+    renderer->DestroyRenderer = GLES_DestroyRenderer;
+    renderer->info = GL_ES_RenderDriver.info;
+    renderer->driverdata = data;
+
+    renderer->info.flags = SDL_RENDERER_ACCELERATED;
+
+    if (GLES_LoadFunctions(data) < 0) {
+        GLES_DestroyRenderer(renderer);
+        return NULL;
+    }
+
+    data->context = SDL_GL_CreateContext(window);
+    if (!data->context) {
+        GLES_DestroyRenderer(renderer);
+        return NULL;
+    }
+    if (SDL_GL_MakeCurrent(window, data->context) < 0) {
+        GLES_DestroyRenderer(renderer);
+        return NULL;
+    }
+
+    if (flags & SDL_RENDERER_PRESENTVSYNC) {
+        SDL_GL_SetSwapInterval(1);
+    } else {
+        SDL_GL_SetSwapInterval(0);
+    }
+    if (SDL_GL_GetSwapInterval() > 0) {
+        renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
+    }
+
+#if SDL_VIDEO_DRIVER_PANDORA
+    data->GL_OES_draw_texture_supported = SDL_FALSE;
+    data->useDrawTexture = SDL_FALSE;
+#else
+    if (SDL_GL_ExtensionSupported("GL_OES_draw_texture")) {
+        data->GL_OES_draw_texture_supported = SDL_TRUE;
+        data->useDrawTexture = SDL_TRUE;
+    } else {
+        data->GL_OES_draw_texture_supported = SDL_FALSE;
+        data->useDrawTexture = SDL_FALSE;
+    }
+#endif
+
+    data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
+    renderer->info.max_texture_width = value;
+    data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
+    renderer->info.max_texture_height = value;
+
+    /* Set up parameters for rendering */
+    data->blendMode = -1;
+    data->glDisable(GL_DEPTH_TEST);
+    data->glDisable(GL_CULL_FACE);
+    data->updateSize = SDL_TRUE;
+
+    data->glEnableClientState(GL_VERTEX_ARRAY);
+    data->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+    
+    return renderer;
+}
+
+static SDL_GLContext SDL_CurrentContext = NULL;
+
+static int
+GLES_ActivateRenderer(SDL_Renderer * renderer)
+{
+
+    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
+    SDL_Window *window = renderer->window;
+
+    if (SDL_CurrentContext != data->context) {
+        if (SDL_GL_MakeCurrent(window, data->context) < 0) {
+            return -1;
+        }
+        SDL_CurrentContext = data->context;
+    }
+    if (data->updateSize) {
+        int w, h;
+
+        SDL_GetWindowSize(window, &w, &h);
+        data->glMatrixMode(GL_PROJECTION);
+        data->glLoadIdentity();
+        data->glMatrixMode(GL_MODELVIEW);
+        data->glLoadIdentity();
+        data->glViewport(0, 0, w, h);
+        data->glOrthof(0.0, (GLfloat) w, (GLfloat) h, 0.0, 0.0, 1.0);
+        data->updateSize = SDL_FALSE;
+    }
+    return 0;
+}
+
+static void
+GLES_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
+{
+    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
+
+    if (event->event == SDL_WINDOWEVENT_RESIZED) {
+        /* Rebind the context to the window area and update matrices */
+        SDL_CurrentContext = NULL;
+        data->updateSize = SDL_TRUE;
+    }
+}
+
+static __inline__ int
+power_of_2(int input)
+{
+    int value = 1;
+
+    while (value < input) {
+        value <<= 1;
+    }
+    return value;
+}
+
+static int
+GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+    GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
+    GLES_TextureData *data;
+    GLint internalFormat;
+    GLenum format, type;
+    int texture_w, texture_h;
+    GLenum result;
+
+    GLES_ActivateRenderer(renderer);
+
+    switch (texture->format) {
+    case SDL_PIXELFORMAT_ABGR8888:
+        internalFormat = GL_RGBA;
+        format = GL_RGBA;
+        type = GL_UNSIGNED_BYTE;
+        break;
+    default:
+        SDL_SetError("Texture format %s not supported by OpenGL ES",
+                     SDL_GetPixelFormatName(texture->format));
+        return -1;
+    }
+
+    data = (GLES_TextureData *) SDL_calloc(1, sizeof(*data));
+    if (!data) {
+        SDL_OutOfMemory();
+        return -1;
+    }
+
+    if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
+        data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
+        data->pixels = SDL_malloc(texture->h * data->pitch);
+        if (!data->pixels) {
+            SDL_OutOfMemory();
+            SDL_free(data);
+            return -1;
+        }
+    }
+
+    texture->driverdata = data;
+
+    renderdata->glGetError();
+    renderdata->glEnable(GL_TEXTURE_2D);
+    renderdata->glGenTextures(1, &data->texture);
+
+    data->type = GL_TEXTURE_2D;
+    /* no NPOV textures allowed in OpenGL ES (yet) */
+    texture_w = power_of_2(texture->w);
+    texture_h = power_of_2(texture->h);
+    data->texw = (GLfloat) texture->w / texture_w;
+    data->texh = (GLfloat) texture->h / texture_h;
+
+    data->format = format;
+    data->formattype = type;
+    renderdata->glBindTexture(data->type, data->texture);
+    renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER,
+                                GL_LINEAR);
+    renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER,
+                                GL_LINEAR);
+    renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
+                                GL_CLAMP_TO_EDGE);
+    renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
+                                GL_CLAMP_TO_EDGE);
+
+    renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
+                             texture_h, 0, format, type, NULL);
+    renderdata->glDisable(GL_TEXTURE_2D);
+
+    result = renderdata->glGetError();
+    if (result != GL_NO_ERROR) {
+        GLES_SetError("glTexImage2D()", result);
+        return -1;
+    }
+    return 0;
+}
+
+static void
+SetupTextureUpdate(GLES_RenderData * renderdata, SDL_Texture * texture,
+                   int pitch)
+{
+    renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+}
+
+static int
+GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+                   const SDL_Rect * rect, const void *pixels, int pitch)
+{
+    GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
+    GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
+    GLenum result;
+    int bpp = SDL_BYTESPERPIXEL(texture->format);
+    void * temp_buffer;
+    void * temp_ptr;
+    int i;
+
+    GLES_ActivateRenderer(renderer);
+
+    renderdata->glGetError();
+    SetupTextureUpdate(renderdata, texture, pitch);
+    renderdata->glEnable(data->type);
+    renderdata->glBindTexture(data->type, data->texture);
+
+    if( rect->w * bpp == pitch ) {
+         temp_buffer = (void *)pixels; /* No need to reformat */
+    } else {
+         /* Reformatting of mem area required */
+         temp_buffer = SDL_malloc(rect->w * rect->h * bpp);
+         temp_ptr = temp_buffer;
+         for (i = 0; i < rect->h; i++) {
+             SDL_memcpy(temp_ptr, pixels, rect->w * bpp);
+             temp_ptr += rect->w * bpp;
+             pixels += pitch;
+         }
+    }
+
+    renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w,
+                                rect->h, data->format, data->formattype,
+                                temp_buffer);
+
+    if( temp_buffer != pixels ) {
+        SDL_free(temp_buffer);
+    }
+
+    renderdata->glDisable(data->type);
+    result = renderdata->glGetError();
+    if (result != GL_NO_ERROR) {
+        GLES_SetError("glTexSubImage2D()", result);
+        return -1;
+    }
+    return 0;
+}
+
+static int
+GLES_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+                 const SDL_Rect * rect, void **pixels, int *pitch)
+{
+    GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
+
+    *pixels =
+        (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
+                  rect->x * SDL_BYTESPERPIXEL(texture->format));
+    *pitch = data->pitch;
+    return 0;
+}
+
+static void
+GLES_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+    GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
+    GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
+
+    GLES_ActivateRenderer(renderer);
+
+    SetupTextureUpdate(renderdata, texture, data->pitch);
+    renderdata->glEnable(data->type);
+    renderdata->glBindTexture(data->type, data->texture);
+    renderdata->glTexSubImage2D(data->type, 0, 0, 0, texture->w,
+                                texture->h, data->format, data->formattype,
+                                data->pixels);
+    renderdata->glDisable(data->type);
+}
+
+static void
+GLES_SetBlendMode(GLES_RenderData * data, int blendMode)
+{
+    if (blendMode != data->blendMode) {
+        switch (blendMode) {
+        case SDL_BLENDMODE_NONE:
+            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+            data->glDisable(GL_BLEND);
+            break;
+        case SDL_BLENDMODE_BLEND:
+            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+            data->glEnable(GL_BLEND);
+            data->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+            break;
+        case SDL_BLENDMODE_ADD:
+            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+            data->glEnable(GL_BLEND);
+            data->glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+            break;
+        case SDL_BLENDMODE_MOD:
+            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+            data->glEnable(GL_BLEND);
+            data->glBlendFunc(GL_ZERO, GL_SRC_COLOR);
+            break;
+        }
+        data->blendMode = blendMode;
+    }
+}
+
+static int
+GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
+                      int count)
+{
+    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
+    int i;
+    GLshort *vertices;
+
+    GLES_ActivateRenderer(renderer);
+
+    GLES_SetBlendMode(data, renderer->blendMode);
+
+    data->glColor4f((GLfloat) renderer->r * inv255f,
+                    (GLfloat) renderer->g * inv255f,
+                    (GLfloat) renderer->b * inv255f,
+                    (GLfloat) renderer->a * inv255f);
+
+    vertices = SDL_stack_alloc(GLshort, count*2);
+    for (i = 0; i < count; ++i) {
+        vertices[2*i+0] = (GLshort)points[i].x;
+        vertices[2*i+1] = (GLshort)points[i].y;
+    }
+    data->glVertexPointer(2, GL_SHORT, 0, vertices);
+    data->glDrawArrays(GL_POINTS, 0, count);
+    SDL_stack_free(vertices);
+
+    return 0;
+}
+
+static int
+GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
+                     int count)
+{
+    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
+    int i;
+    GLshort *vertices;
+
+    GLES_ActivateRenderer(renderer);
+
+    GLES_SetBlendMode(data, renderer->blendMode);
+
+    data->glColor4f((GLfloat) renderer->r * inv255f,
+                    (GLfloat) renderer->g * inv255f,
+                    (GLfloat) renderer->b * inv255f,
+                    (GLfloat) renderer->a * inv255f);
+
+    vertices = SDL_stack_alloc(GLshort, count*2);
+    for (i = 0; i < count; ++i) {
+        vertices[2*i+0] = (GLshort)points[i].x;
+        vertices[2*i+1] = (GLshort)points[i].y;
+    }
+    data->glVertexPointer(2, GL_SHORT, 0, vertices);
+    if (count > 2 && 
+        points[0].x == points[count-1].x && points[0].y == points[count-1].y) {
+        /* GL_LINE_LOOP takes care of the final segment */
+        --count;
+        data->glDrawArrays(GL_LINE_LOOP, 0, count);
+    } else {
+        data->glDrawArrays(GL_LINE_STRIP, 0, count);
+    }
+    SDL_stack_free(vertices);
+
+    return 0;
+}
+
+static int
+GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
+                     int count)
+{
+    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
+    int i;
+
+    GLES_ActivateRenderer(renderer);
+
+    GLES_SetBlendMode(data, renderer->blendMode);
+
+    data->glColor4f((GLfloat) renderer->r * inv255f,
+                    (GLfloat) renderer->g * inv255f,
+                    (GLfloat) renderer->b * inv255f,
+                    (GLfloat) renderer->a * inv255f);
+
+    for (i = 0; i < count; ++i) {
+        const SDL_Rect *rect = rects[i];
+        GLshort minx = rect->x;
+        GLshort maxx = rect->x + rect->w;
+        GLshort miny = rect->y;
+        GLshort maxy = rect->y + rect->h;
+        GLshort vertices[8];
+        vertices[0] = minx;
+        vertices[1] = miny;
+        vertices[2] = maxx;
+        vertices[3] = miny;
+        vertices[4] = minx;
+        vertices[5] = maxy;
+        vertices[6] = maxx;
+        vertices[7] = maxy;
+
+        data->glVertexPointer(2, GL_SHORT, 0, vertices);
+        data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+    }
+
+    return 0;
+}
+
+static int
+GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
+                const SDL_Rect * srcrect, const SDL_Rect * dstrect)
+{
+
+    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
+    GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata;
+    int minx, miny, maxx, maxy;
+    GLfloat minu, maxu, minv, maxv;
+    int i;
+    void *temp_buffer;          /* used for reformatting dirty rect pixels */
+    void *temp_ptr;
+
+    GLES_ActivateRenderer(renderer);
+
+    data->glEnable(GL_TEXTURE_2D);
+
+    data->glBindTexture(texturedata->type, texturedata->texture);
+
+    if (texture->modMode) {
+        data->glColor4f((GLfloat) texture->r * inv255f,
+                        (GLfloat) texture->g * inv255f,
+                        (GLfloat) texture->b * inv255f,
+                        (GLfloat) texture->a * inv255f);
+    } else {
+        data->glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+    }
+
+    GLES_SetBlendMode(data, texture->blendMode);
+
+    if (data->GL_OES_draw_texture_supported && data->useDrawTexture) {
+        /* this code is a little funny because the viewport is upside down vs SDL's coordinate system */
+        GLint cropRect[4];
+        int w, h;
+        SDL_Window *window = renderer->window;
+
+        SDL_GetWindowSize(window, &w, &h);
+        cropRect[0] = srcrect->x;
+        cropRect[1] = srcrect->y + srcrect->h;
+        cropRect[2] = srcrect->w;
+        cropRect[3] = -srcrect->h;
+        data->glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES,
+                               cropRect);
+        data->glDrawTexiOES(dstrect->x, h - dstrect->y - dstrect->h, 0,
+                            dstrect->w, dstrect->h);
+    } else {
+
+        minx = dstrect->x;
+        miny = dstrect->y;
+        maxx = dstrect->x + dstrect->w;
+        maxy = dstrect->y + dstrect->h;
+
+        minu = (GLfloat) srcrect->x / texture->w;
+        minu *= texturedata->texw;
+        maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w;
+        maxu *= texturedata->texw;
+        minv = (GLfloat) srcrect->y / texture->h;
+        minv *= texturedata->texh;
+        maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
+        maxv *= texturedata->texh;
+
+        GLshort vertices[8];
+        GLfloat texCoords[8];
+
+        vertices[0] = minx;
+        vertices[1] = miny;
+        vertices[2] = maxx;
+        vertices[3] = miny;
+        vertices[4] = minx;
+        vertices[5] = maxy;
+        vertices[6] = maxx;
+        vertices[7] = maxy;
+
+        texCoords[0] = minu;
+        texCoords[1] = minv;
+        texCoords[2] = maxu;
+        texCoords[3] = minv;
+        texCoords[4] = minu;
+        texCoords[5] = maxv;
+        texCoords[6] = maxu;
+        texCoords[7] = maxv;
+
+        data->glVertexPointer(2, GL_SHORT, 0, vertices);
+        data->glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
+        data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+    }
+
+    data->glDisable(GL_TEXTURE_2D);
+
+    return 0;
+}
+
+static void
+GLES_RenderPresent(SDL_Renderer * renderer)
+{
+    GLES_ActivateRenderer(renderer);
+
+    SDL_GL_SwapWindow(renderer->window);
+}
+
+static void
+GLES_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+    GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
+
+    GLES_ActivateRenderer(renderer);
+
+    if (!data) {
+        return;
+    }
+    if (data->texture) {
+        glDeleteTextures(1, &data->texture);
+    }
+    if (data->pixels) {
+        SDL_free(data->pixels);
+    }
+    SDL_free(data);
+    texture->driverdata = NULL;
+}
+
+static void
+GLES_DestroyRenderer(SDL_Renderer * renderer)
+{
+    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
+
+    if (data) {
+        if (data->context) {
+            SDL_GL_DeleteContext(data->context);
+        }
+        SDL_free(data);
+    }
+    SDL_free(renderer);
+}
+
+#endif /* SDL_VIDEO_RENDER_OGL_ES */
+
+/* vi: set ts=4 sw=4 expandtab: */
--- a/src/render/opengles/SDL_renderer_gles.c	Sat Feb 05 11:54:46 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,748 +0,0 @@
-/*
-    SDL - Simple DirectMedia Layer
-    Copyright (C) 1997-2010 Sam Lantinga
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    Sam Lantinga
-    slouken@libsdl.org
-*/
-#include "SDL_config.h"
-
-#if SDL_VIDEO_RENDER_OGL_ES
-
-#include "SDL_opengles.h"
-#include "../SDL_sysrender.h"
-
-#if defined(SDL_VIDEO_DRIVER_PANDORA)
-
-/* Empty function stub to get OpenGL ES 1.x support without  */
-/* OpenGL ES extension GL_OES_draw_texture supported         */
-GL_API void GL_APIENTRY
-glDrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)
-{
-    return;
-}
-
-#endif /* PANDORA */
-
-/* OpenGL ES 1.1 renderer implementation, based on the OpenGL renderer */
-
-/* Used to re-create the window with OpenGL capability */
-extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags);
-
-static const float inv255f = 1.0f / 255.0f;
-
-static SDL_Renderer *GLES_CreateRenderer(SDL_Window * window, Uint32 flags);
-static void GLES_WindowEvent(SDL_Renderer * renderer,
-                             const SDL_WindowEvent *event);
-static int GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
-static int GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
-                              const SDL_Rect * rect, const void *pixels,
-                              int pitch);
-static int GLES_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
-                            const SDL_Rect * rect, void **pixels, int *pitch);
-static void GLES_UnlockTexture(SDL_Renderer * renderer,
-                               SDL_Texture * texture);
-static int GLES_RenderDrawPoints(SDL_Renderer * renderer,
-                                 const SDL_Point * points, int count);
-static int GLES_RenderDrawLines(SDL_Renderer * renderer,
-                                const SDL_Point * points, int count);
-static int GLES_RenderFillRects(SDL_Renderer * renderer,
-                                const SDL_Rect ** rects, int count);
-static int GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
-                           const SDL_Rect * srcrect,
-                           const SDL_Rect * dstrect);
-static void GLES_RenderPresent(SDL_Renderer * renderer);
-static void GLES_DestroyTexture(SDL_Renderer * renderer,
-                                SDL_Texture * texture);
-static void GLES_DestroyRenderer(SDL_Renderer * renderer);
-
-
-SDL_RenderDriver GL_ES_RenderDriver = {
-    GLES_CreateRenderer,
-    {
-     "opengl_es",
-     (SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED),
-     1,
-     {SDL_PIXELFORMAT_ABGR8888},
-     0,
-     0}
-};
-
-typedef struct
-{
-    SDL_GLContext context;
-    SDL_bool updateSize;
-    int blendMode;
-
-#ifndef APIENTRY
-#define APIENTRY
-#endif
-
-    SDL_bool useDrawTexture;
-    SDL_bool GL_OES_draw_texture_supported;
-
-    /* OpenGL ES functions */
-#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
-#include "../../video/SDL_glesfuncs.h"
-#undef SDL_PROC
-
-} GLES_RenderData;
-
-typedef struct
-{
-    GLuint texture;
-    GLenum type;
-    GLfloat texw;
-    GLfloat texh;
-    GLenum format;
-    GLenum formattype;
-    void *pixels;
-    int pitch;
-} GLES_TextureData;
-
-static void
-GLES_SetError(const char *prefix, GLenum result)
-{
-    const char *error;
-
-    switch (result) {
-    case GL_NO_ERROR:
-        error = "GL_NO_ERROR";
-        break;
-    case GL_INVALID_ENUM:
-        error = "GL_INVALID_ENUM";
-        break;
-    case GL_INVALID_VALUE:
-        error = "GL_INVALID_VALUE";
-        break;
-    case GL_INVALID_OPERATION:
-        error = "GL_INVALID_OPERATION";
-        break;
-    case GL_STACK_OVERFLOW:
-        error = "GL_STACK_OVERFLOW";
-        break;
-    case GL_STACK_UNDERFLOW:
-        error = "GL_STACK_UNDERFLOW";
-        break;
-    case GL_OUT_OF_MEMORY:
-        error = "GL_OUT_OF_MEMORY";
-        break;
-    default:
-        error = "UNKNOWN";
-        break;
-    }
-    SDL_SetError("%s: %s", prefix, error);
-}
-
-static int
-GLES_LoadFunctions(GLES_RenderData * data)
-{
-
-#define SDL_PROC(ret,func,params) \
-    data->func = func;
-#include "../../video/SDL_glesfuncs.h"
-#undef SDL_PROC
-
-    return 0;
-}
-
-SDL_Renderer *
-GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
-{
-
-    SDL_Renderer *renderer;
-    GLES_RenderData *data;
-    GLint value;
-    Uint32 window_flags;
-
-    window_flags = SDL_GetWindowFlags(window);
-    if (!(window_flags & SDL_WINDOW_OPENGL)) {
-        if (SDL_RecreateWindow(window, window_flags | SDL_WINDOW_OPENGL) < 0) {
-            return NULL;
-        }
-    }
-
-    renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
-    if (!renderer) {
-        SDL_OutOfMemory();
-        return NULL;
-    }
-
-    data = (GLES_RenderData *) SDL_calloc(1, sizeof(*data));
-    if (!data) {
-        GLES_DestroyRenderer(renderer);
-        SDL_OutOfMemory();
-        return NULL;
-    }
-
-    renderer->WindowEvent = GLES_WindowEvent;
-    renderer->CreateTexture = GLES_CreateTexture;
-    renderer->UpdateTexture = GLES_UpdateTexture;
-    renderer->LockTexture = GLES_LockTexture;
-    renderer->UnlockTexture = GLES_UnlockTexture;
-    renderer->RenderDrawPoints = GLES_RenderDrawPoints;
-    renderer->RenderDrawLines = GLES_RenderDrawLines;
-    renderer->RenderFillRects = GLES_RenderFillRects;
-    renderer->RenderCopy = GLES_RenderCopy;
-    renderer->RenderPresent = GLES_RenderPresent;
-    renderer->DestroyTexture = GLES_DestroyTexture;
-    renderer->DestroyRenderer = GLES_DestroyRenderer;
-    renderer->info = GL_ES_RenderDriver.info;
-    renderer->driverdata = data;
-
-    renderer->info.flags = SDL_RENDERER_ACCELERATED;
-
-    if (GLES_LoadFunctions(data) < 0) {
-        GLES_DestroyRenderer(renderer);
-        return NULL;
-    }
-
-    data->context = SDL_GL_CreateContext(window);
-    if (!data->context) {
-        GLES_DestroyRenderer(renderer);
-        return NULL;
-    }
-    if (SDL_GL_MakeCurrent(window, data->context) < 0) {
-        GLES_DestroyRenderer(renderer);
-        return NULL;
-    }
-
-    if (flags & SDL_RENDERER_PRESENTVSYNC) {
-        SDL_GL_SetSwapInterval(1);
-    } else {
-        SDL_GL_SetSwapInterval(0);
-    }
-    if (SDL_GL_GetSwapInterval() > 0) {
-        renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
-    }
-
-#if SDL_VIDEO_DRIVER_PANDORA
-    data->GL_OES_draw_texture_supported = SDL_FALSE;
-    data->useDrawTexture = SDL_FALSE;
-#else
-    if (SDL_GL_ExtensionSupported("GL_OES_draw_texture")) {
-        data->GL_OES_draw_texture_supported = SDL_TRUE;
-        data->useDrawTexture = SDL_TRUE;
-    } else {
-        data->GL_OES_draw_texture_supported = SDL_FALSE;
-        data->useDrawTexture = SDL_FALSE;
-    }
-#endif
-
-    data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
-    renderer->info.max_texture_width = value;
-    data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
-    renderer->info.max_texture_height = value;
-
-    /* Set up parameters for rendering */
-    data->blendMode = -1;
-    data->glDisable(GL_DEPTH_TEST);
-    data->glDisable(GL_CULL_FACE);
-    data->updateSize = SDL_TRUE;
-
-    data->glEnableClientState(GL_VERTEX_ARRAY);
-    data->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-    
-    return renderer;
-}
-
-static SDL_GLContext SDL_CurrentContext = NULL;
-
-static int
-GLES_ActivateRenderer(SDL_Renderer * renderer)
-{
-
-    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
-    SDL_Window *window = renderer->window;
-
-    if (SDL_CurrentContext != data->context) {
-        if (SDL_GL_MakeCurrent(window, data->context) < 0) {
-            return -1;
-        }
-        SDL_CurrentContext = data->context;
-    }
-    if (data->updateSize) {
-        int w, h;
-
-        SDL_GetWindowSize(window, &w, &h);
-        data->glMatrixMode(GL_PROJECTION);
-        data->glLoadIdentity();
-        data->glMatrixMode(GL_MODELVIEW);
-        data->glLoadIdentity();
-        data->glViewport(0, 0, w, h);
-        data->glOrthof(0.0, (GLfloat) w, (GLfloat) h, 0.0, 0.0, 1.0);
-        data->updateSize = SDL_FALSE;
-    }
-    return 0;
-}
-
-static void
-GLES_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
-{
-    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
-
-    if (event->event == SDL_WINDOWEVENT_RESIZED) {
-        /* Rebind the context to the window area and update matrices */
-        SDL_CurrentContext = NULL;
-        data->updateSize = SDL_TRUE;
-    }
-}
-
-static __inline__ int
-power_of_2(int input)
-{
-    int value = 1;
-
-    while (value < input) {
-        value <<= 1;
-    }
-    return value;
-}
-
-static int
-GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
-{
-    GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
-    GLES_TextureData *data;
-    GLint internalFormat;
-    GLenum format, type;
-    int texture_w, texture_h;
-    GLenum result;
-
-    GLES_ActivateRenderer(renderer);
-
-    switch (texture->format) {
-    case SDL_PIXELFORMAT_ABGR8888:
-        internalFormat = GL_RGBA;
-        format = GL_RGBA;
-        type = GL_UNSIGNED_BYTE;
-        break;
-    default:
-        SDL_SetError("Texture format %s not supported by OpenGL ES",
-                     SDL_GetPixelFormatName(texture->format));
-        return -1;
-    }
-
-    data = (GLES_TextureData *) SDL_calloc(1, sizeof(*data));
-    if (!data) {
-        SDL_OutOfMemory();
-        return -1;
-    }
-
-    if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
-        data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
-        data->pixels = SDL_malloc(texture->h * data->pitch);
-        if (!data->pixels) {
-            SDL_OutOfMemory();
-            SDL_free(data);
-            return -1;
-        }
-    }
-
-    texture->driverdata = data;
-
-    renderdata->glGetError();
-    renderdata->glEnable(GL_TEXTURE_2D);
-    renderdata->glGenTextures(1, &data->texture);
-
-    data->type = GL_TEXTURE_2D;
-    /* no NPOV textures allowed in OpenGL ES (yet) */
-    texture_w = power_of_2(texture->w);
-    texture_h = power_of_2(texture->h);
-    data->texw = (GLfloat) texture->w / texture_w;
-    data->texh = (GLfloat) texture->h / texture_h;
-
-    data->format = format;
-    data->formattype = type;
-    renderdata->glBindTexture(data->type, data->texture);
-    renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER,
-                                GL_LINEAR);
-    renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER,
-                                GL_LINEAR);
-    renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
-                                GL_CLAMP_TO_EDGE);
-    renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
-                                GL_CLAMP_TO_EDGE);
-
-    renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
-                             texture_h, 0, format, type, NULL);
-    renderdata->glDisable(GL_TEXTURE_2D);
-
-    result = renderdata->glGetError();
-    if (result != GL_NO_ERROR) {
-        GLES_SetError("glTexImage2D()", result);
-        return -1;
-    }
-    return 0;
-}
-
-static void
-SetupTextureUpdate(GLES_RenderData * renderdata, SDL_Texture * texture,
-                   int pitch)
-{
-    renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-}
-
-static int
-GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
-                   const SDL_Rect * rect, const void *pixels, int pitch)
-{
-    GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
-    GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
-    GLenum result;
-    int bpp = SDL_BYTESPERPIXEL(texture->format);
-    void * temp_buffer;
-    void * temp_ptr;
-    int i;
-
-    GLES_ActivateRenderer(renderer);
-
-    renderdata->glGetError();
-    SetupTextureUpdate(renderdata, texture, pitch);
-    renderdata->glEnable(data->type);
-    renderdata->glBindTexture(data->type, data->texture);
-
-    if( rect->w * bpp == pitch ) {
-         temp_buffer = (void *)pixels; /* No need to reformat */
-    } else {
-         /* Reformatting of mem area required */
-         temp_buffer = SDL_malloc(rect->w * rect->h * bpp);
-         temp_ptr = temp_buffer;
-         for (i = 0; i < rect->h; i++) {
-             SDL_memcpy(temp_ptr, pixels, rect->w * bpp);
-             temp_ptr += rect->w * bpp;
-             pixels += pitch;
-         }
-    }
-
-    renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w,
-                                rect->h, data->format, data->formattype,
-                                temp_buffer);
-
-    if( temp_buffer != pixels ) {
-        SDL_free(temp_buffer);
-    }
-
-    renderdata->glDisable(data->type);
-    result = renderdata->glGetError();
-    if (result != GL_NO_ERROR) {
-        GLES_SetError("glTexSubImage2D()", result);
-        return -1;
-    }
-    return 0;
-}
-
-static int
-GLES_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
-                 const SDL_Rect * rect, void **pixels, int *pitch)
-{
-    GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
-
-    *pixels =
-        (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
-                  rect->x * SDL_BYTESPERPIXEL(texture->format));
-    *pitch = data->pitch;
-    return 0;
-}
-
-static void
-GLES_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
-{
-    GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
-    GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
-
-    GLES_ActivateRenderer(renderer);
-
-    SetupTextureUpdate(renderdata, texture, data->pitch);
-    renderdata->glEnable(data->type);
-    renderdata->glBindTexture(data->type, data->texture);
-    renderdata->glTexSubImage2D(data->type, 0, 0, 0, texture->w,
-                                texture->h, data->format, data->formattype,
-                                data->pixels);
-    renderdata->glDisable(data->type);
-}
-
-static void
-GLES_SetBlendMode(GLES_RenderData * data, int blendMode)
-{
-    if (blendMode != data->blendMode) {
-        switch (blendMode) {
-        case SDL_BLENDMODE_NONE:
-            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-            data->glDisable(GL_BLEND);
-            break;
-        case SDL_BLENDMODE_BLEND:
-            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-            data->glEnable(GL_BLEND);
-            data->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-            break;
-        case SDL_BLENDMODE_ADD:
-            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-            data->glEnable(GL_BLEND);
-            data->glBlendFunc(GL_SRC_ALPHA, GL_ONE);
-            break;
-        case SDL_BLENDMODE_MOD:
-            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-            data->glEnable(GL_BLEND);
-            data->glBlendFunc(GL_ZERO, GL_SRC_COLOR);
-            break;
-        }
-        data->blendMode = blendMode;
-    }
-}
-
-static int
-GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
-                      int count)
-{
-    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
-    int i;
-    GLshort *vertices;
-
-    GLES_ActivateRenderer(renderer);
-
-    GLES_SetBlendMode(data, renderer->blendMode);
-
-    data->glColor4f((GLfloat) renderer->r * inv255f,
-                    (GLfloat) renderer->g * inv255f,
-                    (GLfloat) renderer->b * inv255f,
-                    (GLfloat) renderer->a * inv255f);
-
-    vertices = SDL_stack_alloc(GLshort, count*2);
-    for (i = 0; i < count; ++i) {
-        vertices[2*i+0] = (GLshort)points[i].x;
-        vertices[2*i+1] = (GLshort)points[i].y;
-    }
-    data->glVertexPointer(2, GL_SHORT, 0, vertices);
-    data->glDrawArrays(GL_POINTS, 0, count);
-    SDL_stack_free(vertices);
-
-    return 0;
-}
-
-static int
-GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
-                     int count)
-{
-    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
-    int i;
-    GLshort *vertices;
-
-    GLES_ActivateRenderer(renderer);
-
-    GLES_SetBlendMode(data, renderer->blendMode);
-
-    data->glColor4f((GLfloat) renderer->r * inv255f,
-                    (GLfloat) renderer->g * inv255f,
-                    (GLfloat) renderer->b * inv255f,
-                    (GLfloat) renderer->a * inv255f);
-
-    vertices = SDL_stack_alloc(GLshort, count*2);
-    for (i = 0; i < count; ++i) {
-        vertices[2*i+0] = (GLshort)points[i].x;
-        vertices[2*i+1] = (GLshort)points[i].y;
-    }
-    data->glVertexPointer(2, GL_SHORT, 0, vertices);
-    if (count > 2 && 
-        points[0].x == points[count-1].x && points[0].y == points[count-1].y) {
-        /* GL_LINE_LOOP takes care of the final segment */
-        --count;
-        data->glDrawArrays(GL_LINE_LOOP, 0, count);
-    } else {
-        data->glDrawArrays(GL_LINE_STRIP, 0, count);
-    }
-    SDL_stack_free(vertices);
-
-    return 0;
-}
-
-static int
-GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
-                     int count)
-{
-    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
-    int i;
-
-    GLES_ActivateRenderer(renderer);
-
-    GLES_SetBlendMode(data, renderer->blendMode);
-
-    data->glColor4f((GLfloat) renderer->r * inv255f,
-                    (GLfloat) renderer->g * inv255f,
-                    (GLfloat) renderer->b * inv255f,
-                    (GLfloat) renderer->a * inv255f);
-
-    for (i = 0; i < count; ++i) {
-        const SDL_Rect *rect = rects[i];
-        GLshort minx = rect->x;
-        GLshort maxx = rect->x + rect->w;
-        GLshort miny = rect->y;
-        GLshort maxy = rect->y + rect->h;
-        GLshort vertices[8];
-        vertices[0] = minx;
-        vertices[1] = miny;
-        vertices[2] = maxx;
-        vertices[3] = miny;
-        vertices[4] = minx;
-        vertices[5] = maxy;
-        vertices[6] = maxx;
-        vertices[7] = maxy;
-
-        data->glVertexPointer(2, GL_SHORT, 0, vertices);
-        data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-    }
-
-    return 0;
-}
-
-static int
-GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
-                const SDL_Rect * srcrect, const SDL_Rect * dstrect)
-{
-
-    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
-    GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata;
-    int minx, miny, maxx, maxy;
-    GLfloat minu, maxu, minv, maxv;
-    int i;
-    void *temp_buffer;          /* used for reformatting dirty rect pixels */
-    void *temp_ptr;
-
-    GLES_ActivateRenderer(renderer);
-
-    data->glEnable(GL_TEXTURE_2D);
-
-    data->glBindTexture(texturedata->type, texturedata->texture);
-
-    if (texture->modMode) {
-        data->glColor4f((GLfloat) texture->r * inv255f,
-                        (GLfloat) texture->g * inv255f,
-                        (GLfloat) texture->b * inv255f,
-                        (GLfloat) texture->a * inv255f);
-    } else {
-        data->glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
-    }
-
-    GLES_SetBlendMode(data, texture->blendMode);
-
-    if (data->GL_OES_draw_texture_supported && data->useDrawTexture) {
-        /* this code is a little funny because the viewport is upside down vs SDL's coordinate system */
-        GLint cropRect[4];
-        int w, h;
-        SDL_Window *window = renderer->window;
-
-        SDL_GetWindowSize(window, &w, &h);
-        cropRect[0] = srcrect->x;
-        cropRect[1] = srcrect->y + srcrect->h;
-        cropRect[2] = srcrect->w;
-        cropRect[3] = -srcrect->h;
-        data->glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES,
-                               cropRect);
-        data->glDrawTexiOES(dstrect->x, h - dstrect->y - dstrect->h, 0,
-                            dstrect->w, dstrect->h);
-    } else {
-
-        minx = dstrect->x;
-        miny = dstrect->y;
-        maxx = dstrect->x + dstrect->w;
-        maxy = dstrect->y + dstrect->h;
-
-        minu = (GLfloat) srcrect->x / texture->w;
-        minu *= texturedata->texw;
-        maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w;
-        maxu *= texturedata->texw;
-        minv = (GLfloat) srcrect->y / texture->h;
-        minv *= texturedata->texh;
-        maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
-        maxv *= texturedata->texh;
-
-        GLshort vertices[8];
-        GLfloat texCoords[8];
-
-        vertices[0] = minx;
-        vertices[1] = miny;
-        vertices[2] = maxx;
-        vertices[3] = miny;
-        vertices[4] = minx;
-        vertices[5] = maxy;
-        vertices[6] = maxx;
-        vertices[7] = maxy;
-
-        texCoords[0] = minu;
-        texCoords[1] = minv;
-        texCoords[2] = maxu;
-        texCoords[3] = minv;
-        texCoords[4] = minu;
-        texCoords[5] = maxv;
-        texCoords[6] = maxu;
-        texCoords[7] = maxv;
-
-        data->glVertexPointer(2, GL_SHORT, 0, vertices);
-        data->glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
-        data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-    }
-
-    data->glDisable(GL_TEXTURE_2D);
-
-    return 0;
-}
-
-static void
-GLES_RenderPresent(SDL_Renderer * renderer)
-{
-    GLES_ActivateRenderer(renderer);
-
-    SDL_GL_SwapWindow(renderer->window);
-}
-
-static void
-GLES_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
-{
-    GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
-
-    GLES_ActivateRenderer(renderer);
-
-    if (!data) {
-        return;
-    }
-    if (data->texture) {
-        glDeleteTextures(1, &data->texture);
-    }
-    if (data->pixels) {
-        SDL_free(data->pixels);
-    }
-    SDL_free(data);
-    texture->driverdata = NULL;
-}
-
-static void
-GLES_DestroyRenderer(SDL_Renderer * renderer)
-{
-    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
-
-    if (data) {
-        if (data->context) {
-            SDL_GL_DeleteContext(data->context);
-        }
-        SDL_free(data);
-    }
-    SDL_free(renderer);
-}
-
-#endif /* SDL_VIDEO_RENDER_OGL_ES */
-
-/* vi: set ts=4 sw=4 expandtab: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/render/software/SDL_render_sw.c	Sat Feb 05 12:01:11 2011 -0800
@@ -0,0 +1,418 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2010 Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+#include "../SDL_sysrender.h"
+#include "../../video/SDL_pixels_c.h"
+
+#include "SDL_draw.h"
+#include "SDL_blendfillrect.h"
+#include "SDL_blendline.h"
+#include "SDL_blendpoint.h"
+#include "SDL_drawline.h"
+#include "SDL_drawpoint.h"
+
+
+/* SDL surface based renderer implementation */
+
+static SDL_Renderer *SW_CreateRenderer(SDL_Window * window, Uint32 flags);
+static void SW_WindowEvent(SDL_Renderer * renderer,
+                           const SDL_WindowEvent *event);
+static int SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
+static int SW_SetTextureColorMod(SDL_Renderer * renderer,
+                                 SDL_Texture * texture);
+static int SW_SetTextureAlphaMod(SDL_Renderer * renderer,
+                                 SDL_Texture * texture);
+static int SW_SetTextureBlendMode(SDL_Renderer * renderer,
+                                  SDL_Texture * texture);
+static int SW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+                            const SDL_Rect * rect, const void *pixels,
+                            int pitch);
+static int SW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+                          const SDL_Rect * rect, void **pixels, int *pitch);
+static void SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
+static int SW_RenderDrawPoints(SDL_Renderer * renderer,
+                               const SDL_Point * points, int count);
+static int SW_RenderDrawLines(SDL_Renderer * renderer,
+                              const SDL_Point * points, int count);
+static int SW_RenderFillRects(SDL_Renderer * renderer,
+                              const SDL_Rect ** rects, int count);
+static int SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
+                         const SDL_Rect * srcrect, const SDL_Rect * dstrect);
+static int SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+                               Uint32 format, void * pixels, int pitch);
+static void SW_RenderPresent(SDL_Renderer * renderer);
+static void SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture);
+static void SW_DestroyRenderer(SDL_Renderer * renderer);
+
+
+SDL_RenderDriver SW_RenderDriver = {
+    SW_CreateRenderer,
+    {
+     "software",
+     0,
+     8,
+     {
+      SDL_PIXELFORMAT_RGB555,
+      SDL_PIXELFORMAT_RGB565,
+      SDL_PIXELFORMAT_RGB888,
+      SDL_PIXELFORMAT_BGR888,
+      SDL_PIXELFORMAT_ARGB8888,
+      SDL_PIXELFORMAT_RGBA8888,
+      SDL_PIXELFORMAT_ABGR8888,
+      SDL_PIXELFORMAT_BGRA8888
+     },
+     0,
+     0}
+};
+
+typedef struct
+{
+    SDL_bool updateSize;
+    SDL_Surface *surface;
+} SW_RenderData;
+
+
+SDL_Renderer *
+SW_CreateRendererForSurface(SDL_Surface * surface)
+{
+    SDL_Renderer *renderer;
+    SW_RenderData *data;
+
+    if (!surface) {
+        SDL_SetError("Can't create renderer for NULL surface");
+        return NULL;
+    }
+
+    renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
+    if (!renderer) {
+        SDL_OutOfMemory();
+        return NULL;
+    }
+
+    data = (SW_RenderData *) SDL_calloc(1, sizeof(*data));
+    if (!data) {
+        SW_DestroyRenderer(renderer);
+        SDL_OutOfMemory();
+        return NULL;
+    }
+    data->surface = surface;
+
+    renderer->WindowEvent = SW_WindowEvent;
+    renderer->CreateTexture = SW_CreateTexture;
+    renderer->SetTextureColorMod = SW_SetTextureColorMod;
+    renderer->SetTextureAlphaMod = SW_SetTextureAlphaMod;
+    renderer->SetTextureBlendMode = SW_SetTextureBlendMode;
+    renderer->UpdateTexture = SW_UpdateTexture;
+    renderer->LockTexture = SW_LockTexture;
+    renderer->UnlockTexture = SW_UnlockTexture;
+    renderer->DestroyTexture = SW_DestroyTexture;
+    renderer->RenderDrawPoints = SW_RenderDrawPoints;
+    renderer->RenderDrawLines = SW_RenderDrawLines;
+    renderer->RenderFillRects = SW_RenderFillRects;
+    renderer->RenderCopy = SW_RenderCopy;
+    renderer->RenderReadPixels = SW_RenderReadPixels;
+    renderer->RenderPresent = SW_RenderPresent;
+    renderer->DestroyRenderer = SW_DestroyRenderer;
+    renderer->info = SW_RenderDriver.info;
+    renderer->driverdata = data;
+
+    return renderer;
+}
+
+SDL_Renderer *
+SW_CreateRenderer(SDL_Window * window, Uint32 flags)
+{
+    SDL_Surface *surface;
+
+    surface = SDL_GetWindowSurface(window);
+    if (!surface) {
+        return NULL;
+    }
+    return SW_CreateRendererForSurface(surface);
+}
+
+static SDL_Surface *
+SW_ActivateRenderer(SDL_Renderer * renderer)
+{
+    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
+    SDL_Window *window = renderer->window;
+
+    if (data->updateSize) {
+        data->surface = SDL_GetWindowSurface(window);
+        data->updateSize = SDL_FALSE;
+    }
+    return data->surface;
+}
+
+static void
+SW_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
+{
+    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
+
+    if (event->event == SDL_WINDOWEVENT_RESIZED) {
+        data->updateSize = SDL_TRUE;
+    }
+}
+
+static int
+SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+    int bpp;
+    Uint32 Rmask, Gmask, Bmask, Amask;
+
+    if (!SDL_PixelFormatEnumToMasks
+        (texture->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
+        SDL_SetError("Unknown texture format");
+        return -1;
+    }
+
+    texture->driverdata =
+        SDL_CreateRGBSurface(0, texture->w, texture->h, bpp, Rmask, Gmask,
+                             Bmask, Amask);
+    SDL_SetSurfaceColorMod(texture->driverdata, texture->r, texture->g,
+                           texture->b);
+    SDL_SetSurfaceAlphaMod(texture->driverdata, texture->a);
+    SDL_SetSurfaceBlendMode(texture->driverdata, texture->blendMode);
+
+    if (texture->access == SDL_TEXTUREACCESS_STATIC) {
+        SDL_SetSurfaceRLE(texture->driverdata, 1);
+    }
+
+    if (!texture->driverdata) {
+        return -1;
+    }
+    return 0;
+}
+
+static int
+SW_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+    SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
+    return SDL_SetSurfaceColorMod(surface, texture->r, texture->g,
+                                  texture->b);
+}
+
+static int
+SW_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+    SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
+    return SDL_SetSurfaceAlphaMod(surface, texture->a);
+}
+
+static int
+SW_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+    SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
+    return SDL_SetSurfaceBlendMode(surface, texture->blendMode);
+}
+
+static int
+SW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+                 const SDL_Rect * rect, const void *pixels, int pitch)
+{
+    SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
+    Uint8 *src, *dst;
+    int row;
+    size_t length;
+
+    src = (Uint8 *) pixels;
+    dst = (Uint8 *) surface->pixels +
+                        rect->y * surface->pitch +
+                        rect->x * surface->format->BytesPerPixel;
+    length = rect->w * surface->format->BytesPerPixel;
+    for (row = 0; row < rect->h; ++row) {
+        SDL_memcpy(dst, src, length);
+        src += pitch;
+        dst += surface->pitch;
+    }
+    return 0;
+}
+
+static int
+SW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+               const SDL_Rect * rect, void **pixels, int *pitch)
+{
+    SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
+
+    *pixels =
+        (void *) ((Uint8 *) surface->pixels + rect->y * surface->pitch +
+                  rect->x * surface->format->BytesPerPixel);
+    *pitch = surface->pitch;
+    return 0;
+}
+
+static void
+SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+}
+
+static int
+SW_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
+                    int count)
+{
+    SDL_Surface *surface = SW_ActivateRenderer(renderer);
+
+    if (!surface) {
+        return -1;
+    }
+
+    /* Draw the points! */
+    if (renderer->blendMode == SDL_BLENDMODE_NONE) {
+        Uint32 color = SDL_MapRGBA(surface->format,
+                                   renderer->r, renderer->g, renderer->b,
+                                   renderer->a);
+
+        return SDL_DrawPoints(surface, points, count, color);
+    } else {
+        return SDL_BlendPoints(surface, points, count,
+                               renderer->blendMode,
+                               renderer->r, renderer->g, renderer->b,
+                               renderer->a);
+    }
+}
+
+static int
+SW_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
+                   int count)
+{
+    SDL_Surface *surface = SW_ActivateRenderer(renderer);
+
+    if (!surface) {
+        return -1;
+    }
+
+    /* Draw the lines! */
+    if (renderer->blendMode == SDL_BLENDMODE_NONE) {
+        Uint32 color = SDL_MapRGBA(surface->format,
+                                   renderer->r, renderer->g, renderer->b,
+                                   renderer->a);
+
+        return SDL_DrawLines(surface, points, count, color);
+    } else {
+        return SDL_BlendLines(surface, points, count,
+                              renderer->blendMode,
+                              renderer->r, renderer->g, renderer->b,
+                              renderer->a);
+    }
+}
+
+static int
+SW_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
+                   int count)
+{
+    SDL_Surface *surface = SW_ActivateRenderer(renderer);
+
+    if (!surface) {
+        return -1;
+    }
+
+    if (renderer->blendMode == SDL_BLENDMODE_NONE) {
+        Uint32 color = SDL_MapRGBA(surface->format,
+                                   renderer->r, renderer->g, renderer->b,
+                                   renderer->a);
+        return SDL_FillRects(surface, rects, count, color);
+    } else {
+        return SDL_BlendFillRects(surface, rects, count,
+                                     renderer->blendMode,
+                                     renderer->r, renderer->g, renderer->b,
+                                     renderer->a);
+    }
+}
+
+static int
+SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
+              const SDL_Rect * srcrect, const SDL_Rect * dstrect)
+{
+    SDL_Surface *surface = SW_ActivateRenderer(renderer);
+    SDL_Surface *src = (SDL_Surface *) texture->driverdata;
+    SDL_Rect final_rect = *dstrect;
+
+    if (!surface) {
+        return -1;
+    }
+    return SDL_BlitSurface(src, srcrect, surface, &final_rect);
+}
+
+static int
+SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+                    Uint32 format, void * pixels, int pitch)
+{
+    SDL_Surface *surface = SW_ActivateRenderer(renderer);
+    Uint32 src_format;
+    void *src_pixels;
+
+    if (!surface) {
+        return -1;
+    }
+
+    if (rect->x < 0 || rect->x+rect->w > surface->w ||
+        rect->y < 0 || rect->y+rect->h > surface->h) {
+        SDL_SetError("Tried to read outside of surface bounds");
+        return -1;
+    }
+
+    src_format = SDL_MasksToPixelFormatEnum(
+                    surface->format->BitsPerPixel,
+                    surface->format->Rmask, surface->format->Gmask,
+                    surface->format->Bmask, surface->format->Amask);
+
+    src_pixels = (void*)((Uint8 *) surface->pixels +
+                    rect->y * surface->pitch +
+                    rect->x * surface->format->BytesPerPixel);
+
+    return SDL_ConvertPixels(rect->w, rect->h,
+                             src_format, src_pixels, surface->pitch,
+                             format, pixels, pitch);
+}
+
+static void
+SW_RenderPresent(SDL_Renderer * renderer)
+{
+    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
+    SDL_Window *window = renderer->window;
+
+    if (window) {
+        SDL_UpdateWindowSurface(window);
+    }
+}
+
+static void
+SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+    SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
+
+    SDL_FreeSurface(surface);
+}
+
+static void
+SW_DestroyRenderer(SDL_Renderer * renderer)
+{
+    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
+
+    if (data) {
+        SDL_free(data);
+    }
+    SDL_free(renderer);
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/render/software/SDL_render_sw_c.h	Sat Feb 05 12:01:11 2011 -0800
@@ -0,0 +1,25 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2010 Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+extern SDL_Renderer * SW_CreateRendererForSurface(SDL_Surface * surface);
+
+/* vi: set ts=4 sw=4 expandtab: */
--- a/src/render/software/SDL_renderer_sw.c	Sat Feb 05 11:54:46 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,418 +0,0 @@
-/*
-    SDL - Simple DirectMedia Layer
-    Copyright (C) 1997-2010 Sam Lantinga
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    Sam Lantinga
-    slouken@libsdl.org
-*/
-#include "SDL_config.h"
-
-#include "../SDL_sysrender.h"
-#include "../../video/SDL_pixels_c.h"
-
-#include "SDL_draw.h"
-#include "SDL_blendfillrect.h"
-#include "SDL_blendline.h"
-#include "SDL_blendpoint.h"
-#include "SDL_drawline.h"
-#include "SDL_drawpoint.h"
-
-
-/* SDL surface based renderer implementation */
-
-static SDL_Renderer *SW_CreateRenderer(SDL_Window * window, Uint32 flags);
-static void SW_WindowEvent(SDL_Renderer * renderer,
-                           const SDL_WindowEvent *event);
-static int SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
-static int SW_SetTextureColorMod(SDL_Renderer * renderer,
-                                 SDL_Texture * texture);
-static int SW_SetTextureAlphaMod(SDL_Renderer * renderer,
-                                 SDL_Texture * texture);
-static int SW_SetTextureBlendMode(SDL_Renderer * renderer,
-                                  SDL_Texture * texture);
-static int SW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
-                            const SDL_Rect * rect, const void *pixels,
-                            int pitch);
-static int SW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
-                          const SDL_Rect * rect, void **pixels, int *pitch);
-static void SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
-static int SW_RenderDrawPoints(SDL_Renderer * renderer,
-                               const SDL_Point * points, int count);
-static int SW_RenderDrawLines(SDL_Renderer * renderer,
-                              const SDL_Point * points, int count);
-static int SW_RenderFillRects(SDL_Renderer * renderer,
-                              const SDL_Rect ** rects, int count);
-static int SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
-                         const SDL_Rect * srcrect, const SDL_Rect * dstrect);
-static int SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
-                               Uint32 format, void * pixels, int pitch);
-static void SW_RenderPresent(SDL_Renderer * renderer);
-static void SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture);
-static void SW_DestroyRenderer(SDL_Renderer * renderer);
-
-
-SDL_RenderDriver SW_RenderDriver = {
-    SW_CreateRenderer,
-    {
-     "software",
-     0,
-     8,
-     {
-      SDL_PIXELFORMAT_RGB555,
-      SDL_PIXELFORMAT_RGB565,
-      SDL_PIXELFORMAT_RGB888,
-      SDL_PIXELFORMAT_BGR888,
-      SDL_PIXELFORMAT_ARGB8888,
-      SDL_PIXELFORMAT_RGBA8888,
-      SDL_PIXELFORMAT_ABGR8888,
-      SDL_PIXELFORMAT_BGRA8888
-     },
-     0,
-     0}
-};
-
-typedef struct
-{
-    SDL_bool updateSize;
-    SDL_Surface *surface;
-} SW_RenderData;
-
-
-SDL_Renderer *
-SW_CreateRendererForSurface(SDL_Surface * surface)
-{
-    SDL_Renderer *renderer;
-    SW_RenderData *data;
-
-    if (!surface) {
-        SDL_SetError("Can't create renderer for NULL surface");
-        return NULL;
-    }
-
-    renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
-    if (!renderer) {
-        SDL_OutOfMemory();
-        return NULL;
-    }
-
-    data = (SW_RenderData *) SDL_calloc(1, sizeof(*data));
-    if (!data) {
-        SW_DestroyRenderer(renderer);
-        SDL_OutOfMemory();
-        return NULL;
-    }
-    data->surface = surface;
-
-    renderer->WindowEvent = SW_WindowEvent;
-    renderer->CreateTexture = SW_CreateTexture;
-    renderer->SetTextureColorMod = SW_SetTextureColorMod;
-    renderer->SetTextureAlphaMod = SW_SetTextureAlphaMod;
-    renderer->SetTextureBlendMode = SW_SetTextureBlendMode;
-    renderer->UpdateTexture = SW_UpdateTexture;
-    renderer->LockTexture = SW_LockTexture;
-    renderer->UnlockTexture = SW_UnlockTexture;
-    renderer->DestroyTexture = SW_DestroyTexture;
-    renderer->RenderDrawPoints = SW_RenderDrawPoints;
-    renderer->RenderDrawLines = SW_RenderDrawLines;
-    renderer->RenderFillRects = SW_RenderFillRects;
-    renderer->RenderCopy = SW_RenderCopy;
-    renderer->RenderReadPixels = SW_RenderReadPixels;
-    renderer->RenderPresent = SW_RenderPresent;
-    renderer->DestroyRenderer = SW_DestroyRenderer;
-    renderer->info = SW_RenderDriver.info;
-    renderer->driverdata = data;
-
-    return renderer;
-}
-
-SDL_Renderer *
-SW_CreateRenderer(SDL_Window * window, Uint32 flags)
-{
-    SDL_Surface *surface;
-
-    surface = SDL_GetWindowSurface(window);
-    if (!surface) {
-        return NULL;
-    }
-    return SW_CreateRendererForSurface(surface);
-}
-
-static SDL_Surface *
-SW_ActivateRenderer(SDL_Renderer * renderer)
-{
-    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
-    SDL_Window *window = renderer->window;
-
-    if (data->updateSize) {
-        data->surface = SDL_GetWindowSurface(window);
-        data->updateSize = SDL_FALSE;
-    }
-    return data->surface;
-}
-
-static void
-SW_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
-{
-    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
-
-    if (event->event == SDL_WINDOWEVENT_RESIZED) {
-        data->updateSize = SDL_TRUE;
-    }
-}
-
-static int
-SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
-{
-    int bpp;
-    Uint32 Rmask, Gmask, Bmask, Amask;
-
-    if (!SDL_PixelFormatEnumToMasks
-        (texture->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
-        SDL_SetError("Unknown texture format");
-        return -1;
-    }
-
-    texture->driverdata =
-        SDL_CreateRGBSurface(0, texture->w, texture->h, bpp, Rmask, Gmask,
-                             Bmask, Amask);
-    SDL_SetSurfaceColorMod(texture->driverdata, texture->r, texture->g,
-                           texture->b);
-    SDL_SetSurfaceAlphaMod(texture->driverdata, texture->a);
-    SDL_SetSurfaceBlendMode(texture->driverdata, texture->blendMode);
-
-    if (texture->access == SDL_TEXTUREACCESS_STATIC) {
-        SDL_SetSurfaceRLE(texture->driverdata, 1);
-    }
-
-    if (!texture->driverdata) {
-        return -1;
-    }
-    return 0;
-}
-
-static int
-SW_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture)
-{
-    SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
-    return SDL_SetSurfaceColorMod(surface, texture->r, texture->g,
-                                  texture->b);
-}
-
-static int
-SW_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture)
-{
-    SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
-    return SDL_SetSurfaceAlphaMod(surface, texture->a);
-}
-
-static int
-SW_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture)
-{
-    SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
-    return SDL_SetSurfaceBlendMode(surface, texture->blendMode);
-}
-
-static int
-SW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
-                 const SDL_Rect * rect, const void *pixels, int pitch)
-{
-    SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
-    Uint8 *src, *dst;
-    int row;
-    size_t length;
-
-    src = (Uint8 *) pixels;
-    dst = (Uint8 *) surface->pixels +
-                        rect->y * surface->pitch +
-                        rect->x * surface->format->BytesPerPixel;
-    length = rect->w * surface->format->BytesPerPixel;
-    for (row = 0; row < rect->h; ++row) {
-        SDL_memcpy(dst, src, length);
-        src += pitch;
-        dst += surface->pitch;
-    }
-    return 0;
-}
-
-static int
-SW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
-               const SDL_Rect * rect, void **pixels, int *pitch)
-{
-    SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
-
-    *pixels =
-        (void *) ((Uint8 *) surface->pixels + rect->y * surface->pitch +
-                  rect->x * surface->format->BytesPerPixel);
-    *pitch = surface->pitch;
-    return 0;
-}
-
-static void
-SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
-{
-}
-
-static int
-SW_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
-                    int count)
-{
-    SDL_Surface *surface = SW_ActivateRenderer(renderer);
-
-    if (!surface) {
-        return -1;
-    }
-
-    /* Draw the points! */
-    if (renderer->blendMode == SDL_BLENDMODE_NONE) {
-        Uint32 color = SDL_MapRGBA(surface->format,
-                                   renderer->r, renderer->g, renderer->b,
-                                   renderer->a);
-
-        return SDL_DrawPoints(surface, points, count, color);
-    } else {
-        return SDL_BlendPoints(surface, points, count,
-                               renderer->blendMode,
-                               renderer->r, renderer->g, renderer->b,
-                               renderer->a);
-    }
-}
-
-static int
-SW_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
-                   int count)
-{
-    SDL_Surface *surface = SW_ActivateRenderer(renderer);
-
-    if (!surface) {
-        return -1;
-    }
-
-    /* Draw the lines! */
-    if (renderer->blendMode == SDL_BLENDMODE_NONE) {
-        Uint32 color = SDL_MapRGBA(surface->format,
-                                   renderer->r, renderer->g, renderer->b,
-                                   renderer->a);
-
-        return SDL_DrawLines(surface, points, count, color);
-    } else {
-        return SDL_BlendLines(surface, points, count,
-                              renderer->blendMode,
-                              renderer->r, renderer->g, renderer->b,
-                              renderer->a);
-    }
-}
-
-static int
-SW_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
-                   int count)
-{
-    SDL_Surface *surface = SW_ActivateRenderer(renderer);
-
-    if (!surface) {
-        return -1;
-    }
-
-    if (renderer->blendMode == SDL_BLENDMODE_NONE) {
-        Uint32 color = SDL_MapRGBA(surface->format,
-                                   renderer->r, renderer->g, renderer->b,
-                                   renderer->a);
-        return SDL_FillRects(surface, rects, count, color);
-    } else {
-        return SDL_BlendFillRects(surface, rects, count,
-                                     renderer->blendMode,
-                                     renderer->r, renderer->g, renderer->b,
-                                     renderer->a);
-    }
-}
-
-static int
-SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
-              const SDL_Rect * srcrect, const SDL_Rect * dstrect)
-{
-    SDL_Surface *surface = SW_ActivateRenderer(renderer);
-    SDL_Surface *src = (SDL_Surface *) texture->driverdata;
-    SDL_Rect final_rect = *dstrect;
-
-    if (!surface) {
-        return -1;
-    }
-    return SDL_BlitSurface(src, srcrect, surface, &final_rect);
-}
-
-static int
-SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
-                    Uint32 format, void * pixels, int pitch)
-{
-    SDL_Surface *surface = SW_ActivateRenderer(renderer);
-    Uint32 src_format;
-    void *src_pixels;
-
-    if (!surface) {
-        return -1;
-    }
-
-    if (rect->x < 0 || rect->x+rect->w > surface->w ||
-        rect->y < 0 || rect->y+rect->h > surface->h) {
-        SDL_SetError("Tried to read outside of surface bounds");
-        return -1;
-    }
-
-    src_format = SDL_MasksToPixelFormatEnum(
-                    surface->format->BitsPerPixel,
-                    surface->format->Rmask, surface->format->Gmask,
-                    surface->format->Bmask, surface->format->Amask);
-
-    src_pixels = (void*)((Uint8 *) surface->pixels +
-                    rect->y * surface->pitch +
-                    rect->x * surface->format->BytesPerPixel);
-
-    return SDL_ConvertPixels(rect->w, rect->h,
-                             src_format, src_pixels, surface->pitch,
-                             format, pixels, pitch);
-}
-
-static void
-SW_RenderPresent(SDL_Renderer * renderer)
-{
-    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
-    SDL_Window *window = renderer->window;
-
-    if (window) {
-        SDL_UpdateWindowSurface(window);
-    }
-}
-
-static void
-SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
-{
-    SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
-
-    SDL_FreeSurface(surface);
-}
-
-static void
-SW_DestroyRenderer(SDL_Renderer * renderer)
-{
-    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
-
-    if (data) {
-        SDL_free(data);
-    }
-    SDL_free(renderer);
-}
-
-/* vi: set ts=4 sw=4 expandtab: */
--- a/src/render/software/SDL_renderer_sw_c.h	Sat Feb 05 11:54:46 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-/*
-    SDL - Simple DirectMedia Layer
-    Copyright (C) 1997-2010 Sam Lantinga
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    Sam Lantinga
-    slouken@libsdl.org
-*/
-
-extern SDL_Renderer * SW_CreateRendererForSurface(SDL_Surface * surface);
-
-/* vi: set ts=4 sw=4 expandtab: */