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 DEBUG_ERROR
|
||||
|
||||
/* Private functions */
|
||||
|
||||
static const char *
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "../SDL_rect_c.h"
|
||||
#include "../SDL_pixels_c.h"
|
||||
#include "../SDL_yuv_sw_c.h"
|
||||
#include "SDL_surface.h"
|
||||
|
||||
/* X11 renderer implementation */
|
||||
|
||||
|
@ -97,13 +98,21 @@ typedef struct
|
|||
Window xwindow;
|
||||
Pixmap pixmaps[3];
|
||||
#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 pixmap_picts[3];
|
||||
Picture drawable_pict;
|
||||
Picture stencil_pict;
|
||||
int blend_op;
|
||||
XRenderPictFormat* xwindow_pict_fmt;
|
||||
GC mask_gc;
|
||||
GC stencil_gc;
|
||||
SDL_bool use_xrender;
|
||||
#endif
|
||||
int current_pixmap;
|
||||
|
@ -286,21 +295,74 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags)
|
|||
renderer->info.blend_modes |=
|
||||
(SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MASK);
|
||||
// Create a clip mask that is used for rendering primitives.
|
||||
data->mask = XCreatePixmap(data->display, data->xwindow,
|
||||
window->w, window->h, 1);
|
||||
if (!data->mask) {
|
||||
SDL_SetError("XCreatePixmap() failed");
|
||||
return NULL;
|
||||
}
|
||||
data->stencil = XCreatePixmap(data->display, data->xwindow,
|
||||
window->w, window->h, 8);
|
||||
|
||||
// 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);
|
||||
if (!data->mask_gc) {
|
||||
SDL_SetError("XCreateGC() failed");
|
||||
return NULL;
|
||||
XSetBackground(data->display, data->stencil_gc, 0x00);
|
||||
XSetForeground(data->display, data->stencil_gc, 0xFF);
|
||||
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");
|
||||
}
|
||||
XSetBackground(data->display, data->mask_gc, 0);
|
||||
XSetForeground(data->display, data->mask_gc, 1);
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
// Set the default blending mode.
|
||||
renderer->blendMode = SDL_BLENDMODE_BLEND;
|
||||
data->blend_op = PictOpOver;
|
||||
|
@ -693,14 +755,6 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
|||
if (!data->image)
|
||||
#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);
|
||||
if (!data->pixels) {
|
||||
X11_DestroyTexture(renderer, texture);
|
||||
|
@ -999,9 +1053,28 @@ X11_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
|
|||
SDL_Window *window = renderer->window;
|
||||
XPoint *xpoints, *xpoint;
|
||||
int i, xcount;
|
||||
SDL_Rect clip, rect;
|
||||
|
||||
clip.x = 0;
|
||||
clip.y = 0;
|
||||
clip.w = window->w;
|
||||
clip.h = window->h;
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
||||
#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_DrawPoints(data->stencil_surface, points, count, 0xFF);
|
||||
|
||||
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) {
|
||||
SDL_Rect rect;
|
||||
|
||||
/* Get the smallest rectangle that contains everything */
|
||||
rect.x = 0;
|
||||
|
@ -1029,31 +1102,25 @@ X11_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
|
|||
++xcount;
|
||||
}
|
||||
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
||||
if (data->use_xrender == SDL_TRUE) {
|
||||
XRenderColor foreground;
|
||||
XRenderPictureAttributes attributes;
|
||||
unsigned long valuemask;
|
||||
|
||||
foreground = xrenderdrawcolor(renderer);
|
||||
/* Set the clip mask to restrict rendering to
|
||||
* the primitive being drawn
|
||||
*/
|
||||
attributes.clip_mask = data->mask;
|
||||
valuemask = CPClipMask;
|
||||
|
||||
XSetForeground(data->display, data->mask_gc, 0);
|
||||
XFillRectangle(data->display, data->mask, data->mask_gc,
|
||||
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->mask_gc, 1);
|
||||
|
||||
XDrawPoints(data->display, data->mask, data->mask_gc, xpoints, xcount,
|
||||
XSetForeground(data->display, data->stencil_gc, 0xFF);
|
||||
XDrawPoints(data->display, data->stencil, data->stencil_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);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
||||
if (data->use_xrender) {
|
||||
XRenderColor foreground;
|
||||
foreground = xrenderdrawcolor(renderer);
|
||||
XRenderFillRectangle(data->display, PictOpSrc, data->brush_pict,
|
||||
&foreground, 0, 0, 1, 1);
|
||||
XRenderComposite(data->display, data->blend_op, data->brush_pict,
|
||||
data->stencil_pict, data->drawable_pict,
|
||||
0, 0, 0, 0, 0, 0, window->w, window->h);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
@ -1067,6 +1134,7 @@ X11_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
|
|||
CoordModeOrigin);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_stack_free(xpoints);
|
||||
|
||||
return 0;
|
||||
|
@ -1089,17 +1157,30 @@ X11_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
|
|||
clip.y = 0;
|
||||
clip.w = window->w;
|
||||
clip.h = window->h;
|
||||
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
||||
#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_DrawLines(data->stencil_surface, points, count, 0xFF);
|
||||
|
||||
XShmPutImage(data->display, data->stencil, data->stencil_gc, data->stencil_image,
|
||||
0, 0, 0, 0, window->w, window->h, False);
|
||||
} else
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
Pixmap drawable;
|
||||
GC gc;
|
||||
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
||||
if (data->use_xrender == SDL_TRUE) {
|
||||
drawable = data->mask;
|
||||
gc = data->mask_gc;
|
||||
XSetForeground(data->display, data->mask_gc, 0);
|
||||
XFillRectangle(data->display, data->mask, data->mask_gc,
|
||||
if (data->use_xrender) {
|
||||
drawable = data->stencil;
|
||||
gc = data->stencil_gc;
|
||||
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->mask_gc, 1);
|
||||
XSetForeground(data->display, data->stencil_gc, 0xFF);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
@ -1224,17 +1305,15 @@ X11_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
|
|||
SDL_AddDirtyRect(&data->dirty, &rect);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
||||
if(data->use_xrender == SDL_TRUE) {
|
||||
if (data->use_xrender) {
|
||||
XRenderColor xrforeground = xrenderdrawcolor(renderer);
|
||||
XRenderPictureAttributes attributes;
|
||||
attributes.clip_mask = data->mask;
|
||||
unsigned long valuemask = CPClipMask;
|
||||
XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes);
|
||||
/*XRenderFillRectangle(data->display, data->blend_op, data->drawable_pict,
|
||||
&xrforeground, 0, 0, window->w, window->h);*/
|
||||
attributes.clip_mask = None;
|
||||
XRenderChangePicture(data->display, data->drawable_pict, valuemask, &attributes);
|
||||
XRenderFillRectangle(data->display, PictOpSrc, data->brush_pict,
|
||||
&xrforeground, 0, 0, 1, 1);
|
||||
XRenderComposite(data->display, data->blend_op, data->brush_pict,
|
||||
data->stencil_pict, data->drawable_pict,
|
||||
0, 0, 0, 0, 0, 0, window->w, window->h);
|
||||
}
|
||||
#endif
|
||||
SDL_stack_free(xpoints);
|
||||
|
@ -1258,6 +1337,22 @@ X11_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
|
|||
clip.w = window->w;
|
||||
clip.h = window->h;
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
||||
#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;
|
||||
|
@ -1274,28 +1369,28 @@ X11_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
|
|||
SDL_AddDirtyRect(&data->dirty, &rect);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
||||
if(data->use_xrender == SDL_TRUE) {
|
||||
XRenderColor foreground;
|
||||
XRenderPictureAttributes attributes;
|
||||
unsigned long valuemask;
|
||||
|
||||
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,
|
||||
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->mask_gc, 1);
|
||||
XSetForeground(data->display, data->stencil_gc, 0xFF);
|
||||
|
||||
XDrawRectangles(data->display, data->mask, data->mask_gc, xrects, xcount);
|
||||
XRenderChangePicture(data->display, data->drawable_pict, valuemask, &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, valuemask, &attributes);
|
||||
XDrawRectangles(data->display, data->stencil, data->stencil_gc, xrects, xcount);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
||||
if (data->use_xrender) {
|
||||
XRenderColor foreground;
|
||||
foreground = xrenderdrawcolor(renderer);
|
||||
|
||||
XRenderFillRectangle(data->display, PictOpSrc, data->brush_pict,
|
||||
&foreground, 0, 0, 1, 1);
|
||||
|
||||
XRenderComposite(data->display, data->blend_op, data->brush_pict,
|
||||
data->stencil_pict, data->drawable_pict,
|
||||
0, 0, 0, 0, 0, 0, window->w, window->h);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
@ -1349,26 +1444,11 @@ X11_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
|
|||
}
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
||||
if(data->use_xrender == SDL_TRUE) {
|
||||
if (data->use_xrender) {
|
||||
XRenderColor foreground;
|
||||
XRenderPictureAttributes attributes;
|
||||
|
||||
foreground = xrenderdrawcolor(renderer);
|
||||
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);
|
||||
|
||||
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);
|
||||
XRenderFillRectangles(data->display, data->blend_op, data->drawable_pict,
|
||||
&foreground, xrects, xcount);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
@ -1383,7 +1463,6 @@ X11_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
|
|||
}
|
||||
|
||||
SDL_stack_free(xrects);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1726,11 +1805,11 @@ X11_DestroyRenderer(SDL_Renderer * renderer)
|
|||
XFreeGC(data->display, data->gc);
|
||||
}
|
||||
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
|
||||
if (data->mask_gc) {
|
||||
XFreeGC(data->display, data->mask_gc);
|
||||
if (data->stencil_gc) {
|
||||
XFreeGC(data->display, data->stencil_gc);
|
||||
}
|
||||
if (data->mask) {
|
||||
XFreePixmap(data->display, data->mask);
|
||||
if (data->stencil) {
|
||||
XFreePixmap(data->display, data->stencil);
|
||||
}
|
||||
if (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(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(Status,XInitImage,(XImage *image),(image),return)
|
||||
|
||||
#if NeedWidePrototypes
|
||||
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(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,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
|
||||
/* *INDENT-ON* */
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue