Start experimental branch for client-side rasterization. experimental
authorSunny Sachanandani <sunnysachanandani@gmail.com>
Sun, 18 Jul 2010 12:43:04 +0530
branchexperimental
changeset 459795be206b3cb7
parent 4596 dc26c37ad70e
child 4598 66e13a224bd6
Start experimental branch for client-side rasterization.
src/SDL_error.c
src/video/x11/SDL_x11render.c
src/video/x11/SDL_x11sym.h
     1.1 --- a/src/SDL_error.c	Sun Jul 18 08:28:35 2010 +0530
     1.2 +++ b/src/SDL_error.c	Sun Jul 18 12:43:04 2010 +0530
     1.3 @@ -38,6 +38,8 @@
     1.4  
     1.5  #define SDL_ERRBUFIZE	1024
     1.6  
     1.7 +#define DEBUG_ERROR
     1.8 +
     1.9  /* Private functions */
    1.10  
    1.11  static const char *
     2.1 --- a/src/video/x11/SDL_x11render.c	Sun Jul 18 08:28:35 2010 +0530
     2.2 +++ b/src/video/x11/SDL_x11render.c	Sun Jul 18 12:43:04 2010 +0530
     2.3 @@ -30,6 +30,7 @@
     2.4  #include "../SDL_rect_c.h"
     2.5  #include "../SDL_pixels_c.h"
     2.6  #include "../SDL_yuv_sw_c.h"
     2.7 +#include "SDL_surface.h"
     2.8  
     2.9  /* X11 renderer implementation */
    2.10  
    2.11 @@ -97,13 +98,21 @@
    2.12      Window xwindow;
    2.13      Pixmap pixmaps[3];
    2.14  #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
    2.15 -    Pixmap mask;
    2.16 +    Pixmap stencil;
    2.17 +    Pixmap brush;
    2.18 +    Picture brush_pict;
    2.19 +#ifndef NO_SHARED_MEMORY
    2.20 +    XImage *stencil_image;
    2.21 +    SDL_Surface *stencil_surface;
    2.22 +    XShmSegmentInfo stencil_shminfo;
    2.23 +#endif
    2.24      Picture xwindow_pict;
    2.25      Picture pixmap_picts[3];
    2.26      Picture drawable_pict;
    2.27 +    Picture stencil_pict;
    2.28      int blend_op;
    2.29      XRenderPictFormat* xwindow_pict_fmt;
    2.30 -    GC mask_gc;
    2.31 +    GC stencil_gc;
    2.32      SDL_bool use_xrender;
    2.33  #endif
    2.34      int current_pixmap;
    2.35 @@ -286,21 +295,74 @@
    2.36          renderer->info.blend_modes |=
    2.37              (SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MASK);
    2.38          // Create a clip mask that is used for rendering primitives.
    2.39 -        data->mask = XCreatePixmap(data->display, data->xwindow,
    2.40 -                                   window->w, window->h, 1);
    2.41 -        if (!data->mask) {
    2.42 -            SDL_SetError("XCreatePixmap() failed");
    2.43 -            return NULL;
    2.44 +        data->stencil = XCreatePixmap(data->display, data->xwindow,
    2.45 +                                   window->w, window->h, 8);
    2.46 +        
    2.47 +        // Create the GC for the clip mask.
    2.48 +        data->stencil_gc = XCreateGC(data->display, data->stencil,
    2.49 +                                  GCGraphicsExposures, &gcv);
    2.50 +        XSetBackground(data->display, data->stencil_gc, 0x00);
    2.51 +        XSetForeground(data->display, data->stencil_gc, 0xFF);
    2.52 +        data->stencil_pict =
    2.53 +            XRenderCreatePicture(data->display, data->stencil,
    2.54 +                                 XRenderFindStandardFormat(data->display,
    2.55 +                                                           PictStandardA8),
    2.56 +                                 0, NULL);
    2.57 +        data->brush =
    2.58 +            XCreatePixmap(data->display, data->xwindow, 1, 1, 32);
    2.59 +        XRenderPictureAttributes brush_attr;
    2.60 +        brush_attr.repeat = RepeatNormal;
    2.61 +        data->brush_pict =
    2.62 +            XRenderCreatePicture(data->display, data->brush,
    2.63 +                                 XRenderFindStandardFormat(data->display,
    2.64 +                                                           PictStandardARGB32),
    2.65 +                                 CPRepeat, &brush_attr);
    2.66 +#ifndef NO_SHARED_MEMORY
    2.67 +        /* Create a mask image using MIT-SHM */
    2.68 +        data->stencil_image = NULL;
    2.69 +        data->stencil_surface = NULL;
    2.70 +        XShmSegmentInfo *shminfo = &data->stencil_shminfo;
    2.71 +        while (SDL_X11_HAVE_SHM) {
    2.72 +            data->stencil_image =
    2.73 +                XShmCreateImage(data->display, data->visual, 8, ZPixmap,
    2.74 +                                NULL, shminfo, window->w, window->h);
    2.75 +            if (!data->stencil_image) {
    2.76 +                printf("XShmCreateImage() failed");
    2.77 +                break;
    2.78 +            } else {
    2.79 +                printf("image created\n");
    2.80 +            }
    2.81 +            shminfo->shmid = shmget(IPC_PRIVATE,
    2.82 +                                    data->stencil_image->bytes_per_line *
    2.83 +                                    data->stencil_image->height,
    2.84 +                                    IPC_CREAT|0777);
    2.85 +            if (!shminfo->shmid) {
    2.86 +                printf("shmget() failed");
    2.87 +                break;
    2.88 +            } else {
    2.89 +                printf("shmid aquired\n");
    2.90 +            }
    2.91 +            shminfo->shmaddr = data->stencil_image->data = shmat(shminfo->shmid, 0, 0);
    2.92 +            shminfo->readOnly = False;
    2.93 +            XShmAttach(data->display, shminfo);
    2.94 +            XSync(data->display, False);
    2.95 +            shmctl(shminfo->shmid, IPC_RMID, NULL);
    2.96 +            data->stencil_surface =
    2.97 +                SDL_CreateRGBSurfaceFrom(shminfo->shmaddr,
    2.98 +                                         data->stencil_image->width,
    2.99 +                                         data->stencil_image->height,
   2.100 +                                         8,
   2.101 +                                         data->stencil_image->bytes_per_line,
   2.102 +                                         0, 0, 0, 0xFF);
   2.103 +            if (!data->stencil_surface) {
   2.104 +                printf("SDL_CreateRGBSurfaceFrom() failed");
   2.105 +                break;
   2.106 +            } else {
   2.107 +                printf("surface created\n");
   2.108 +            }
   2.109 +            break;
   2.110          }
   2.111 -        // Create the GC for the clip mask.
   2.112 -        data->mask_gc = XCreateGC(data->display, data->mask,
   2.113 -                                  GCGraphicsExposures, &gcv);
   2.114 -        if (!data->mask_gc) {
   2.115 -            SDL_SetError("XCreateGC() failed");
   2.116 -            return NULL;
   2.117 -        }
   2.118 -        XSetBackground(data->display, data->mask_gc, 0);
   2.119 -        XSetForeground(data->display, data->mask_gc, 1);
   2.120 +#endif
   2.121          // Set the default blending mode.
   2.122          renderer->blendMode = SDL_BLENDMODE_BLEND;
   2.123          data->blend_op = PictOpOver;
   2.124 @@ -693,14 +755,6 @@
   2.125          if (!data->image)
   2.126  #endif /* not NO_SHARED_MEMORY */
   2.127          {
   2.128 -            /* This is the case where the server does not have
   2.129 -               shared memory support and the texture is streaming.
   2.130 -               It does not make sense to use Xrender here because
   2.131 -               we would have to copy the data onto a server side
   2.132 -               pixmap with XPutImage first and only then can we 
   2.133 -               use Xrender
   2.134 -            */
   2.135 -
   2.136              data->pixels = SDL_malloc(texture->h * data->pitch);
   2.137              if (!data->pixels) {
   2.138                  X11_DestroyTexture(renderer, texture);
   2.139 @@ -999,61 +1053,74 @@
   2.140      SDL_Window *window = renderer->window;
   2.141      XPoint *xpoints, *xpoint;
   2.142      int i, xcount;
   2.143 +    SDL_Rect clip, rect;
   2.144  
   2.145 -    if (data->makedirty) {
   2.146 -        SDL_Rect rect;
   2.147 +    clip.x = 0;
   2.148 +    clip.y = 0;
   2.149 +    clip.w = window->w;
   2.150 +    clip.h = window->h;
   2.151  
   2.152 -        /* Get the smallest rectangle that contains everything */
   2.153 -        rect.x = 0;
   2.154 -        rect.y = 0;
   2.155 -        rect.w = window->w;
   2.156 -        rect.h = window->h;
   2.157 -        if (!SDL_EnclosePoints(points, count, &rect, &rect)) {
   2.158 -            /* Nothing to draw */
   2.159 -            return 0;
   2.160 +#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
   2.161 +#ifndef NO_SHARED_MEMORY
   2.162 +    if (data->use_xrender && data->stencil_image && data->stencil_surface) {
   2.163 +        SDL_FillRect(data->stencil_surface, NULL, 0x00);
   2.164 +
   2.165 +        SDL_SetClipRect(data->stencil_surface, NULL);
   2.166 +        SDL_DrawPoints(data->stencil_surface, points, count, 0xFF);
   2.167 +
   2.168 +        XShmPutImage(data->display, data->stencil, data->stencil_gc, data->stencil_image,
   2.169 +                     0, 0, 0, 0, window->w, window->h, False);
   2.170 +    } else
   2.171 +#endif
   2.172 +#endif
   2.173 +    {
   2.174 +        if (data->makedirty) {
   2.175 +
   2.176 +            /* Get the smallest rectangle that contains everything */
   2.177 +            rect.x = 0;
   2.178 +            rect.y = 0;
   2.179 +            rect.w = window->w;
   2.180 +            rect.h = window->h;
   2.181 +            if (!SDL_EnclosePoints(points, count, &rect, &rect)) {
   2.182 +                /* Nothing to draw */
   2.183 +                return 0;
   2.184 +            }
   2.185 +            SDL_AddDirtyRect(&data->dirty, &rect);
   2.186          }
   2.187 -        SDL_AddDirtyRect(&data->dirty, &rect);
   2.188 -    }
   2.189  
   2.190 -    xpoint = xpoints = SDL_stack_alloc(XPoint, count);
   2.191 -    xcount = 0;
   2.192 -    for (i = 0; i < count; ++i) {
   2.193 -        int x = points[i].x;
   2.194 -        int y = points[i].y;
   2.195 -        if (x < 0 || x >= window->w || y < 0 || y >= window->h) {
   2.196 -            continue;
   2.197 +        xpoint = xpoints = SDL_stack_alloc(XPoint, count);
   2.198 +        xcount = 0;
   2.199 +        for (i = 0; i < count; ++i) {
   2.200 +            int x = points[i].x;
   2.201 +            int y = points[i].y;
   2.202 +            if (x < 0 || x >= window->w || y < 0 || y >= window->h) {
   2.203 +                continue;
   2.204 +            }
   2.205 +            xpoint->x = (short)x;
   2.206 +            xpoint->y = (short)y;
   2.207 +            ++xpoint;
   2.208 +            ++xcount;
   2.209          }
   2.210 -        xpoint->x = (short)x;
   2.211 -        xpoint->y = (short)y;
   2.212 -        ++xpoint;
   2.213 -        ++xcount;
   2.214 +#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
   2.215 +        if (data->use_xrender) {
   2.216 +            XSetForeground(data->display, data->stencil_gc, 0x00);
   2.217 +            XFillRectangle(data->display, data->stencil, data->stencil_gc,
   2.218 +                           0, 0, window->w, window->h);
   2.219 +            XSetForeground(data->display, data->stencil_gc, 0xFF);
   2.220 +            XDrawPoints(data->display, data->stencil, data->stencil_gc, xpoints, xcount,
   2.221 +                        CoordModeOrigin);
   2.222 +        }
   2.223 +#endif
   2.224      }
   2.225  #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
   2.226 -    if (data->use_xrender == SDL_TRUE) {
   2.227 +    if (data->use_xrender) {
   2.228          XRenderColor foreground;
   2.229 -        XRenderPictureAttributes attributes;
   2.230 -        unsigned long valuemask;
   2.231 -        
   2.232          foreground = xrenderdrawcolor(renderer);
   2.233 -        /* Set the clip mask to restrict rendering to
   2.234 -         * the primitive being drawn
   2.235 -         */
   2.236 -        attributes.clip_mask = data->mask;
   2.237 -        valuemask = CPClipMask;
   2.238 -        
   2.239 -        XSetForeground(data->display, data->mask_gc, 0);
   2.240 -        XFillRectangle(data->display, data->mask, data->mask_gc,
   2.241 -                       0, 0, window->w, window->h);
   2.242 -        XSetForeground(data->display, data->mask_gc, 1);
   2.243 -
   2.244 -        XDrawPoints(data->display, data->mask, data->mask_gc, xpoints, xcount,
   2.245 -                    CoordModeOrigin);
   2.246 -        XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes);
   2.247 -        /*XRenderFillRectangle(data->display, data->blend_op, data->drawable_pict,
   2.248 -                             &foreground, 0, 0, window->w, window->h);*/
   2.249 -        // Reset the clip_mask
   2.250 -        attributes.clip_mask = None;
   2.251 -        XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes);
   2.252 +        XRenderFillRectangle(data->display, PictOpSrc, data->brush_pict,
   2.253 +                             &foreground, 0, 0, 1, 1);
   2.254 +        XRenderComposite(data->display, data->blend_op, data->brush_pict,
   2.255 +                         data->stencil_pict, data->drawable_pict,
   2.256 +                         0, 0, 0, 0, 0, 0, window->w, window->h);
   2.257      }
   2.258      else
   2.259  #endif
   2.260 @@ -1067,6 +1134,7 @@
   2.261                          CoordModeOrigin);
   2.262          }
   2.263      }
   2.264 +
   2.265      SDL_stack_free(xpoints);
   2.266  
   2.267      return 0;
   2.268 @@ -1089,81 +1157,141 @@
   2.269      clip.y = 0;
   2.270      clip.w = window->w;
   2.271      clip.h = window->h;
   2.272 +#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
   2.273 +#ifndef NO_SHARED_MEMORY
   2.274 +    if (data->use_xrender && data->stencil_image && data->stencil_surface) {
   2.275 +        SDL_FillRect(data->stencil_surface, NULL, 0x00);
   2.276  
   2.277 -    Pixmap drawable;
   2.278 -    GC gc;
   2.279 -#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
   2.280 -    if (data->use_xrender == SDL_TRUE) {
   2.281 -        drawable = data->mask;
   2.282 -        gc = data->mask_gc;
   2.283 -        XSetForeground(data->display, data->mask_gc, 0);
   2.284 -        XFillRectangle(data->display, data->mask, data->mask_gc,
   2.285 -                       0, 0, window->w, window->h);
   2.286 -        XSetForeground(data->display, data->mask_gc, 1);
   2.287 -    }
   2.288 -    else
   2.289 +        SDL_SetClipRect(data->stencil_surface, NULL);
   2.290 +        SDL_DrawLines(data->stencil_surface, points, count, 0xFF);
   2.291 +
   2.292 +        XShmPutImage(data->display, data->stencil, data->stencil_gc, data->stencil_image,
   2.293 +                     0, 0, 0, 0, window->w, window->h, False);
   2.294 +    } else
   2.295 +#endif
   2.296  #endif
   2.297      {
   2.298 -        drawable = data->drawable;
   2.299 -        gc = data->gc;
   2.300 -    }
   2.301 -
   2.302 -    foreground = renderdrawcolor(renderer, 1);
   2.303 -    XSetForeground(data->display, data->gc, foreground);
   2.304 -
   2.305 -    xpoint = xpoints = SDL_stack_alloc(XPoint, count);
   2.306 -    xcount = 0;
   2.307 -    minx = INT_MAX;
   2.308 -    miny = INT_MAX;
   2.309 -    maxx = INT_MIN;
   2.310 -    maxy = INT_MIN;
   2.311 -    for (i = 0; i < count; ++i) {
   2.312 -        int x = points[i].x;
   2.313 -        int y = points[i].y;
   2.314 -
   2.315 -        /* If the point is inside the window, add it to the list */
   2.316 -        if (x >= 0 && x < window->w && y >= 0 && y < window->h) {
   2.317 -            if (x < minx) {
   2.318 -                minx = x;
   2.319 -            } else if (x > maxx) {
   2.320 -                maxx = x;
   2.321 -            }
   2.322 -            if (y < miny) {
   2.323 -                miny = y;
   2.324 -            } else if (y > maxy) {
   2.325 -                maxy = y;
   2.326 -            }
   2.327 -            xpoint->x = (short)x;
   2.328 -            xpoint->y = (short)y;
   2.329 -            ++xpoint;
   2.330 -            ++xcount;
   2.331 -            continue;
   2.332 +        Pixmap drawable;
   2.333 +        GC gc;
   2.334 +#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
   2.335 +        if (data->use_xrender) {
   2.336 +            drawable = data->stencil;
   2.337 +            gc = data->stencil_gc;
   2.338 +            XSetForeground(data->display, data->stencil_gc, 0x00);
   2.339 +            XFillRectangle(data->display, data->stencil, data->stencil_gc,
   2.340 +                           0, 0, window->w, window->h);
   2.341 +            XSetForeground(data->display, data->stencil_gc, 0xFF);
   2.342 +        }
   2.343 +        else
   2.344 +#endif
   2.345 +        {
   2.346 +            drawable = data->drawable;
   2.347 +            gc = data->gc;
   2.348          }
   2.349  
   2.350 -        /* We need to clip the line segments joined by this point */
   2.351 -        if (xcount > 0) {
   2.352 -            int x1 = xpoint[-1].x;
   2.353 -            int y1 = xpoint[-1].y;
   2.354 -            int x2 = x;
   2.355 -            int y2 = y;
   2.356 -            if (SDL_IntersectRectAndLine(&clip, &x1, &y1, &x2, &y2)) {
   2.357 -                if (x2 < minx) {
   2.358 -                    minx = x2;
   2.359 -                } else if (x2 > maxx) {
   2.360 -                    maxx = x2;
   2.361 +        foreground = renderdrawcolor(renderer, 1);
   2.362 +        XSetForeground(data->display, data->gc, foreground);
   2.363 +
   2.364 +        xpoint = xpoints = SDL_stack_alloc(XPoint, count);
   2.365 +        xcount = 0;
   2.366 +        minx = INT_MAX;
   2.367 +        miny = INT_MAX;
   2.368 +        maxx = INT_MIN;
   2.369 +        maxy = INT_MIN;
   2.370 +        for (i = 0; i < count; ++i) {
   2.371 +            int x = points[i].x;
   2.372 +            int y = points[i].y;
   2.373 +
   2.374 +            /* If the point is inside the window, add it to the list */
   2.375 +            if (x >= 0 && x < window->w && y >= 0 && y < window->h) {
   2.376 +                if (x < minx) {
   2.377 +                    minx = x;
   2.378 +                } else if (x > maxx) {
   2.379 +                    maxx = x;
   2.380                  }
   2.381 -                if (y2 < miny) {
   2.382 -                    miny = y2;
   2.383 -                } else if (y2 > maxy) {
   2.384 -                    maxy = y2;
   2.385 +                if (y < miny) {
   2.386 +                    miny = y;
   2.387 +                } else if (y > maxy) {
   2.388 +                    maxy = y;
   2.389                  }
   2.390 -                xpoint->x = (short)x2;
   2.391 -                xpoint->y = (short)y2;
   2.392 +                xpoint->x = (short)x;
   2.393 +                xpoint->y = (short)y;
   2.394                  ++xpoint;
   2.395                  ++xcount;
   2.396 +                continue;
   2.397              }
   2.398 -            XDrawLines(data->display, drawable, gc,
   2.399 -                       xpoints, xcount, CoordModeOrigin);
   2.400 +
   2.401 +            /* We need to clip the line segments joined by this point */
   2.402 +            if (xcount > 0) {
   2.403 +                int x1 = xpoint[-1].x;
   2.404 +                int y1 = xpoint[-1].y;
   2.405 +                int x2 = x;
   2.406 +                int y2 = y;
   2.407 +                if (SDL_IntersectRectAndLine(&clip, &x1, &y1, &x2, &y2)) {
   2.408 +                    if (x2 < minx) {
   2.409 +                        minx = x2;
   2.410 +                    } else if (x2 > maxx) {
   2.411 +                        maxx = x2;
   2.412 +                    }
   2.413 +                    if (y2 < miny) {
   2.414 +                        miny = y2;
   2.415 +                    } else if (y2 > maxy) {
   2.416 +                        maxy = y2;
   2.417 +                    }
   2.418 +                    xpoint->x = (short)x2;
   2.419 +                    xpoint->y = (short)y2;
   2.420 +                    ++xpoint;
   2.421 +                    ++xcount;
   2.422 +                }
   2.423 +                XDrawLines(data->display, drawable, gc,
   2.424 +                           xpoints, xcount, CoordModeOrigin);
   2.425 +                if (xpoints[0].x != x2 || xpoints[0].y != y2) {
   2.426 +                    XDrawPoint(data->display, drawable, gc, x2, y2);
   2.427 +                }
   2.428 +                if (data->makedirty) {
   2.429 +                    SDL_Rect rect;
   2.430 +
   2.431 +                    rect.x = minx;
   2.432 +                    rect.y = miny;
   2.433 +                    rect.w = (maxx - minx) + 1;
   2.434 +                    rect.h = (maxy - miny) + 1;
   2.435 +                    SDL_AddDirtyRect(&data->dirty, &rect);
   2.436 +                }
   2.437 +                xpoint = xpoints;
   2.438 +                xcount = 0;
   2.439 +                minx = INT_MAX;
   2.440 +                miny = INT_MAX;
   2.441 +                maxx = INT_MIN;
   2.442 +                maxy = INT_MIN;
   2.443 +            }
   2.444 +            if (i < (count-1)) {
   2.445 +                int x1 = x;
   2.446 +                int y1 = y;
   2.447 +                int x2 = points[i+1].x;
   2.448 +                int y2 = points[i+1].y;
   2.449 +                if (SDL_IntersectRectAndLine(&clip, &x1, &y1, &x2, &y2)) {
   2.450 +                    if (x1 < minx) {
   2.451 +                        minx = x1;
   2.452 +                    } else if (x1 > maxx) {
   2.453 +                        maxx = x1;
   2.454 +                    }
   2.455 +                    if (y1 < miny) {
   2.456 +                        miny = y1;
   2.457 +                    } else if (y1 > maxy) {
   2.458 +                        maxy = y1;
   2.459 +                    }
   2.460 +                    xpoint->x = (short)x1;
   2.461 +                    xpoint->y = (short)y1;
   2.462 +                    ++xpoint;
   2.463 +                    ++xcount;
   2.464 +                }
   2.465 +            }
   2.466 +        }
   2.467 +        if (xcount > 1) {
   2.468 +            int x2 = xpoint[-1].x;
   2.469 +            int y2 = xpoint[-1].y;
   2.470 +            XDrawLines(data->display, drawable, gc, xpoints, xcount,
   2.471 +                       CoordModeOrigin);
   2.472              if (xpoints[0].x != x2 || xpoints[0].y != y2) {
   2.473                  XDrawPoint(data->display, drawable, gc, x2, y2);
   2.474              }
   2.475 @@ -1176,65 +1304,16 @@
   2.476                  rect.h = (maxy - miny) + 1;
   2.477                  SDL_AddDirtyRect(&data->dirty, &rect);
   2.478              }
   2.479 -            xpoint = xpoints;
   2.480 -            xcount = 0;
   2.481 -            minx = INT_MAX;
   2.482 -            miny = INT_MAX;
   2.483 -            maxx = INT_MIN;
   2.484 -            maxy = INT_MIN;
   2.485 -        }
   2.486 -        if (i < (count-1)) {
   2.487 -            int x1 = x;
   2.488 -            int y1 = y;
   2.489 -            int x2 = points[i+1].x;
   2.490 -            int y2 = points[i+1].y;
   2.491 -            if (SDL_IntersectRectAndLine(&clip, &x1, &y1, &x2, &y2)) {
   2.492 -                if (x1 < minx) {
   2.493 -                    minx = x1;
   2.494 -                } else if (x1 > maxx) {
   2.495 -                    maxx = x1;
   2.496 -                }
   2.497 -                if (y1 < miny) {
   2.498 -                    miny = y1;
   2.499 -                } else if (y1 > maxy) {
   2.500 -                    maxy = y1;
   2.501 -                }
   2.502 -                xpoint->x = (short)x1;
   2.503 -                xpoint->y = (short)y1;
   2.504 -                ++xpoint;
   2.505 -                ++xcount;
   2.506 -            }
   2.507 -        }
   2.508 -    }
   2.509 -    if (xcount > 1) {
   2.510 -        int x2 = xpoint[-1].x;
   2.511 -        int y2 = xpoint[-1].y;
   2.512 -        XDrawLines(data->display, drawable, gc, xpoints, xcount,
   2.513 -                   CoordModeOrigin);
   2.514 -        if (xpoints[0].x != x2 || xpoints[0].y != y2) {
   2.515 -            XDrawPoint(data->display, drawable, gc, x2, y2);
   2.516 -        }
   2.517 -        if (data->makedirty) {
   2.518 -            SDL_Rect rect;
   2.519 -
   2.520 -            rect.x = minx;
   2.521 -            rect.y = miny;
   2.522 -            rect.w = (maxx - minx) + 1;
   2.523 -            rect.h = (maxy - miny) + 1;
   2.524 -            SDL_AddDirtyRect(&data->dirty, &rect);
   2.525          }
   2.526      }
   2.527  #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
   2.528 -    if(data->use_xrender == SDL_TRUE) {
   2.529 +    if (data->use_xrender) {
   2.530          XRenderColor xrforeground = xrenderdrawcolor(renderer);
   2.531 -        XRenderPictureAttributes attributes;
   2.532 -        attributes.clip_mask = data->mask;
   2.533 -        unsigned long valuemask = CPClipMask;
   2.534 -        XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes);
   2.535 -        /*XRenderFillRectangle(data->display, data->blend_op, data->drawable_pict,
   2.536 -                             &xrforeground, 0, 0, window->w, window->h);*/
   2.537 -        attributes.clip_mask = None;
   2.538 -        XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes);
   2.539 +        XRenderFillRectangle(data->display, PictOpSrc, data->brush_pict,
   2.540 +                             &xrforeground, 0, 0, 1, 1);
   2.541 +        XRenderComposite(data->display, data->blend_op, data->brush_pict,
   2.542 +                         data->stencil_pict, data->drawable_pict,
   2.543 +                         0, 0, 0, 0, 0, 0, window->w, window->h);
   2.544      }
   2.545  #endif
   2.546      SDL_stack_free(xpoints);
   2.547 @@ -1258,44 +1337,60 @@
   2.548      clip.w = window->w;
   2.549      clip.h = window->h;
   2.550  
   2.551 -    for (i = 0; i < count; ++i) {
   2.552 -        if (!SDL_IntersectRect(rects[i], &clip, &rect)) {
   2.553 -            continue;
   2.554 +#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
   2.555 +#ifndef NO_SHARED_MEMORY
   2.556 +    if (data->use_xrender && data->stencil_image && data->stencil_surface) {
   2.557 +        SDL_FillRect(data->stencil_surface, NULL, 0x00);
   2.558 +
   2.559 +        SDL_SetClipRect(data->stencil_surface, NULL);
   2.560 +        SDL_DrawRects(data->stencil_surface, rects, count, 1);
   2.561 +
   2.562 +        XShmPutImage(data->display, data->stencil, data->stencil_gc, data->stencil_image,
   2.563 +                     0, 0, 0, 0, window->w, window->h, False);
   2.564 +    }
   2.565 +    else
   2.566 +#endif
   2.567 +#endif
   2.568 +    {
   2.569 +
   2.570 +        for (i = 0; i < count; ++i) {
   2.571 +            if (!SDL_IntersectRect(rects[i], &clip, &rect)) {
   2.572 +                continue;
   2.573 +            }
   2.574 +
   2.575 +            xrect->x = (short)rect.x;
   2.576 +            xrect->y = (short)rect.y;
   2.577 +            xrect->width = (unsigned short)rect.w;
   2.578 +            xrect->height = (unsigned short)rect.h;
   2.579 +            ++xrect;
   2.580 +            ++xcount;
   2.581 +
   2.582 +            if (data->makedirty) {
   2.583 +                SDL_AddDirtyRect(&data->dirty, &rect);
   2.584 +            }
   2.585          }
   2.586 +#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
   2.587 +        if (data->use_xrender) {
   2.588 +            XSetForeground(data->display, data->stencil_gc, 0x00);
   2.589 +            XFillRectangle(data->display, data->stencil, data->stencil_gc,
   2.590 +                           0, 0, window->w, window->h);
   2.591 +            XSetForeground(data->display, data->stencil_gc, 0xFF);
   2.592  
   2.593 -        xrect->x = (short)rect.x;
   2.594 -        xrect->y = (short)rect.y;
   2.595 -        xrect->width = (unsigned short)rect.w;
   2.596 -        xrect->height = (unsigned short)rect.h;
   2.597 -        ++xrect;
   2.598 -        ++xcount;
   2.599 +            XDrawRectangles(data->display, data->stencil, data->stencil_gc, xrects, xcount);
   2.600 +        }
   2.601 +#endif
   2.602 +    } 
   2.603 +#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
   2.604 +    if (data->use_xrender) {
   2.605 +        XRenderColor foreground;
   2.606 +        foreground = xrenderdrawcolor(renderer);
   2.607  
   2.608 -        if (data->makedirty) {
   2.609 -            SDL_AddDirtyRect(&data->dirty, &rect);
   2.610 -        }
   2.611 -    }
   2.612 -     
   2.613 -#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
   2.614 -    if(data->use_xrender == SDL_TRUE) {
   2.615 -        XRenderColor foreground;
   2.616 -        XRenderPictureAttributes attributes;
   2.617 -        unsigned long valuemask;
   2.618 +        XRenderFillRectangle(data->display, PictOpSrc, data->brush_pict,
   2.619 +                             &foreground, 0, 0, 1, 1);
   2.620  
   2.621 -        foreground = xrenderdrawcolor(renderer);
   2.622 -        valuemask = CPClipMask;
   2.623 -        attributes.clip_mask = data->mask;
   2.624 -        
   2.625 -        XSetForeground(data->display, data->mask_gc, 0);
   2.626 -        XFillRectangle(data->display, data->mask, data->mask_gc,
   2.627 -                       0, 0, window->w, window->h);
   2.628 -        XSetForeground(data->display, data->mask_gc, 1);
   2.629 -
   2.630 -        XDrawRectangles(data->display, data->mask, data->mask_gc, xrects, xcount);
   2.631 -        XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes);
   2.632 -        /*XRenderFillRectangle(data->display, data->blend_op, data->drawable_pict,
   2.633 -                             &foreground, 0, 0, window->w, window->h);*/
   2.634 -        attributes.clip_mask = None;
   2.635 -        XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes);
   2.636 +        XRenderComposite(data->display, data->blend_op, data->brush_pict,
   2.637 +                         data->stencil_pict, data->drawable_pict,
   2.638 +                         0, 0, 0, 0, 0, 0, window->w, window->h);
   2.639      }
   2.640      else
   2.641  #endif
   2.642 @@ -1326,7 +1421,7 @@
   2.643      clip.y = 0;
   2.644      clip.w = window->w;
   2.645      clip.h = window->h;
   2.646 -
   2.647 +    
   2.648      int i, xcount;
   2.649      XRectangle *xrects, *xrect;
   2.650      xrect = xrects = SDL_stack_alloc(XRectangle, count);
   2.651 @@ -1349,26 +1444,11 @@
   2.652      }
   2.653  
   2.654  #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
   2.655 -    if(data->use_xrender == SDL_TRUE) {
   2.656 +    if (data->use_xrender) {
   2.657          XRenderColor foreground;
   2.658 -        XRenderPictureAttributes attributes;
   2.659 -
   2.660          foreground = xrenderdrawcolor(renderer);
   2.661 -        attributes.clip_mask = data->mask;
   2.662 -        
   2.663 -        XSetForeground(data->display, data->mask_gc, 0);
   2.664 -        XFillRectangle(data->display, data->mask, data->mask_gc,
   2.665 -                       0, 0, window->w, window->h);
   2.666 -        XSetForeground(data->display, data->mask_gc, 1);
   2.667 -
   2.668 -        XFillRectangles(data->display, data->mask, data->mask_gc,
   2.669 -                        xrects, xcount);
   2.670 -
   2.671 -        XRenderChangePicture(data->display, data->drawable_pict, CPClipMask, &attributes);
   2.672 -        /*XRenderFillRectangle(data->display, data->blend_op, data->drawable_pict,
   2.673 -                               &foreground, 0, 0, window->w, window->h);*/
   2.674 -        attributes.clip_mask = None;
   2.675 -        XRenderChangePicture(data->display, data->drawable_pict, CPClipMask, &attributes);
   2.676 +        XRenderFillRectangles(data->display, data->blend_op, data->drawable_pict,
   2.677 +                              &foreground, xrects, xcount);
   2.678      }
   2.679      else
   2.680  #endif
   2.681 @@ -1383,7 +1463,6 @@
   2.682      }
   2.683  
   2.684      SDL_stack_free(xrects);
   2.685 -
   2.686      return 0;
   2.687  }
   2.688  
   2.689 @@ -1726,11 +1805,11 @@
   2.690              XFreeGC(data->display, data->gc);
   2.691          }
   2.692  #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
   2.693 -        if (data->mask_gc) {
   2.694 -            XFreeGC(data->display, data->mask_gc);
   2.695 +        if (data->stencil_gc) {
   2.696 +            XFreeGC(data->display, data->stencil_gc);
   2.697          }
   2.698 -        if (data->mask) {
   2.699 -            XFreePixmap(data->display, data->mask);
   2.700 +        if (data->stencil) {
   2.701 +            XFreePixmap(data->display, data->stencil);
   2.702          }
   2.703          if (data->drawable_pict) {
   2.704              XRenderFreePicture(data->display, data->drawable_pict);
     3.1 --- a/src/video/x11/SDL_x11sym.h	Sun Jul 18 08:28:35 2010 +0530
     3.2 +++ b/src/video/x11/SDL_x11sym.h	Sun Jul 18 12:43:04 2010 +0530
     3.3 @@ -153,6 +153,7 @@
     3.4  SDL_X11_SYM(XExtensionErrorHandler,XSetExtensionErrorHandler,(XExtensionErrorHandler a),(a),return)
     3.5  SDL_X11_SYM(int,XFillRectangle,(Display *dpy,Drawable d,GC gc,int x,int y,unsigned int width,unsigned int height),(dpy,d,gc,x,y,width,height),return)
     3.6  SDL_X11_SYM(int,XSetBackground,(Display *dpy,GC gc,unsigned long background),(dpy,gc,background),return)
     3.7 +SDL_X11_SYM(Status,XInitImage,(XImage *image),(image),return)
     3.8  
     3.9  #if NeedWidePrototypes
    3.10  SDL_X11_SYM(KeySym,XKeycodeToKeysym,(Display* a,unsigned int b,int c),(a,b,c),return)
    3.11 @@ -249,6 +250,7 @@
    3.12  SDL_X11_SYM(Picture,XRenderCreateSolidFill,(Display *dpy,const XRenderColor *color),(dpy,color),return)
    3.13  SDL_X11_SYM(void,XRenderSetPictureTransform,(Display *dpy,Picture picture,XTransform *transform),(dpy,picture,transform),return)
    3.14  SDL_X11_SYM(void,XRenderFillRectangle,(Display *dpy,int op,Picture dst,_Xconst XRenderColor *color,int x,int y,unsigned int width,unsigned int height),(dpy,op,dst,color,x,y,width,height),return)
    3.15 +SDL_X11_SYM(void,XRenderFillRectangles,(Display *dpy,int op,Picture dst,_Xconst XRenderColor *color,_Xconst XRectangle *rectangles,int n_rects),(dpy,op,dst,color,rectangles,n_rects),return)
    3.16  #endif
    3.17  /* *INDENT-ON* */
    3.18