Changed the concept of a render clip rect to a render viewport.
authorSam Lantinga <slouken@libsdl.org>
Tue, 15 Feb 2011 13:59:59 -0800
changeset 5297 1800dc39b74c
parent 5296 48067bfc300c
child 5298 7b1cac2c2230
Changed the concept of a render clip rect to a render viewport. The render viewport is automatically re-centered when the window changes size, so applications that don't care will not have to handle recalculating their rendering coordinates. Fixed API for drawing and filling multiple rectangles - the parameter should be an array of rects, not an array of pointers to rects. Fixed API for updating window rects for consistency with other APIs - the order is pointer to array followed by count in array.
include/SDL_render.h
include/SDL_surface.h
include/SDL_video.h
src/SDL_compat.c
src/render/SDL_render.c
src/render/SDL_sysrender.h
src/render/direct3d/SDL_render_d3d.c
src/render/opengl/SDL_render_gl.c
src/render/opengles/SDL_render_gles.c
src/render/opengles2/SDL_render_gles2.c
src/render/software/SDL_blendfillrect.c
src/render/software/SDL_blendfillrect.h
src/render/software/SDL_render_sw.c
src/video/SDL_fillrect.c
src/video/SDL_sysvideo.h
src/video/SDL_video.c
src/video/dummy/SDL_nullframebuffer.c
src/video/dummy/SDL_nullframebuffer_c.h
src/video/nds/SDL_ndsvideo.c
src/video/windows/SDL_windowsframebuffer.c
src/video/windows/SDL_windowsframebuffer.h
src/video/x11/SDL_x11framebuffer.c
src/video/x11/SDL_x11framebuffer.h
test/testdraw2.c
test/testintersections.c
test/testscale.c
test/testsprite2.c
--- a/include/SDL_render.h	Mon Feb 14 11:50:18 2011 -0600
+++ b/include/SDL_render.h	Tue Feb 15 13:59:59 2011 -0800
@@ -364,16 +364,23 @@
 extern DECLSPEC void SDLCALL SDL_UnlockTexture(SDL_Texture * texture);
 
 /**
- *  \brief Set the clipping rectangle for rendering on the current target
+ *  \brief Set the drawing area for rendering on the current target.
  *
- *  \param rect The rectangle to clip rendering to, or NULL to disable clipping.
+ *  \param rect The rectangle representing the drawing area, or NULL to set the viewport to the entire target.
+ *
+ *  The x,y of the viewport rect represents the origin for rendering.
  *
- *  The contents of the window are not defined after calling
- *  SDL_RenderPresent(), so you should clear the clip rectangle and draw
- *  over the entire window each frame.
+ *  \note When the window is resized, the current viewport is automatically
+ *        centered within the new window size.
  */
-extern DECLSPEC void SDLCALL SDL_RenderSetClipRect(SDL_Renderer * renderer,
-                                                   const SDL_Rect * rect);
+extern DECLSPEC int SDLCALL SDL_RenderSetViewport(SDL_Renderer * renderer,
+                                                  const SDL_Rect * rect);
+
+/**
+ *  \brief Get the drawing area for the current target.
+ */
+extern DECLSPEC void SDLCALL SDL_RenderGetViewport(SDL_Renderer * renderer,
+                                                   SDL_Rect * rect);
 
 /**
  *  \brief Set the color used for drawing operations (Fill and Line).
@@ -434,6 +441,8 @@
 
 /**
  *  \brief Clear the current rendering target with the drawing color
+ *
+ *  This function clears the entire rendering target, ignoring the viewport.
  */
 extern DECLSPEC int SDLCALL SDL_RenderClear(SDL_Renderer * renderer);
 
@@ -504,7 +513,7 @@
  *  \return 0 on success, or -1 on error
  */
 extern DECLSPEC int SDLCALL SDL_RenderDrawRects(SDL_Renderer * renderer,
-                                                const SDL_Rect ** rects,
+                                                const SDL_Rect * rects,
                                                 int count);
 
 /**
@@ -527,7 +536,7 @@
  *  \return 0 on success, or -1 on error
  */
 extern DECLSPEC int SDLCALL SDL_RenderFillRects(SDL_Renderer * renderer,
-                                                const SDL_Rect ** rect,
+                                                const SDL_Rect * rect,
                                                 int count);
 
 /**
--- a/include/SDL_surface.h	Mon Feb 14 11:50:18 2011 -0600
+++ b/include/SDL_surface.h	Tue Feb 15 13:59:59 2011 -0800
@@ -374,7 +374,7 @@
 extern DECLSPEC int SDLCALL SDL_FillRect
     (SDL_Surface * dst, const SDL_Rect * rect, Uint32 color);
 extern DECLSPEC int SDLCALL SDL_FillRects
-    (SDL_Surface * dst, const SDL_Rect ** rects, int count, Uint32 color);
+    (SDL_Surface * dst, const SDL_Rect * rects, int count, Uint32 color);
 
 /**
  *  Performs a fast blit from the source surface to the destination surface.
--- a/include/SDL_video.h	Mon Feb 14 11:50:18 2011 -0600
+++ b/include/SDL_video.h	Tue Feb 15 13:59:59 2011 -0800
@@ -581,8 +581,8 @@
  *  \sa SDL_UpdateWindowSurfaceRect()
  */
 extern DECLSPEC int SDLCALL SDL_UpdateWindowSurfaceRects(SDL_Window * window,
-                                                         int numrects,
-                                                         SDL_Rect * rects);
+                                                         SDL_Rect * rects,
+                                                         int numrects);
 
 /**
  *  \brief Set a window's input grab mode.
--- a/src/SDL_compat.c	Mon Feb 14 11:50:18 2011 -0600
+++ b/src/SDL_compat.c	Tue Feb 15 13:59:59 2011 -0800
@@ -785,10 +785,10 @@
                 stackrect->w = rect->w;
                 stackrect->h = rect->h;
             }
-            SDL_UpdateWindowSurfaceRects(SDL_VideoWindow, numrects, stackrects);
+            SDL_UpdateWindowSurfaceRects(SDL_VideoWindow, stackrects, numrects);
             SDL_stack_free(stackrects);
         } else {
-            SDL_UpdateWindowSurfaceRects(SDL_VideoWindow, numrects, rects);
+            SDL_UpdateWindowSurfaceRects(SDL_VideoWindow, rects, numrects);
         }
     }
 }
--- a/src/render/SDL_render.c	Mon Feb 14 11:50:18 2011 -0600
+++ b/src/render/SDL_render.c	Tue Feb 15 13:59:59 2011 -0800
@@ -89,10 +89,25 @@
 {
     SDL_Renderer *renderer = (SDL_Renderer *)userdata;
 
-    if (event->type == SDL_WINDOWEVENT && renderer->WindowEvent) {
+    if (event->type == SDL_WINDOWEVENT) {
         SDL_Window *window = SDL_GetWindowFromID(event->window.windowID);
         if (window == renderer->window) {
-            renderer->WindowEvent(renderer, &event->window);
+            if (renderer->WindowEvent) {
+                renderer->WindowEvent(renderer, &event->window);
+            }
+
+            if (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
+                /* Try to keep the previous viewport centered */
+                int w, h;
+                SDL_Rect viewport;
+
+                SDL_GetWindowSize(window, &w, &h);
+                viewport.x = (w - renderer->viewport.w) / 2;
+                viewport.y = (h - renderer->viewport.h) / 2;
+                viewport.w = renderer->viewport.w;
+                viewport.h = renderer->viewport.h;
+                SDL_RenderSetViewport(renderer, &viewport);
+            }
         }
     }
     return 0;
@@ -160,6 +175,8 @@
         renderer->magic = &renderer_magic;
         renderer->window = window;
 
+        SDL_RenderSetViewport(renderer, NULL);
+
         SDL_AddEventWatch(SDL_RendererEventWatch, renderer);
 
         SDL_LogInfo(SDL_LOG_CATEGORY_RENDER,
@@ -172,7 +189,16 @@
 SDL_CreateSoftwareRenderer(SDL_Surface * surface)
 {
 #if !SDL_RENDER_DISABLED
-    return SW_CreateRendererForSurface(surface);
+    SDL_Renderer *renderer;
+
+    renderer = SW_CreateRendererForSurface(surface);
+
+    if (renderer) {
+        renderer->magic = &renderer_magic;
+
+        SDL_RenderSetViewport(renderer, NULL);
+    }
+    return renderer;
 #else
     SDL_SetError("SDL not built with rendering support");
     return NULL;
@@ -342,12 +368,13 @@
             SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch);
         }
     } else {
-        SDL_PixelFormat dst_fmt;
+        SDL_PixelFormat *dst_fmt;
         SDL_Surface *temp = NULL;
 
         /* Set up a destination surface for the texture update */
-        SDL_InitFormat(&dst_fmt, format);
-        temp = SDL_ConvertSurface(surface, &dst_fmt, 0);
+        dst_fmt = SDL_AllocFormat(format);
+        temp = SDL_ConvertSurface(surface, dst_fmt, 0);
+        SDL_FreeFormat(dst_fmt);
         if (temp) {
             SDL_UpdateTexture(texture, NULL, temp->pixels, temp->pitch);
             SDL_FreeSurface(temp);
@@ -733,12 +760,34 @@
     }
 }
 
+int
+SDL_RenderSetViewport(SDL_Renderer * renderer, const SDL_Rect * rect)
+{
+    CHECK_RENDERER_MAGIC(renderer, -1);
+
+    if (rect) {
+        renderer->viewport = *rect;
+    } else {
+        renderer->viewport.x = 0;
+        renderer->viewport.y = 0;
+        if (renderer->window) {
+            SDL_GetWindowSize(renderer->window,
+                              &renderer->viewport.w, &renderer->viewport.h);
+        } else {
+            /* This will be filled in by UpdateViewport() */
+            renderer->viewport.w = 0;
+            renderer->viewport.h = 0;
+        }
+    }
+    return renderer->UpdateViewport(renderer);
+}
+
 void
-SDL_RenderSetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect)
+SDL_RenderGetViewport(SDL_Renderer * renderer, SDL_Rect * rect)
 {
     CHECK_RENDERER_MAGIC(renderer, );
 
-    renderer->SetClipRect(renderer, rect);
+    *rect = renderer->viewport;
 }
 
 int
@@ -884,7 +933,8 @@
 
         full_rect.x = 0;
         full_rect.y = 0;
-        SDL_GetWindowSize(window, &full_rect.w, &full_rect.h);
+        full_rect.w = renderer->viewport.w;
+        full_rect.h = renderer->viewport.h;
         rect = &full_rect;
     }
 
@@ -903,7 +953,7 @@
 
 int
 SDL_RenderDrawRects(SDL_Renderer * renderer,
-                    const SDL_Rect ** rects, int count)
+                    const SDL_Rect * rects, int count)
 {
     int i;
 
@@ -917,9 +967,8 @@
         return 0;
     }
 
-    /* Check for NULL rect, which means fill entire window */
     for (i = 0; i < count; ++i) {
-        if (SDL_RenderDrawRect(renderer, rects[i]) < 0) {
+        if (SDL_RenderDrawRect(renderer, &rects[i]) < 0) {
             return -1;
         }
     }
@@ -929,15 +978,13 @@
 int
 SDL_RenderFillRect(SDL_Renderer * renderer, const SDL_Rect * rect)
 {
-    return SDL_RenderFillRects(renderer, &rect, 1);
+    return SDL_RenderFillRects(renderer, rect, 1);
 }
 
 int
 SDL_RenderFillRects(SDL_Renderer * renderer,
-                    const SDL_Rect ** rects, int count)
+                    const SDL_Rect * rects, int count)
 {
-    int i;
-
     CHECK_RENDERER_MAGIC(renderer, -1);
 
     if (!rects) {
@@ -947,21 +994,6 @@
     if (count < 1) {
         return 0;
     }
-
-    /* Check for NULL rect, which means fill entire window */
-    for (i = 0; i < count; ++i) {
-        if (rects[i] == NULL) {
-            SDL_Window *window = renderer->window;
-            SDL_Rect full_rect;
-            const SDL_Rect *rect;
-
-            full_rect.x = 0;
-            full_rect.y = 0;
-            SDL_GetWindowSize(window, &full_rect.w, &full_rect.h);
-            rect = &full_rect;
-            return renderer->RenderFillRects(renderer, &rect, 1);
-        }
-    }
     return renderer->RenderFillRects(renderer, rects, count);
 }
 
@@ -994,7 +1026,8 @@
 
     real_dstrect.x = 0;
     real_dstrect.y = 0;
-    SDL_GetWindowSize(window, &real_dstrect.w, &real_dstrect.h);
+    real_dstrect.w = renderer->viewport.w;
+    real_dstrect.h = renderer->viewport.h;
     if (dstrect) {
         if (!SDL_IntersectRect(dstrect, &real_dstrect, &real_dstrect)) {
             return 0;
@@ -1043,7 +1076,8 @@
 
     real_rect.x = 0;
     real_rect.y = 0;
-    SDL_GetWindowSize(window, &real_rect.w, &real_rect.h);
+    real_rect.w = renderer->viewport.w;
+    real_rect.h = renderer->viewport.h;
     if (rect) {
         if (!SDL_IntersectRect(rect, &real_rect, &real_rect)) {
             return 0;
--- a/src/render/SDL_sysrender.h	Mon Feb 14 11:50:18 2011 -0600
+++ b/src/render/SDL_sysrender.h	Tue Feb 15 13:59:59 2011 -0800
@@ -78,13 +78,13 @@
     int (*LockTexture) (SDL_Renderer * renderer, SDL_Texture * texture,
                         const SDL_Rect * rect, void **pixels, int *pitch);
     void (*UnlockTexture) (SDL_Renderer * renderer, SDL_Texture * texture);
-    void (*SetClipRect) (SDL_Renderer * renderer, const SDL_Rect *rect);
+    int (*UpdateViewport) (SDL_Renderer * renderer);
     int (*RenderClear) (SDL_Renderer * renderer);
     int (*RenderDrawPoints) (SDL_Renderer * renderer, const SDL_Point * points,
                              int count);
     int (*RenderDrawLines) (SDL_Renderer * renderer, const SDL_Point * points,
                             int count);
-    int (*RenderFillRects) (SDL_Renderer * renderer, const SDL_Rect ** rects,
+    int (*RenderFillRects) (SDL_Renderer * renderer, const SDL_Rect * rects,
                             int count);
     int (*RenderCopy) (SDL_Renderer * renderer, SDL_Texture * texture,
                        const SDL_Rect * srcrect, const SDL_Rect * dstrect);
@@ -101,6 +101,9 @@
     /* The window associated with the renderer */
     SDL_Window *window;
 
+    /* The drawable area within the window */
+    SDL_Rect viewport;
+
     /* The list of textures */
     SDL_Texture *textures;
 
--- a/src/render/direct3d/SDL_render_d3d.c	Mon Feb 14 11:50:18 2011 -0600
+++ b/src/render/direct3d/SDL_render_d3d.c	Tue Feb 15 13:59:59 2011 -0800
@@ -90,6 +90,8 @@
 /* Direct3D renderer implementation */
 
 static SDL_Renderer *D3D_CreateRenderer(SDL_Window * window, Uint32 flags);
+static void D3D_WindowEvent(SDL_Renderer * renderer,
+                            const SDL_WindowEvent *event);
 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,
@@ -97,13 +99,14 @@
 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 void D3D_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect);
+static int D3D_UpdateViewport(SDL_Renderer * renderer);
+static int D3D_RenderClear(SDL_Renderer * renderer);
 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);
+                               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,
@@ -132,6 +135,7 @@
     IDirect3DDevice9 *device;
     UINT adapter;
     D3DPRESENT_PARAMETERS pparams;
+    SDL_bool updateSize;
     SDL_bool beginScene;
 } D3D_RenderData;
 
@@ -143,7 +147,6 @@
 typedef struct
 {
     float x, y, z;
-    float rhw;
     DWORD color;
     float u, v;
 } Vertex;
@@ -257,6 +260,74 @@
     }
 }
 
+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_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
+    IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE,
+                                    D3DCULL_NONE);
+    IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE);
+    return 0;
+}
+
+static int
+D3D_ActivateRenderer(SDL_Renderer * renderer)
+{
+    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
+    HRESULT result;
+
+    if (data->updateSize) {
+        SDL_Window *window = renderer->window;
+        int w, h;
+
+        SDL_GetWindowSize(window, &w, &h);
+        data->pparams.BackBufferWidth = w;
+        data->pparams.BackBufferHeight = h;
+        if (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) {
+            data->pparams.BackBufferFormat =
+                PixelFormatToD3DFMT(SDL_GetWindowPixelFormat(window));
+        } else {
+            data->pparams.BackBufferFormat = D3DFMT_UNKNOWN;
+        }
+        if (D3D_Reset(renderer) < 0) {
+            return -1;
+        }
+        D3D_UpdateViewport(renderer);
+
+        data->updateSize = SDL_FALSE;
+    }
+    if (data->beginScene) {
+        result = IDirect3DDevice9_BeginScene(data->device);
+        if (result == D3DERR_DEVICELOST) {
+            if (D3D_Reset(renderer) < 0) {
+                return -1;
+            }
+            result = IDirect3DDevice9_BeginScene(data->device);
+        }
+        if (FAILED(result)) {
+            D3D_SetError("BeginScene()", result);
+            return -1;
+        }
+        data->beginScene = SDL_FALSE;
+    }
+    return 0;
+}
+
 SDL_Renderer *
 D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
 {
@@ -270,6 +341,7 @@
     Uint32 window_flags;
     int w, h;
     SDL_DisplayMode fullscreen_mode;
+    D3DMATRIX matrix;
 
     renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
     if (!renderer) {
@@ -306,11 +378,13 @@
         return NULL;
     }
 
+    renderer->WindowEvent = D3D_WindowEvent;
     renderer->CreateTexture = D3D_CreateTexture;
     renderer->UpdateTexture = D3D_UpdateTexture;
     renderer->LockTexture = D3D_LockTexture;
     renderer->UnlockTexture = D3D_UnlockTexture;
-    renderer->SetClipRect = D3D_SetClipRect;
+    renderer->UpdateViewport = D3D_UpdateViewport;
+    renderer->RenderClear = D3D_RenderClear;
     renderer->RenderDrawPoints = D3D_RenderDrawPoints;
     renderer->RenderDrawLines = D3D_RenderDrawLines;
     renderer->RenderFillRects = D3D_RenderFillRects;
@@ -405,7 +479,7 @@
     /* Set up parameters for rendering */
     IDirect3DDevice9_SetVertexShader(data->device, NULL);
     IDirect3DDevice9_SetFVF(data->device,
-                            D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
+                            D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
     IDirect3DDevice9_SetRenderState(data->device, D3DRS_ZENABLE, D3DZB_FALSE);
     IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE,
                                     D3DCULL_NONE);
@@ -430,55 +504,39 @@
     IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_ALPHAOP,
                                           D3DTOP_DISABLE);
 
+    /* Set an identity world and view matrix */
+    matrix.m[0][0] = 1.0f;
+    matrix.m[0][1] = 0.0f;
+    matrix.m[0][2] = 0.0f;
+    matrix.m[0][3] = 0.0f;
+    matrix.m[1][0] = 0.0f;
+    matrix.m[1][1] = 1.0f;
+    matrix.m[1][2] = 0.0f;
+    matrix.m[1][3] = 0.0f;
+    matrix.m[2][0] = 0.0f;
+    matrix.m[2][1] = 0.0f;
+    matrix.m[2][2] = 1.0f;
+    matrix.m[2][3] = 0.0f;
+    matrix.m[3][0] = 0.0f;
+    matrix.m[3][1] = 0.0f;
+    matrix.m[3][2] = 0.0f;
+    matrix.m[3][3] = 1.0f;
+    IDirect3DDevice9_SetTransform(data->device, D3DTS_WORLD, &matrix);
+    IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, &matrix);
+
     return renderer;
 }
 
-static int
-D3D_Reset(SDL_Renderer * renderer)
+static void
+D3D_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
 {
     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;
-        }
+    if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
+        data->updateSize = SDL_TRUE;
     }
-    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)
 {
@@ -604,25 +662,83 @@
     IDirect3DTexture9_UnlockRect(data->texture, 0);
 }
 
-static void
-D3D_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect)
+static int
+D3D_UpdateViewport(SDL_Renderer * renderer)
 {
     D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
+    D3DVIEWPORT9 viewport;
+    D3DMATRIX matrix;
 
-    if (rect) {
-        RECT d3drect;
+    /* Set the viewport */
+    viewport.X = renderer->viewport.x;
+    viewport.Y = renderer->viewport.y;
+    viewport.Width = renderer->viewport.w;
+    viewport.Height = renderer->viewport.h;
+    viewport.MinZ = 0.0f;
+    viewport.MaxZ = 1.0f;
+    IDirect3DDevice9_SetViewport(data->device, &viewport);
+
+    /* Set an orthographic projection matrix */
+    matrix.m[0][0] = 2.0f / renderer->viewport.w;
+    matrix.m[0][1] = 0.0f;
+    matrix.m[0][2] = 0.0f;
+    matrix.m[0][3] = 0.0f;
+    matrix.m[1][0] = 0.0f;
+    matrix.m[1][1] = -2.0f / renderer->viewport.h;
+    matrix.m[1][2] = 0.0f;
+    matrix.m[1][3] = 0.0f;
+    matrix.m[2][0] = 0.0f;
+    matrix.m[2][1] = 0.0f;
+    matrix.m[2][2] = 1.0f;
+    matrix.m[2][3] = 0.0f;
+    matrix.m[3][0] = -1.0f;
+    matrix.m[3][1] = 1.0f;
+    matrix.m[3][2] = 0.0f;
+    matrix.m[3][3] = 1.0f;
+    IDirect3DDevice9_SetTransform(data->device, D3DTS_PROJECTION, &matrix);
+
+    return 0;
+}
 
-        d3drect.left = rect->x;
-        d3drect.right = rect->x + rect->w;
-        d3drect.top = rect->y;
-        d3drect.bottom = rect->y + rect->h;
-        IDirect3DDevice9_SetScissorRect(data->device, &d3drect);
-        IDirect3DDevice9_SetRenderState(data->device, D3DRS_SCISSORTESTENABLE,
-                                        TRUE);
-    } else {
-        IDirect3DDevice9_SetRenderState(data->device, D3DRS_SCISSORTESTENABLE,
-                                        FALSE);
+static int
+D3D_RenderClear(SDL_Renderer * renderer)
+{
+    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
+    D3DVIEWPORT9 viewport;
+    DWORD color;
+    HRESULT result;
+
+    if (D3D_ActivateRenderer(renderer) < 0) {
+        return -1;
     }
+
+    /* Clear is defined to clear the entire render target */
+    viewport.X = 0;
+    viewport.Y = 0;
+    viewport.Width = data->pparams.BackBufferWidth;
+    viewport.Height = data->pparams.BackBufferHeight;
+    viewport.MinZ = 0.0f;
+    viewport.MaxZ = 1.0f;
+    IDirect3DDevice9_SetViewport(data->device, &viewport);
+
+    color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b);
+
+    result = IDirect3DDevice9_Clear(data->device, 0, NULL, D3DCLEAR_TARGET, color, 0.0f, 0);
+
+    /* Reset the viewport */
+    viewport.X = renderer->viewport.x;
+    viewport.Y = renderer->viewport.y;
+    viewport.Width = renderer->viewport.w;
+    viewport.Height = renderer->viewport.h;
+    viewport.MinZ = 0.0f;
+    viewport.MaxZ = 1.0f;
+    IDirect3DDevice9_SetViewport(data->device, &viewport);
+
+    if (FAILED(result)) {
+        D3D_SetError("Clear()", result);
+        return -1;
+    }
+    return 0;
 }
 
 static void
@@ -670,9 +786,8 @@
     int i;
     HRESULT result;
 
-    if (data->beginScene) {
-        IDirect3DDevice9_BeginScene(data->device);
-        data->beginScene = SDL_FALSE;
+    if (D3D_ActivateRenderer(renderer) < 0) {
+        return -1;
     }
 
     D3D_SetBlendMode(data, renderer->blendMode);
@@ -692,7 +807,6 @@
         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;
@@ -718,9 +832,8 @@
     int i;
     HRESULT result;
 
-    if (data->beginScene) {
-        IDirect3DDevice9_BeginScene(data->device);
-        data->beginScene = SDL_FALSE;
+    if (D3D_ActivateRenderer(renderer) < 0) {
+        return -1;
     }
 
     D3D_SetBlendMode(data, renderer->blendMode);
@@ -740,7 +853,6 @@
         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;
@@ -766,7 +878,7 @@
 }
 
 static int
-D3D_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
+D3D_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects,
                     int count)
 {
     D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
@@ -776,9 +888,8 @@
     Vertex vertices[4];
     HRESULT result;
 
-    if (data->beginScene) {
-        IDirect3DDevice9_BeginScene(data->device);
-        data->beginScene = SDL_FALSE;
+    if (D3D_ActivateRenderer(renderer) < 0) {
+        return -1;
     }
 
     D3D_SetBlendMode(data, renderer->blendMode);
@@ -794,7 +905,7 @@
     color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b);
 
     for (i = 0; i < count; ++i) {
-        const SDL_Rect *rect = rects[i];
+        const SDL_Rect *rect = &rects[i];
 
         minx = (float) rect->x;
         miny = (float) rect->y;
@@ -804,7 +915,6 @@
         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;
@@ -812,7 +922,6 @@
         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;
@@ -820,7 +929,6 @@
         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;
@@ -828,7 +936,6 @@
         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;
@@ -857,9 +964,8 @@
     Vertex vertices[4];
     HRESULT result;
 
-    if (data->beginScene) {
-        IDirect3DDevice9_BeginScene(data->device);
-        data->beginScene = SDL_FALSE;
+    if (D3D_ActivateRenderer(renderer) < 0) {
+        return -1;
     }
 
     minx = (float) dstrect->x - 0.5f;
@@ -877,7 +983,6 @@
     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;
@@ -885,7 +990,6 @@
     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;
@@ -893,7 +997,6 @@
     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;
@@ -901,7 +1004,6 @@
     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;
--- a/src/render/opengl/SDL_render_gl.c	Mon Feb 14 11:50:18 2011 -0600
+++ b/src/render/opengl/SDL_render_gl.c	Tue Feb 15 13:59:59 2011 -0800
@@ -55,14 +55,14 @@
 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 void GL_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect);
+static int GL_UpdateViewport(SDL_Renderer * renderer);
 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);
+                              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,
@@ -86,7 +86,6 @@
 typedef struct
 {
     SDL_GLContext context;
-    SDL_bool updateSize;
     SDL_bool GL_ARB_texture_rectangle_supported;
     int blendMode;
 
@@ -185,6 +184,24 @@
     return 0;
 }
 
+static SDL_GLContext SDL_CurrentContext = NULL;
+
+static int
+GL_ActivateRenderer(SDL_Renderer * renderer)
+{
+    GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+
+    if (SDL_CurrentContext != data->context) {
+        if (SDL_GL_MakeCurrent(renderer->window, data->context) < 0) {
+            return -1;
+        }
+        SDL_CurrentContext = data->context;
+
+        GL_UpdateViewport(renderer);
+    }
+    return 0;
+}
+
 SDL_Renderer *
 GL_CreateRenderer(SDL_Window * window, Uint32 flags)
 {
@@ -219,7 +236,7 @@
     renderer->UpdateTexture = GL_UpdateTexture;
     renderer->LockTexture = GL_LockTexture;
     renderer->UnlockTexture = GL_UnlockTexture;
-    renderer->SetClipRect = GL_SetClipRect;
+    renderer->UpdateViewport = GL_UpdateViewport;
     renderer->RenderClear = GL_RenderClear;
     renderer->RenderDrawPoints = GL_RenderDrawPoints;
     renderer->RenderDrawLines = GL_RenderDrawLines;
@@ -230,10 +247,9 @@
     renderer->DestroyTexture = GL_DestroyTexture;
     renderer->DestroyRenderer = GL_DestroyRenderer;
     renderer->info = GL_RenderDriver.info;
+    renderer->info.flags = SDL_RENDERER_ACCELERATED;
     renderer->driverdata = data;
 
-    renderer->info.flags = SDL_RENDERER_ACCELERATED;
-
     data->context = SDL_GL_CreateContext(window);
     if (!data->context) {
         GL_DestroyRenderer(renderer);
@@ -309,40 +325,12 @@
     data->glDisable(GL_CULL_FACE);
     /* This ended up causing video discrepancies between OpenGL and Direct3D */
     /*data->glEnable(GL_LINE_SMOOTH);*/
-    data->updateSize = SDL_TRUE;
+    data->glMatrixMode(GL_MODELVIEW);
+    data->glLoadIdentity();
 
     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)
 {
@@ -351,7 +339,6 @@
     if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
         /* Rebind the context to the window area and update matrices */
         SDL_CurrentContext = NULL;
-        data->updateSize = SDL_TRUE;
     }
 }
 
@@ -622,22 +609,26 @@
     GL_UpdateTexture(renderer, texture, rect, pixels, data->pitch);
 }
 
-static void
-GL_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect)
+static int
+GL_UpdateViewport(SDL_Renderer * renderer)
 {
     GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
 
-    GL_ActivateRenderer(renderer);
+    if (SDL_CurrentContext != data->context) {
+        /* We'll update the viewport after we rebind the context */
+        return 0;
+    }
 
-    if (rect) {
-        int w, h;
+    data->glViewport(renderer->viewport.x, renderer->viewport.y,
+                     renderer->viewport.w, renderer->viewport.h);
 
-        SDL_GetWindowSize(renderer->window, &w, &h);
-        data->glScissor(rect->x, (h-(rect->y+rect->h)), rect->w, rect->h);
-        data->glEnable(GL_SCISSOR_TEST);
-    } else {
-        data->glDisable(GL_SCISSOR_TEST);
-    }
+    data->glMatrixMode(GL_PROJECTION);
+    data->glLoadIdentity();
+    data->glOrtho((GLdouble) 0,
+                  (GLdouble) renderer->viewport.w,
+                  (GLdouble) renderer->viewport.h,
+                  (GLdouble) 0, 0.0, 1.0);
+    return 0;
 }
 
 static void
@@ -785,7 +776,7 @@
 }
 
 static int
-GL_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
+GL_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, int count)
 {
     GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
     int i;
@@ -801,7 +792,7 @@
                     (GLfloat) renderer->a * inv255f);
 
     for (i = 0; i < count; ++i) {
-        const SDL_Rect *rect = rects[i];
+        const SDL_Rect *rect = &rects[i];
 
         data->glRecti(rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
     }
--- a/src/render/opengles/SDL_render_gles.c	Mon Feb 14 11:50:18 2011 -0600
+++ b/src/render/opengles/SDL_render_gles.c	Tue Feb 15 13:59:59 2011 -0800
@@ -53,13 +53,13 @@
                             const SDL_Rect * rect, void **pixels, int *pitch);
 static void GLES_UnlockTexture(SDL_Renderer * renderer,
                                SDL_Texture * texture);
-static void GLES_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect);
+static int GLES_UpdateViewport(SDL_Renderer * renderer);
 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);
+                                const SDL_Rect * rects, int count);
 static int GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
                            const SDL_Rect * srcrect,
                            const SDL_Rect * dstrect);
@@ -83,7 +83,6 @@
 typedef struct
 {
     SDL_GLContext context;
-    SDL_bool updateSize;
     int blendMode;
 
     SDL_bool useDrawTexture;
@@ -136,6 +135,24 @@
     SDL_SetError("%s: %s", prefix, error);
 }
 
+static SDL_GLContext SDL_CurrentContext = NULL;
+
+static int
+GLES_ActivateRenderer(SDL_Renderer * renderer)
+{
+    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
+
+    if (SDL_CurrentContext != data->context) {
+        if (SDL_GL_MakeCurrent(renderer->window, data->context) < 0) {
+            return -1;
+        }
+        SDL_CurrentContext = data->context;
+
+        GLES_UpdateViewport(renderer);
+    }
+    return 0;
+}
+
 SDL_Renderer *
 GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
 {
@@ -162,7 +179,7 @@
     renderer->UpdateTexture = GLES_UpdateTexture;
     renderer->LockTexture = GLES_LockTexture;
     renderer->UnlockTexture = GLES_UnlockTexture;
-    renderer->SetClipRect = GLES_SetClipRect;
+    renderer->UpdateViewport = GLES_UpdateViewport;
     renderer->RenderDrawPoints = GLES_RenderDrawPoints;
     renderer->RenderDrawLines = GLES_RenderDrawLines;
     renderer->RenderFillRects = GLES_RenderFillRects;
@@ -171,10 +188,9 @@
     renderer->DestroyTexture = GLES_DestroyTexture;
     renderer->DestroyRenderer = GLES_DestroyRenderer;
     renderer->info = GLES_RenderDriver.info;
+    renderer->info.flags = SDL_RENDERER_ACCELERATED;
     renderer->driverdata = data;
 
-    renderer->info.flags = SDL_RENDERER_ACCELERATED;
-
     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
 
@@ -219,7 +235,8 @@
     data->blendMode = -1;
     glDisable(GL_DEPTH_TEST);
     glDisable(GL_CULL_FACE);
-    data->updateSize = SDL_TRUE;
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
 
     glEnableClientState(GL_VERTEX_ARRAY);
     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
@@ -227,35 +244,6 @@
     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);
-        glMatrixMode(GL_PROJECTION);
-        glLoadIdentity();
-        glMatrixMode(GL_MODELVIEW);
-        glLoadIdentity();
-        glViewport(0, 0, w, h);
-        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)
 {
@@ -264,7 +252,6 @@
     if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
         /* Rebind the context to the window area and update matrices */
         SDL_CurrentContext = NULL;
-        data->updateSize = SDL_TRUE;
     }
 }
 
@@ -444,20 +431,26 @@
     GLES_UpdateTexture(renderer, texture, &rect, data->pixels, data->pitch);
 }
 
-static void
-GLES_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect)
+static int
+GLES_UpdateViewport(SDL_Renderer * renderer)
 {
-    GLES_ActivateRenderer(renderer);
+    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
+
+    if (SDL_CurrentContext != data->context) {
+        /* We'll update the viewport after we rebind the context */
+        return 0;
+    }
 
-    if (rect) {
-        int w, h;
+    glViewport(renderer->viewport.x, renderer->viewport.y,
+               renderer->viewport.w, renderer->viewport.h);
 
-        SDL_GetWindowSize(renderer->window, &w, &h);
-        glScissor(rect->x, (h-(rect->y+rect->h)), rect->w, rect->h);
-        glEnable(GL_SCISSOR_TEST);
-    } else {
-        glDisable(GL_SCISSOR_TEST);
-    }
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glOrthof((GLfloat) 0,
+			 (GLfloat) renderer->viewport.w,
+             (GLfloat) renderer->viewport.h,
+             (GLfloat) 0, 0.0, 1.0);
+    return 0;
 }
 
 static void
@@ -555,7 +548,7 @@
 }
 
 static int
-GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
+GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects,
                      int count)
 {
     GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
@@ -571,7 +564,7 @@
                     (GLfloat) renderer->a * inv255f);
 
     for (i = 0; i < count; ++i) {
-        const SDL_Rect *rect = rects[i];
+        const SDL_Rect *rect = &rects[i];
         GLshort minx = rect->x;
         GLshort maxx = rect->x + rect->w;
         GLshort miny = rect->y;
--- a/src/render/opengles2/SDL_render_gles2.c	Mon Feb 14 11:50:18 2011 -0600
+++ b/src/render/opengles2/SDL_render_gles2.c	Tue Feb 15 13:59:59 2011 -0800
@@ -123,7 +123,6 @@
     GLES2_ShaderCache shader_cache;
     GLES2_ProgramCache program_cache;
     GLES2_ProgramCacheEntry *current_program;
-	SDL_bool updateSize;
 } GLES2_DriverContext;
 
 #define GLES2_MAX_CACHED_PROGRAMS 8
@@ -135,7 +134,7 @@
 static int GLES2_ActivateRenderer(SDL_Renderer *renderer);
 static void GLES2_WindowEvent(SDL_Renderer * renderer,
                               const SDL_WindowEvent *event);
-static void GLES2_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect);
+static int GLES2_UpdateViewport(SDL_Renderer * renderer);
 static void GLES2_DestroyRenderer(SDL_Renderer *renderer);
 
 static SDL_GLContext SDL_CurrentContext = NULL;
@@ -144,23 +143,17 @@
 GLES2_ActivateRenderer(SDL_Renderer * renderer)
 {
     GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
-    SDL_Window *window = renderer->window;
 
     if (SDL_CurrentContext != rdata->context) {
         /* Null out the current program to ensure we set it again */
         rdata->current_program = NULL;
 
-        if (SDL_GL_MakeCurrent(window, rdata->context) < 0) {
+        if (SDL_GL_MakeCurrent(renderer->window, rdata->context) < 0) {
             return -1;
         }
         SDL_CurrentContext = rdata->context;
-    }
-    if (rdata->updateSize) {
-        int w, h;
 
-        SDL_GetWindowSize(window, &w, &h);
-        glViewport(0, 0, w, h);
-        rdata->updateSize = SDL_FALSE;
+        GLES2_UpdateViewport(renderer);
     }
     return 0;
 }
@@ -173,24 +166,22 @@
     if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
         /* Rebind the context to the window area */
         SDL_CurrentContext = NULL;
-        rdata->updateSize = SDL_TRUE;
     }
 }
 
-static void
-GLES2_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect)
+static int
+GLES2_UpdateViewport(SDL_Renderer * renderer)
 {
-    GLES2_ActivateRenderer(renderer);
+    GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
 
-    if (rect) {
-        int w, h;
+    if (SDL_CurrentContext != rdata->context) {
+        /* We'll update the viewport after we rebind the context */
+        return 0;
+    }
 
-        SDL_GetWindowSize(renderer->window, &w, &h);
-        glScissor(rect->x, (h-(rect->y+rect->h)), rect->w, rect->h);
-        glEnable(GL_SCISSOR_TEST);
-    } else {
-        glDisable(GL_SCISSOR_TEST);
-    }
+    glViewport(renderer->viewport.x, renderer->viewport.y,
+               renderer->viewport.w, renderer->viewport.h);
+    return 0;
 }
 
 static void
@@ -735,21 +726,16 @@
 GLES2_SetOrthographicProjection(SDL_Renderer *renderer)
 {
     GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
-    SDL_Window *window = renderer->window;
-    int w, h;
     GLfloat projection[4][4];
     GLuint locProjection;
 
-    /* Get the window width and height */
-    SDL_GetWindowSize(window, &w, &h);
-
     /* Prepare an orthographic projection */
-    projection[0][0] = 2.0f / w;
+    projection[0][0] = 2.0f / renderer->viewport.w;
     projection[0][1] = 0.0f;
     projection[0][2] = 0.0f;
     projection[0][3] = 0.0f;
     projection[1][0] = 0.0f;
-    projection[1][1] = -2.0f / h;
+    projection[1][1] = -2.0f / renderer->viewport.h;
     projection[1][2] = 0.0f;
     projection[1][3] = 0.0f;
     projection[2][0] = 0.0f;
@@ -782,7 +768,7 @@
 static int GLES2_RenderClear(SDL_Renderer *renderer);
 static int GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int count);
 static int GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points, int count);
-static int GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect **rects, int count);
+static int GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect *rects, int count);
 static int GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect,
                             const SDL_Rect *dstrect);
 static void GLES2_RenderPresent(SDL_Renderer *renderer);
@@ -936,7 +922,7 @@
 }
 
 static int
-GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect **rects, int count)
+GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect *rects, int count)
 {
     GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
     GLfloat vertices[8];
@@ -968,12 +954,13 @@
 
     /* Emit a line loop for each rectangle */
     glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION);
-    for (idx = 0; idx < count; ++idx)
-    {
-        GLfloat xMin = (GLfloat)rects[idx]->x;
-        GLfloat xMax = (GLfloat)(rects[idx]->x + rects[idx]->w);
-        GLfloat yMin = (GLfloat)rects[idx]->y;
-        GLfloat yMax = (GLfloat)(rects[idx]->y + rects[idx]->h);
+    for (idx = 0; idx < count; ++idx) {
+        const SDL_Rect *rect = &rects[idx];
+
+        GLfloat xMin = (GLfloat)rect->x;
+        GLfloat xMax = (GLfloat)(rect->x + rect->w);
+        GLfloat yMin = (GLfloat)rect->y;
+        GLfloat yMax = (GLfloat)(rect->y + rect->h);
 
         vertices[0] = xMin;
         vertices[1] = yMin;
@@ -1108,11 +1095,9 @@
         return NULL;
     }
     renderer->info = GLES2_RenderDriver.info;
-    renderer->window = window;
+    renderer->info.flags = SDL_RENDERER_ACCELERATED;
     renderer->driverdata = rdata;
 
-    renderer->info.flags = SDL_RENDERER_ACCELERATED;
-
     /* Create an OpenGL ES 2.0 context */
     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
@@ -1169,8 +1154,6 @@
     if (hasCompiler)
         rdata->shader_formats[nFormats - 1] = (GLenum)-1;
 #endif /* ZUNE_HD */
-	
-    rdata->updateSize = SDL_TRUE;
 
     /* Populate the function pointers for the module */
     renderer->WindowEvent         = &GLES2_WindowEvent;
@@ -1178,7 +1161,7 @@
     renderer->UpdateTexture       = &GLES2_UpdateTexture;
     renderer->LockTexture         = &GLES2_LockTexture;
     renderer->UnlockTexture       = &GLES2_UnlockTexture;
-    renderer->SetClipRect         = &GLES2_SetClipRect;
+    renderer->UpdateViewport      = &GLES2_UpdateViewport;
     renderer->RenderClear         = &GLES2_RenderClear;
     renderer->RenderDrawPoints    = &GLES2_RenderDrawPoints;
     renderer->RenderDrawLines     = &GLES2_RenderDrawLines;
--- a/src/render/software/SDL_blendfillrect.c	Mon Feb 14 11:50:18 2011 -0600
+++ b/src/render/software/SDL_blendfillrect.c	Tue Feb 15 13:59:59 2011 -0800
@@ -265,10 +265,10 @@
 }
 
 int
-SDL_BlendFillRects(SDL_Surface * dst, const SDL_Rect ** rects, int count,
+SDL_BlendFillRects(SDL_Surface * dst, const SDL_Rect * rects, int count,
                    SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
 {
-    SDL_Rect clipped;
+    SDL_Rect rect;
     int i;
     int (*func)(SDL_Surface * dst, const SDL_Rect * rect,
                 SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) = NULL;
@@ -329,20 +329,11 @@
     }
 
     for (i = 0; i < count; ++i) {
-        const SDL_Rect * rect = rects[i];
-
-        /* If 'rect' == NULL, then fill the whole surface */
-        if (rect) {
-            /* Perform clipping */
-            if (!SDL_IntersectRect(rect, &dst->clip_rect, &clipped)) {
-                continue;
-            }
-            rect = &clipped;
-        } else {
-            rect = &dst->clip_rect;
+        /* Perform clipping */
+        if (!SDL_IntersectRect(&rects[i], &dst->clip_rect, &rect)) {
+            continue;
         }
-
-        status = func(dst, rect, blendMode, r, g, b, a);
+        status = func(dst, &rect, blendMode, r, g, b, a);
     }
     return status;
 }
--- a/src/render/software/SDL_blendfillrect.h	Mon Feb 14 11:50:18 2011 -0600
+++ b/src/render/software/SDL_blendfillrect.h	Tue Feb 15 13:59:59 2011 -0800
@@ -23,6 +23,6 @@
 
 
 extern int SDL_BlendFillRect(SDL_Surface * dst, const SDL_Rect * rect, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
-extern int SDL_BlendFillRects(SDL_Surface * dst, const SDL_Rect ** rects, int count, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
+extern int SDL_BlendFillRects(SDL_Surface * dst, const SDL_Rect * rects, int count, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/render/software/SDL_render_sw.c	Mon Feb 14 11:50:18 2011 -0600
+++ b/src/render/software/SDL_render_sw.c	Tue Feb 15 13:59:59 2011 -0800
@@ -51,13 +51,14 @@
 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 void SW_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect);
+static int SW_UpdateViewport(SDL_Renderer * renderer);
+static int SW_RenderClear(SDL_Renderer * renderer);
 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);
+                              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,
@@ -89,11 +90,23 @@
 
 typedef struct
 {
-    SDL_bool updateSize;
     SDL_Surface *surface;
 } SW_RenderData;
 
 
+static SDL_Surface *
+SW_ActivateRenderer(SDL_Renderer * renderer)
+{
+    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
+
+    if (!data->surface) {
+        data->surface = SDL_GetWindowSurface(renderer->window);
+
+        SW_UpdateViewport(renderer);
+    }
+    return data->surface;
+}
+
 SDL_Renderer *
 SW_CreateRendererForSurface(SDL_Surface * surface)
 {
@@ -127,8 +140,9 @@
     renderer->UpdateTexture = SW_UpdateTexture;
     renderer->LockTexture = SW_LockTexture;
     renderer->UnlockTexture = SW_UnlockTexture;
-    renderer->SetClipRect = SW_SetClipRect;
+    renderer->UpdateViewport = SW_UpdateViewport;
     renderer->DestroyTexture = SW_DestroyTexture;
+    renderer->RenderClear = SW_RenderClear;
     renderer->RenderDrawPoints = SW_RenderDrawPoints;
     renderer->RenderDrawLines = SW_RenderDrawLines;
     renderer->RenderFillRects = SW_RenderFillRects;
@@ -139,6 +153,8 @@
     renderer->info = SW_RenderDriver.info;
     renderer->driverdata = data;
 
+    SW_ActivateRenderer(renderer);
+
     return renderer;
 }
 
@@ -154,26 +170,13 @@
     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_SIZE_CHANGED) {
-        data->updateSize = SDL_TRUE;
+        data->surface = NULL;
     }
 }
 
@@ -269,15 +272,46 @@
 {
 }
 
-static void
-SW_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect)
+static int
+SW_UpdateViewport(SDL_Renderer * renderer)
+{
+    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
+    SDL_Surface *surface = data->surface;
+
+    if (!surface) {
+        /* We'll update the viewport after we recreate the surface */
+        return 0;
+    }
+
+    if (!renderer->viewport.w && !renderer->viewport.h) {
+        /* There may be no window, so update the viewport directly */
+        renderer->viewport.w = surface->w;
+        renderer->viewport.h = surface->h;
+    }
+    //SDL_SetClipRect(data->surface, &renderer->viewport);
+    return 0;
+}
+
+static int
+SW_RenderClear(SDL_Renderer * renderer)
 {
     SDL_Surface *surface = SW_ActivateRenderer(renderer);
+    Uint32 color;
+    SDL_Rect clip_rect;
 
     if (!surface) {
-        return;
+        return -1;
     }
-    SDL_SetClipRect(surface, rect);
+
+    color = SDL_MapRGBA(surface->format,
+                        renderer->r, renderer->g, renderer->b, renderer->a);
+
+    /* By definition the clear ignores the clip rect */
+    clip_rect = surface->clip_rect;
+    SDL_SetClipRect(surface, NULL);
+    SDL_FillRect(surface, NULL, color);
+    SDL_SetClipRect(surface, &clip_rect);
+    return 0;
 }
 
 static int
@@ -285,24 +319,44 @@
                     int count)
 {
     SDL_Surface *surface = SW_ActivateRenderer(renderer);
+    SDL_Point *temp = NULL;
+    int status;
 
     if (!surface) {
         return -1;
     }
 
+    if (renderer->viewport.x || renderer->viewport.y) {
+        int i;
+        int x = renderer->viewport.x;
+        int y = renderer->viewport.y;
+
+        temp = SDL_stack_alloc(SDL_Point, count);
+        for (i = 0; i < count; ++i) {
+            temp[i].x = x + points[i].x;
+            temp[i].y = y + points[i].x;
+        }
+        points = temp;
+    }
+
     /* 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);
+        status = SDL_DrawPoints(surface, points, count, color);
     } else {
-        return SDL_BlendPoints(surface, points, count,
-                               renderer->blendMode,
-                               renderer->r, renderer->g, renderer->b,
-                               renderer->a);
+        status = SDL_BlendPoints(surface, points, count,
+                                renderer->blendMode,
+                                renderer->r, renderer->g, renderer->b,
+                                renderer->a);
     }
+
+    if (temp) {
+        SDL_stack_free(temp);
+    }
+    return status;
 }
 
 static int
@@ -310,47 +364,88 @@
                    int count)
 {
     SDL_Surface *surface = SW_ActivateRenderer(renderer);
+    SDL_Point *temp = NULL;
+    int status;
 
     if (!surface) {
         return -1;
     }
 
+    if (renderer->viewport.x || renderer->viewport.y) {
+        int i;
+        int x = renderer->viewport.x;
+        int y = renderer->viewport.y;
+
+        temp = SDL_stack_alloc(SDL_Point, count);
+        for (i = 0; i < count; ++i) {
+            temp[i].x = x + points[i].x;
+            temp[i].y = y + points[i].y;
+        }
+        points = temp;
+    }
+
     /* 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);
+        status = SDL_DrawLines(surface, points, count, color);
     } else {
-        return SDL_BlendLines(surface, points, count,
-                              renderer->blendMode,
-                              renderer->r, renderer->g, renderer->b,
-                              renderer->a);
+        status = SDL_BlendLines(surface, points, count,
+                                renderer->blendMode,
+                                renderer->r, renderer->g, renderer->b,
+                                renderer->a);
     }
+
+    if (temp) {
+        SDL_stack_free(temp);
+    }
+    return status;
 }
 
 static int
-SW_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
-                   int count)
+SW_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, int count)
 {
     SDL_Surface *surface = SW_ActivateRenderer(renderer);
+    SDL_Rect *temp = NULL;
+    int status;
 
     if (!surface) {
         return -1;
     }
 
+    if (renderer->viewport.x || renderer->viewport.y) {
+        int i;
+        int x = renderer->viewport.x;
+        int y = renderer->viewport.y;
+
+        temp = SDL_stack_alloc(SDL_Rect, count);
+        for (i = 0; i < count; ++i) {
+            temp[i].x = x + rects[i].x;
+            temp[i].y = y + rects[i].y;
+            temp[i].w = rects[i].w;
+            temp[i].h = rects[i].h;
+        }
+        rects = temp;
+    }
+
     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);
+        status = SDL_FillRects(surface, rects, count, color);
     } else {
-        return SDL_BlendFillRects(surface, rects, count,
-                                     renderer->blendMode,
-                                     renderer->r, renderer->g, renderer->b,
-                                     renderer->a);
+        status = SDL_BlendFillRects(surface, rects, count,
+                                    renderer->blendMode,
+                                    renderer->r, renderer->g, renderer->b,
+                                    renderer->a);
     }
+
+    if (temp) {
+        SDL_stack_free(temp);
+    }
+    return status;
 }
 
 static int
@@ -365,6 +460,10 @@
         return -1;
     }
 
+    if (renderer->viewport.x || renderer->viewport.y) {
+        final_rect.x += renderer->viewport.x;
+        final_rect.y += renderer->viewport.y;
+    }
     if ( srcrect->w == final_rect.w && srcrect->h == final_rect.h ) {
         return SDL_BlitSurface(src, srcrect, surface, &final_rect);
     } else {
@@ -379,22 +478,27 @@
     SDL_Surface *surface = SW_ActivateRenderer(renderer);
     Uint32 src_format;
     void *src_pixels;
+    SDL_Rect final_rect;
 
     if (!surface) {
         return -1;
     }
 
+    if (renderer->viewport.x || renderer->viewport.y) {
+        final_rect.x = renderer->viewport.x + rect->x;
+        final_rect.y = renderer->viewport.y + rect->y;
+        final_rect.w = rect->w;
+        final_rect.h = rect->h;
+        rect = &final_rect;
+    }
+
     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_format = surface->format->format;
     src_pixels = (void*)((Uint8 *) surface->pixels +
                     rect->y * surface->pitch +
                     rect->x * surface->format->BytesPerPixel);
--- a/src/video/SDL_fillrect.c	Mon Feb 14 11:50:18 2011 -0600
+++ b/src/video/SDL_fillrect.c	Tue Feb 15 13:59:59 2011 -0800
@@ -417,14 +417,19 @@
 }
 
 int
-SDL_FillRects(SDL_Surface * dst, const SDL_Rect ** rects, int count,
+SDL_FillRects(SDL_Surface * dst, const SDL_Rect * rects, int count,
               Uint32 color)
 {
     int i;
     int status = 0;
 
+    if (!rects) {
+        SDL_SetError("SDL_FillRects() passed NULL rects");
+        return -1;
+    }
+
     for (i = 0; i < count; ++i) {
-        status = SDL_FillRect(dst, rects[i], color);
+        status += SDL_FillRect(dst, &rects[i], color);
     }
     return status;
 }
--- a/src/video/SDL_sysvideo.h	Mon Feb 14 11:50:18 2011 -0600
+++ b/src/video/SDL_sysvideo.h	Tue Feb 15 13:59:59 2011 -0800
@@ -185,7 +185,7 @@
     void (*SetWindowGrab) (_THIS, SDL_Window * window);
     void (*DestroyWindow) (_THIS, SDL_Window * window);
     int (*CreateWindowFramebuffer) (_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch);
-    int (*UpdateWindowFramebuffer) (_THIS, SDL_Window * window, int numrects, SDL_Rect * rects);
+    int (*UpdateWindowFramebuffer) (_THIS, SDL_Window * window, SDL_Rect * rects, int numrects);
     void (*DestroyWindowFramebuffer) (_THIS, SDL_Window * window);
 
     /* * * */
--- a/src/video/SDL_video.c	Mon Feb 14 11:50:18 2011 -0600
+++ b/src/video/SDL_video.c	Tue Feb 15 13:59:59 2011 -0800
@@ -300,11 +300,15 @@
 
     *pixels = data->pixels;
     *pitch = data->pitch;
+
+    /* Make sure we're not double-scaling the viewport */
+    SDL_RenderSetViewport(data->renderer, NULL);
+
     return 0;
 }
 
 static int
-SDL_UpdateWindowTexture(_THIS, SDL_Window * window, int numrects, SDL_Rect * rects)
+SDL_UpdateWindowTexture(_THIS, SDL_Window * window, SDL_Rect * rects, int numrects)
 {
     SDL_WindowTextureData *data;
     SDL_Rect rect;
@@ -1629,12 +1633,12 @@
     full_rect.y = 0;
     full_rect.w = window->w;
     full_rect.h = window->h;
-    return SDL_UpdateWindowSurfaceRects(window, 1, &full_rect);
+    return SDL_UpdateWindowSurfaceRects(window, &full_rect, 1);
 }
 
 int
-SDL_UpdateWindowSurfaceRects(SDL_Window * window,
-                             int numrects, SDL_Rect * rects)
+SDL_UpdateWindowSurfaceRects(SDL_Window * window, SDL_Rect * rects,
+                             int numrects)
 {
     CHECK_WINDOW_MAGIC(window, -1);
 
@@ -1643,7 +1647,7 @@
         return -1;
     }
 
-    return _this->UpdateWindowFramebuffer(_this, window, numrects, rects);
+    return _this->UpdateWindowFramebuffer(_this, window, rects, numrects);
 }
 
 void
--- a/src/video/dummy/SDL_nullframebuffer.c	Mon Feb 14 11:50:18 2011 -0600
+++ b/src/video/dummy/SDL_nullframebuffer.c	Tue Feb 15 13:59:59 2011 -0800
@@ -56,7 +56,7 @@
     return 0;
 }
 
-int SDL_DUMMY_UpdateWindowFramebuffer(_THIS, SDL_Window * window, int numrects, SDL_Rect * rects)
+int SDL_DUMMY_UpdateWindowFramebuffer(_THIS, SDL_Window * window, SDL_Rect * rects, int numrects)
 {
     static int frame_number;
     SDL_Surface *surface;
--- a/src/video/dummy/SDL_nullframebuffer_c.h	Mon Feb 14 11:50:18 2011 -0600
+++ b/src/video/dummy/SDL_nullframebuffer_c.h	Tue Feb 15 13:59:59 2011 -0800
@@ -22,7 +22,7 @@
 #include "SDL_config.h"
 
 extern int SDL_DUMMY_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch);
-extern int SDL_DUMMY_UpdateWindowFramebuffer(_THIS, SDL_Window * window, int numrects, SDL_Rect * rects);
+extern int SDL_DUMMY_UpdateWindowFramebuffer(_THIS, SDL_Window * window, SDL_Rect * rects, int numrects);
 extern void SDL_DUMMY_DestroyWindowFramebuffer(_THIS, SDL_Window * window);
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/nds/SDL_ndsvideo.c	Mon Feb 14 11:50:18 2011 -0600
+++ b/src/video/nds/SDL_ndsvideo.c	Tue Feb 15 13:59:59 2011 -0800
@@ -163,8 +163,8 @@
 	return 0;
 }
 
-static int NDS_UpdateWindowFramebuffer(_THIS, SDL_Window * window, int numrects,
-									   SDL_Rect * rects)
+static int NDS_UpdateWindowFramebuffer(_THIS, SDL_Window * window,
+									   SDL_Rect * rects, int numrects)
 {
 	/* Nothing to do because writes are done directly into the
 	 * framebuffer. */
--- a/src/video/windows/SDL_windowsframebuffer.c	Mon Feb 14 11:50:18 2011 -0600
+++ b/src/video/windows/SDL_windowsframebuffer.c	Tue Feb 15 13:59:59 2011 -0800
@@ -100,7 +100,7 @@
     return 0;
 }
 
-int WIN_UpdateWindowFramebuffer(_THIS, SDL_Window * window, int numrects, SDL_Rect * rects)
+int WIN_UpdateWindowFramebuffer(_THIS, SDL_Window * window, SDL_Rect * rects, int numrects)
 {
     SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
 
--- a/src/video/windows/SDL_windowsframebuffer.h	Mon Feb 14 11:50:18 2011 -0600
+++ b/src/video/windows/SDL_windowsframebuffer.h	Tue Feb 15 13:59:59 2011 -0800
@@ -22,7 +22,7 @@
 #include "SDL_config.h"
 
 extern int WIN_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch);
-extern int WIN_UpdateWindowFramebuffer(_THIS, SDL_Window * window, int numrects, SDL_Rect * rects);
+extern int WIN_UpdateWindowFramebuffer(_THIS, SDL_Window * window, SDL_Rect * rects, int numrects);
 extern void WIN_DestroyWindowFramebuffer(_THIS, SDL_Window * window);
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/x11/SDL_x11framebuffer.c	Mon Feb 14 11:50:18 2011 -0600
+++ b/src/video/x11/SDL_x11framebuffer.c	Tue Feb 15 13:59:59 2011 -0800
@@ -147,8 +147,8 @@
 }
 
 int
-X11_UpdateWindowFramebuffer(_THIS, SDL_Window * window,
-                            int numrects, SDL_Rect * rects)
+X11_UpdateWindowFramebuffer(_THIS, SDL_Window * window, SDL_Rect * rects,
+                            int numrects)
 {
     SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
     Display *display = data->videodata->display;
--- a/src/video/x11/SDL_x11framebuffer.h	Mon Feb 14 11:50:18 2011 -0600
+++ b/src/video/x11/SDL_x11framebuffer.h	Tue Feb 15 13:59:59 2011 -0800
@@ -26,7 +26,7 @@
                                        Uint32 * format,
                                        void ** pixels, int *pitch);
 extern int X11_UpdateWindowFramebuffer(_THIS, SDL_Window * window,
-                                       int numrects, SDL_Rect * rects);
+                                       SDL_Rect * rects, int numrects);
 extern void X11_DestroyWindowFramebuffer(_THIS, SDL_Window * window);
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/test/testdraw2.c	Mon Feb 14 11:50:18 2011 -0600
+++ b/test/testdraw2.c	Tue Feb 15 13:59:59 2011 -0800
@@ -19,14 +19,14 @@
 static SDL_BlendMode blendMode = SDL_BLENDMODE_NONE;
 
 void
-DrawPoints(SDL_Window * window, SDL_Renderer * renderer)
+DrawPoints(SDL_Renderer * renderer)
 {
     int i;
     int x, y;
-    int window_w, window_h;
+    SDL_Rect viewport;
 
     /* Query the sizes */
-    SDL_GetWindowSize(window, &window_w, &window_h);
+    SDL_RenderGetViewport(renderer, &viewport);
 
     for (i = 0; i < num_objects * 4; ++i) {
         /* Cycle the color and alpha, if desired */
@@ -55,21 +55,21 @@
         SDL_SetRenderDrawColor(renderer, 255, (Uint8) current_color,
                                (Uint8) current_color, (Uint8) current_alpha);
 
-        x = rand() % window_w;
-        y = rand() % window_h;
+        x = rand() % viewport.w;
+        y = rand() % viewport.h;
         SDL_RenderDrawPoint(renderer, x, y);
     }
 }
 
 void
-DrawLines(SDL_Window * window, SDL_Renderer * renderer)
+DrawLines(SDL_Renderer * renderer)
 {
     int i;
     int x1, y1, x2, y2;
-    int window_w, window_h;
+    SDL_Rect viewport;
 
     /* Query the sizes */
-    SDL_GetWindowSize(window, &window_w, &window_h);
+    SDL_RenderGetViewport(renderer, &viewport);
 
     for (i = 0; i < num_objects; ++i) {
         /* Cycle the color and alpha, if desired */
@@ -99,29 +99,29 @@
                                (Uint8) current_color, (Uint8) current_alpha);
 
         if (i == 0) {
-            SDL_RenderDrawLine(renderer, 0, 0, window_w - 1, window_h - 1);
-            SDL_RenderDrawLine(renderer, 0, window_h - 1, window_w - 1, 0);
-            SDL_RenderDrawLine(renderer, 0, window_h / 2, window_w - 1, window_h / 2);
-            SDL_RenderDrawLine(renderer, window_w / 2, 0, window_w / 2, window_h - 1);
+            SDL_RenderDrawLine(renderer, 0, 0, viewport.w - 1, viewport.h - 1);
+            SDL_RenderDrawLine(renderer, 0, viewport.h - 1, viewport.w - 1, 0);
+            SDL_RenderDrawLine(renderer, 0, viewport.h / 2, viewport.w - 1, viewport.h / 2);
+            SDL_RenderDrawLine(renderer, viewport.w / 2, 0, viewport.w / 2, viewport.h - 1);
         } else {
-            x1 = (rand() % (window_w*2)) - window_w;
-            x2 = (rand() % (window_w*2)) - window_w;
-            y1 = (rand() % (window_h*2)) - window_h;
-            y2 = (rand() % (window_h*2)) - window_h;
+            x1 = (rand() % (viewport.w*2)) - viewport.w;
+            x2 = (rand() % (viewport.w*2)) - viewport.w;
+            y1 = (rand() % (viewport.h*2)) - viewport.h;
+            y2 = (rand() % (viewport.h*2)) - viewport.h;
             SDL_RenderDrawLine(renderer, x1, y1, x2, y2);
         }
     }
 }
 
 void
-DrawRects(SDL_Window * window, SDL_Renderer * renderer)
+DrawRects(SDL_Renderer * renderer)
 {
     int i;
     SDL_Rect rect;
-    int window_w, window_h;
+    SDL_Rect viewport;
 
     /* Query the sizes */
-    SDL_GetWindowSize(window, &window_w, &window_h);
+    SDL_RenderGetViewport(renderer, &viewport);
 
     for (i = 0; i < num_objects / 4; ++i) {
         /* Cycle the color and alpha, if desired */
@@ -150,10 +150,10 @@
         SDL_SetRenderDrawColor(renderer, 255, (Uint8) current_color,
                                (Uint8) current_color, (Uint8) current_alpha);
 
-        rect.w = rand() % (window_h / 2);
-        rect.h = rand() % (window_h / 2);
-        rect.x = (rand() % (window_w*2) - window_w) - (rect.w / 2);
-        rect.y = (rand() % (window_h*2) - window_h) - (rect.h / 2);
+        rect.w = rand() % (viewport.h / 2);
+        rect.h = rand() % (viewport.h / 2);
+        rect.x = (rand() % (viewport.w*2) - viewport.w) - (rect.w / 2);
+        rect.y = (rand() % (viewport.h*2) - viewport.h) - (rect.h / 2);
         SDL_RenderFillRect(renderer, &rect);
     }
 }
@@ -243,9 +243,9 @@
             SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
             SDL_RenderClear(renderer);
 
-            DrawRects(state->windows[i], renderer);
-            DrawLines(state->windows[i], renderer);
-            DrawPoints(state->windows[i], renderer);
+            DrawRects(renderer);
+            DrawLines(renderer);
+            DrawPoints(renderer);
 
             SDL_RenderPresent(renderer);
         }
--- a/test/testintersections.c	Mon Feb 14 11:50:18 2011 -0600
+++ b/test/testintersections.c	Tue Feb 15 13:59:59 2011 -0800
@@ -20,14 +20,14 @@
 static SDL_BlendMode blendMode = SDL_BLENDMODE_NONE;
 
 void
-DrawPoints(SDL_Window * window, SDL_Renderer * renderer)
+DrawPoints(SDL_Renderer * renderer)
 {
     int i;
     int x, y;
-    int window_w, window_h;
+    SDL_Rect viewport;
 
     /* Query the sizes */
-    SDL_GetWindowSize(window, &window_w, &window_h);
+    SDL_RenderGetViewport(renderer, &viewport);
 
     for (i = 0; i < num_objects * 4; ++i) {
         /* Cycle the color and alpha, if desired */
@@ -56,8 +56,8 @@
         SDL_SetRenderDrawColor(renderer, 255, (Uint8) current_color,
                                (Uint8) current_color, (Uint8) current_alpha);
 
-        x = rand() % window_w;
-        y = rand() % window_h;
+        x = rand() % viewport.w;
+        y = rand() % viewport.h;
         SDL_RenderDrawPoint(renderer, x, y);
     }
 }
@@ -84,23 +84,23 @@
 
 
 void
-DrawLines(SDL_Window * window, SDL_Renderer * renderer)
+DrawLines(SDL_Renderer * renderer)
 {
     int i;
     int x1, y1, x2, y2;
-    int window_w, window_h;
+    SDL_Rect viewport;
 
     /* Query the sizes */
-    SDL_GetWindowSize(window, &window_w, &window_h);
+    SDL_RenderGetViewport(renderer, &viewport);
+
+    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
 
     for (i = 0; i < num_lines; ++i) {
-        SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
-
         if (i == -1) {
-            SDL_RenderDrawLine(renderer, 0, 0, window_w - 1, window_h - 1);
-            SDL_RenderDrawLine(renderer, 0, window_h - 1, window_w - 1, 0);
-            SDL_RenderDrawLine(renderer, 0, window_h / 2, window_w - 1, window_h / 2);
-            SDL_RenderDrawLine(renderer, window_w / 2, 0, window_w / 2, window_h - 1);
+            SDL_RenderDrawLine(renderer, 0, 0, viewport.w - 1, viewport.h - 1);
+            SDL_RenderDrawLine(renderer, 0, viewport.h - 1, viewport.w - 1, 0);
+            SDL_RenderDrawLine(renderer, 0, viewport.h / 2, viewport.w - 1, viewport.h / 2);
+            SDL_RenderDrawLine(renderer, viewport.w / 2, 0, viewport.w / 2, viewport.h - 1);
         } else {
             SDL_RenderDrawLine(renderer, lines[i].x, lines[i].y, lines[i].w, lines[i].h);
         }
@@ -135,27 +135,18 @@
 }
 
 static void
-DrawRects(SDL_Window * window, SDL_Renderer * renderer)
+DrawRects(SDL_Renderer * renderer)
 {
-    int i;
-    int window_w, window_h;
-
-    /* Query the sizes */
-    SDL_GetWindowSize(window, &window_w, &window_h);
-
-    for (i = 0; i < num_rects; ++i) {
-        SDL_SetRenderDrawColor(renderer, 255, 127, 0, 255);
-        SDL_RenderFillRect(renderer, &rects[i]);
-    }
+    SDL_SetRenderDrawColor(renderer, 255, 127, 0, 255);
+    SDL_RenderFillRects(renderer, rects, num_rects);
 }
 
 static void
-DrawRectLineIntersections(SDL_Window * window, SDL_Renderer * renderer)
+DrawRectLineIntersections(SDL_Renderer * renderer)
 {
-    int i, j, window_w, window_h;
+    int i, j;
 
-    /* Query the sizes */
-    SDL_GetWindowSize(window, &window_w, &window_h);
+    SDL_SetRenderDrawColor(renderer, 0, 255, 55, 255);
 
     for (i = 0; i < num_rects; i++)
         for (j = 0; j < num_lines; j++) {
@@ -169,22 +160,22 @@
             y2 = lines[j].h;
 
             if (SDL_IntersectRectAndLine(&r, &x1, &y1, &x2, &y2)) {
-                SDL_SetRenderDrawColor(renderer, 0, 255, 55, 255);
                 SDL_RenderDrawLine(renderer, x1, y1, x2, y2);
             }
         }
 }
 
 static void
-DrawRectRectIntersections(SDL_Window * window, SDL_Renderer * renderer)
+DrawRectRectIntersections(SDL_Renderer * renderer)
 {
     int i, j;
 
+    SDL_SetRenderDrawColor(renderer, 255, 200, 0, 255);
+
     for (i = 0; i < num_rects; i++)
         for (j = i + 1; j < num_rects; j++) {
             SDL_Rect r;
             if (SDL_IntersectRect(&rects[i], &rects[j], &r)) {
-                SDL_SetRenderDrawColor(renderer, 255, 200, 0, 255);
                 SDL_RenderFillRect(renderer, &r);
             }
         }
@@ -310,11 +301,11 @@
             SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
             SDL_RenderClear(renderer);
 
-            DrawRects(state->windows[i], renderer);
-            DrawPoints(state->windows[i], renderer);
-            DrawRectRectIntersections(state->windows[i], renderer);
-            DrawLines(state->windows[i], renderer);
-            DrawRectLineIntersections(state->windows[i], renderer);
+            DrawRects(renderer);
+            DrawPoints(renderer);
+            DrawRectRectIntersections(renderer);
+            DrawLines(renderer);
+            DrawRectLineIntersections(renderer);
 
             SDL_RenderPresent(renderer);
         }
--- a/test/testscale.c	Mon Feb 14 11:50:18 2011 -0600
+++ b/test/testscale.c	Tue Feb 15 13:59:59 2011 -0800
@@ -82,9 +82,9 @@
 void
 Draw(DrawState *s)
 {
-    int w, h;
+    SDL_Rect viewport;
 
-    SDL_GetWindowSize(s->window, &w, &h);
+    SDL_RenderGetViewport(s->renderer, &viewport);
 
     /* Draw the background */
     SDL_RenderCopy(s->renderer, s->background, NULL, NULL);
@@ -93,7 +93,7 @@
     s->sprite_rect.w += s->scale_direction;
     s->sprite_rect.h += s->scale_direction;
     if (s->scale_direction > 0) {
-        if (s->sprite_rect.w >= w || s->sprite_rect.h >= h) {
+        if (s->sprite_rect.w >= viewport.w || s->sprite_rect.h >= viewport.h) {
             s->scale_direction = -1;
         }
     } else {
@@ -101,8 +101,8 @@
             s->scale_direction = 1;
         }
     }
-    s->sprite_rect.x = (w - s->sprite_rect.w) / 2;
-    s->sprite_rect.y = (h - s->sprite_rect.h) / 2;
+    s->sprite_rect.x = (viewport.w - s->sprite_rect.w) / 2;
+    s->sprite_rect.y = (viewport.h - s->sprite_rect.h) / 2;
 
     SDL_RenderCopy(s->renderer, s->sprite, NULL, &s->sprite_rect);
 
--- a/test/testsprite2.c	Mon Feb 14 11:50:18 2011 -0600
+++ b/test/testsprite2.c	Tue Feb 15 13:59:59 2011 -0800
@@ -92,15 +92,14 @@
 }
 
 void
-MoveSprites(SDL_Window * window, SDL_Renderer * renderer, SDL_Texture * sprite)
+MoveSprites(SDL_Renderer * renderer, SDL_Texture * sprite)
 {
     int i, n;
-    int window_w, window_h;
-    SDL_Rect temp;
+    SDL_Rect viewport, temp;
     SDL_Rect *position, *velocity;
 
     /* Query the sizes */
-    SDL_GetWindowSize(window, &window_w, &window_h);
+    SDL_RenderGetViewport(renderer, &viewport);
 
     /* Cycle the color and alpha, if desired */
     if (cycle_color) {
@@ -136,16 +135,16 @@
     /* Test points */
     SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0x00, 0xFF);
     SDL_RenderDrawPoint(renderer, 0, 0);
-    SDL_RenderDrawPoint(renderer, window_w-1, 0);
-    SDL_RenderDrawPoint(renderer, 0, window_h-1);
-    SDL_RenderDrawPoint(renderer, window_w-1, window_h-1);
+    SDL_RenderDrawPoint(renderer, viewport.w-1, 0);
+    SDL_RenderDrawPoint(renderer, 0, viewport.h-1);
+    SDL_RenderDrawPoint(renderer, viewport.w-1, viewport.h-1);
 
     /* Test horizontal and vertical lines */
     SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0x00, 0xFF);
-    SDL_RenderDrawLine(renderer, 1, 0, window_w-2, 0);
-    SDL_RenderDrawLine(renderer, 1, window_h-1, window_w-2, window_h-1);
-    SDL_RenderDrawLine(renderer, 0, 1, 0, window_h-2);
-    SDL_RenderDrawLine(renderer, window_w-1, 1, window_w-1, window_h-2);
+    SDL_RenderDrawLine(renderer, 1, 0, viewport.w-2, 0);
+    SDL_RenderDrawLine(renderer, 1, viewport.h-1, viewport.w-2, viewport.h-1);
+    SDL_RenderDrawLine(renderer, 0, 1, 0, viewport.h-2);
+    SDL_RenderDrawLine(renderer, viewport.w-1, 1, viewport.w-1, viewport.h-2);
 
     /* Test fill and copy */
     SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
@@ -155,20 +154,20 @@
     temp.h = sprite_h;
     SDL_RenderFillRect(renderer, &temp);
     SDL_RenderCopy(renderer, sprite, NULL, &temp);
-    temp.x = window_w-sprite_w-1;
+    temp.x = viewport.w-sprite_w-1;
     temp.y = 1;
     temp.w = sprite_w;
     temp.h = sprite_h;
     SDL_RenderFillRect(renderer, &temp);
     SDL_RenderCopy(renderer, sprite, NULL, &temp);
     temp.x = 1;
-    temp.y = window_h-sprite_h-1;
+    temp.y = viewport.h-sprite_h-1;
     temp.w = sprite_w;
     temp.h = sprite_h;
     SDL_RenderFillRect(renderer, &temp);
     SDL_RenderCopy(renderer, sprite, NULL, &temp);
-    temp.x = window_w-sprite_w-1;
-    temp.y = window_h-sprite_h-1;
+    temp.x = viewport.w-sprite_w-1;
+    temp.y = viewport.h-sprite_h-1;
     temp.w = sprite_w;
     temp.h = sprite_h;
     SDL_RenderFillRect(renderer, &temp);
@@ -177,9 +176,9 @@
     /* Test diagonal lines */
     SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0x00, 0xFF);
     SDL_RenderDrawLine(renderer, sprite_w, sprite_h,
-                       window_w-sprite_w-2, window_h-sprite_h-2);
-    SDL_RenderDrawLine(renderer, window_w-sprite_w-2, sprite_h,
-                       sprite_w, window_h-sprite_h-2);
+                       viewport.w-sprite_w-2, viewport.h-sprite_h-2);
+    SDL_RenderDrawLine(renderer, viewport.w-sprite_w-2, sprite_h,
+                       sprite_w, viewport.h-sprite_h-2);
 
     /* Move the sprite, bounce at the wall, and draw */
     n = 0;
@@ -187,12 +186,12 @@
         position = &positions[i];
         velocity = &velocities[i];
         position->x += velocity->x;
-        if ((position->x < 0) || (position->x >= (window_w - sprite_w))) {
+        if ((position->x < 0) || (position->x >= (viewport.w - sprite_w))) {
             velocity->x = -velocity->x;
             position->x += velocity->x;
         }
         position->y += velocity->y;
-        if ((position->y < 0) || (position->y >= (window_h - sprite_h))) {
+        if ((position->y < 0) || (position->y >= (viewport.h - sprite_h))) {
             velocity->y = -velocity->y;
             position->y += velocity->y;
         }
@@ -313,7 +312,7 @@
             CommonEvent(state, &event, &done);
         }
         for (i = 0; i < state->num_windows; ++i) {
-            MoveSprites(state->windows[i], state->renderers[i], sprites[i]);
+            MoveSprites(state->renderers[i], sprites[i]);
         }
     }