First pass on SDL render clip rect functionality
authorSam Lantinga <slouken@libsdl.org>
Sat, 04 May 2013 04:46:00 -0700
changeset 7141e276777b4247
parent 7140 e1896b95a8a7
child 7142 f4a670e51cde
First pass on SDL render clip rect functionality
include/SDL_render.h
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_render_sw.c
src/test/SDL_test_common.c
src/video/directfb/SDL_DirectFB_render.c
     1.1 --- a/include/SDL_render.h	Fri May 03 14:11:41 2013 +0930
     1.2 +++ b/include/SDL_render.h	Sat May 04 04:46:00 2013 -0700
     1.3 @@ -469,6 +469,8 @@
     1.4   *
     1.5   *  The x,y of the viewport rect represents the origin for rendering.
     1.6   *
     1.7 + *  \return 0 on success, or -1 on error
     1.8 + *
     1.9   *  \note When the window is resized, the current viewport is automatically
    1.10   *        centered within the new window size.
    1.11   *
    1.12 @@ -487,6 +489,30 @@
    1.13                                                     SDL_Rect * rect);
    1.14  
    1.15  /**
    1.16 + *  \brief Set the clip rectangle for the current target.
    1.17 + *  
    1.18 + *  \param rect   A pointer to the rectangle to set as the clip rectangle, or
    1.19 + *                NULL to disable clipping.
    1.20 + *
    1.21 + *  \return 0 on success, or -1 on error
    1.22 + *
    1.23 + *  \sa SDL_RenderGetClipRect()
    1.24 + */
    1.25 +extern DECLSPEC int SDLCALL SDL_RenderSetClipRect(SDL_Renderer * renderer,
    1.26 +                                                  const SDL_Rect * rect);
    1.27 +
    1.28 +/**
    1.29 + *  \brief Get the clip rectangle for the current target.
    1.30 + *  
    1.31 + *  \param rect   A pointer filled in with the current clip rectangle, or
    1.32 + *                an empty rectangle if clipping is disabled.
    1.33 + *
    1.34 + *  \sa SDL_RenderSetClipRect()
    1.35 + */
    1.36 +extern DECLSPEC void SDLCALL SDL_RenderGetClipRect(SDL_Renderer * renderer,
    1.37 +                                                   SDL_Rect * rect);
    1.38 +
    1.39 +/**
    1.40   *  \brief Set the drawing scale for rendering on the current target.
    1.41   *
    1.42   *  \param scaleX The horizontal scaling factor
     2.1 --- a/src/render/SDL_render.c	Fri May 03 14:11:41 2013 +0930
     2.2 +++ b/src/render/SDL_render.c	Sat May 04 04:46:00 2013 -0700
     2.3 @@ -932,6 +932,7 @@
     2.4      if (texture && !renderer->target) {
     2.5          /* Make a backup of the viewport */
     2.6          renderer->viewport_backup = renderer->viewport;
     2.7 +        renderer->clip_rect_backup = renderer->clip_rect;
     2.8          renderer->scale_backup = renderer->scale;
     2.9          renderer->logical_w_backup = renderer->logical_w;
    2.10          renderer->logical_h_backup = renderer->logical_h;
    2.11 @@ -953,6 +954,7 @@
    2.12          renderer->logical_h = 0;
    2.13      } else {
    2.14          renderer->viewport = renderer->viewport_backup;
    2.15 +        renderer->clip_rect = renderer->clip_rect_backup;
    2.16          renderer->scale = renderer->scale_backup;
    2.17          renderer->logical_w = renderer->logical_w_backup;
    2.18          renderer->logical_h = renderer->logical_h_backup;
    2.19 @@ -960,6 +962,9 @@
    2.20      if (renderer->UpdateViewport(renderer) < 0) {
    2.21          return -1;
    2.22      }
    2.23 +    if (renderer->UpdateClipRect(renderer) < 0) {
    2.24 +        return -1;
    2.25 +    }
    2.26  
    2.27      /* All set! */
    2.28      return 0;
    2.29 @@ -1098,6 +1103,35 @@
    2.30  }
    2.31  
    2.32  int
    2.33 +SDL_RenderSetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect)
    2.34 +{
    2.35 +    CHECK_RENDERER_MAGIC(renderer, )
    2.36 +
    2.37 +    if (rect) {
    2.38 +        renderer->clip_rect.x = (int)SDL_floor(rect->x * renderer->scale.x);
    2.39 +        renderer->clip_rect.y = (int)SDL_floor(rect->y * renderer->scale.y);
    2.40 +        renderer->clip_rect.w = (int)SDL_ceil(rect->w * renderer->scale.x);
    2.41 +        renderer->clip_rect.h = (int)SDL_ceil(rect->h * renderer->scale.y);
    2.42 +    } else {
    2.43 +        SDL_zero(renderer->clip_rect);
    2.44 +    }
    2.45 +    return renderer->UpdateClipRect(renderer);
    2.46 +}
    2.47 +
    2.48 +void
    2.49 +SDL_RenderGetClipRect(SDL_Renderer * renderer, SDL_Rect * rect)
    2.50 +{
    2.51 +    CHECK_RENDERER_MAGIC(renderer, )
    2.52 +
    2.53 +    if (rect) {
    2.54 +        rect->x = (int)(renderer->clip_rect.x / renderer->scale.x);
    2.55 +        rect->y = (int)(renderer->clip_rect.y / renderer->scale.y);
    2.56 +        rect->w = (int)(renderer->clip_rect.w / renderer->scale.x);
    2.57 +        rect->h = (int)(renderer->clip_rect.h / renderer->scale.y);
    2.58 +    }
    2.59 +}
    2.60 +
    2.61 +int
    2.62  SDL_RenderSetScale(SDL_Renderer * renderer, float scaleX, float scaleY)
    2.63  {
    2.64      CHECK_RENDERER_MAGIC(renderer, -1);
     3.1 --- a/src/render/SDL_sysrender.h	Fri May 03 14:11:41 2013 +0930
     3.2 +++ b/src/render/SDL_sysrender.h	Sat May 04 04:46:00 2013 -0700
     3.3 @@ -93,6 +93,7 @@
     3.4      void (*UnlockTexture) (SDL_Renderer * renderer, SDL_Texture * texture);
     3.5      int (*SetRenderTarget) (SDL_Renderer * renderer, SDL_Texture * texture);
     3.6      int (*UpdateViewport) (SDL_Renderer * renderer);
     3.7 +    int (*UpdateClipRect) (SDL_Renderer * renderer);
     3.8      int (*RenderClear) (SDL_Renderer * renderer);
     3.9      int (*RenderDrawPoints) (SDL_Renderer * renderer, const SDL_FPoint * points,
    3.10                               int count);
    3.11 @@ -133,6 +134,10 @@
    3.12      SDL_Rect viewport;
    3.13      SDL_Rect viewport_backup;
    3.14  
    3.15 +    /* The clip rectangle within the window */
    3.16 +    SDL_Rect clip_rect;
    3.17 +    SDL_Rect clip_rect_backup;
    3.18 +
    3.19      /* The render output coordinate scale */
    3.20      SDL_FPoint scale;
    3.21      SDL_FPoint scale_backup;
     4.1 --- a/src/render/direct3d/SDL_render_d3d.c	Fri May 03 14:11:41 2013 +0930
     4.2 +++ b/src/render/direct3d/SDL_render_d3d.c	Sat May 04 04:46:00 2013 -0700
     4.3 @@ -186,6 +186,7 @@
     4.4  static void D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
     4.5  static int D3D_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture);
     4.6  static int D3D_UpdateViewport(SDL_Renderer * renderer);
     4.7 +static int D3D_UpdateClipRect(SDL_Renderer * renderer);
     4.8  static int D3D_RenderClear(SDL_Renderer * renderer);
     4.9  static int D3D_RenderDrawPoints(SDL_Renderer * renderer,
    4.10                                  const SDL_FPoint * points, int count);
    4.11 @@ -510,6 +511,7 @@
    4.12      renderer->UnlockTexture = D3D_UnlockTexture;
    4.13      renderer->SetRenderTarget = D3D_SetRenderTarget;
    4.14      renderer->UpdateViewport = D3D_UpdateViewport;
    4.15 +    renderer->UpdateClipRect = D3D_UpdateClipRect;
    4.16      renderer->RenderClear = D3D_RenderClear;
    4.17      renderer->RenderDrawPoints = D3D_RenderDrawPoints;
    4.18      renderer->RenderDrawLines = D3D_RenderDrawLines;
    4.19 @@ -815,6 +817,39 @@
    4.20  }
    4.21  
    4.22  static int
    4.23 +D3D_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
    4.24 +{
    4.25 +    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
    4.26 +    D3D_TextureData *texturedata;
    4.27 +    HRESULT result;
    4.28 +
    4.29 +    D3D_ActivateRenderer(renderer);
    4.30 +
    4.31 +    /* Release the previous render target if it wasn't the default one */
    4.32 +    if (data->currentRenderTarget != NULL) {
    4.33 +        IDirect3DSurface9_Release(data->currentRenderTarget);
    4.34 +        data->currentRenderTarget = NULL;
    4.35 +    }
    4.36 +
    4.37 +    if (texture == NULL) {
    4.38 +        IDirect3DDevice9_SetRenderTarget(data->device, 0, data->defaultRenderTarget);
    4.39 +        return 0;
    4.40 +    }
    4.41 +
    4.42 +    texturedata = (D3D_TextureData *) texture->driverdata;
    4.43 +    result = IDirect3DTexture9_GetSurfaceLevel(texturedata->texture, 0, &data->currentRenderTarget);
    4.44 +    if(FAILED(result)) {
    4.45 +        return D3D_SetError("GetSurfaceLevel()", result);
    4.46 +    }
    4.47 +    result = IDirect3DDevice9_SetRenderTarget(data->device, 0, data->currentRenderTarget);
    4.48 +    if(FAILED(result)) {
    4.49 +        return D3D_SetError("SetRenderTarget()", result);
    4.50 +    }
    4.51 +
    4.52 +    return 0;
    4.53 +}
    4.54 +
    4.55 +static int
    4.56  D3D_UpdateViewport(SDL_Renderer * renderer)
    4.57  {
    4.58      D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
    4.59 @@ -853,35 +888,28 @@
    4.60  }
    4.61  
    4.62  static int
    4.63 -D3D_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
    4.64 +D3D_UpdateClipRect(SDL_Renderer * renderer)
    4.65  {
    4.66 +    const SDL_Rect *rect = &renderer->clip_rect;
    4.67      D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
    4.68 -    D3D_TextureData *texturedata;
    4.69 +    RECT r;
    4.70      HRESULT result;
    4.71  
    4.72 -    D3D_ActivateRenderer(renderer);
    4.73 +    if (!SDL_RectEmpty(rect)) {
    4.74 +        IDirect3DDevice9_SetRenderState(data->device, D3DRS_SCISSORTESTENABLE, TRUE);
    4.75 +        r.left = rect->x;
    4.76 +        r.top = rect->y;
    4.77 +        r.right = rect->w + rect->w;
    4.78 +        r.bottom = rect->y + rect->h;
    4.79  
    4.80 -    /* Release the previous render target if it wasn't the default one */
    4.81 -    if (data->currentRenderTarget != NULL) {
    4.82 -        IDirect3DSurface9_Release(data->currentRenderTarget);
    4.83 -        data->currentRenderTarget = NULL;
    4.84 +        result = IDirect3DDevice9_SetScissorRect(data->device, &r);
    4.85 +        if (result != D3D_OK) {
    4.86 +            D3D_SetError("SetScissor()", result);
    4.87 +            return -1;
    4.88 +        }
    4.89 +    } else {
    4.90 +        IDirect3DDevice9_SetRenderState(data->device, D3DRS_SCISSORTESTENABLE, FALSE);
    4.91      }
    4.92 -
    4.93 -    if (texture == NULL) {
    4.94 -        IDirect3DDevice9_SetRenderTarget(data->device, 0, data->defaultRenderTarget);
    4.95 -        return 0;
    4.96 -    }
    4.97 -
    4.98 -    texturedata = (D3D_TextureData *) texture->driverdata;
    4.99 -    result = IDirect3DTexture9_GetSurfaceLevel(texturedata->texture, 0, &data->currentRenderTarget);
   4.100 -    if(FAILED(result)) {
   4.101 -        return D3D_SetError("GetSurfaceLevel()", result);
   4.102 -    }
   4.103 -    result = IDirect3DDevice9_SetRenderTarget(data->device, 0, data->currentRenderTarget);
   4.104 -    if(FAILED(result)) {
   4.105 -        return D3D_SetError("SetRenderTarget()", result);
   4.106 -    }
   4.107 -
   4.108      return 0;
   4.109  }
   4.110  
     5.1 --- a/src/render/opengl/SDL_render_gl.c	Fri May 03 14:11:41 2013 +0930
     5.2 +++ b/src/render/opengl/SDL_render_gl.c	Sat May 04 04:46:00 2013 -0700
     5.3 @@ -56,6 +56,7 @@
     5.4  static void GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
     5.5  static int GL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture);
     5.6  static int GL_UpdateViewport(SDL_Renderer * renderer);
     5.7 +static int GL_UpdateClipRect(SDL_Renderer * renderer);
     5.8  static int GL_RenderClear(SDL_Renderer * renderer);
     5.9  static int GL_RenderDrawPoints(SDL_Renderer * renderer,
    5.10                                 const SDL_FPoint * points, int count);
    5.11 @@ -324,6 +325,7 @@
    5.12      renderer->UnlockTexture = GL_UnlockTexture;
    5.13      renderer->SetRenderTarget = GL_SetRenderTarget;
    5.14      renderer->UpdateViewport = GL_UpdateViewport;
    5.15 +    renderer->UpdateClipRect = GL_UpdateClipRect;
    5.16      renderer->RenderClear = GL_RenderClear;
    5.17      renderer->RenderDrawPoints = GL_RenderDrawPoints;
    5.18      renderer->RenderDrawLines = GL_RenderDrawLines;
    5.19 @@ -784,6 +786,21 @@
    5.20      return 0;
    5.21  }
    5.22  
    5.23 +static int
    5.24 +GL_UpdateClipRect(SDL_Renderer * renderer)
    5.25 +{
    5.26 +    const SDL_Rect *rect = &renderer->clip_rect;
    5.27 +    GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
    5.28 +
    5.29 +    if (!SDL_RectEmpty(rect)) {
    5.30 +        data->glEnable(GL_SCISSOR_TEST);
    5.31 +        data->glScissor(rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
    5.32 +    } else {
    5.33 +        data->glDisable(GL_SCISSOR_TEST);
    5.34 +    }
    5.35 +    return 0;
    5.36 +}
    5.37 +
    5.38  static void
    5.39  GL_SetShader(GL_RenderData * data, GL_Shader shader)
    5.40  {
     6.1 --- a/src/render/opengles/SDL_render_gles.c	Fri May 03 14:11:41 2013 +0930
     6.2 +++ b/src/render/opengles/SDL_render_gles.c	Sat May 04 04:46:00 2013 -0700
     6.3 @@ -59,6 +59,7 @@
     6.4  static int GLES_SetRenderTarget(SDL_Renderer * renderer,
     6.5                                   SDL_Texture * texture);
     6.6  static int GLES_UpdateViewport(SDL_Renderer * renderer);
     6.7 +static int GLES_UpdateClipRect(SDL_Renderer * renderer);
     6.8  static int GLES_RenderClear(SDL_Renderer * renderer);
     6.9  static int GLES_RenderDrawPoints(SDL_Renderer * renderer,
    6.10                                   const SDL_FPoint * points, int count);
    6.11 @@ -303,6 +304,7 @@
    6.12      renderer->UnlockTexture = GLES_UnlockTexture;
    6.13      renderer->SetRenderTarget = GLES_SetRenderTarget;
    6.14      renderer->UpdateViewport = GLES_UpdateViewport;
    6.15 +    renderer->UpdateClipRect = GLES_UpdateClipRect;
    6.16      renderer->RenderClear = GLES_RenderClear;
    6.17      renderer->RenderDrawPoints = GLES_RenderDrawPoints;
    6.18      renderer->RenderDrawLines = GLES_RenderDrawLines;
    6.19 @@ -630,6 +632,20 @@
    6.20      return 0;
    6.21  }
    6.22  
    6.23 +static int
    6.24 +GLES_UpdateClipRect(SDL_Renderer * renderer)
    6.25 +{
    6.26 +    const SDL_Rect *rect = &renderer->clip_rect;
    6.27 +
    6.28 +    if (!SDL_RectEmpty(rect)) {
    6.29 +        glEnable(GL_SCISSOR_TEST);
    6.30 +        glScissor(rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
    6.31 +    } else {
    6.32 +        glDisable(GL_SCISSOR_TEST);
    6.33 +    }
    6.34 +    return 0;
    6.35 +}
    6.36 +
    6.37  static void
    6.38  GLES_SetColor(GLES_RenderData * data, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
    6.39  {
     7.1 --- a/src/render/opengles2/SDL_render_gles2.c	Fri May 03 14:11:41 2013 +0930
     7.2 +++ b/src/render/opengles2/SDL_render_gles2.c	Sat May 04 04:46:00 2013 -0700
     7.3 @@ -275,6 +275,20 @@
     7.4      return 0;
     7.5  }
     7.6  
     7.7 +static int
     7.8 +GLES2_UpdateClipRect(SDL_Renderer * renderer)
     7.9 +{
    7.10 +    const SDL_Rect *rect = &renderer->clip_rect;
    7.11 +
    7.12 +    if (!SDL_RectEmpty(rect)) {
    7.13 +        glEnable(GL_SCISSOR_TEST);
    7.14 +        glScissor(rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
    7.15 +    } else {
    7.16 +        glDisable(GL_SCISSOR_TEST);
    7.17 +    }
    7.18 +    return 0;
    7.19 +}
    7.20 +
    7.21  static void
    7.22  GLES2_DestroyRenderer(SDL_Renderer *renderer)
    7.23  {
    7.24 @@ -934,11 +948,11 @@
    7.25  static int GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_FRect *rects, int count);
    7.26  static int GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect,
    7.27                              const SDL_FRect *dstrect);
    7.28 -static int GLES2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
    7.29 -                    Uint32 pixel_format, void * pixels, int pitch);
    7.30  static int GLES2_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
    7.31                           const SDL_Rect * srcrect, const SDL_FRect * dstrect,
    7.32                           const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip);
    7.33 +static int GLES2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
    7.34 +                    Uint32 pixel_format, void * pixels, int pitch);
    7.35  static void GLES2_RenderPresent(SDL_Renderer *renderer);
    7.36  
    7.37  
    7.38 @@ -1708,13 +1722,14 @@
    7.39      renderer->UnlockTexture       = &GLES2_UnlockTexture;
    7.40      renderer->SetRenderTarget     = &GLES2_SetRenderTarget;
    7.41      renderer->UpdateViewport      = &GLES2_UpdateViewport;
    7.42 +    renderer->UpdateClipRect      = &GLES2_UpdateClipRect;
    7.43      renderer->RenderClear         = &GLES2_RenderClear;
    7.44      renderer->RenderDrawPoints    = &GLES2_RenderDrawPoints;
    7.45      renderer->RenderDrawLines     = &GLES2_RenderDrawLines;
    7.46      renderer->RenderFillRects     = &GLES2_RenderFillRects;
    7.47      renderer->RenderCopy          = &GLES2_RenderCopy;
    7.48 +    renderer->RenderCopyEx        = &GLES2_RenderCopyEx;
    7.49      renderer->RenderReadPixels    = &GLES2_RenderReadPixels;
    7.50 -    renderer->RenderCopyEx        = &GLES2_RenderCopyEx;
    7.51      renderer->RenderPresent       = &GLES2_RenderPresent;
    7.52      renderer->DestroyTexture      = &GLES2_DestroyTexture;
    7.53      renderer->DestroyRenderer     = &GLES2_DestroyRenderer;
     8.1 --- a/src/render/software/SDL_render_sw.c	Fri May 03 14:11:41 2013 +0930
     8.2 +++ b/src/render/software/SDL_render_sw.c	Sat May 04 04:46:00 2013 -0700
     8.3 @@ -54,6 +54,7 @@
     8.4  static void SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
     8.5  static int SW_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture);
     8.6  static int SW_UpdateViewport(SDL_Renderer * renderer);
     8.7 +static int SW_UpdateClipRect(SDL_Renderer * renderer);
     8.8  static int SW_RenderClear(SDL_Renderer * renderer);
     8.9  static int SW_RenderDrawPoints(SDL_Renderer * renderer,
    8.10                                 const SDL_FPoint * points, int count);
    8.11 @@ -151,6 +152,7 @@
    8.12      renderer->UnlockTexture = SW_UnlockTexture;
    8.13      renderer->SetRenderTarget = SW_SetRenderTarget;
    8.14      renderer->UpdateViewport = SW_UpdateViewport;
    8.15 +    renderer->UpdateClipRect = SW_UpdateClipRect;
    8.16      renderer->RenderClear = SW_RenderClear;
    8.17      renderer->RenderDrawPoints = SW_RenderDrawPoints;
    8.18      renderer->RenderDrawLines = SW_RenderDrawLines;
    8.19 @@ -321,6 +323,20 @@
    8.20  }
    8.21  
    8.22  static int
    8.23 +SW_UpdateClipRect(SDL_Renderer * renderer)
    8.24 +{
    8.25 +    const SDL_Rect *rect = &renderer->clip_rect;
    8.26 +    SDL_Surface* framebuffer = (SDL_Surface *) renderer->driverdata;
    8.27 +
    8.28 +    if (!SDL_RectEmpty(rect)) {
    8.29 +        SDL_SetClipRect(framebuffer, rect);
    8.30 +    } else {
    8.31 +        SDL_SetClipRect(framebuffer, NULL);
    8.32 +    }
    8.33 +    return 0;
    8.34 +}
    8.35 +
    8.36 +static int
    8.37  SW_RenderClear(SDL_Renderer * renderer)
    8.38  {
    8.39      SDL_Surface *surface = SW_ActivateRenderer(renderer);
     9.1 --- a/src/test/SDL_test_common.c	Fri May 03 14:11:41 2013 +0930
     9.2 +++ b/src/test/SDL_test_common.c	Sat May 04 04:46:00 2013 -0700
     9.3 @@ -1202,6 +1202,26 @@
     9.4                  SDL_SetClipboardText("SDL rocks!\nYou know it!");
     9.5                  printf("Copied text to clipboard\n");
     9.6              }
     9.7 +            if (event->key.keysym.mod & KMOD_ALT) {
     9.8 +                /* Alt-C toggle a render clip rectangle */
     9.9 +                for (i = 0; i < state->num_windows; ++i) {
    9.10 +                    int w, h;
    9.11 +                    if (state->renderers[i]) {
    9.12 +                        SDL_Rect clip;
    9.13 +                        SDL_GetWindowSize(state->windows[i], &w, &h);
    9.14 +                        SDL_RenderGetClipRect(state->renderers[i], &clip);
    9.15 +                        if (SDL_RectEmpty(&clip)) {
    9.16 +                            clip.x = w/4;
    9.17 +                            clip.y = h/4;
    9.18 +                            clip.w = w/2;
    9.19 +                            clip.h = h/2;
    9.20 +                            SDL_RenderSetClipRect(state->renderers[i], &clip);
    9.21 +                        } else {
    9.22 +                            SDL_RenderSetClipRect(state->renderers[i], NULL);
    9.23 +                        }
    9.24 +                    }
    9.25 +                }
    9.26 +            }
    9.27              break;
    9.28          case SDLK_v:
    9.29              if (event->key.keysym.mod & KMOD_CTRL) {
    10.1 --- a/src/video/directfb/SDL_DirectFB_render.c	Fri May 03 14:11:41 2013 +0930
    10.2 +++ b/src/video/directfb/SDL_DirectFB_render.c	Sat May 04 04:46:00 2013 -0700
    10.3 @@ -116,6 +116,7 @@
    10.4  static int DirectFB_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
    10.5                        Uint32 format, const void * pixels, int pitch);
    10.6  static int DirectFB_UpdateViewport(SDL_Renderer * renderer);
    10.7 +static int DirectFB_UpdateClipRect(SDL_Renderer * renderer);
    10.8  static int DirectFB_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture);
    10.9  
   10.10  static int PrepareDraw(SDL_Renderer * renderer);
   10.11 @@ -380,8 +381,6 @@
   10.12      /* SetDrawColor - no needed */
   10.13      renderer->RenderFillRects = DirectFB_RenderFillRects;
   10.14  
   10.15 -    /* RenderDrawEllipse - no reference implementation yet */
   10.16 -    /* RenderFillEllipse - no reference implementation yet */
   10.17      renderer->RenderCopy = DirectFB_RenderCopy;
   10.18      renderer->RenderPresent = DirectFB_RenderPresent;
   10.19  
   10.20 @@ -392,6 +391,7 @@
   10.21      renderer->DestroyTexture = DirectFB_DestroyTexture;
   10.22      renderer->DestroyRenderer = DirectFB_DestroyRenderer;
   10.23      renderer->UpdateViewport = DirectFB_UpdateViewport;
   10.24 +    renderer->UpdateClipRect = DirectFB_UpdateClipRect;
   10.25      renderer->SetRenderTarget = DirectFB_SetRenderTarget;
   10.26  
   10.27  #if 0
   10.28 @@ -1259,6 +1259,28 @@
   10.29  }
   10.30  
   10.31  static int
   10.32 +DirectFB_UpdateClipRect(SDL_Renderer * renderer)
   10.33 +{
   10.34 +    const SDL_Rect *rect = &renderer->clip_rect;
   10.35 +    DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
   10.36 +    IDirectFBSurface *destsurf = get_dfb_surface(data->window);
   10.37 +    DFBRegion region;
   10.38 +
   10.39 +    if (!SDL_RectEmpty(rect)) {
   10.40 +        region.x1 = rect->x;
   10.41 +        region.x2 = rect->x + rect->w;
   10.42 +        region.y1 = rect->y;
   10.43 +        region.y2 = rect->y + rect->h;
   10.44 +        SDL_DFB_CHECKERR(destsurf->SetClip(destsurf, &region));
   10.45 +    } else {
   10.46 +        SDL_DFB_CHECKERR(destsurf->SetClip(destsurf, NULL));
   10.47 +    }
   10.48 +    return 0;
   10.49 +  error:
   10.50 +    return -1;
   10.51 +}
   10.52 +
   10.53 +static int
   10.54  DirectFB_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
   10.55                       Uint32 format, void * pixels, int pitch)
   10.56  {