Start experimental branch for client-side rasterization.
--HG-- branch : experimental
This commit is contained in:
parent
7c46b950ed
commit
6a534a4046
3 changed files with 329 additions and 246 deletions
|
@ -38,6 +38,8 @@ extern SDL_error *SDL_GetErrBuf(void);
|
||||||
|
|
||||||
#define SDL_ERRBUFIZE 1024
|
#define SDL_ERRBUFIZE 1024
|
||||||
|
|
||||||
|
#define DEBUG_ERROR
|
||||||
|
|
||||||
/* Private functions */
|
/* Private functions */
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "../SDL_rect_c.h"
|
#include "../SDL_rect_c.h"
|
||||||
#include "../SDL_pixels_c.h"
|
#include "../SDL_pixels_c.h"
|
||||||
#include "../SDL_yuv_sw_c.h"
|
#include "../SDL_yuv_sw_c.h"
|
||||||
|
#include "SDL_surface.h"
|
||||||
|
|
||||||
/* X11 renderer implementation */
|
/* X11 renderer implementation */
|
||||||
|
|
||||||
|
@ -97,13 +98,21 @@ typedef struct
|
||||||
Window xwindow;
|
Window xwindow;
|
||||||
Pixmap pixmaps[3];
|
Pixmap pixmaps[3];
|
||||||
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
||||||
Pixmap mask;
|
Pixmap stencil;
|
||||||
|
Pixmap brush;
|
||||||
|
Picture brush_pict;
|
||||||
|
#ifndef NO_SHARED_MEMORY
|
||||||
|
XImage *stencil_image;
|
||||||
|
SDL_Surface *stencil_surface;
|
||||||
|
XShmSegmentInfo stencil_shminfo;
|
||||||
|
#endif
|
||||||
Picture xwindow_pict;
|
Picture xwindow_pict;
|
||||||
Picture pixmap_picts[3];
|
Picture pixmap_picts[3];
|
||||||
Picture drawable_pict;
|
Picture drawable_pict;
|
||||||
|
Picture stencil_pict;
|
||||||
int blend_op;
|
int blend_op;
|
||||||
XRenderPictFormat* xwindow_pict_fmt;
|
XRenderPictFormat* xwindow_pict_fmt;
|
||||||
GC mask_gc;
|
GC stencil_gc;
|
||||||
SDL_bool use_xrender;
|
SDL_bool use_xrender;
|
||||||
#endif
|
#endif
|
||||||
int current_pixmap;
|
int current_pixmap;
|
||||||
|
@ -286,21 +295,74 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||||
renderer->info.blend_modes |=
|
renderer->info.blend_modes |=
|
||||||
(SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MASK);
|
(SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MASK);
|
||||||
// Create a clip mask that is used for rendering primitives.
|
// Create a clip mask that is used for rendering primitives.
|
||||||
data->mask = XCreatePixmap(data->display, data->xwindow,
|
data->stencil = XCreatePixmap(data->display, data->xwindow,
|
||||||
window->w, window->h, 1);
|
window->w, window->h, 8);
|
||||||
if (!data->mask) {
|
|
||||||
SDL_SetError("XCreatePixmap() failed");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
// Create the GC for the clip mask.
|
// Create the GC for the clip mask.
|
||||||
data->mask_gc = XCreateGC(data->display, data->mask,
|
data->stencil_gc = XCreateGC(data->display, data->stencil,
|
||||||
GCGraphicsExposures, &gcv);
|
GCGraphicsExposures, &gcv);
|
||||||
if (!data->mask_gc) {
|
XSetBackground(data->display, data->stencil_gc, 0x00);
|
||||||
SDL_SetError("XCreateGC() failed");
|
XSetForeground(data->display, data->stencil_gc, 0xFF);
|
||||||
return NULL;
|
data->stencil_pict =
|
||||||
|
XRenderCreatePicture(data->display, data->stencil,
|
||||||
|
XRenderFindStandardFormat(data->display,
|
||||||
|
PictStandardA8),
|
||||||
|
0, NULL);
|
||||||
|
data->brush =
|
||||||
|
XCreatePixmap(data->display, data->xwindow, 1, 1, 32);
|
||||||
|
XRenderPictureAttributes brush_attr;
|
||||||
|
brush_attr.repeat = RepeatNormal;
|
||||||
|
data->brush_pict =
|
||||||
|
XRenderCreatePicture(data->display, data->brush,
|
||||||
|
XRenderFindStandardFormat(data->display,
|
||||||
|
PictStandardARGB32),
|
||||||
|
CPRepeat, &brush_attr);
|
||||||
|
#ifndef NO_SHARED_MEMORY
|
||||||
|
/* Create a mask image using MIT-SHM */
|
||||||
|
data->stencil_image = NULL;
|
||||||
|
data->stencil_surface = NULL;
|
||||||
|
XShmSegmentInfo *shminfo = &data->stencil_shminfo;
|
||||||
|
while (SDL_X11_HAVE_SHM) {
|
||||||
|
data->stencil_image =
|
||||||
|
XShmCreateImage(data->display, data->visual, 8, ZPixmap,
|
||||||
|
NULL, shminfo, window->w, window->h);
|
||||||
|
if (!data->stencil_image) {
|
||||||
|
printf("XShmCreateImage() failed");
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
printf("image created\n");
|
||||||
|
}
|
||||||
|
shminfo->shmid = shmget(IPC_PRIVATE,
|
||||||
|
data->stencil_image->bytes_per_line *
|
||||||
|
data->stencil_image->height,
|
||||||
|
IPC_CREAT|0777);
|
||||||
|
if (!shminfo->shmid) {
|
||||||
|
printf("shmget() failed");
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
printf("shmid aquired\n");
|
||||||
|
}
|
||||||
|
shminfo->shmaddr = data->stencil_image->data = shmat(shminfo->shmid, 0, 0);
|
||||||
|
shminfo->readOnly = False;
|
||||||
|
XShmAttach(data->display, shminfo);
|
||||||
|
XSync(data->display, False);
|
||||||
|
shmctl(shminfo->shmid, IPC_RMID, NULL);
|
||||||
|
data->stencil_surface =
|
||||||
|
SDL_CreateRGBSurfaceFrom(shminfo->shmaddr,
|
||||||
|
data->stencil_image->width,
|
||||||
|
data->stencil_image->height,
|
||||||
|
8,
|
||||||
|
data->stencil_image->bytes_per_line,
|
||||||
|
0, 0, 0, 0xFF);
|
||||||
|
if (!data->stencil_surface) {
|
||||||
|
printf("SDL_CreateRGBSurfaceFrom() failed");
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
printf("surface created\n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
XSetBackground(data->display, data->mask_gc, 0);
|
#endif
|
||||||
XSetForeground(data->display, data->mask_gc, 1);
|
|
||||||
// Set the default blending mode.
|
// Set the default blending mode.
|
||||||
renderer->blendMode = SDL_BLENDMODE_BLEND;
|
renderer->blendMode = SDL_BLENDMODE_BLEND;
|
||||||
data->blend_op = PictOpOver;
|
data->blend_op = PictOpOver;
|
||||||
|
@ -693,14 +755,6 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||||
if (!data->image)
|
if (!data->image)
|
||||||
#endif /* not NO_SHARED_MEMORY */
|
#endif /* not NO_SHARED_MEMORY */
|
||||||
{
|
{
|
||||||
/* This is the case where the server does not have
|
|
||||||
shared memory support and the texture is streaming.
|
|
||||||
It does not make sense to use Xrender here because
|
|
||||||
we would have to copy the data onto a server side
|
|
||||||
pixmap with XPutImage first and only then can we
|
|
||||||
use Xrender
|
|
||||||
*/
|
|
||||||
|
|
||||||
data->pixels = SDL_malloc(texture->h * data->pitch);
|
data->pixels = SDL_malloc(texture->h * data->pitch);
|
||||||
if (!data->pixels) {
|
if (!data->pixels) {
|
||||||
X11_DestroyTexture(renderer, texture);
|
X11_DestroyTexture(renderer, texture);
|
||||||
|
@ -999,61 +1053,74 @@ X11_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
|
||||||
SDL_Window *window = renderer->window;
|
SDL_Window *window = renderer->window;
|
||||||
XPoint *xpoints, *xpoint;
|
XPoint *xpoints, *xpoint;
|
||||||
int i, xcount;
|
int i, xcount;
|
||||||
|
SDL_Rect clip, rect;
|
||||||
|
|
||||||
if (data->makedirty) {
|
clip.x = 0;
|
||||||
SDL_Rect rect;
|
clip.y = 0;
|
||||||
|
clip.w = window->w;
|
||||||
|
clip.h = window->h;
|
||||||
|
|
||||||
/* Get the smallest rectangle that contains everything */
|
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
||||||
rect.x = 0;
|
#ifndef NO_SHARED_MEMORY
|
||||||
rect.y = 0;
|
if (data->use_xrender && data->stencil_image && data->stencil_surface) {
|
||||||
rect.w = window->w;
|
SDL_FillRect(data->stencil_surface, NULL, 0x00);
|
||||||
rect.h = window->h;
|
|
||||||
if (!SDL_EnclosePoints(points, count, &rect, &rect)) {
|
SDL_SetClipRect(data->stencil_surface, NULL);
|
||||||
/* Nothing to draw */
|
SDL_DrawPoints(data->stencil_surface, points, count, 0xFF);
|
||||||
return 0;
|
|
||||||
|
XShmPutImage(data->display, data->stencil, data->stencil_gc, data->stencil_image,
|
||||||
|
0, 0, 0, 0, window->w, window->h, False);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if (data->makedirty) {
|
||||||
|
|
||||||
|
/* Get the smallest rectangle that contains everything */
|
||||||
|
rect.x = 0;
|
||||||
|
rect.y = 0;
|
||||||
|
rect.w = window->w;
|
||||||
|
rect.h = window->h;
|
||||||
|
if (!SDL_EnclosePoints(points, count, &rect, &rect)) {
|
||||||
|
/* Nothing to draw */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
SDL_AddDirtyRect(&data->dirty, &rect);
|
||||||
}
|
}
|
||||||
SDL_AddDirtyRect(&data->dirty, &rect);
|
|
||||||
}
|
|
||||||
|
|
||||||
xpoint = xpoints = SDL_stack_alloc(XPoint, count);
|
xpoint = xpoints = SDL_stack_alloc(XPoint, count);
|
||||||
xcount = 0;
|
xcount = 0;
|
||||||
for (i = 0; i < count; ++i) {
|
for (i = 0; i < count; ++i) {
|
||||||
int x = points[i].x;
|
int x = points[i].x;
|
||||||
int y = points[i].y;
|
int y = points[i].y;
|
||||||
if (x < 0 || x >= window->w || y < 0 || y >= window->h) {
|
if (x < 0 || x >= window->w || y < 0 || y >= window->h) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
xpoint->x = (short)x;
|
||||||
|
xpoint->y = (short)y;
|
||||||
|
++xpoint;
|
||||||
|
++xcount;
|
||||||
}
|
}
|
||||||
xpoint->x = (short)x;
|
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
||||||
xpoint->y = (short)y;
|
if (data->use_xrender) {
|
||||||
++xpoint;
|
XSetForeground(data->display, data->stencil_gc, 0x00);
|
||||||
++xcount;
|
XFillRectangle(data->display, data->stencil, data->stencil_gc,
|
||||||
|
0, 0, window->w, window->h);
|
||||||
|
XSetForeground(data->display, data->stencil_gc, 0xFF);
|
||||||
|
XDrawPoints(data->display, data->stencil, data->stencil_gc, xpoints, xcount,
|
||||||
|
CoordModeOrigin);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
||||||
if (data->use_xrender == SDL_TRUE) {
|
if (data->use_xrender) {
|
||||||
XRenderColor foreground;
|
XRenderColor foreground;
|
||||||
XRenderPictureAttributes attributes;
|
|
||||||
unsigned long valuemask;
|
|
||||||
|
|
||||||
foreground = xrenderdrawcolor(renderer);
|
foreground = xrenderdrawcolor(renderer);
|
||||||
/* Set the clip mask to restrict rendering to
|
XRenderFillRectangle(data->display, PictOpSrc, data->brush_pict,
|
||||||
* the primitive being drawn
|
&foreground, 0, 0, 1, 1);
|
||||||
*/
|
XRenderComposite(data->display, data->blend_op, data->brush_pict,
|
||||||
attributes.clip_mask = data->mask;
|
data->stencil_pict, data->drawable_pict,
|
||||||
valuemask = CPClipMask;
|
0, 0, 0, 0, 0, 0, window->w, window->h);
|
||||||
|
|
||||||
XSetForeground(data->display, data->mask_gc, 0);
|
|
||||||
XFillRectangle(data->display, data->mask, data->mask_gc,
|
|
||||||
0, 0, window->w, window->h);
|
|
||||||
XSetForeground(data->display, data->mask_gc, 1);
|
|
||||||
|
|
||||||
XDrawPoints(data->display, data->mask, data->mask_gc, xpoints, xcount,
|
|
||||||
CoordModeOrigin);
|
|
||||||
XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes);
|
|
||||||
/*XRenderFillRectangle(data->display, data->blend_op, data->drawable_pict,
|
|
||||||
&foreground, 0, 0, window->w, window->h);*/
|
|
||||||
// Reset the clip_mask
|
|
||||||
attributes.clip_mask = None;
|
|
||||||
XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
@ -1067,6 +1134,7 @@ X11_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
|
||||||
CoordModeOrigin);
|
CoordModeOrigin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_stack_free(xpoints);
|
SDL_stack_free(xpoints);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1089,81 +1157,141 @@ X11_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
|
||||||
clip.y = 0;
|
clip.y = 0;
|
||||||
clip.w = window->w;
|
clip.w = window->w;
|
||||||
clip.h = window->h;
|
clip.h = window->h;
|
||||||
|
|
||||||
Pixmap drawable;
|
|
||||||
GC gc;
|
|
||||||
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
||||||
if (data->use_xrender == SDL_TRUE) {
|
#ifndef NO_SHARED_MEMORY
|
||||||
drawable = data->mask;
|
if (data->use_xrender && data->stencil_image && data->stencil_surface) {
|
||||||
gc = data->mask_gc;
|
SDL_FillRect(data->stencil_surface, NULL, 0x00);
|
||||||
XSetForeground(data->display, data->mask_gc, 0);
|
|
||||||
XFillRectangle(data->display, data->mask, data->mask_gc,
|
SDL_SetClipRect(data->stencil_surface, NULL);
|
||||||
0, 0, window->w, window->h);
|
SDL_DrawLines(data->stencil_surface, points, count, 0xFF);
|
||||||
XSetForeground(data->display, data->mask_gc, 1);
|
|
||||||
}
|
XShmPutImage(data->display, data->stencil, data->stencil_gc, data->stencil_image,
|
||||||
else
|
0, 0, 0, 0, window->w, window->h, False);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
drawable = data->drawable;
|
Pixmap drawable;
|
||||||
gc = data->gc;
|
GC gc;
|
||||||
}
|
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
||||||
|
if (data->use_xrender) {
|
||||||
foreground = renderdrawcolor(renderer, 1);
|
drawable = data->stencil;
|
||||||
XSetForeground(data->display, data->gc, foreground);
|
gc = data->stencil_gc;
|
||||||
|
XSetForeground(data->display, data->stencil_gc, 0x00);
|
||||||
xpoint = xpoints = SDL_stack_alloc(XPoint, count);
|
XFillRectangle(data->display, data->stencil, data->stencil_gc,
|
||||||
xcount = 0;
|
0, 0, window->w, window->h);
|
||||||
minx = INT_MAX;
|
XSetForeground(data->display, data->stencil_gc, 0xFF);
|
||||||
miny = INT_MAX;
|
}
|
||||||
maxx = INT_MIN;
|
else
|
||||||
maxy = INT_MIN;
|
#endif
|
||||||
for (i = 0; i < count; ++i) {
|
{
|
||||||
int x = points[i].x;
|
drawable = data->drawable;
|
||||||
int y = points[i].y;
|
gc = data->gc;
|
||||||
|
|
||||||
/* If the point is inside the window, add it to the list */
|
|
||||||
if (x >= 0 && x < window->w && y >= 0 && y < window->h) {
|
|
||||||
if (x < minx) {
|
|
||||||
minx = x;
|
|
||||||
} else if (x > maxx) {
|
|
||||||
maxx = x;
|
|
||||||
}
|
|
||||||
if (y < miny) {
|
|
||||||
miny = y;
|
|
||||||
} else if (y > maxy) {
|
|
||||||
maxy = y;
|
|
||||||
}
|
|
||||||
xpoint->x = (short)x;
|
|
||||||
xpoint->y = (short)y;
|
|
||||||
++xpoint;
|
|
||||||
++xcount;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We need to clip the line segments joined by this point */
|
foreground = renderdrawcolor(renderer, 1);
|
||||||
if (xcount > 0) {
|
XSetForeground(data->display, data->gc, foreground);
|
||||||
int x1 = xpoint[-1].x;
|
|
||||||
int y1 = xpoint[-1].y;
|
xpoint = xpoints = SDL_stack_alloc(XPoint, count);
|
||||||
int x2 = x;
|
xcount = 0;
|
||||||
int y2 = y;
|
minx = INT_MAX;
|
||||||
if (SDL_IntersectRectAndLine(&clip, &x1, &y1, &x2, &y2)) {
|
miny = INT_MAX;
|
||||||
if (x2 < minx) {
|
maxx = INT_MIN;
|
||||||
minx = x2;
|
maxy = INT_MIN;
|
||||||
} else if (x2 > maxx) {
|
for (i = 0; i < count; ++i) {
|
||||||
maxx = x2;
|
int x = points[i].x;
|
||||||
|
int y = points[i].y;
|
||||||
|
|
||||||
|
/* If the point is inside the window, add it to the list */
|
||||||
|
if (x >= 0 && x < window->w && y >= 0 && y < window->h) {
|
||||||
|
if (x < minx) {
|
||||||
|
minx = x;
|
||||||
|
} else if (x > maxx) {
|
||||||
|
maxx = x;
|
||||||
}
|
}
|
||||||
if (y2 < miny) {
|
if (y < miny) {
|
||||||
miny = y2;
|
miny = y;
|
||||||
} else if (y2 > maxy) {
|
} else if (y > maxy) {
|
||||||
maxy = y2;
|
maxy = y;
|
||||||
}
|
}
|
||||||
xpoint->x = (short)x2;
|
xpoint->x = (short)x;
|
||||||
xpoint->y = (short)y2;
|
xpoint->y = (short)y;
|
||||||
++xpoint;
|
++xpoint;
|
||||||
++xcount;
|
++xcount;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
XDrawLines(data->display, drawable, gc,
|
|
||||||
xpoints, xcount, CoordModeOrigin);
|
/* We need to clip the line segments joined by this point */
|
||||||
|
if (xcount > 0) {
|
||||||
|
int x1 = xpoint[-1].x;
|
||||||
|
int y1 = xpoint[-1].y;
|
||||||
|
int x2 = x;
|
||||||
|
int y2 = y;
|
||||||
|
if (SDL_IntersectRectAndLine(&clip, &x1, &y1, &x2, &y2)) {
|
||||||
|
if (x2 < minx) {
|
||||||
|
minx = x2;
|
||||||
|
} else if (x2 > maxx) {
|
||||||
|
maxx = x2;
|
||||||
|
}
|
||||||
|
if (y2 < miny) {
|
||||||
|
miny = y2;
|
||||||
|
} else if (y2 > maxy) {
|
||||||
|
maxy = y2;
|
||||||
|
}
|
||||||
|
xpoint->x = (short)x2;
|
||||||
|
xpoint->y = (short)y2;
|
||||||
|
++xpoint;
|
||||||
|
++xcount;
|
||||||
|
}
|
||||||
|
XDrawLines(data->display, drawable, gc,
|
||||||
|
xpoints, xcount, CoordModeOrigin);
|
||||||
|
if (xpoints[0].x != x2 || xpoints[0].y != y2) {
|
||||||
|
XDrawPoint(data->display, drawable, gc, x2, y2);
|
||||||
|
}
|
||||||
|
if (data->makedirty) {
|
||||||
|
SDL_Rect rect;
|
||||||
|
|
||||||
|
rect.x = minx;
|
||||||
|
rect.y = miny;
|
||||||
|
rect.w = (maxx - minx) + 1;
|
||||||
|
rect.h = (maxy - miny) + 1;
|
||||||
|
SDL_AddDirtyRect(&data->dirty, &rect);
|
||||||
|
}
|
||||||
|
xpoint = xpoints;
|
||||||
|
xcount = 0;
|
||||||
|
minx = INT_MAX;
|
||||||
|
miny = INT_MAX;
|
||||||
|
maxx = INT_MIN;
|
||||||
|
maxy = INT_MIN;
|
||||||
|
}
|
||||||
|
if (i < (count-1)) {
|
||||||
|
int x1 = x;
|
||||||
|
int y1 = y;
|
||||||
|
int x2 = points[i+1].x;
|
||||||
|
int y2 = points[i+1].y;
|
||||||
|
if (SDL_IntersectRectAndLine(&clip, &x1, &y1, &x2, &y2)) {
|
||||||
|
if (x1 < minx) {
|
||||||
|
minx = x1;
|
||||||
|
} else if (x1 > maxx) {
|
||||||
|
maxx = x1;
|
||||||
|
}
|
||||||
|
if (y1 < miny) {
|
||||||
|
miny = y1;
|
||||||
|
} else if (y1 > maxy) {
|
||||||
|
maxy = y1;
|
||||||
|
}
|
||||||
|
xpoint->x = (short)x1;
|
||||||
|
xpoint->y = (short)y1;
|
||||||
|
++xpoint;
|
||||||
|
++xcount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (xcount > 1) {
|
||||||
|
int x2 = xpoint[-1].x;
|
||||||
|
int y2 = xpoint[-1].y;
|
||||||
|
XDrawLines(data->display, drawable, gc, xpoints, xcount,
|
||||||
|
CoordModeOrigin);
|
||||||
if (xpoints[0].x != x2 || xpoints[0].y != y2) {
|
if (xpoints[0].x != x2 || xpoints[0].y != y2) {
|
||||||
XDrawPoint(data->display, drawable, gc, x2, y2);
|
XDrawPoint(data->display, drawable, gc, x2, y2);
|
||||||
}
|
}
|
||||||
|
@ -1176,65 +1304,16 @@ X11_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
|
||||||
rect.h = (maxy - miny) + 1;
|
rect.h = (maxy - miny) + 1;
|
||||||
SDL_AddDirtyRect(&data->dirty, &rect);
|
SDL_AddDirtyRect(&data->dirty, &rect);
|
||||||
}
|
}
|
||||||
xpoint = xpoints;
|
|
||||||
xcount = 0;
|
|
||||||
minx = INT_MAX;
|
|
||||||
miny = INT_MAX;
|
|
||||||
maxx = INT_MIN;
|
|
||||||
maxy = INT_MIN;
|
|
||||||
}
|
|
||||||
if (i < (count-1)) {
|
|
||||||
int x1 = x;
|
|
||||||
int y1 = y;
|
|
||||||
int x2 = points[i+1].x;
|
|
||||||
int y2 = points[i+1].y;
|
|
||||||
if (SDL_IntersectRectAndLine(&clip, &x1, &y1, &x2, &y2)) {
|
|
||||||
if (x1 < minx) {
|
|
||||||
minx = x1;
|
|
||||||
} else if (x1 > maxx) {
|
|
||||||
maxx = x1;
|
|
||||||
}
|
|
||||||
if (y1 < miny) {
|
|
||||||
miny = y1;
|
|
||||||
} else if (y1 > maxy) {
|
|
||||||
maxy = y1;
|
|
||||||
}
|
|
||||||
xpoint->x = (short)x1;
|
|
||||||
xpoint->y = (short)y1;
|
|
||||||
++xpoint;
|
|
||||||
++xcount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (xcount > 1) {
|
|
||||||
int x2 = xpoint[-1].x;
|
|
||||||
int y2 = xpoint[-1].y;
|
|
||||||
XDrawLines(data->display, drawable, gc, xpoints, xcount,
|
|
||||||
CoordModeOrigin);
|
|
||||||
if (xpoints[0].x != x2 || xpoints[0].y != y2) {
|
|
||||||
XDrawPoint(data->display, drawable, gc, x2, y2);
|
|
||||||
}
|
|
||||||
if (data->makedirty) {
|
|
||||||
SDL_Rect rect;
|
|
||||||
|
|
||||||
rect.x = minx;
|
|
||||||
rect.y = miny;
|
|
||||||
rect.w = (maxx - minx) + 1;
|
|
||||||
rect.h = (maxy - miny) + 1;
|
|
||||||
SDL_AddDirtyRect(&data->dirty, &rect);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
||||||
if(data->use_xrender == SDL_TRUE) {
|
if (data->use_xrender) {
|
||||||
XRenderColor xrforeground = xrenderdrawcolor(renderer);
|
XRenderColor xrforeground = xrenderdrawcolor(renderer);
|
||||||
XRenderPictureAttributes attributes;
|
XRenderFillRectangle(data->display, PictOpSrc, data->brush_pict,
|
||||||
attributes.clip_mask = data->mask;
|
&xrforeground, 0, 0, 1, 1);
|
||||||
unsigned long valuemask = CPClipMask;
|
XRenderComposite(data->display, data->blend_op, data->brush_pict,
|
||||||
XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes);
|
data->stencil_pict, data->drawable_pict,
|
||||||
/*XRenderFillRectangle(data->display, data->blend_op, data->drawable_pict,
|
0, 0, 0, 0, 0, 0, window->w, window->h);
|
||||||
&xrforeground, 0, 0, window->w, window->h);*/
|
|
||||||
attributes.clip_mask = None;
|
|
||||||
XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
SDL_stack_free(xpoints);
|
SDL_stack_free(xpoints);
|
||||||
|
@ -1258,44 +1337,60 @@ X11_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
|
||||||
clip.w = window->w;
|
clip.w = window->w;
|
||||||
clip.h = window->h;
|
clip.h = window->h;
|
||||||
|
|
||||||
for (i = 0; i < count; ++i) {
|
|
||||||
if (!SDL_IntersectRect(rects[i], &clip, &rect)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
xrect->x = (short)rect.x;
|
|
||||||
xrect->y = (short)rect.y;
|
|
||||||
xrect->width = (unsigned short)rect.w;
|
|
||||||
xrect->height = (unsigned short)rect.h;
|
|
||||||
++xrect;
|
|
||||||
++xcount;
|
|
||||||
|
|
||||||
if (data->makedirty) {
|
|
||||||
SDL_AddDirtyRect(&data->dirty, &rect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
||||||
if(data->use_xrender == SDL_TRUE) {
|
#ifndef NO_SHARED_MEMORY
|
||||||
|
if (data->use_xrender && data->stencil_image && data->stencil_surface) {
|
||||||
|
SDL_FillRect(data->stencil_surface, NULL, 0x00);
|
||||||
|
|
||||||
|
SDL_SetClipRect(data->stencil_surface, NULL);
|
||||||
|
SDL_DrawRects(data->stencil_surface, rects, count, 1);
|
||||||
|
|
||||||
|
XShmPutImage(data->display, data->stencil, data->stencil_gc, data->stencil_image,
|
||||||
|
0, 0, 0, 0, window->w, window->h, False);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
|
||||||
|
for (i = 0; i < count; ++i) {
|
||||||
|
if (!SDL_IntersectRect(rects[i], &clip, &rect)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
xrect->x = (short)rect.x;
|
||||||
|
xrect->y = (short)rect.y;
|
||||||
|
xrect->width = (unsigned short)rect.w;
|
||||||
|
xrect->height = (unsigned short)rect.h;
|
||||||
|
++xrect;
|
||||||
|
++xcount;
|
||||||
|
|
||||||
|
if (data->makedirty) {
|
||||||
|
SDL_AddDirtyRect(&data->dirty, &rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
||||||
|
if (data->use_xrender) {
|
||||||
|
XSetForeground(data->display, data->stencil_gc, 0x00);
|
||||||
|
XFillRectangle(data->display, data->stencil, data->stencil_gc,
|
||||||
|
0, 0, window->w, window->h);
|
||||||
|
XSetForeground(data->display, data->stencil_gc, 0xFF);
|
||||||
|
|
||||||
|
XDrawRectangles(data->display, data->stencil, data->stencil_gc, xrects, xcount);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
||||||
|
if (data->use_xrender) {
|
||||||
XRenderColor foreground;
|
XRenderColor foreground;
|
||||||
XRenderPictureAttributes attributes;
|
|
||||||
unsigned long valuemask;
|
|
||||||
|
|
||||||
foreground = xrenderdrawcolor(renderer);
|
foreground = xrenderdrawcolor(renderer);
|
||||||
valuemask = CPClipMask;
|
|
||||||
attributes.clip_mask = data->mask;
|
|
||||||
|
|
||||||
XSetForeground(data->display, data->mask_gc, 0);
|
|
||||||
XFillRectangle(data->display, data->mask, data->mask_gc,
|
|
||||||
0, 0, window->w, window->h);
|
|
||||||
XSetForeground(data->display, data->mask_gc, 1);
|
|
||||||
|
|
||||||
XDrawRectangles(data->display, data->mask, data->mask_gc, xrects, xcount);
|
XRenderFillRectangle(data->display, PictOpSrc, data->brush_pict,
|
||||||
XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes);
|
&foreground, 0, 0, 1, 1);
|
||||||
/*XRenderFillRectangle(data->display, data->blend_op, data->drawable_pict,
|
|
||||||
&foreground, 0, 0, window->w, window->h);*/
|
XRenderComposite(data->display, data->blend_op, data->brush_pict,
|
||||||
attributes.clip_mask = None;
|
data->stencil_pict, data->drawable_pict,
|
||||||
XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes);
|
0, 0, 0, 0, 0, 0, window->w, window->h);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
@ -1326,7 +1421,7 @@ X11_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
|
||||||
clip.y = 0;
|
clip.y = 0;
|
||||||
clip.w = window->w;
|
clip.w = window->w;
|
||||||
clip.h = window->h;
|
clip.h = window->h;
|
||||||
|
|
||||||
int i, xcount;
|
int i, xcount;
|
||||||
XRectangle *xrects, *xrect;
|
XRectangle *xrects, *xrect;
|
||||||
xrect = xrects = SDL_stack_alloc(XRectangle, count);
|
xrect = xrects = SDL_stack_alloc(XRectangle, count);
|
||||||
|
@ -1349,26 +1444,11 @@ X11_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
||||||
if(data->use_xrender == SDL_TRUE) {
|
if (data->use_xrender) {
|
||||||
XRenderColor foreground;
|
XRenderColor foreground;
|
||||||
XRenderPictureAttributes attributes;
|
|
||||||
|
|
||||||
foreground = xrenderdrawcolor(renderer);
|
foreground = xrenderdrawcolor(renderer);
|
||||||
attributes.clip_mask = data->mask;
|
XRenderFillRectangles(data->display, data->blend_op, data->drawable_pict,
|
||||||
|
&foreground, xrects, xcount);
|
||||||
XSetForeground(data->display, data->mask_gc, 0);
|
|
||||||
XFillRectangle(data->display, data->mask, data->mask_gc,
|
|
||||||
0, 0, window->w, window->h);
|
|
||||||
XSetForeground(data->display, data->mask_gc, 1);
|
|
||||||
|
|
||||||
XFillRectangles(data->display, data->mask, data->mask_gc,
|
|
||||||
xrects, xcount);
|
|
||||||
|
|
||||||
XRenderChangePicture(data->display, data->drawable_pict, CPClipMask, &attributes);
|
|
||||||
/*XRenderFillRectangle(data->display, data->blend_op, data->drawable_pict,
|
|
||||||
&foreground, 0, 0, window->w, window->h);*/
|
|
||||||
attributes.clip_mask = None;
|
|
||||||
XRenderChangePicture(data->display, data->drawable_pict, CPClipMask, &attributes);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
@ -1383,7 +1463,6 @@ X11_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_stack_free(xrects);
|
SDL_stack_free(xrects);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1726,11 +1805,11 @@ X11_DestroyRenderer(SDL_Renderer * renderer)
|
||||||
XFreeGC(data->display, data->gc);
|
XFreeGC(data->display, data->gc);
|
||||||
}
|
}
|
||||||
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
||||||
if (data->mask_gc) {
|
if (data->stencil_gc) {
|
||||||
XFreeGC(data->display, data->mask_gc);
|
XFreeGC(data->display, data->stencil_gc);
|
||||||
}
|
}
|
||||||
if (data->mask) {
|
if (data->stencil) {
|
||||||
XFreePixmap(data->display, data->mask);
|
XFreePixmap(data->display, data->stencil);
|
||||||
}
|
}
|
||||||
if (data->drawable_pict) {
|
if (data->drawable_pict) {
|
||||||
XRenderFreePicture(data->display, data->drawable_pict);
|
XRenderFreePicture(data->display, data->drawable_pict);
|
||||||
|
|
|
@ -153,6 +153,7 @@ SDL_X11_SYM(SDL_X11_XESetEventToWireRetType,XESetEventToWire,(Display* a,int b,S
|
||||||
SDL_X11_SYM(XExtensionErrorHandler,XSetExtensionErrorHandler,(XExtensionErrorHandler a),(a),return)
|
SDL_X11_SYM(XExtensionErrorHandler,XSetExtensionErrorHandler,(XExtensionErrorHandler a),(a),return)
|
||||||
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)
|
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)
|
||||||
SDL_X11_SYM(int,XSetBackground,(Display *dpy,GC gc,unsigned long background),(dpy,gc,background),return)
|
SDL_X11_SYM(int,XSetBackground,(Display *dpy,GC gc,unsigned long background),(dpy,gc,background),return)
|
||||||
|
SDL_X11_SYM(Status,XInitImage,(XImage *image),(image),return)
|
||||||
|
|
||||||
#if NeedWidePrototypes
|
#if NeedWidePrototypes
|
||||||
SDL_X11_SYM(KeySym,XKeycodeToKeysym,(Display* a,unsigned int b,int c),(a,b,c),return)
|
SDL_X11_SYM(KeySym,XKeycodeToKeysym,(Display* a,unsigned int b,int c),(a,b,c),return)
|
||||||
|
@ -249,6 +250,7 @@ SDL_X11_SYM(void,XRenderComposite,(Display *dpy,int op,Picture src,Picture mask,
|
||||||
SDL_X11_SYM(Picture,XRenderCreateSolidFill,(Display *dpy,const XRenderColor *color),(dpy,color),return)
|
SDL_X11_SYM(Picture,XRenderCreateSolidFill,(Display *dpy,const XRenderColor *color),(dpy,color),return)
|
||||||
SDL_X11_SYM(void,XRenderSetPictureTransform,(Display *dpy,Picture picture,XTransform *transform),(dpy,picture,transform),return)
|
SDL_X11_SYM(void,XRenderSetPictureTransform,(Display *dpy,Picture picture,XTransform *transform),(dpy,picture,transform),return)
|
||||||
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)
|
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)
|
||||||
|
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)
|
||||||
#endif
|
#endif
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue