Commit 77391892 authored by Sunny Sachanandani's avatar Sunny Sachanandani

Massive speed-up. Fixed the format that is set for the renderer. Included...

Massive speed-up. Fixed the format that is set for the renderer. Included runtime checks for XDamage.
parent 84a58d8f
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
#include <X11/extensions/Xdamage.h> #include <X11/extensions/Xdamage.h>
#include <X11/extensions/Xfixes.h> #include <X11/extensions/Xfixes.h>
#define SDL_VIDEO_DRIVER_X11_XDAMAGE
/* X11 renderer implementation */ /* X11 renderer implementation */
static SDL_Renderer *X11_CreateRenderer(SDL_Window * window, Uint32 flags); static SDL_Renderer *X11_CreateRenderer(SDL_Window * window, Uint32 flags);
...@@ -108,11 +110,15 @@ typedef struct ...@@ -108,11 +110,15 @@ typedef struct
Picture drawable_pict; Picture drawable_pict;
Picture stencil_pict; Picture stencil_pict;
int blend_op; int blend_op;
XRenderPictFormat* xwindow_pict_fmt; XRenderPictFormat *xwindow_pict_fmt;
XRenderPictFormat *drawable_pict_fmt;
GC stencil_gc; GC stencil_gc;
SDL_bool use_xrender; SDL_bool use_xrender;
#ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
SDL_bool use_xdamage;
Damage stencil_damage; Damage stencil_damage;
XserverRegion stencil_parts; XserverRegion stencil_parts;
#endif
#endif #endif
int current_pixmap; int current_pixmap;
Drawable drawable; Drawable drawable;
...@@ -255,16 +261,35 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags) ...@@ -255,16 +261,35 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags)
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
data->use_xrender = SDL_FALSE; data->use_xrender = SDL_FALSE;
data->use_xdamage = SDL_FALSE;
int event_basep, error_basep;
if (SDL_X11_HAVE_XRENDER) { if (SDL_X11_HAVE_XRENDER) {
// Query the extension. This is the server runtime check. /* Query the extension. This is the server runtime check. */
int event_basep, error_basep;
if(XRenderQueryExtension(data->display, if(XRenderQueryExtension(data->display,
&event_basep, &error_basep) == True) &event_basep, &error_basep) == True)
data->use_xrender = SDL_TRUE; data->use_xrender = SDL_TRUE;
} }
#ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
if (data->use_xrender) { if (data->use_xrender) {
// Find the PictFormat from the visual. /* Query XDamage and XFixes */
// Should be an RGB PictFormat most of the time. if(XDamageQueryExtension(data->display,
&event_basep,
&error_basep) == True &&
(XFixesQueryExtension(data->display,
&event_basep,
&error_basep) == True)) {
int major_version, minor_version;
XFixesQueryVersion(data->display,
&major_version,
&minor_version);
/* Only XFixes v 2 or greater
* Required for XFixesSetPictureClipRegion() */
if(major_version >= 2)
data->use_xdamage = SDL_TRUE;
}
#endif
/* Find the PictFormat from the visual.
* Should be an RGB PictFormat most of the time. */
data->xwindow_pict_fmt = XRenderFindVisualFormat(data->display, data->xwindow_pict_fmt = XRenderFindVisualFormat(data->display,
data->visual); data->visual);
if (!data->xwindow_pict_fmt) { if (!data->xwindow_pict_fmt) {
...@@ -289,14 +314,14 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags) ...@@ -289,14 +314,14 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags)
0, 0, 0, 0,
0, 0, 0, 0,
window->w, window->h); window->w, window->h);
// Add some blending modes to the list of supported blending modes /* Add some blending modes to the list of supported blending modes */
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->stencil = XCreatePixmap(data->display, data->xwindow, data->stencil = XCreatePixmap(data->display, data->xwindow,
window->w, window->h, 8); window->w, window->h, 8);
// Create the GC for the clip mask. /* Create the GC for the clip mask. */
data->stencil_gc = XCreateGC(data->display, data->stencil, data->stencil_gc = XCreateGC(data->display, data->stencil,
GCGraphicsExposures, &gcv); GCGraphicsExposures, &gcv);
XSetBackground(data->display, data->stencil_gc, 0x00); XSetBackground(data->display, data->stencil_gc, 0x00);
...@@ -309,9 +334,13 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags) ...@@ -309,9 +334,13 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags)
XRenderFindStandardFormat(data->display, XRenderFindStandardFormat(data->display,
PictStandardA8), PictStandardA8),
0, NULL); 0, NULL);
data->stencil_damage = #ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
XDamageCreate(data->display, data->stencil, XDamageReportNonEmpty); if (data->use_xdamage) {
XDamageSubtract(data->display, data->stencil_damage, None, data->stencil_parts); data->stencil_damage =
XDamageCreate(data->display, data->stencil, XDamageReportNonEmpty);
XDamageSubtract(data->display, data->stencil_damage, None, data->stencil_parts);
}
#endif
data->brush = data->brush =
XCreatePixmap(data->display, data->xwindow, 1, 1, 32); XCreatePixmap(data->display, data->xwindow, 1, 1, 32);
XRenderPictureAttributes brush_attr; XRenderPictureAttributes brush_attr;
...@@ -341,6 +370,15 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags) ...@@ -341,6 +370,15 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer->info.flags |= SDL_RENDERER_PRESENTCOPY; renderer->info.flags |= SDL_RENDERER_PRESENTCOPY;
n = 1; n = 1;
} }
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if (data->use_xrender) {
if (n > 0)
data->drawable_pict_fmt =
XRenderFindStandardFormat(data->display, PictStandardARGB32);
else
data->drawable_pict_fmt = data->xwindow_pict_fmt;
}
#endif
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if (data->use_xrender) { if (data->use_xrender) {
...@@ -364,8 +402,8 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags) ...@@ -364,8 +402,8 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags)
} }
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if (data->use_xrender) { if (data->use_xrender) {
// Create xrender pictures for each of the pixmaps /* Create xrender pictures for each of the pixmaps
// and clear the pixmaps. * and clear the pixmaps. */
data->pixmap_picts[i] = data->pixmap_picts[i] =
XRenderCreatePicture(data->display, XRenderCreatePicture(data->display,
data->pixmaps[i], data->pixmaps[i],
...@@ -406,13 +444,29 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags) ...@@ -406,13 +444,29 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags)
} }
data->current_pixmap = 0; data->current_pixmap = 0;
/* Get the format of the window */ #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if (!SDL_PixelFormatEnumToMasks if (data->use_xrender) {
(display->current_mode.format, &bpp, &Rmask, &Gmask, &Bmask, bpp = data->drawable_pict_fmt->depth;
&Amask)) { Rmask = ((data->drawable_pict_fmt->direct.redMask)
SDL_SetError("Unknown display format"); << (data->drawable_pict_fmt->direct.red));
X11_DestroyRenderer(renderer); Gmask = ((data->drawable_pict_fmt->direct.greenMask)
return NULL; << (data->drawable_pict_fmt->direct.green));
Bmask = ((data->drawable_pict_fmt->direct.blueMask)
<< (data->drawable_pict_fmt->direct.blue));
Amask = ((data->drawable_pict_fmt->direct.alphaMask)
<< (data->drawable_pict_fmt->direct.alpha));
}
else
#endif
{
/* Get the format of the window */
if (!SDL_PixelFormatEnumToMasks
(display->current_mode.format, &bpp, &Rmask, &Gmask, &Bmask,
&Amask)) {
SDL_SetError("Unknown display format");
X11_DestroyRenderer(renderer);
return NULL;
}
} }
SDL_InitFormat(&data->format, bpp, Rmask, Gmask, Bmask, Amask); SDL_InitFormat(&data->format, bpp, Rmask, Gmask, Bmask, Amask);
...@@ -1011,15 +1065,14 @@ X11_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, ...@@ -1011,15 +1065,14 @@ 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; SDL_Rect clip;
/*Damage damage;
XserverRegion parts;*/
clip.x = 0; clip.x = 0;
clip.y = 0; clip.y = 0;
clip.w = window->w; clip.w = window->w;
clip.h = window->h; clip.h = window->h;
if (data->makedirty) { if (data->makedirty) {
SDL_Rect rect;
/* Get the smallest rectangle that contains everything */ /* Get the smallest rectangle that contains everything */
rect.x = 0; rect.x = 0;
...@@ -1048,34 +1101,75 @@ X11_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, ...@@ -1048,34 +1101,75 @@ X11_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
} }
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if (data->use_xrender) { if (data->use_xrender &&
(renderer->blendMode != SDL_BLENDMODE_NONE) &&
!(renderer->a == 0xFF &&
renderer->blendMode != SDL_BLENDMODE_ADD &&
renderer->blendMode != SDL_BLENDMODE_MOD))
{
XSetForeground(data->display, data->stencil_gc, 0x00); XSetForeground(data->display, data->stencil_gc, 0x00);
XFixesSetGCClipRegion(data->display, data->stencil_gc, 0, 0, data->stencil_parts); #ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
if (data->use_xdamage)
{
/* Update only those parts which were changed
* in the previous drawing operation */
XFixesSetGCClipRegion(data->display, data->stencil_gc,
0, 0, data->stencil_parts);
}
#endif
XFillRectangle(data->display, data->stencil, data->stencil_gc, XFillRectangle(data->display, data->stencil, data->stencil_gc,
rect.x, rect.y, rect.w, rect.h); 0, 0, window->w, window->h);
XFixesSetGCClipRegion(data->display, data->stencil_gc, 0, 0, None); #ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
if (data->use_xdamage)
{
XFixesSetGCClipRegion(data->display, data->stencil_gc, 0, 0, None);
}
#endif
XSetForeground(data->display, data->stencil_gc, 0xFF); XSetForeground(data->display, data->stencil_gc, 0xFF);
/*damage =
XDamageCreate(data->display, data->stencil, XDamageReportRawRectangles);*/
XDrawPoints(data->display, data->stencil, data->stencil_gc, xpoints, xcount, XDrawPoints(data->display, data->stencil, data->stencil_gc, xpoints, xcount,
CoordModeOrigin); CoordModeOrigin);
XDamageSubtract(data->display, data->stencil_damage, None, data->stencil_parts); #ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
if (data->use_xdamage)
{
/* Store the damaged region in stencil_parts */
XDamageSubtract(data->display, data->stencil_damage, None, data->stencil_parts);
}
#endif
} }
#endif #endif
} }
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if (data->use_xrender) { if (data->use_xrender &&
(renderer->blendMode != SDL_BLENDMODE_NONE) &&
!(renderer->a == 0xFF &&
renderer->blendMode != SDL_BLENDMODE_ADD &&
renderer->blendMode != SDL_BLENDMODE_MOD))
{
XRenderColor foreground; XRenderColor foreground;
foreground = xrenderdrawcolor(renderer); foreground = xrenderdrawcolor(renderer);
XRenderFillRectangle(data->display, PictOpSrc, data->brush_pict, XRenderFillRectangle(data->display, PictOpSrc, data->brush_pict,
&foreground, 0, 0, 1, 1); &foreground, 0, 0, 1, 1);
XFixesSetPictureClipRegion(data->display, data->drawable_pict, 0, 0, data->stencil_parts); #ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
if (data->use_xdamage)
{
/* Update only those parts which drawn
* to in the current drawing operation */
XFixesSetPictureClipRegion(data->display, data->drawable_pict,
0, 0, data->stencil_parts);
}
#endif
XRenderComposite(data->display, data->blend_op, data->brush_pict, XRenderComposite(data->display, data->blend_op, data->brush_pict,
data->stencil_pict, data->drawable_pict, data->stencil_pict, data->drawable_pict,
rect.x, rect.y, rect.x, rect.y, rect.x, rect.y, rect.w, rect.h); 0, 0, 0, 0, 0, 0, window->w, window->h);
XFixesSetPictureClipRegion(data->display, data->drawable_pict, 0, 0, None); #ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
//XDamageDestroy(data->display, damage); if (data->use_xdamage)
{
XFixesSetPictureClipRegion(data->display, data->drawable_pict, 0, 0, None);
}
#endif
} }
else else
#endif #endif
...@@ -1107,8 +1201,6 @@ X11_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, ...@@ -1107,8 +1201,6 @@ X11_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
int i, xcount; int i, xcount;
int minx, miny; int minx, miny;
int maxx, maxy; int maxx, maxy;
XserverRegion parts;
Damage damage;
clip.x = 0; clip.x = 0;
clip.y = 0; clip.y = 0;
...@@ -1118,17 +1210,29 @@ X11_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, ...@@ -1118,17 +1210,29 @@ X11_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
Pixmap drawable; Pixmap drawable;
GC gc; GC gc;
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if (data->use_xrender) { if (data->use_xrender &&
(renderer->blendMode != SDL_BLENDMODE_NONE) &&
!(renderer->a == 0xFF &&
renderer->blendMode != SDL_BLENDMODE_ADD &&
renderer->blendMode != SDL_BLENDMODE_MOD))
{
drawable = data->stencil; drawable = data->stencil;
gc = data->stencil_gc; gc = data->stencil_gc;
XSetForeground(data->display, data->stencil_gc, 0x00); XSetForeground(data->display, data->stencil_gc, 0x00);
XFixesSetGCClipRegion(data->display, data->stencil_gc, 0, 0, data->stencil_parts); #ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
if (data->use_xdamage)
XFixesSetGCClipRegion(data->display, data->stencil_gc,
0, 0, data->stencil_parts);
#endif
XFillRectangle(data->display, data->stencil, data->stencil_gc, XFillRectangle(data->display, data->stencil, data->stencil_gc,
0, 0, window->w, window->h); 0, 0, window->w, window->h);
XFixesSetGCClipRegion(data->display, data->stencil_gc, 0, 0, None); #ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
if (data->use_xdamage)
XFixesSetGCClipRegion(data->display, data->stencil_gc,
0, 0, None);
#endif
XSetForeground(data->display, data->stencil_gc, 0xFF); XSetForeground(data->display, data->stencil_gc, 0xFF);
/*damage =
XDamageCreate(data->display, data->stencil, XDamageReportRawRectangles);*/
} }
else else
#endif #endif
...@@ -1255,17 +1359,32 @@ X11_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, ...@@ -1255,17 +1359,32 @@ X11_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
} }
} }
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if (data->use_xrender) { if (data->use_xrender &&
(renderer->blendMode != SDL_BLENDMODE_NONE) &&
!(renderer->a == 0xFF &&
renderer->blendMode != SDL_BLENDMODE_ADD &&
renderer->blendMode != SDL_BLENDMODE_MOD))
{
XRenderColor xrforeground = xrenderdrawcolor(renderer); XRenderColor xrforeground = xrenderdrawcolor(renderer);
XRenderFillRectangle(data->display, PictOpSrc, data->brush_pict, XRenderFillRectangle(data->display, PictOpSrc, data->brush_pict,
&xrforeground, 0, 0, 1, 1); &xrforeground, 0, 0, 1, 1);
XDamageSubtract(data->display, data->stencil_damage, None, data->stencil_parts); #ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
XFixesSetPictureClipRegion(data->display, data->drawable_pict, 0, 0, data->stencil_parts); if (data->use_xdamage)
{
XDamageSubtract(data->display, data->stencil_damage, None, data->stencil_parts);
XFixesSetPictureClipRegion(data->display, data->drawable_pict,
0, 0, data->stencil_parts);
}
#endif
XRenderComposite(data->display, data->blend_op, data->brush_pict, XRenderComposite(data->display, data->blend_op, data->brush_pict,
data->stencil_pict, data->drawable_pict, data->stencil_pict, data->drawable_pict,
0, 0, 0, 0, 0, 0, window->w, window->h); 0, 0, 0, 0, 0, 0, window->w, window->h);
XFixesSetPictureClipRegion(data->display, data->drawable_pict, 0, 0, None); #ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
//XDamageDestroy(data->display, damage); if (data->use_xdamage)
XFixesSetPictureClipRegion(data->display, data->drawable_pict,
0, 0, None);
#endif
} }
#endif #endif
SDL_stack_free(xpoints); SDL_stack_free(xpoints);
...@@ -1306,34 +1425,65 @@ X11_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count) ...@@ -1306,34 +1425,65 @@ X11_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
SDL_AddDirtyRect(&data->dirty, &rect); SDL_AddDirtyRect(&data->dirty, &rect);
} }
} }
/*
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if (data->use_xrender) { if (data->use_xrender &&
(renderer->blendMode != SDL_BLENDMODE_NONE) &&
!(renderer->a == 0xFF &&
renderer->blendMode != SDL_BLENDMODE_ADD &&
renderer->blendMode != SDL_BLENDMODE_MOD))
{
XSetForeground(data->display, data->stencil_gc, 0x00); XSetForeground(data->display, data->stencil_gc, 0x00);
#ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
if (data->use_xdamage)
XFixesSetGCClipRegion(data->display, data->stencil_gc,
0, 0, data->stencil_parts);
#endif
XFillRectangle(data->display, data->stencil, data->stencil_gc, XFillRectangle(data->display, data->stencil, data->stencil_gc,
0, 0, window->w, window->h); 0, 0, window->w, window->h);
#ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
if (data->use_xdamage)
XFixesSetGCClipRegion(data->display, data->stencil_gc,
0, 0, None);
#endif
XSetForeground(data->display, data->stencil_gc, 0xFF); XSetForeground(data->display, data->stencil_gc, 0xFF);
XDrawRectangles(data->display, data->stencil, data->stencil_gc, xrects, xcount); XDrawRectangles(data->display, data->stencil, data->stencil_gc, xrects, xcount);
#ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
if (data->use_xdamage)
XDamageSubtract(data->display, data->stencil_damage,
None, data->stencil_parts);
#endif
} }
#endif #endif
*/
} }
/*
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if (data->use_xrender) { if (data->use_xrender &&
(renderer->blendMode != SDL_BLENDMODE_NONE) &&
!(renderer->a == 0xFF &&
renderer->blendMode != SDL_BLENDMODE_ADD &&
renderer->blendMode != SDL_BLENDMODE_MOD))
{
XRenderColor foreground; XRenderColor foreground;
foreground = xrenderdrawcolor(renderer); foreground = xrenderdrawcolor(renderer);
XRenderFillRectangle(data->display, PictOpSrc, data->brush_pict, XRenderFillRectangle(data->display, PictOpSrc, data->brush_pict,
&foreground, 0, 0, 1, 1); &foreground, 0, 0, 1, 1);
#ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
if (data->use_xdamage)
XFixesSetPictureClipRegion(data->display, data->drawable_pict,
0, 0, data->stencil_parts);
#endif
XRenderComposite(data->display, data->blend_op, data->brush_pict, XRenderComposite(data->display, data->blend_op, data->brush_pict,
data->stencil_pict, data->drawable_pict, data->stencil_pict, data->drawable_pict,
0, 0, 0, 0, 0, 0, window->w, window->h); 0, 0, 0, 0, 0, 0, window->w, window->h);
#ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
if (data->use_xdamage)
XFixesSetPictureClipRegion(data->display, data->drawable_pict,
0, 0, None);
#endif
} }
else else
#endif #endif
*/
{ {
unsigned long foreground; unsigned long foreground;
......
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