Commit 6a534a40 authored by Sunny Sachanandani's avatar Sunny Sachanandani

Start experimental branch for client-side rasterization.

--HG--
branch : experimental
parent 7c46b950
......@@ -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");
}
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");
}
XSetBackground(data->display, data->mask_gc, 0);
XSetForeground(data->display, data->mask_gc, 1);
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) {
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 == SDL_TRUE) {
if (data->use_xrender) {
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,
0, 0, window->w, window->h);
XSetForeground(data->display, data->mask_gc, 1);
XRenderFillRectangle(data->display, PictOpSrc, data->brush_pict,
&foreground, 0, 0, 1, 1);
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);
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* */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment