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