Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
libSDL
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
PocketInsanity
libSDL
Commits
d8e7cebd
Commit
d8e7cebd
authored
Jul 28, 2010
by
Sam Lantinga
Browse files
Options
Browse Files
Download
Plain Diff
Merged Sunny's XRender changes from SDL-gsoc2010_xrender
parents
8d14ec12
b277b530
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
1556 additions
and
313 deletions
+1556
-313
configure.in
configure.in
+67
-6
SDL_config.h.in
include/SDL_config.h.in
+7
-0
SDL_video.h
include/SDL_video.h
+1
-1
SDL_error.c
src/SDL_error.c
+2
-0
SDL_x11dyn.h
src/video/x11/SDL_x11dyn.h
+12
-0
SDL_x11render.c
src/video/x11/SDL_x11render.c
+1418
-305
SDL_x11sym.h
src/video/x11/SDL_x11sym.h
+40
-0
SDL_x11video.h
src/video/x11/SDL_x11video.h
+9
-1
No files found.
configure.in
View file @
d8e7cebd
...
...
@@ -1055,6 +1055,8 @@ AC_HELP_STRING([--enable-x11-shared], [dynamically load X11 support [[default=ma
xrandr_lib=[`find_lib "libXrandr.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`]
xinput_lib=[`find_lib "libXi.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`]
xss_lib=[`find_lib "libXss.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`]
xdamage_lib=[`find_lib "libXdamage.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`]
xfixes_lib=[`find_lib "libXfixes.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`]
;;
esac
...
...
@@ -1128,16 +1130,13 @@ AC_HELP_STRING([--enable-video-x11-xrandr], [enable X11 Xrandr extension for ful
])
if test x$have_xrandr_h_hdr = xyes; then
if test x$enable_x11_shared = xyes && test x$xrandr_lib != x ; then
echo "-- dynamic libXrender -> $xrender_lib"
echo "-- dynamic libXrandr -> $xrandr_lib"
AC_DEFINE_UNQUOTED(SDL_VIDEO_DRIVER_X11_DYNAMIC_XRENDER, "$xrender_lib")
AC_DEFINE_UNQUOTED(SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR, "$xrandr_lib")
definitely_enable_video_x11_xrandr=yes
else
AC_CHECK_LIB(Xrender, XRenderQueryExtension, have_xrender_lib=yes)
AC_CHECK_LIB(Xrandr, XRRQueryExtension, have_xrandr_lib=yes)
if test x$have_xr
ender_lib = xyes && test x$have_xr
andr_lib = xyes ; then
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lXrandr
-lXrender
"
if test x$have_xrandr_lib = xyes ; then
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lXrandr"
definitely_enable_video_x11_xrandr=yes
fi
fi
...
...
@@ -1199,7 +1198,69 @@ AC_HELP_STRING([--enable-video-x11-scrnsaver], [enable X11 screensaver extension
if test x$definitely_enable_video_x11_scrnsaver = xyes; then
AC_DEFINE(SDL_VIDEO_DRIVER_X11_SCRNSAVER)
fi
AC_ARG_ENABLE(video-x11-xrender,
AC_HELP_STRING([--enable-video-x11-xrender], [enable X11 Xrender extension [[default=yes]]]),
, enable_video_x11_xrender=yes)
if test x$enable_video_x11_xrender = xyes; then
AC_CHECK_HEADER(X11/extensions/Xrender.h,
have_xrender_h_hdr=yes,
have_xrender_h_hdr=no,
[#include <X11/Xlib.h>
])
if test x$have_xrender_h_hdr = xyes; then
if test x$enable_x11_shared = xyes && test x$xrender_lib != x ; then
echo "-- dynamic libXrender -> $xrender_lib"
AC_DEFINE_UNQUOTED(SDL_VIDEO_DRIVER_X11_DYNAMIC_XRENDER, "$xrender_lib")
definitely_enable_video_x11_xrender=yes
else
AC_CHECK_LIB(Xrender, XRenderQueryExtension, have_xrender_lib=yes)
if test x$have_xrender_lib = xyes ; then
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lXrender"
definitely_enable_video_x11_xrender=yes
fi
fi
fi
fi
if test x$definitely_enable_video_x11_xrender = xyes; then
AC_DEFINE(SDL_VIDEO_DRIVER_X11_XRENDER)
fi
AC_ARG_ENABLE(video-x11-xdamage-xfixes,
AC_HELP_STRING([--enable-video-x11-xdamage-xfixes], [enable X11 Xdamage and Xfixes extensions [[default=yes]]]),
, enable_video_x11_xdamage=yes)
if test x$enable_video_x11_xdamage = xyes && test x$definitely_enable_video_x11_xrender = xyes ; then
AC_CHECK_HEADER(X11/extensions/Xdamage.h,
have_xdamage_h_hdr=yes,
have_xdamage_h_hdr=no,
[#include <X11/Xlib.h>
])
AC_CHECK_HEADER(X11/extensions/Xfixes.h,
have_xfixes_h_hdr=yes,
have_xfixes_h_hdr=no,
[#include <X11/Xlib.h>
])
if test x$have_xdamage_h_hdr = xyes && test x$have_xfixes_h_hdr = xyes ; then
if test x$enable_x11_shared = xyes && test x$xdamage_lib != x && test x$xfixes_lib != x ; then
echo "-- dynamic libXdamage -> $xdamage_lib"
echo "-- dynamic libXfixes -> $xfixes_lib"
AC_DEFINE_UNQUOTED(SDL_VIDEO_DRIVER_X11_DYNAMIC_XDAMAGE, "$xdamage_lib")
AC_DEFINE_UNQUOTED(SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES, "$xfixes_lib")
definitely_enable_video_x11_xdamage=yes
definitely_enable_video_x11_xfixes=yes
else
AC_CHECK_LIB(Xdamage, XDamageQueryExtension, have_xdamage_lib=yes)
AC_CHECK_LIB(Xfixes, XFixesQueryExtension, have_xfixes_lib=yes)
if test x$have_xdamage_lib = xyes && test x$have_xfixes_lib = xyes ; then
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lXdamage -lXfixes"
definitely_enable_video_x11_xdamage=yes
definitely_enable_video_x11_xfixes=yes
fi
fi
fi
fi
if test x$definitely_enable_video_x11_xdamage = xyes && test x$definitely_enable_video_x11_xfixes = xyes ; then
AC_DEFINE(SDL_VIDEO_DRIVER_X11_XDAMAGE)
AC_DEFINE(SDL_VIDEO_DRIVER_X11_XFIXES)
fi
AC_ARG_ENABLE(render-x11,
AC_HELP_STRING([--enable-render-x11], [enable the X11 render driver [[default=yes]]]),
, enable_render_x11=yes)
...
...
include/SDL_config.h.in
View file @
d8e7cebd
...
...
@@ -272,12 +272,19 @@
#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRENDER
#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT
#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS
#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XDAMAGE
#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES
#undef SDL_VIDEO_DRIVER_X11_VIDMODE
#undef SDL_VIDEO_DRIVER_X11_XINERAMA
#undef SDL_VIDEO_DRIVER_X11_XRANDR
#undef SDL_VIDEO_DRIVER_X11_XINPUT
#undef SDL_VIDEO_DRIVER_X11_SCRNSAVER
#undef SDL_VIDEO_DRIVER_X11_XV
#undef SDL_VIDEO_DRIVER_X11_XRENDER
#undef SDL_VIDEO_DRIVER_X11_XDAMAGE
#undef SDL_VIDEO_DRIVER_X11_XFIXES
#undef SDL_VIDEO_RENDER_X11
#undef SDL_VIDEO_RENDER_D3D
#undef SDL_VIDEO_RENDER_GDI
...
...
include/SDL_video.h
View file @
d8e7cebd
...
...
@@ -189,7 +189,7 @@ typedef struct SDL_RendererInfo
Uint32
blend_modes
;
/**< A mask of supported blend modes */
Uint32
scale_modes
;
/**< A mask of supported scale modes */
Uint32
num_texture_formats
;
/**< The number of available texture formats */
Uint32
texture_formats
[
2
0
];
/**< The available texture formats */
Uint32
texture_formats
[
5
0
];
/**< The available texture formats */
int
max_texture_width
;
/**< The maximimum texture width */
int
max_texture_height
;
/**< The maximimum texture height */
}
SDL_RendererInfo
;
...
...
src/SDL_error.c
View file @
d8e7cebd
...
...
@@ -26,6 +26,8 @@
#include "SDL_error.h"
#include "SDL_error_c.h"
/*#define DEBUG_ERROR*/
/* Routine to get the thread-specific error variable */
#if SDL_THREADS_DISABLED
/* !!! FIXME: what does this comment mean? Victim of Search and Replace? */
...
...
src/video/x11/SDL_x11dyn.h
View file @
d8e7cebd
...
...
@@ -52,6 +52,18 @@
#include <X11/extensions/XInput.h>
#endif
#if SDL_VIDEO_DRIVER_X11_XRENDER
#include <X11/extensions/Xrender.h>
#endif
#if SDL_VIDEO_DRIVER_X11_XDAMAGE
#include <X11/extensions/Xdamage.h>
#endif
#if SDL_VIDEO_DRIVER_X11_XFIXES
#include <X11/extensions/Xfixes.h>
#endif
/*
* When using the "dynamic X11" functionality, we duplicate all the Xlib
* symbols that would be referenced by SDL inside of SDL itself.
...
...
src/video/x11/SDL_x11render.c
View file @
d8e7cebd
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
...
...
@@ -39,6 +40,8 @@ static int X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
static
int
X11_QueryTexturePixels
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
,
void
**
pixels
,
int
*
pitch
);
static
int
X11_SetTextureRGBAMod
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
);
static
int
X11_SetTextureBlendMode
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
);
static
int
X11_SetTextureScaleMode
(
SDL_Renderer
*
renderer
,
...
...
@@ -96,6 +99,25 @@ typedef struct
int
scanline_pad
;
Window
xwindow
;
Pixmap
pixmaps
[
3
];
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
Pixmap
stencil
;
Pixmap
brush
;
Picture
brush_pict
;
Picture
xwindow_pict
;
Picture
pixmap_picts
[
3
];
Picture
drawable_pict
;
Picture
stencil_pict
;
int
blend_op
;
XRenderPictFormat
*
xwindow_pict_fmt
;
XRenderPictFormat
*
drawable_pict_fmt
;
GC
stencil_gc
;
SDL_bool
use_xrender
;
#ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
SDL_bool
use_xdamage
;
Damage
stencil_damage
;
XserverRegion
stencil_parts
;
#endif
#endif
int
current_pixmap
;
Drawable
drawable
;
SDL_PixelFormat
format
;
...
...
@@ -109,6 +131,17 @@ typedef struct
SDL_SW_YUVTexture
*
yuv
;
Uint32
format
;
Pixmap
pixmap
;
int
depth
;
Visual
*
visual
;
GC
gc
;
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
Picture
picture
;
Pixmap
modulated_pixmap
;
Picture
modulated_picture
;
XRenderPictFormat
*
picture_fmt
;
int
blend_op
;
const
char
*
filter
;
#endif
XImage
*
image
;
#ifndef NO_SHARED_MEMORY
/* MIT shared memory extension information */
...
...
@@ -149,11 +182,109 @@ UpdateYUVTextureData(SDL_Texture * texture)
texture
->
h
,
data
->
pixels
,
data
->
pitch
);
}
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
static
SDL_bool
CheckXRender
(
Display
*
display
,
int
*
major
,
int
*
minor
)
{
const
char
*
env
;
*
major
=
*
minor
=
0
;
env
=
SDL_getenv
(
"SDL_VIDEO_X11_XRENDER"
);
if
(
env
&&
!
SDL_atoi
(
env
))
{
return
SDL_FALSE
;
}
if
(
!
SDL_X11_HAVE_XRENDER
)
{
return
SDL_FALSE
;
}
if
(
!
XRenderQueryVersion
(
display
,
major
,
minor
))
{
return
SDL_FALSE
;
}
return
SDL_TRUE
;
}
#endif
#ifdef SDL_VIDEO_DRIVER_X11_XFIXES
static
SDL_bool
CheckXFixes
(
Display
*
display
,
int
*
major
,
int
*
minor
)
{
const
char
*
env
;
*
major
=
*
minor
=
0
;
env
=
SDL_getenv
(
"SDL_VIDEO_X11_XFIXES"
);
if
(
env
&&
!
SDL_atoi
(
env
))
{
return
SDL_FALSE
;
}
if
(
!
SDL_X11_HAVE_XFIXES
)
{
return
SDL_FALSE
;
}
if
(
!
XFixesQueryVersion
(
display
,
major
,
minor
))
{
return
SDL_FALSE
;
}
return
SDL_TRUE
;
}
#endif
#ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
static
SDL_bool
CheckXDamage
(
Display
*
display
,
int
*
major
,
int
*
minor
)
{
const
char
*
env
;
*
major
=
*
minor
=
0
;
env
=
SDL_getenv
(
"SDL_VIDEO_X11_XDAMAGE"
);
if
(
env
&&
!
SDL_atoi
(
env
))
{
return
SDL_FALSE
;
}
if
(
!
SDL_X11_HAVE_XDAMAGE
)
{
return
SDL_FALSE
;
}
if
(
!
XDamageQueryVersion
(
display
,
major
,
minor
))
{
return
SDL_FALSE
;
}
return
SDL_TRUE
;
}
#endif
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
static
Uint32
XRenderPictFormatToSDLPixelFormatEnum
(
XRenderPictFormat
*
pict_format
)
{
if
(
pict_format
->
type
!=
PictTypeDirect
)
{
SDL_SetError
(
"Indexed pict formats not supported ATM"
);
return
0
;
}
Uint32
Amask
,
Rmask
,
Gmask
,
Bmask
;
int
bpp
;
Rmask
=
pict_format
->
direct
.
redMask
<<
pict_format
->
direct
.
red
;
Gmask
=
pict_format
->
direct
.
greenMask
<<
pict_format
->
direct
.
green
;
Bmask
=
pict_format
->
direct
.
blueMask
<<
pict_format
->
direct
.
blue
;
Amask
=
pict_format
->
direct
.
alphaMask
<<
pict_format
->
direct
.
alpha
;
bpp
=
pict_format
->
depth
;
Uint32
format
;
format
=
SDL_MasksToPixelFormatEnum
(
bpp
,
Rmask
,
Gmask
,
Bmask
,
Amask
);
return
format
;
}
#endif
void
X11_AddRenderDriver
(
_THIS
)
{
SDL_RendererInfo
*
info
=
&
X11_RenderDriver
.
info
;
SDL_DisplayMode
*
mode
=
&
SDL_CurrentDisplay
->
desktop_mode
;
SDL_VideoData
*
data
=
(
SDL_VideoData
*
)
_this
->
driverdata
;
int
i
;
info
->
texture_formats
[
info
->
num_texture_formats
++
]
=
mode
->
format
;
...
...
@@ -163,6 +294,34 @@ X11_AddRenderDriver(_THIS)
info
->
texture_formats
[
info
->
num_texture_formats
++
]
=
SDL_PIXELFORMAT_UYVY
;
info
->
texture_formats
[
info
->
num_texture_formats
++
]
=
SDL_PIXELFORMAT_YVYU
;
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
int
major
,
minor
;
if
(
CheckXRender
(
data
->
display
,
&
major
,
&
minor
))
{
XRenderPictFormat
templ
;
templ
.
type
=
PictTypeDirect
;
XRenderPictFormat
*
pict_format
;
Uint32
format
;
int
i
=
0
;
while
(
info
->
num_texture_formats
<
50
)
{
pict_format
=
XRenderFindFormat
(
data
->
display
,
PictFormatType
,
&
templ
,
i
++
);
if
(
pict_format
)
{
format
=
XRenderPictFormatToSDLPixelFormatEnum
(
pict_format
);
if
(
format
!=
SDL_PIXELTYPE_UNKNOWN
)
{
info
->
texture_formats
[
info
->
num_texture_formats
++
]
=
format
;
}
}
else
break
;
}
info
->
blend_modes
|=
(
SDL_BLENDMODE_BLEND
|
SDL_BLENDMODE_ADD
|
SDL_BLENDMODE_MOD
|
SDL_BLENDMODE_MASK
);
info
->
scale_modes
|=
(
SDL_TEXTURESCALEMODE_FAST
|
SDL_TEXTURESCALEMODE_SLOW
|
SDL_TEXTURESCALEMODE_BEST
);
info
->
mod_modes
|=
(
SDL_TEXTUREMODULATE_COLOR
|
SDL_TEXTUREMODULATE_ALPHA
);
}
#endif
for
(
i
=
0
;
i
<
_this
->
num_displays
;
++
i
)
{
SDL_AddRenderDriver
(
&
_this
->
displays
[
i
],
&
X11_RenderDriver
);
}
...
...
@@ -177,6 +336,7 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags)
SDL_Renderer
*
renderer
;
X11_RenderData
*
data
;
XGCValues
gcv
;
gcv
.
graphics_exposures
=
False
;
int
i
,
n
;
int
bpp
;
Uint32
Rmask
,
Gmask
,
Bmask
,
Amask
;
...
...
@@ -199,10 +359,12 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags)
data
->
depth
=
displaydata
->
depth
;
data
->
scanline_pad
=
displaydata
->
scanline_pad
;
data
->
xwindow
=
windowdata
->
xwindow
;
renderer
->
DisplayModeChanged
=
X11_DisplayModeChanged
;
renderer
->
CreateTexture
=
X11_CreateTexture
;
renderer
->
QueryTexturePixels
=
X11_QueryTexturePixels
;
renderer
->
SetTextureAlphaMod
=
X11_SetTextureRGBAMod
;
renderer
->
SetTextureColorMod
=
X11_SetTextureRGBAMod
;
renderer
->
SetTextureBlendMode
=
X11_SetTextureBlendMode
;
renderer
->
SetTextureScaleMode
=
X11_SetTextureScaleMode
;
renderer
->
UpdateTexture
=
X11_UpdateTexture
;
...
...
@@ -225,6 +387,82 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer
->
info
.
flags
=
SDL_RENDERER_ACCELERATED
;
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
int
major
,
minor
;
data
->
use_xrender
=
CheckXRender
(
data
->
display
,
&
major
,
&
minor
);
#ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
if
(
CheckXDamage
(
data
->
display
,
&
major
,
&
minor
))
{
if
(
CheckXFixes
(
data
->
display
,
&
major
,
&
minor
))
{
if
(
major
>=
2
)
data
->
use_xdamage
=
SDL_TRUE
;
}
}
#endif
if
(
data
->
use_xrender
)
{
/* Find the PictFormat from the visual.
* Should be an RGB PictFormat most of the time. */
data
->
xwindow_pict_fmt
=
XRenderFindVisualFormat
(
data
->
display
,
data
->
visual
);
if
(
!
data
->
xwindow_pict_fmt
)
{
SDL_SetError
(
"XRenderFindVisualFormat() failed"
);
return
NULL
;
}
data
->
xwindow_pict
=
XRenderCreatePicture
(
data
->
display
,
data
->
xwindow
,
data
->
xwindow_pict_fmt
,
0
,
NULL
);
if
(
!
data
->
xwindow_pict
)
{
SDL_SetError
(
"XRenderCreatePicture() failed"
);
return
NULL
;
}
// FIXME: Clear the window. Is this required?
XRenderComposite
(
data
->
display
,
PictOpClear
,
data
->
xwindow_pict
,
None
,
data
->
xwindow_pict
,
0
,
0
,
0
,
0
,
0
,
0
,
window
->
w
,
window
->
h
);
/* Create a clip mask that is used for rendering primitives. */
data
->
stencil
=
XCreatePixmap
(
data
->
display
,
data
->
xwindow
,
window
->
w
,
window
->
h
,
32
);
/* Create the GC for the clip mask. */
data
->
stencil_gc
=
XCreateGC
(
data
->
display
,
data
->
stencil
,
GCGraphicsExposures
,
&
gcv
);
XSetBackground
(
data
->
display
,
data
->
stencil_gc
,
0
);
XSetForeground
(
data
->
display
,
data
->
stencil_gc
,
0
);
XFillRectangle
(
data
->
display
,
data
->
stencil
,
data
->
stencil_gc
,
0
,
0
,
window
->
w
,
window
->
h
);
XSetForeground
(
data
->
display
,
data
->
stencil_gc
,
0xFFFFFFFF
);
data
->
stencil_pict
=
XRenderCreatePicture
(
data
->
display
,
data
->
stencil
,
XRenderFindStandardFormat
(
data
->
display
,
PictStandardARGB32
),
0
,
NULL
);
#ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
if
(
data
->
use_xdamage
)
{
data
->
stencil_damage
=
XDamageCreate
(
data
->
display
,
data
->
stencil
,
XDamageReportNonEmpty
);
XDamageSubtract
(
data
->
display
,
data
->
stencil_damage
,
None
,
data
->
stencil_parts
);
}
#endif
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
);
// Set the default blending mode.
renderer
->
blendMode
=
SDL_BLENDMODE_BLEND
;
data
->
blend_op
=
PictOpOver
;
}
#endif
if
(
flags
&
SDL_RENDERER_SINGLEBUFFER
)
{
renderer
->
info
.
flags
|=
(
SDL_RENDERER_SINGLEBUFFER
|
SDL_RENDERER_PRESENTCOPY
);
...
...
@@ -239,39 +477,110 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer
->
info
.
flags
|=
SDL_RENDERER_PRESENTCOPY
;
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
)
{
data
->
pixmaps
[
i
]
=
XCreatePixmap
(
data
->
display
,
data
->
xwindow
,
window
->
w
,
window
->
h
,
displaydata
->
depth
);
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
data
->
use_xrender
)
{
data
->
pixmaps
[
i
]
=
XCreatePixmap
(
data
->
display
,
data
->
xwindow
,
window
->
w
,
window
->
h
,
32
);
}
else
#endif
{
data
->
pixmaps
[
i
]
=
XCreatePixmap
(
data
->
display
,
data
->
xwindow
,
window
->
w
,
window
->
h
,
displaydata
->
depth
);
}
if
(
data
->
pixmaps
[
i
]
==
None
)
{
X11_DestroyRenderer
(
renderer
);
SDL_SetError
(
"XCreatePixmap() failed"
);
return
NULL
;
}
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
data
->
use_xrender
)
{
/* Create xrender pictures for each of the pixmaps
* and clear the pixmaps. */
data
->
pixmap_picts
[
i
]
=
XRenderCreatePicture
(
data
->
display
,
data
->
pixmaps
[
i
],
XRenderFindStandardFormat
(
data
->
display
,
PictStandardARGB32
),
0
,
None
);
if
(
!
data
->
pixmap_picts
[
i
])
{
SDL_SetError
(
"XRenderCreatePicture() failed"
);
return
NULL
;
}
XRenderComposite
(
data
->
display
,
PictOpClear
,
data
->
pixmap_picts
[
i
],
None
,
data
->
pixmap_picts
[
i
],
0
,
0
,
0
,
0
,
0
,
0
,
window
->
w
,
window
->
h
);
}
#endif
}
if
(
n
>
0
)
{
data
->
drawable
=
data
->
pixmaps
[
0
];
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
data
->
use_xrender
==
SDL_TRUE
)
data
->
drawable_pict
=
data
->
pixmap_picts
[
0
];
#endif
data
->
makedirty
=
SDL_TRUE
;
}
else
{
data
->
drawable
=
data
->
xwindow
;
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
data
->
use_xrender
==
SDL_TRUE
)
data
->
drawable_pict
=
data
->
xwindow_pict
;
#endif
data
->
makedirty
=
SDL_FALSE
;
}
data
->
current_pixmap
=
0
;
/* 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
;
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
data
->
use_xrender
)
{
bpp
=
data
->
drawable_pict_fmt
->
depth
;
Rmask
=
((
data
->
drawable_pict_fmt
->
direct
.
redMask
)
<<
(
data
->
drawable_pict_fmt
->
direct
.
red
));
Gmask
=
((
data
->
drawable_pict_fmt
->
direct
.
greenMask
)
<<
(
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
);
/* Create the drawing context */
gcv
.
graphics_exposures
=
False
;
data
->
gc
=
XCreateGC
(
data
->
display
,
data
->
xwindow
,
GCGraphicsExposures
,
&
gcv
);
XCreateGC
(
data
->
display
,
data
->
drawable
,
GCGraphicsExposures
,
&
gcv
);
if
(
!
data
->
gc
)
{
X11_DestroyRenderer
(
renderer
);
SDL_SetError
(
"XCreateGC() failed"
);
...
...
@@ -288,6 +597,47 @@ X11_DisplayModeChanged(SDL_Renderer * renderer)
SDL_Window
*
window
=
renderer
->
window
;
int
i
,
n
;
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
data
->
use_xrender
)
{
XRenderFreePicture
(
data
->
display
,
data
->
xwindow_pict
);
data
->
xwindow_pict_fmt
=
XRenderFindVisualFormat
(
data
->
display
,
data
->
visual
);
data
->
xwindow_pict
=
XRenderCreatePicture
(
data
->
display
,
data
->
xwindow
,
data
->
xwindow_pict_fmt
,
0
,
NULL
);
XRenderComposite
(
data
->
display
,
PictOpClear
,
data
->
xwindow_pict
,
None
,
data
->
xwindow_pict
,
0
,
0
,
0
,
0
,
0
,
0
,
window
->
w
,
window
->
h
);
XFreePixmap
(
data
->
display
,
data
->
stencil
);
/* Create a clip mask that is used for rendering primitives. */
data
->
stencil
=
XCreatePixmap
(
data
->
display
,
data
->
xwindow
,
window
->
w
,
window
->
h
,
32
);
XRenderFreePicture
(
data
->
display
,
data
->
stencil_pict
);
data
->
stencil_pict
=
XRenderCreatePicture
(
data
->
display
,
data
->
stencil
,
XRenderFindStandardFormat
(
data
->
display
,
PictStandardARGB32
),
0
,
NULL
);
#ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
XDamageDestroy
(
data
->
display
,
data
->
stencil_damage
);
if
(
data
->
use_xdamage
)
{
data
->
stencil_damage
=
XDamageCreate
(
data
->
display
,
data
->
stencil
,
XDamageReportNonEmpty
);
XDamageSubtract
(
data
->
display
,
data
->
stencil_damage
,
None
,
data
->
stencil_parts
);
}
#endif
}
#endif
if
(
renderer
->
info
.
flags
&
SDL_RENDERER_SINGLEBUFFER
)
{
n
=
0
;
}
else
if
(
renderer
->
info
.
flags
&
SDL_RENDERER_PRESENTFLIP2
)
{
...
...
@@ -301,25 +651,170 @@ X11_DisplayModeChanged(SDL_Renderer * renderer)
if
(
data
->
pixmaps
[
i
]
!=
None
)
{
XFreePixmap
(
data
->
display
,
data
->
pixmaps
[
i
]);
data
->
pixmaps
[
i
]
=
None
;
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
XRenderFreePicture
(
data
->
display
,
data
->
pixmap_picts
[
i
]);
data
->
pixmap_picts
[
i
]
=
None
;
#endif
}
}
for
(
i
=
0
;
i
<
n
;
++
i
)
{
data
->
pixmaps
[
i
]
=
XCreatePixmap
(
data
->
display
,
data
->
xwindow
,
window
->
w
,
window
->
h
,
data
->
depth
);
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
data
->
use_xrender
)
{
data
->
pixmaps
[
i
]
=
XCreatePixmap
(
data
->
display
,
data
->
xwindow
,
window
->
w
,
window
->
h
,
32
);
}
else
#endif
{
data
->
pixmaps
[
i
]
=
XCreatePixmap
(
data
->
display
,
data
->
xwindow
,
window
->
w
,
window
->
h
,
data
->
depth
);
}
if
(
data
->
pixmaps
[
i
]
==
None
)
{
SDL_SetError
(
"XCreatePixmap() failed"
);
return
-
1
;
}
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
data
->
use_xrender
)
{
data
->
pixmap_picts
[
i
]
=
XRenderCreatePicture
(
data
->
display
,
data
->
pixmaps
[
i
],
XRenderFindStandardFormat
(
data
->
display
,
PictStandardARGB32
),
0
,
None
);
if
(
!
data
->
pixmap_picts
[
i
])
{
SDL_SetError
(
"XRenderCreatePicture() failed"
);
return
-
1
;
}
XRenderComposite
(
data
->
display
,
PictOpClear
,
data
->
pixmap_picts
[
i
],
None
,
data
->
pixmap_picts
[
i
],
0
,
0
,
0
,
0
,
0
,
0
,
window
->
w
,
window
->
h
);
}
#endif
}
if
(
n
>
0
)
{
data
->
drawable
=
data
->
pixmaps
[
0
];
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
data
->
drawable_pict
=
data
->
pixmap_picts
[
0
];
#endif
}
data
->
current_pixmap
=
0
;
return
0
;
}
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
static
void
SDLMaskToXRenderMask
(
Uint32
sdl_mask
,
short
*
comp
,
short
*
compMask
)
{
if
(
sdl_mask
==
0
)
{
*
comp
=
0
;
*
compMask
=
0
;
}
else
{
(
*
comp
)
=
0
;
(
*
compMask
)
=
0
;
while
(
!
(
sdl_mask
&
1
))
{
(
*
comp
)
++
;
sdl_mask
>>=
1
;
}
while
(
sdl_mask
&
1
)
{
(
*
compMask
)
=
((
*
compMask
)
<<
1
)
|
1
;
sdl_mask
>>=
1
;
}
}
}
static
XRenderPictFormat
*
PixelFormatEnumToXRenderPictFormat
(
SDL_Renderer
*
renderer
,
Uint32
format
)
{
XRenderPictFormat
*
pict_fmt
=
NULL
;
X11_RenderData
*
data
=
(
X11_RenderData
*
)
renderer
->
driverdata
;
if
(
data
->
use_xrender
)
{
int
bpp
;
Uint32
Amask
,
Rmask
,
Gmask
,
Bmask
;
if
(
!
SDL_PixelFormatEnumToMasks
(
format
,
&
bpp
,
&
Rmask
,
&
Gmask
,
&
Bmask
,
&
Amask
))
{
SDL_SetError
(
"Unknown pixel format"
);
return
NULL
;
}
XRenderPictFormat
templ
;
unsigned
long
mask
=
(
PictFormatType
|
PictFormatDepth
|
PictFormatRed
|
PictFormatRedMask
|
PictFormatGreen
|
PictFormatGreenMask
|
PictFormatBlue
|
PictFormatBlueMask
|
PictFormatAlpha
|
PictFormatAlphaMask
);
templ
.
type
=
PictTypeDirect
;
templ
.
depth
=
bpp
;
SDLMaskToXRenderMask
(
Amask
,
&
(
templ
.
direct
.
alpha
),
&
(
templ
.
direct
.
alphaMask
));
SDLMaskToXRenderMask
(
Rmask
,
&
(
templ
.
direct
.
red
),
&
(
templ
.
direct
.
redMask
));
SDLMaskToXRenderMask
(
Gmask
,
&
(
templ
.
direct
.
green
),
&
(
templ
.
direct
.
greenMask
));
SDLMaskToXRenderMask
(
Bmask
,
&
(
templ
.
direct
.
blue
),
&
(
templ
.
direct
.
blueMask
));
pict_fmt
=
XRenderFindFormat
(
data
->
display
,
mask
,
&
templ
,
0
);
}
return
pict_fmt
;
}
static
Visual
*
PixelFormatEnumToVisual
(
SDL_Renderer
*
renderer
,
Uint32
format
)
{
X11_RenderData
*
data
=
(
X11_RenderData
*
)
renderer
->
driverdata
;
if
(
data
->
use_xrender
)
{
int
bpp
;
Uint32
Amask
,
Rmask
,
Gmask
,
Bmask
;
SDL_PixelFormatEnumToMasks
(
format
,
&
bpp
,
&
Rmask
,
&
Gmask
,
&
Bmask
,
&
Amask
);
XVisualInfo
vinfo_templ
;
long
vinfo_mask
;
int
nitems_return
;
vinfo_mask
=
(
VisualDepthMask
|
VisualRedMaskMask
|
VisualGreenMaskMask
|
VisualBlueMaskMask
);
vinfo_templ
.
depth
=
bpp
;
vinfo_templ
.
red_mask
=
Rmask
;
vinfo_templ
.
green_mask
=
Gmask
;
vinfo_templ
.
blue_mask
=
Bmask
;
XVisualInfo
*
ret
=
XGetVisualInfo
(
data
->
display
,
vinfo_mask
,
&
vinfo_templ
,
&
nitems_return
);
if
(
nitems_return
)
{
return
ret
[
0
].
visual
;
}
}
return
NULL
;
}
static
XRenderColor
SDLColorToXRenderColor
(
Uint8
r
,
Uint8
g
,
Uint8
b
,
Uint8
a
)
{
double
rd
,
gd
,
bd
,
ad
;
XRenderColor
ret
;
rd
=
r
/
255
.
0
;
gd
=
g
/
255
.
0
;
bd
=
b
/
255
.
0
;
ad
=
a
/
255
.
0
;
ret
.
red
=
(
unsigned
short
)
(
rd
*
ad
*
0xFFFF
);
ret
.
green
=
(
unsigned
short
)
(
gd
*
ad
*
0xFFFF
);
ret
.
blue
=
(
unsigned
short
)
(
bd
*
ad
*
0xFFFF
);
ret
.
alpha
=
(
unsigned
short
)
(
ad
*
0xFFFF
);
return
ret
;
}
#endif
static
int
X11_CreateTexture
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
)
{
...
...
@@ -328,15 +823,18 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
SDL_VideoDisplay
*
display
=
window
->
display
;
X11_TextureData
*
data
;
int
pitch_alignmask
=
((
renderdata
->
scanline_pad
/
8
)
-
1
);
XGCValues
gcv
;
data
=
(
X11_TextureData
*
)
SDL_calloc
(
1
,
sizeof
(
*
data
));
if
(
!
data
)
{
SDL_OutOfMemory
();
return
-
1
;
}
data
->
depth
=
renderdata
->
depth
;
data
->
visual
=
renderdata
->
visual
;
data
->
gc
=
renderdata
->
gc
;
texture
->
driverdata
=
data
;
if
(
SDL_ISPIXELFORMAT_FOURCC
(
texture
->
format
))
{
data
->
yuv
=
SDL_SW_CreateYUVTexture
(
texture
->
format
,
texture
->
w
,
texture
->
h
);
...
...
@@ -345,18 +843,26 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
}
data
->
format
=
display
->
current_mode
.
format
;
}
else
{
/* The image/pixmap depth must be the same as the window or you
get a BadMatch error when trying to putimage or copyarea.
*/
if
(
texture
->
format
!=
display
->
current_mode
.
format
)
{
SDL_SetError
(
"Texture format doesn't match window format"
);
return
-
1
;
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
renderdata
->
use_xrender
)
{
Uint32
Amask
,
Rmask
,
Gmask
,
Bmask
;
SDL_PixelFormatEnumToMasks
(
texture
->
format
,
&
(
data
->
depth
),
&
Rmask
,
&
Gmask
,
&
Bmask
,
&
Amask
);
data
->
visual
=
PixelFormatEnumToVisual
(
renderer
,
texture
->
format
);
}
else
#endif
{
if
(
texture
->
format
!=
display
->
current_mode
.
format
)
{
SDL_SetError
(
"Texture format doesn't match window format"
);
return
-
1
;
}
}
data
->
format
=
texture
->
format
;
}
data
->
pitch
=
texture
->
w
*
SDL_BYTESPERPIXEL
(
data
->
format
);
data
->
pitch
=
(
data
->
pitch
+
pitch_alignmask
)
&
~
pitch_alignmask
;
if
(
data
->
yuv
||
texture
->
access
==
SDL_TEXTUREACCESS_STREAMING
)
{
#ifndef NO_SHARED_MEMORY
XShmSegmentInfo
*
shminfo
=
&
data
->
shminfo
;
...
...
@@ -364,37 +870,42 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
shm_error
=
True
;
if
(
SDL_X11_HAVE_SHM
)
{
shminfo
->
shmid
=
shmget
(
IPC_PRIVATE
,
texture
->
h
*
data
->
pitch
,
IPC_CREAT
|
0777
);
if
(
shminfo
->
shmid
>=
0
)
{
shminfo
->
shmaddr
=
(
char
*
)
shmat
(
shminfo
->
shmid
,
0
,
0
);
shminfo
->
readOnly
=
False
;
if
(
shminfo
->
shmaddr
!=
(
char
*
)
-
1
)
{
shm_error
=
False
;
X_handler
=
XSetErrorHandler
(
shm_errhandler
);
XShmAttach
(
renderdata
->
display
,
shminfo
);
XSync
(
renderdata
->
display
,
False
);
XSetErrorHandler
(
X_handler
);
if
(
shm_error
)
{
shmdt
(
shminfo
->
shmaddr
);
}
}
shmctl
(
shminfo
->
shmid
,
IPC_RMID
,
NULL
);
}
}
if
(
!
shm_error
)
{
data
->
pixels
=
shminfo
->
shmaddr
;
data
->
image
=
XShmCreateImage
(
renderdata
->
display
,
render
data
->
visual
,
renderdata
->
depth
,
ZPixmap
,
shminfo
->
shmaddr
,
XShmCreateImage
(
renderdata
->
display
,
data
->
visual
,
data
->
depth
,
ZPixmap
,
NULL
,
shminfo
,
texture
->
w
,
texture
->
h
);
if
(
!
data
->
image
)
{
XShmDetach
(
renderdata
->
display
,
shminfo
);
XSync
(
renderdata
->
display
,
False
);
shmdt
(
shminfo
->
shmaddr
);
shm_error
=
True
;
if
(
data
->
image
)
{
shminfo
->
shmid
=
shmget
(
IPC_PRIVATE
,
texture
->
h
*
data
->
image
->
bytes_per_line
,
IPC_CREAT
|
0777
);
if
(
shminfo
->
shmid
>=
0
)
{
shminfo
->
shmaddr
=
(
char
*
)
shmat
(
shminfo
->
shmid
,
0
,
0
);
shminfo
->
readOnly
=
False
;
if
(
shminfo
->
shmaddr
!=
(
char
*
)
-
1
)
{
shm_error
=
False
;
X_handler
=
XSetErrorHandler
(
shm_errhandler
);
XShmAttach
(
renderdata
->
display
,
shminfo
);
XSync
(
renderdata
->
display
,
False
);
XSetErrorHandler
(
X_handler
);
if
(
shm_error
)
{
XShmDetach
(
renderdata
->
display
,
shminfo
);
shmdt
(
shminfo
->
shmaddr
);
XDestroyImage
(
data
->
image
);
XSync
(
renderdata
->
display
,
False
);
}
else
{
data
->
pixels
=
data
->
image
->
data
=
shminfo
->
shmaddr
;
shmctl
(
shminfo
->
shmid
,
IPC_RMID
,
NULL
);
data
->
pixmap
=
XCreatePixmap
(
renderdata
->
display
,
renderdata
->
xwindow
,
texture
->
w
,
texture
->
h
,
data
->
depth
);
if
(
!
data
->
pixmap
)
{
SDL_SetError
(
"XCreatePixmap() failed"
);
return
-
1
;
}
}
}
}
}
}
if
(
shm_error
)
{
...
...
@@ -403,47 +914,102 @@ X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
if
(
!
data
->
image
)
#endif
/* not NO_SHARED_MEMORY */
{
data
->
pixels
=
SDL_malloc
(
texture
->
h
*
data
->
pitch
);
if
(
!
data
->
pixels
)
{
X11_DestroyTexture
(
renderer
,
texture
);
SDL_OutOfMemory
();
return
-
1
;
}
data
->
image
=
XCreateImage
(
renderdata
->
display
,
render
data
->
visual
,
renderdata
->
depth
,
ZPixmap
,
0
,
data
->
pixels
,
XCreateImage
(
renderdata
->
display
,
data
->
visual
,
data
->
depth
,
ZPixmap
,
0
,
NULL
,
texture
->
w
,
texture
->
h
,
SDL_BYTESPERPIXEL
(
data
->
format
)
*
8
,
data
->
pitch
);
0
);
if
(
!
data
->
image
)
{
X11_DestroyTexture
(
renderer
,
texture
);
SDL_SetError
(
"XCreateImage() failed"
);
return
-
1
;
}
data
->
pixels
=
SDL_malloc
(
texture
->
h
*
data
->
image
->
bytes_per_line
);
if
(
!
data
->
pixels
)
{
X11_DestroyTexture
(
renderer
,
texture
);
SDL_OutOfMemory
();
return
-
1
;
}
data
->
image
->
data
=
data
->
pixels
;
data
->
pixmap
=
XCreatePixmap
(
renderdata
->
display
,
renderdata
->
xwindow
,
texture
->
w
,
texture
->
h
,
data
->
depth
);
if
(
data
->
pixmap
==
None
)
{
X11_DestroyTexture
(
renderer
,
texture
);
SDL_SetError
(
"XCreatePixmap() failed"
);
return
-
1
;
}
}
}
else
{
data
->
image
=
XCreateImage
(
renderdata
->
display
,
data
->
visual
,
data
->
depth
,
ZPixmap
,
0
,
NULL
,
texture
->
w
,
texture
->
h
,
SDL_BYTESPERPIXEL
(
data
->
format
)
*
8
,
0
);
if
(
!
data
->
image
)
{
X11_DestroyTexture
(
renderer
,
texture
);
SDL_SetError
(
"XCreateImage() failed"
);
return
-
1
;
}
}
else
{
data
->
pixmap
=
XCreatePixmap
(
renderdata
->
display
,
renderdata
->
xwindow
,
texture
->
w
,
texture
->
h
,
render
data
->
depth
);
texture
->
h
,
data
->
depth
);
if
(
data
->
pixmap
==
None
)
{
X11_DestroyTexture
(
renderer
,
texture
);
SDL_SetError
(
"XCreatePixmap() failed"
);
return
-
1
;
}
}
data
->
image
=
XCreateImage
(
renderdata
->
display
,
renderdata
->
visual
,
renderdata
->
depth
,
ZPixmap
,
0
,
NULL
,
texture
->
w
,
texture
->
h
,
SDL_BYTESPERPIXEL
(
data
->
format
)
*
8
,
data
->
pitch
);
if
(
!
data
->
image
)
{
data
->
pitch
=
data
->
image
->
bytes_per_line
;
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
renderdata
->
use_xrender
)
{
gcv
.
graphics_exposures
=
False
;
data
->
gc
=
XCreateGC
(
renderdata
->
display
,
data
->
pixmap
,
GCGraphicsExposures
,
&
gcv
);
if
(
!
data
->
gc
)
{
SDL_SetError
(
"XCreateGC() failed"
);
return
-
1
;
}
data
->
picture_fmt
=
PixelFormatEnumToXRenderPictFormat
(
renderer
,
texture
->
format
);
if
(
data
->
picture_fmt
==
NULL
)
{
X11_DestroyTexture
(
renderer
,
texture
);
SDL_SetError
(
"
XCreateImage() failed
"
);
SDL_SetError
(
"
Texture format not supported by driver
"
);
return
-
1
;
}
data
->
picture
=
XRenderCreatePicture
(
renderdata
->
display
,
data
->
pixmap
,
data
->
picture_fmt
,
0
,
NULL
);
if
(
!
data
->
picture
)
{
X11_DestroyTexture
(
renderer
,
texture
);
SDL_SetError
(
"XRenderCreatePicture() failed"
);
return
-
1
;
}
data
->
modulated_pixmap
=
XCreatePixmap
(
renderdata
->
display
,
renderdata
->
xwindow
,
texture
->
w
,
texture
->
h
,
data
->
depth
);
if
(
!
data
->
modulated_pixmap
)
{
X11_DestroyTexture
(
renderer
,
texture
);
SDL_SetError
(
"XCreatePixmap() failed"
);
return
-
1
;
}
data
->
modulated_picture
=
XRenderCreatePicture
(
renderdata
->
display
,
data
->
modulated_pixmap
,
data
->
picture_fmt
,
0
,
NULL
);
if
(
!
data
->
modulated_picture
)
{
X11_DestroyTexture
(
renderer
,
texture
);
SDL_SetError
(
"XRenderCreatePicture() failed"
);
return
-
1
;
}
texture
->
blendMode
=
SDL_BLENDMODE_NONE
;
data
->
blend_op
=
PictOpSrc
;
}
#endif
return
0
;
}
...
...
@@ -462,15 +1028,107 @@ X11_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture,
}
}
static
int
X11_SetTextureRGBAMod
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
)
{
X11_TextureData
*
data
=
(
X11_TextureData
*
)
texture
->
driverdata
;
X11_RenderData
*
renderdata
=
(
X11_RenderData
*
)
renderer
->
driverdata
;
if
(
renderdata
->
use_xrender
)
{
Uint8
r
=
0xFF
,
g
=
0xFF
,
b
=
0xFF
,
a
=
0xFF
;
/* Check if alpha modulation is required. */
if
(
texture
->
modMode
&
SDL_TEXTUREMODULATE_ALPHA
)
{
a
=
texture
->
a
;
}
/* Check if color modulation is required. */
if
(
texture
->
modMode
&
SDL_TEXTUREMODULATE_COLOR
)
{
r
=
texture
->
r
;
g
=
texture
->
g
;
b
=
texture
->
b
;
}
/* We can save some labour if no modulation is required. */
if
(
texture
->
modMode
!=
SDL_TEXTUREMODULATE_NONE
)
{
XRenderColor
mod_color
=
SDLColorToXRenderColor
(
r
,
g
,
b
,
a
);
XRenderFillRectangle
(
renderdata
->
display
,
PictOpSrc
,
renderdata
->
brush_pict
,
&
mod_color
,
0
,
0
,
1
,
1
);
}
/* We can save some labour dealing with component alpha
* if color modulation is not required. */
XRenderPictureAttributes
attr
;
if
(
texture
->
modMode
&
SDL_TEXTUREMODULATE_COLOR
)
{
attr
.
component_alpha
=
True
;
XRenderChangePicture
(
renderdata
->
display
,
renderdata
->
brush_pict
,
CPComponentAlpha
,
&
attr
);
}
/* Again none of this is necessary is no modulation
* is required. */
if
(
texture
->
modMode
!=
SDL_TEXTUREMODULATE_NONE
)
{
XRenderComposite
(
renderdata
->
display
,
PictOpSrc
,
data
->
picture
,
renderdata
->
brush_pict
,
data
->
modulated_picture
,
0
,
0
,
0
,
0
,
0
,
0
,
texture
->
w
,
texture
->
h
);
}
/* We only need to reset the component alpha
* attribute if color modulation is required. */
if
(
texture
->
modMode
&
SDL_TEXTUREMODULATE_COLOR
)
{
attr
.
component_alpha
=
False
;
XRenderChangePicture
(
renderdata
->
display
,
renderdata
->
brush_pict
,
CPComponentAlpha
,
&
attr
);
}
return
0
;
}
else
{
SDL_Unsupported
();
return
-
1
;
}
}
static
int
X11_SetTextureBlendMode
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
)
{
X11_TextureData
*
data
=
(
X11_TextureData
*
)
texture
->
driverdata
;
X11_RenderData
*
renderdata
=
(
X11_RenderData
*
)
renderer
->
driverdata
;
switch
(
texture
->
blendMode
)
{
case
SDL_BLENDMODE_NONE
:
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
renderdata
->
use_xrender
)
{
data
->
blend_op
=
PictOpSrc
;
return
0
;
}
case
SDL_BLENDMODE_MOD
:
case
SDL_BLENDMODE_MASK
:
case
SDL_BLENDMODE_BLEND
:
if
(
renderdata
->
use_xrender
)
{
data
->
blend_op
=
PictOpOver
;
return
0
;
}
case
SDL_BLENDMODE_ADD
:
if
(
renderdata
->
use_xrender
)
{
data
->
blend_op
=
PictOpAdd
;
return
0
;
}
#endif
return
0
;
default:
SDL_Unsupported
();
texture
->
blendMode
=
SDL_BLENDMODE_NONE
;
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
renderdata
->
use_xrender
)
{
texture
->
blendMode
=
SDL_BLENDMODE_BLEND
;
data
->
blend_op
=
PictOpOver
;
}
#endif
return
-
1
;
}
}
...
...
@@ -479,6 +1137,7 @@ static int
X11_SetTextureScaleMode
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
)
{
X11_TextureData
*
data
=
(
X11_TextureData
*
)
texture
->
driverdata
;
X11_RenderData
*
renderdata
=
(
X11_RenderData
*
)
renderer
->
driverdata
;
switch
(
texture
->
scaleMode
)
{
case
SDL_TEXTURESCALEMODE_NONE
:
...
...
@@ -488,10 +1147,33 @@ X11_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture)
if
(
data
->
yuv
||
texture
->
access
==
SDL_TEXTUREACCESS_STREAMING
)
{
return
0
;
}
/* Fall through to unsupported case */
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
renderdata
->
use_xrender
)
{
data
->
filter
=
FilterFast
;
return
0
;
}
case
SDL_TEXTURESCALEMODE_SLOW
:
if
(
renderdata
->
use_xrender
)
{
data
->
filter
=
FilterGood
;
return
0
;
}
case
SDL_TEXTURESCALEMODE_BEST
:
if
(
renderdata
->
use_xrender
)
{
data
->
filter
=
FilterBest
;
return
0
;
}
#endif
/* Fall through to unsupported case */
default:
SDL_Unsupported
();
texture
->
scaleMode
=
SDL_TEXTURESCALEMODE_NONE
;
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
renderdata
->
use_xrender
)
{
texture
->
scaleMode
=
SDL_TEXTURESCALEMODE_FAST
;
data
->
filter
=
FilterFast
;
}
else
#endif
texture
->
scaleMode
=
SDL_TEXTURESCALEMODE_NONE
;
return
-
1
;
}
return
0
;
...
...
@@ -532,7 +1214,7 @@ X11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
data
->
image
->
height
=
rect
->
h
;
data
->
image
->
data
=
(
char
*
)
pixels
;
data
->
image
->
bytes_per_line
=
pitch
;
XPutImage
(
renderdata
->
display
,
data
->
pixmap
,
render
data
->
gc
,
XPutImage
(
renderdata
->
display
,
data
->
pixmap
,
data
->
gc
,
data
->
image
,
0
,
0
,
rect
->
x
,
rect
->
y
,
rect
->
w
,
rect
->
h
);
}
return
0
;
...
...
@@ -575,12 +1257,36 @@ X11_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
static
int
X11_SetDrawBlendMode
(
SDL_Renderer
*
renderer
)
{
X11_RenderData
*
data
=
(
X11_RenderData
*
)
renderer
->
driverdata
;
switch
(
renderer
->
blendMode
)
{
case
SDL_BLENDMODE_NONE
:
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
//PictOpSrc
data
->
blend_op
=
PictOpSrc
;
return
0
;
case
SDL_BLENDMODE_MOD
:
case
SDL_BLENDMODE_MASK
:
case
SDL_BLENDMODE_BLEND
:
// PictOpOver
data
->
blend_op
=
PictOpOver
;
return
0
;
case
SDL_BLENDMODE_ADD
:
// PictOpAdd
data
->
blend_op
=
PictOpAdd
;
return
0
;
/* FIXME case SDL_BLENDMODE_MOD: */
#endif
return
0
;
default:
SDL_Unsupported
();
renderer
->
blendMode
=
SDL_BLENDMODE_NONE
;
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
data
->
use_xrender
)
{
renderer
->
blendMode
=
SDL_BLENDMODE_BLEND
;
data
->
blend_op
=
PictOpOver
;
}
else
#endif
{
renderer
->
blendMode
=
SDL_BLENDMODE_NONE
;
}
return
-
1
;
}
}
...
...
@@ -601,16 +1307,35 @@ renderdrawcolor(SDL_Renderer * renderer, int premult)
return
SDL_MapRGBA
(
&
data
->
format
,
r
,
g
,
b
,
a
);
}
static
XRenderColor
xrenderdrawcolor
(
SDL_Renderer
*
renderer
)
{
XRenderColor
xrender_color
;
if
(
renderer
->
blendMode
==
SDL_BLENDMODE_NONE
)
{
xrender_color
=
SDLColorToXRenderColor
(
renderer
->
r
,
renderer
->
g
,
renderer
->
b
,
0xFF
);
}
else
{
xrender_color
=
SDLColorToXRenderColor
(
renderer
->
r
,
renderer
->
g
,
renderer
->
b
,
renderer
->
a
);
}
return
xrender_color
;
}
static
int
X11_RenderDrawPoints
(
SDL_Renderer
*
renderer
,
const
SDL_Point
*
points
,
int
count
)
{
X11_RenderData
*
data
=
(
X11_RenderData
*
)
renderer
->
driverdata
;
SDL_Window
*
window
=
renderer
->
window
;
unsigned
long
foreground
;
XPoint
*
xpoints
,
*
xpoint
;
int
i
,
xcount
;
SDL_Rect
clip
;
clip
.
x
=
0
;
clip
.
y
=
0
;
clip
.
w
=
window
->
w
;
clip
.
h
=
window
->
h
;
if
(
data
->
makedirty
)
{
SDL_Rect
rect
;
...
...
@@ -625,27 +1350,105 @@ X11_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
}
SDL_AddDirtyRect
(
&
data
->
dirty
,
&
rect
);
}
{
xpoint
=
xpoints
=
SDL_stack_alloc
(
XPoint
,
count
);
xcount
=
0
;
for
(
i
=
0
;
i
<
count
;
++
i
)
{
int
x
=
points
[
i
].
x
;
int
y
=
points
[
i
].
y
;
if
(
x
<
0
||
x
>=
window
->
w
||
y
<
0
||
y
>=
window
->
h
)
{
continue
;
}
xpoint
->
x
=
(
short
)
x
;
xpoint
->
y
=
(
short
)
y
;
++
xpoint
;
++
xcount
;
}
#ifdef SDL_VIDEO_DRIVER_X11_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
,
0
);
#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
,
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
,
0xFFFFFFFF
);
XDrawPoints
(
data
->
display
,
data
->
stencil
,
data
->
stencil_gc
,
xpoints
,
xcount
,
CoordModeOrigin
);
#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
}
foreground
=
renderdrawcolor
(
renderer
,
1
);
XSetForeground
(
data
->
display
,
data
->
gc
,
foreground
);
#ifdef SDL_VIDEO_DRIVER_X11_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
;
foreground
=
xrenderdrawcolor
(
renderer
);
xpoint
=
xpoints
=
SDL_stack_alloc
(
XPoint
,
count
);
xcount
=
0
;
for
(
i
=
0
;
i
<
count
;
++
i
)
{
int
x
=
points
[
i
].
x
;
int
y
=
points
[
i
].
y
;
if
(
x
<
0
||
x
>=
window
->
w
||
y
<
0
||
y
>=
window
->
h
)
{
continue
;
XRenderFillRectangle
(
data
->
display
,
PictOpSrc
,
data
->
brush_pict
,
&
foreground
,
0
,
0
,
1
,
1
);
#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
);
}
xpoint
->
x
=
(
short
)
x
;
xpoint
->
y
=
(
short
)
y
;
++
xpoint
;
++
xcount
;
#endif
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
);
#ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
if
(
data
->
use_xdamage
)
{
XFixesSetPictureClipRegion
(
data
->
display
,
data
->
drawable_pict
,
0
,
0
,
None
);
}
#endif
}
if
(
xcount
>
0
)
{
XDrawPoints
(
data
->
display
,
data
->
drawable
,
data
->
gc
,
xpoints
,
xcount
,
CoordModeOrigin
);
else
#endif
{
unsigned
long
foreground
=
renderdrawcolor
(
renderer
,
1
);
XSetForeground
(
data
->
display
,
data
->
gc
,
foreground
);
if
(
xcount
>
0
)
{
XDrawPoints
(
data
->
display
,
data
->
drawable
,
data
->
gc
,
xpoints
,
xcount
,
CoordModeOrigin
);
}
}
SDL_stack_free
(
xpoints
);
return
0
;
...
...
@@ -668,65 +1471,146 @@ X11_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
clip
.
y
=
0
;
clip
.
w
=
window
->
w
;
clip
.
h
=
window
->
h
;
foreground
=
renderdrawcolor
(
renderer
,
1
);
XSetForeground
(
data
->
display
,
data
->
gc
,
foreground
);
xpoint
=
xpoints
=
SDL_stack_alloc
(
XPoint
,
count
);
xcount
=
0
;
minx
=
INT_MAX
;
miny
=
INT_MAX
;
maxx
=
INT_MIN
;
maxy
=
INT_MIN
;
for
(
i
=
0
;
i
<
count
;
++
i
)
{
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
(
y
<
miny
)
{
miny
=
y
;
}
else
if
(
y
>
maxy
)
{
maxy
=
y
;
}
xpoint
->
x
=
(
short
)
x
;
xpoint
->
y
=
(
short
)
y
;
++
xpoint
;
++
xcount
;
continue
;
{
Pixmap
drawable
;
GC
gc
;
#ifdef SDL_VIDEO_DRIVER_X11_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
;
gc
=
data
->
stencil_gc
;
XSetForeground
(
data
->
display
,
data
->
stencil_gc
,
0
);
#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
,
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
,
0xFFFFFFFF
);
}
else
#endif
{
drawable
=
data
->
drawable
;
gc
=
data
->
gc
;
}
/* 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
;
foreground
=
renderdrawcolor
(
renderer
,
1
);
XSetForeground
(
data
->
display
,
data
->
gc
,
foreground
);
xpoint
=
xpoints
=
SDL_stack_alloc
(
XPoint
,
count
);
xcount
=
0
;
minx
=
INT_MAX
;
miny
=
INT_MAX
;
maxx
=
INT_MIN
;
maxy
=
INT_MIN
;
for
(
i
=
0
;
i
<
count
;
++
i
)
{
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
(
y
2
<
miny
)
{
miny
=
y
2
;
}
else
if
(
y
2
>
maxy
)
{
maxy
=
y
2
;
if
(
y
<
miny
)
{
miny
=
y
;
}
else
if
(
y
>
maxy
)
{
maxy
=
y
;
}
xpoint
->
x
=
(
short
)
x
2
;
xpoint
->
y
=
(
short
)
y
2
;
xpoint
->
x
=
(
short
)
x
;
xpoint
->
y
=
(
short
)
y
;
++
xpoint
;
++
xcount
;
continue
;
}
/* 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
;
}
}
XDrawLines
(
data
->
display
,
data
->
drawable
,
data
->
gc
,
xpoints
,
xcount
,
CoordModeOrigin
);
}
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
,
d
ata
->
drawable
,
data
->
gc
,
x2
,
y2
);
XDrawPoint
(
data
->
display
,
d
rawable
,
gc
,
x2
,
y2
);
}
if
(
data
->
makedirty
)
{
SDL_Rect
rect
;
...
...
@@ -737,54 +1621,37 @@ X11_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
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
,
data
->
drawable
,
data
->
gc
,
xpoints
,
xcount
,
CoordModeOrigin
);
if
(
xpoints
[
0
].
x
!=
x2
||
xpoints
[
0
].
y
!=
y2
)
{
XDrawPoint
(
data
->
display
,
data
->
drawable
,
data
->
gc
,
x2
,
y2
);
}
if
(
data
->
makedirty
)
{
SDL_Rect
rect
;
#ifdef SDL_VIDEO_DRIVER_X11_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
);
XRenderFillRectangle
(
data
->
display
,
PictOpSrc
,
data
->
brush_pict
,
&
xrforeground
,
0
,
0
,
1
,
1
);
#ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
if
(
data
->
use_xdamage
)
{
XDamageSubtract
(
data
->
display
,
data
->
stencil_damage
,
None
,
data
->
stencil_parts
);
rect
.
x
=
minx
;
rect
.
y
=
miny
;
rect
.
w
=
(
maxx
-
minx
)
+
1
;
rect
.
h
=
(
maxy
-
miny
)
+
1
;
SDL_AddDirtyRect
(
&
data
->
dirty
,
&
rect
);
XFixesSetPictureClipRegion
(
data
->
display
,
data
->
drawable_pict
,
0
,
0
,
data
->
stencil_parts
);
}
#endif
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
);
#ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
if
(
data
->
use_xdamage
)
XFixesSetPictureClipRegion
(
data
->
display
,
data
->
drawable_pict
,
0
,
0
,
None
);
#endif
}
#endif
SDL_stack_free
(
xpoints
);
return
0
;
...
...
@@ -796,41 +1663,104 @@ X11_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
X11_RenderData
*
data
=
(
X11_RenderData
*
)
renderer
->
driverdata
;
SDL_Window
*
window
=
renderer
->
window
;
SDL_Rect
clip
,
rect
;
unsigned
long
foreground
;
XRectangle
*
xrects
,
*
xrect
;
int
i
,
xcount
;
XRectangle
*
xrects
,
*
xrect
;
xrect
=
xrects
=
SDL_stack_alloc
(
XRectangle
,
count
);
xcount
=
0
;
clip
.
x
=
0
;
clip
.
y
=
0
;
clip
.
w
=
window
->
w
;
clip
.
h
=
window
->
h
;
{
foreground
=
renderdrawcolor
(
renderer
,
1
);
XSetForeground
(
data
->
display
,
data
->
gc
,
foreground
);
for
(
i
=
0
;
i
<
count
;
++
i
)
{
if
(
!
SDL_IntersectRect
(
rects
[
i
],
&
clip
,
&
rect
))
{
continue
;
}
xrect
=
xrects
=
SDL_stack_alloc
(
XRectangle
,
count
);
xcount
=
0
;
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
-
1
;
xrect
->
height
=
(
unsigned
short
)
rect
.
h
-
1
;
++
xrect
;
++
xcount
;
if
(
data
->
makedirty
)
{
SDL_AddDirtyRect
(
&
data
->
dirty
,
&
rect
);
}
}
#ifdef SDL_VIDEO_DRIVER_X11_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
,
0
);
#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
,
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
,
0xFFFFFFFF
);
xrect
->
x
=
(
short
)
rect
.
x
;
xrect
->
y
=
(
short
)
rect
.
y
;
xrect
->
width
=
(
unsigned
short
)
rect
.
w
;
xrect
->
height
=
(
unsigned
short
)
rect
.
h
;
++
xrect
;
++
xcount
;
XDrawRectangles
(
data
->
display
,
data
->
stencil
,
data
->
stencil_gc
,
xrects
,
xcount
);
if
(
data
->
makedirty
)
{
SDL_AddDirtyRect
(
&
data
->
dirty
,
&
rect
);
#ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
if
(
data
->
use_xdamage
)
XDamageSubtract
(
data
->
display
,
data
->
stencil_damage
,
None
,
data
->
stencil_parts
);
#endif
}
#endif
}
if
(
xcount
>
0
)
{
XDrawRectangles
(
data
->
display
,
data
->
drawable
,
data
->
gc
,
xrects
,
xcount
);
#ifdef SDL_VIDEO_DRIVER_X11_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
;
foreground
=
xrenderdrawcolor
(
renderer
);
XRenderFillRectangle
(
data
->
display
,
PictOpSrc
,
data
->
brush_pict
,
&
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
,
data
->
stencil_pict
,
data
->
drawable_pict
,
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
}
SDL_stack_free
(
xpoints
);
else
#endif
{
unsigned
long
foreground
;
foreground
=
renderdrawcolor
(
renderer
,
1
);
XSetForeground
(
data
->
display
,
data
->
gc
,
foreground
);
if
(
xcount
>
0
)
{
XDrawRectangles
(
data
->
display
,
data
->
drawable
,
data
->
gc
,
xrects
,
xcount
);
}
}
SDL_stack_free
(
xrects
);
return
0
;
}
...
...
@@ -841,18 +1771,14 @@ X11_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
X11_RenderData
*
data
=
(
X11_RenderData
*
)
renderer
->
driverdata
;
SDL_Window
*
window
=
renderer
->
window
;
SDL_Rect
clip
,
rect
;
unsigned
long
foreground
;
XRectangle
*
xrects
,
*
xrect
;
int
i
,
xcount
;
clip
.
x
=
0
;
clip
.
y
=
0
;
clip
.
w
=
window
->
w
;
clip
.
h
=
window
->
h
;
foreground
=
renderdrawcolor
(
renderer
,
1
);
XSetForeground
(
data
->
display
,
data
->
gc
,
foreground
);
int
i
,
xcount
;
XRectangle
*
xrects
,
*
xrect
;
xrect
=
xrects
=
SDL_stack_alloc
(
XRectangle
,
count
);
xcount
=
0
;
for
(
i
=
0
;
i
<
count
;
++
i
)
{
...
...
@@ -871,12 +1797,34 @@ X11_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
SDL_AddDirtyRect
(
&
data
->
dirty
,
&
rect
);
}
}
if
(
xcount
>
0
)
{
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
data
->
use_xrender
)
{
XRenderColor
foreground
;
foreground
=
xrenderdrawcolor
(
renderer
);
if
(
xcount
==
1
)
{
XRenderFillRectangle
(
data
->
display
,
data
->
blend_op
,
data
->
drawable_pict
,
&
foreground
,
xrects
[
0
].
x
,
xrects
[
0
].
y
,
xrects
[
0
].
width
,
xrects
[
0
].
height
);
}
else
if
(
xcount
>
1
)
{
XRenderFillRectangles
(
data
->
display
,
data
->
blend_op
,
data
->
drawable_pict
,
&
foreground
,
xrects
,
xcount
);
}
}
else
#endif
{
unsigned
long
foreground
;
foreground
=
renderdrawcolor
(
renderer
,
1
);
XSetForeground
(
data
->
display
,
data
->
gc
,
foreground
);
XFillRectangles
(
data
->
display
,
data
->
drawable
,
data
->
gc
,
xrects
,
xcount
);
}
SDL_stack_free
(
xpoints
);
SDL_stack_free
(
xrects
);
return
0
;
}
...
...
@@ -890,103 +1838,206 @@ X11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
if
(
data
->
makedirty
)
{
SDL_AddDirtyRect
(
&
data
->
dirty
,
dstrect
);
}
if
(
srcrect
->
w
==
dstrect
->
w
&&
srcrect
->
h
==
dstrect
->
h
)
{
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
data
->
use_xrender
)
{
if
(
texture
->
access
==
SDL_TEXTUREACCESS_STREAMING
)
{
#ifndef NO_SHARED_MEMORY
if
(
texturedata
->
shminfo
.
shmaddr
)
{
XShmPutImage
(
data
->
display
,
data
->
drawable
,
data
->
gc
,
texturedata
->
image
,
srcrect
->
x
,
srcrect
->
y
,
dstrect
->
x
,
dstrect
->
y
,
srcrect
->
w
,
srcrect
->
h
,
False
);
}
else
#endif
if
(
texturedata
->
pixels
)
{
XPutImage
(
data
->
display
,
data
->
drawable
,
data
->
gc
,
texturedata
->
image
,
srcrect
->
x
,
srcrect
->
y
,
dstrect
->
x
,
dstrect
->
y
,
srcrect
->
w
,
srcrect
->
h
);
}
else
{
XCopyArea
(
data
->
display
,
texturedata
->
pixmap
,
data
->
drawable
,
data
->
gc
,
srcrect
->
x
,
srcrect
->
y
,
dstrect
->
w
,
dstrect
->
h
,
dstrect
->
x
,
dstrect
->
y
);
if
(
texturedata
->
shminfo
.
shmaddr
)
{
XShmPutImage
(
data
->
display
,
texturedata
->
pixmap
,
texturedata
->
gc
,
texturedata
->
image
,
srcrect
->
x
,
srcrect
->
y
,
srcrect
->
x
,
srcrect
->
y
,
srcrect
->
w
,
srcrect
->
h
,
False
);
}
else
#endif
if
(
texturedata
->
pixels
)
{
XPutImage
(
data
->
display
,
texturedata
->
pixmap
,
texturedata
->
gc
,
texturedata
->
image
,
srcrect
->
x
,
srcrect
->
y
,
srcrect
->
x
,
srcrect
->
y
,
srcrect
->
w
,
srcrect
->
h
);
}
XSync
(
data
->
display
,
False
);
}
}
else
if
(
texturedata
->
yuv
||
texture
->
access
==
SDL_TEXTUREACCESS_STREAMING
)
{
SDL_Surface
src
,
dst
;
SDL_PixelFormat
fmt
;
SDL_Rect
rect
;
XImage
*
image
=
texturedata
->
scaling_image
;
Picture
src
,
mask
;
XRenderPictureAttributes
attr
;
const
SDL_Rect
*
mrect
;
if
(
!
image
)
{
void
*
pixels
;
int
pitch
;
if
(
texture
->
modMode
==
SDL_TEXTUREMODULATE_NONE
)
{
src
=
texturedata
->
picture
;
}
else
{
src
=
texturedata
->
modulated_picture
;
}
pitch
=
dstrect
->
w
*
SDL_BYTESPERPIXEL
(
texturedata
->
format
);
pixels
=
SDL_malloc
(
dstrect
->
h
*
pitch
);
if
(
!
pixels
)
{
SDL_OutOfMemory
();
return
-
1
;
}
if
(
texture
->
blendMode
==
SDL_BLENDMODE_NONE
)
{
mask
=
None
;
mrect
=
srcrect
;
}
else
if
(
texture
->
blendMode
==
SDL_BLENDMODE_MOD
)
{
mask
=
data
->
stencil_pict
;
mrect
=
dstrect
;
}
else
{
mask
=
texturedata
->
picture
;
mrect
=
srcrect
;
}
image
=
XCreateImage
(
data
->
display
,
data
->
visual
,
data
->
depth
,
ZPixmap
,
0
,
pixels
,
dstrect
->
w
,
dstrect
->
h
,
SDL_BYTESPERPIXEL
(
texturedata
->
format
)
*
8
,
pitch
);
if
(
!
image
)
{
SDL_SetError
(
"XCreateImage() failed"
);
return
-
1
;
if
(
srcrect
->
w
==
dstrect
->
w
&&
srcrect
->
h
==
dstrect
->
h
)
{
if
(
texture
->
blendMode
==
SDL_BLENDMODE_MOD
)
{
XRenderComposite
(
data
->
display
,
PictOpSrc
,
data
->
drawable_pict
,
src
,
data
->
stencil_pict
,
dstrect
->
x
,
dstrect
->
y
,
srcrect
->
x
,
srcrect
->
y
,
dstrect
->
x
,
dstrect
->
y
,
dstrect
->
w
,
dstrect
->
h
);
attr
.
component_alpha
=
True
;
XRenderChangePicture
(
data
->
display
,
data
->
stencil_pict
,
CPComponentAlpha
,
&
attr
);
}
texturedata
->
scaling_image
=
image
;
}
else
if
(
image
->
width
!=
dstrect
->
w
||
image
->
height
!=
dstrect
->
h
||
!
image
->
data
)
{
image
->
width
=
dstrect
->
w
;
image
->
height
=
dstrect
->
h
;
image
->
bytes_per_line
=
image
->
width
*
SDL_BYTESPERPIXEL
(
texturedata
->
format
);
image
->
data
=
(
char
*
)
SDL_realloc
(
image
->
data
,
image
->
height
*
image
->
bytes_per_line
);
if
(
!
image
->
data
)
{
SDL_OutOfMemory
();
return
-
1
;
XRenderComposite
(
data
->
display
,
texturedata
->
blend_op
,
src
,
mask
,
data
->
drawable_pict
,
srcrect
->
x
,
srcrect
->
y
,
mrect
->
x
,
mrect
->
y
,
dstrect
->
x
,
dstrect
->
y
,
dstrect
->
w
,
dstrect
->
h
);
}
else
{
double
xscale
=
((
double
)
dstrect
->
w
)
/
srcrect
->
w
;
double
yscale
=
((
double
)
dstrect
->
h
)
/
srcrect
->
h
;
XTransform
xform
=
{{
{
XDoubleToFixed
(
xscale
),
XDoubleToFixed
(
0
),
XDoubleToFixed
(
0
)},
{
XDoubleToFixed
(
0
),
XDoubleToFixed
(
yscale
),
XDoubleToFixed
(
0
)},
{
XDoubleToFixed
(
0
),
XDoubleToFixed
(
0
),
XDoubleToFixed
(
xscale
*
yscale
)}}};
XRenderSetPictureTransform
(
data
->
display
,
src
,
&
xform
);
if
(
texture
->
blendMode
==
SDL_BLENDMODE_MOD
)
{
XRenderComposite
(
data
->
display
,
PictOpSrc
,
data
->
drawable_pict
,
src
,
data
->
stencil_pict
,
dstrect
->
x
,
dstrect
->
y
,
srcrect
->
x
,
srcrect
->
y
,
dstrect
->
x
,
dstrect
->
y
,
dstrect
->
w
,
dstrect
->
h
);
attr
.
component_alpha
=
True
;
XRenderChangePicture
(
data
->
display
,
data
->
stencil_pict
,
CPComponentAlpha
,
&
attr
);
}
}
/* Set up fake surfaces for SDL_SoftStretch() */
SDL_zero
(
src
);
src
.
format
=
&
fmt
;
src
.
w
=
texture
->
w
;
src
.
h
=
texture
->
h
;
XRenderSetPictureFilter
(
data
->
display
,
src
,
texturedata
->
filter
,
0
,
0
);
XRenderComposite
(
data
->
display
,
texturedata
->
blend_op
,
src
,
mask
,
data
->
drawable_pict
,
srcrect
->
x
,
srcrect
->
y
,
mrect
->
x
,
mrect
->
y
,
dstrect
->
x
,
dstrect
->
y
,
dstrect
->
w
,
dstrect
->
h
);
XTransform
identity
=
{{
{
XDoubleToFixed
(
1
),
XDoubleToFixed
(
0
),
XDoubleToFixed
(
0
)},
{
XDoubleToFixed
(
0
),
XDoubleToFixed
(
1
),
XDoubleToFixed
(
0
)},
{
XDoubleToFixed
(
0
),
XDoubleToFixed
(
0
),
XDoubleToFixed
(
1
)}}};
XRenderSetPictureTransform
(
data
->
display
,
src
,
&
identity
);
}
if
(
renderer
->
blendMode
==
SDL_BLENDMODE_MOD
)
{
attr
.
component_alpha
=
False
;
XRenderChangePicture
(
data
->
display
,
data
->
stencil_pict
,
CPComponentAlpha
,
&
attr
);
}
}
else
#endif
{
if
(
srcrect
->
w
==
dstrect
->
w
&&
srcrect
->
h
==
dstrect
->
h
)
{
#ifndef NO_SHARED_MEMORY
if
(
texturedata
->
shminfo
.
shmaddr
)
{
src
.
pixels
=
texturedata
->
shminfo
.
shmaddr
;
}
else
if
(
texturedata
->
shminfo
.
shmaddr
)
{
XShmPutImage
(
data
->
display
,
data
->
drawable
,
data
->
gc
,
texturedata
->
image
,
srcrect
->
x
,
srcrect
->
y
,
dstrect
->
x
,
dstrect
->
y
,
srcrect
->
w
,
srcrect
->
h
,
False
);
}
else
#endif
src
.
pixels
=
texturedata
->
pixels
;
src
.
pitch
=
texturedata
->
pitch
;
if
(
texturedata
->
pixels
)
{
XPutImage
(
data
->
display
,
data
->
drawable
,
data
->
gc
,
texturedata
->
image
,
srcrect
->
x
,
srcrect
->
y
,
dstrect
->
x
,
dstrect
->
y
,
srcrect
->
w
,
srcrect
->
h
);
}
else
{
XCopyArea
(
data
->
display
,
texturedata
->
pixmap
,
data
->
drawable
,
data
->
gc
,
srcrect
->
x
,
srcrect
->
y
,
dstrect
->
w
,
dstrect
->
h
,
dstrect
->
x
,
dstrect
->
y
);
}
}
else
if
(
texturedata
->
yuv
||
texture
->
access
==
SDL_TEXTUREACCESS_STREAMING
)
{
SDL_Surface
src
,
dst
;
SDL_PixelFormat
fmt
;
SDL_Rect
rect
;
XImage
*
image
=
texturedata
->
scaling_image
;
SDL_zero
(
dst
);
dst
.
format
=
&
fmt
;
dst
.
w
=
image
->
width
;
dst
.
h
=
image
->
height
;
dst
.
pixels
=
image
->
data
;
dst
.
pitch
=
image
->
bytes_per_line
;
if
(
!
image
)
{
void
*
pixels
;
int
pitch
;
pitch
=
dstrect
->
w
*
SDL_BYTESPERPIXEL
(
texturedata
->
format
);
pixels
=
SDL_malloc
(
dstrect
->
h
*
pitch
);
if
(
!
pixels
)
{
SDL_OutOfMemory
();
return
-
1
;
}
fmt
.
BytesPerPixel
=
SDL_BYTESPERPIXEL
(
texturedata
->
format
);
image
=
XCreateImage
(
data
->
display
,
data
->
visual
,
data
->
depth
,
ZPixmap
,
0
,
pixels
,
dstrect
->
w
,
dstrect
->
h
,
SDL_BYTESPERPIXEL
(
texturedata
->
format
)
*
8
,
pitch
);
if
(
!
image
)
{
SDL_SetError
(
"XCreateImage() failed"
);
return
-
1
;
}
texturedata
->
scaling_image
=
image
;
}
else
if
(
image
->
width
!=
dstrect
->
w
||
image
->
height
!=
dstrect
->
h
||
!
image
->
data
)
{
image
->
width
=
dstrect
->
w
;
image
->
height
=
dstrect
->
h
;
image
->
bytes_per_line
=
image
->
width
*
SDL_BYTESPERPIXEL
(
texturedata
->
format
);
image
->
data
=
(
char
*
)
SDL_realloc
(
image
->
data
,
image
->
height
*
image
->
bytes_per_line
);
if
(
!
image
->
data
)
{
SDL_OutOfMemory
();
return
-
1
;
}
}
rect
.
x
=
0
;
rect
.
y
=
0
;
rect
.
w
=
dstrect
->
w
;
rect
.
h
=
dstrect
->
h
;
if
(
SDL_SoftStretch
(
&
src
,
srcrect
,
&
dst
,
&
rect
)
<
0
)
{
return
-
1
;
/* Set up fake surfaces for SDL_SoftStretch() */
SDL_zero
(
src
);
src
.
format
=
&
fmt
;
src
.
w
=
texture
->
w
;
src
.
h
=
texture
->
h
;
#ifndef NO_SHARED_MEMORY
if
(
texturedata
->
shminfo
.
shmaddr
)
{
src
.
pixels
=
texturedata
->
shminfo
.
shmaddr
;
}
else
#endif
src
.
pixels
=
texturedata
->
pixels
;
src
.
pitch
=
texturedata
->
pitch
;
SDL_zero
(
dst
);
dst
.
format
=
&
fmt
;
dst
.
w
=
image
->
width
;
dst
.
h
=
image
->
height
;
dst
.
pixels
=
image
->
data
;
dst
.
pitch
=
image
->
bytes_per_line
;
fmt
.
BytesPerPixel
=
SDL_BYTESPERPIXEL
(
texturedata
->
format
);
rect
.
x
=
0
;
rect
.
y
=
0
;
rect
.
w
=
dstrect
->
w
;
rect
.
h
=
dstrect
->
h
;
if
(
SDL_SoftStretch
(
&
src
,
srcrect
,
&
dst
,
&
rect
)
<
0
)
{
return
-
1
;
}
XPutImage
(
data
->
display
,
data
->
drawable
,
data
->
gc
,
image
,
0
,
0
,
dstrect
->
x
,
dstrect
->
y
,
dstrect
->
w
,
dstrect
->
h
);
}
else
{
XCopyArea
(
data
->
display
,
texturedata
->
pixmap
,
data
->
drawable
,
data
->
gc
,
srcrect
->
x
,
srcrect
->
y
,
dstrect
->
w
,
dstrect
->
h
,
srcrect
->
x
,
srcrect
->
y
);
}
XPutImage
(
data
->
display
,
data
->
drawable
,
data
->
gc
,
image
,
0
,
0
,
dstrect
->
x
,
dstrect
->
y
,
dstrect
->
w
,
dstrect
->
h
);
}
else
{
XCopyArea
(
data
->
display
,
texturedata
->
pixmap
,
data
->
drawable
,
data
->
gc
,
srcrect
->
x
,
srcrect
->
y
,
dstrect
->
w
,
dstrect
->
h
,
srcrect
->
x
,
srcrect
->
y
);
}
return
0
;
}
...
...
@@ -1065,9 +2116,26 @@ X11_RenderPresent(SDL_Renderer * renderer)
if
(
!
(
renderer
->
info
.
flags
&
SDL_RENDERER_SINGLEBUFFER
))
{
for
(
dirty
=
data
->
dirty
.
list
;
dirty
;
dirty
=
dirty
->
next
)
{
const
SDL_Rect
*
rect
=
&
dirty
->
rect
;
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
data
->
use_xrender
)
{
XRenderComposite
(
data
->
display
,
data
->
blend_op
,
data
->
drawable_pict
,
None
,
data
->
xwindow_pict
,
rect
->
x
,
rect
->
y
,
0
,
0
,
rect
->
x
,
rect
->
y
,
rect
->
w
,
rect
->
h
);
}
else
#endif
{
XCopyArea
(
data
->
display
,
data
->
drawable
,
data
->
xwindow
,
data
->
gc
,
rect
->
x
,
rect
->
y
,
rect
->
w
,
rect
->
h
,
rect
->
x
,
rect
->
y
);
}
}
SDL_ClearDirtyRects
(
&
data
->
dirty
);
}
...
...
@@ -1077,9 +2145,15 @@ X11_RenderPresent(SDL_Renderer * renderer)
if
(
renderer
->
info
.
flags
&
SDL_RENDERER_PRESENTFLIP2
)
{
data
->
current_pixmap
=
(
data
->
current_pixmap
+
1
)
%
2
;
data
->
drawable
=
data
->
pixmaps
[
data
->
current_pixmap
];
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
data
->
drawable_pict
=
data
->
pixmap_picts
[
data
->
current_pixmap
];
#endif
}
else
if
(
renderer
->
info
.
flags
&
SDL_RENDERER_PRESENTFLIP3
)
{
data
->
current_pixmap
=
(
data
->
current_pixmap
+
1
)
%
3
;
data
->
drawable
=
data
->
pixmaps
[
data
->
current_pixmap
];
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
data
->
drawable_pict
=
data
->
pixmap_picts
[
data
->
current_pixmap
];
#endif
}
}
...
...
@@ -1109,6 +2183,19 @@ X11_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
shmdt
(
data
->
shminfo
.
shmaddr
);
data
->
pixels
=
NULL
;
}
#endif
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
renderdata
->
use_xrender
)
{
if
(
data
->
picture
)
{
XRenderFreePicture
(
renderdata
->
display
,
data
->
picture
);
}
if
(
data
->
modulated_pixmap
)
{
XFreePixmap
(
renderdata
->
display
,
data
->
modulated_pixmap
);
}
if
(
data
->
modulated_picture
)
{
XRenderFreePicture
(
renderdata
->
display
,
data
->
modulated_picture
);
}
}
#endif
if
(
data
->
scaling_image
)
{
SDL_free
(
data
->
scaling_image
->
data
);
...
...
@@ -1133,10 +2220,36 @@ X11_DestroyRenderer(SDL_Renderer * renderer)
if
(
data
->
pixmaps
[
i
]
!=
None
)
{
XFreePixmap
(
data
->
display
,
data
->
pixmaps
[
i
]);
}
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
data
->
use_xrender
&&
data
->
pixmap_picts
[
i
])
{
XRenderFreePicture
(
data
->
display
,
data
->
pixmap_picts
[
i
]);
}
#endif
}
if
(
data
->
gc
)
{
XFreeGC
(
data
->
display
,
data
->
gc
);
}
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
data
->
use_xrender
)
{
if
(
data
->
stencil_gc
)
{
XFreeGC
(
data
->
display
,
data
->
stencil_gc
);
}
if
(
data
->
stencil
)
{
XFreePixmap
(
data
->
display
,
data
->
stencil
);
}
if
(
data
->
stencil_pict
)
{
XRenderFreePicture
(
data
->
display
,
data
->
stencil_pict
);
}
if
(
data
->
xwindow_pict
)
{
XRenderFreePicture
(
data
->
display
,
data
->
xwindow_pict
);
}
#ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
if
(
data
->
use_xdamage
&&
data
->
stencil_damage
)
{
XDamageDestroy
(
data
->
display
,
data
->
stencil_damage
);
}
#endif
}
#endif
SDL_FreeDirtyRects
(
&
data
->
dirty
);
SDL_free
(
data
);
}
...
...
src/video/x11/SDL_x11sym.h
View file @
d8e7cebd
...
...
@@ -156,6 +156,10 @@ SDL_X11_SYM(SDL_X11_XSynchronizeRetType,XSynchronize,(Display* a,Bool b),(a,b),r
SDL_X11_SYM
(
SDL_X11_XESetWireToEventRetType
,
XESetWireToEvent
,(
Display
*
a
,
int
b
,
SDL_X11_XESetWireToEventRetType
c
),(
a
,
b
,
c
),
return
)
SDL_X11_SYM
(
SDL_X11_XESetEventToWireRetType
,
XESetEventToWire
,(
Display
*
a
,
int
b
,
SDL_X11_XESetEventToWireRetType
c
),(
a
,
b
,
c
),
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
,
XSetBackground
,(
Display
*
dpy
,
GC
gc
,
unsigned
long
background
),(
dpy
,
gc
,
background
),
return
)
SDL_X11_SYM
(
Status
,
XInitImage
,(
XImage
*
image
),(
image
),
return
)
SDL_X11_SYM
(
int
,
XSetClipMask
,(
Display
*
dpy
,
GC
gc
,
Pixmap
pixmap
),(
dpy
,
gc
,
pixmap
),
return
)
#if NeedWidePrototypes
SDL_X11_SYM
(
KeySym
,
XKeycodeToKeysym
,(
Display
*
a
,
unsigned
int
b
,
int
c
),(
a
,
b
,
c
),
return
)
...
...
@@ -182,6 +186,7 @@ SDL_X11_SYM(Status,XShmAttach,(Display* a,XShmSegmentInfo* b),(a,b),return)
SDL_X11_SYM
(
Status
,
XShmDetach
,(
Display
*
a
,
XShmSegmentInfo
*
b
),(
a
,
b
),
return
)
SDL_X11_SYM
(
Status
,
XShmPutImage
,(
Display
*
a
,
Drawable
b
,
GC
c
,
XImage
*
d
,
int
e
,
int
f
,
int
g
,
int
h
,
unsigned
int
i
,
unsigned
int
j
,
Bool
k
),(
a
,
b
,
c
,
d
,
e
,
f
,
g
,
h
,
i
,
j
,
k
),
return
)
SDL_X11_SYM
(
XImage
*
,
XShmCreateImage
,(
Display
*
a
,
Visual
*
b
,
unsigned
int
c
,
int
d
,
char
*
e
,
XShmSegmentInfo
*
f
,
unsigned
int
g
,
unsigned
int
h
),(
a
,
b
,
c
,
d
,
e
,
f
,
g
,
h
),
return
)
SDL_X11_SYM
(
Pixmap
,
XShmCreatePixmap
,(
Display
*
a
,
Drawable
b
,
char
*
c
,
XShmSegmentInfo
*
d
,
unsigned
int
e
,
unsigned
int
f
,
unsigned
int
g
),(
a
,
b
,
c
,
d
,
e
,
f
,
g
),
return
)
SDL_X11_SYM
(
Bool
,
XShmQueryExtension
,(
Display
*
a
),(
a
),
return
)
#endif
...
...
@@ -237,6 +242,41 @@ SDL_X11_SYM(Status,XScreenSaverQueryVersion,(Display *dpy,int *major_versionp,in
SDL_X11_SYM
(
void
,
XScreenSaverSuspend
,(
Display
*
dpy
,
Bool
suspend
),(
dpy
,
suspend
),
return
)
#endif
/* XRender support */
#if SDL_VIDEO_DRIVER_X11_XRENDER
SDL_X11_MODULE
(
XRENDER
)
SDL_X11_SYM
(
Bool
,
XRenderQueryExtension
,(
Display
*
dpy
,
int
*
event_base
,
int
*
error_base
),(
dpy
,
event_base
,
error_base
),
return
)
SDL_X11_SYM
(
Bool
,
XRenderQueryVersion
,(
Display
*
dpy
,
int
*
major
,
int
*
minor
),(
dpy
,
major
,
minor
),
return
)
SDL_X11_SYM
(
XRenderPictFormat
*
,
XRenderFindVisualFormat
,(
Display
*
dpy
,
_Xconst
Visual
*
visual
),(
dpy
,
visual
),
return
)
SDL_X11_SYM
(
XRenderPictFormat
*
,
XRenderFindStandardFormat
,(
Display
*
dpy
,
int
format
),(
dpy
,
format
),
return
)
SDL_X11_SYM
(
XRenderPictFormat
*
,
XRenderFindFormat
,(
Display
*
dpy
,
unsigned
long
mask
,
_Xconst
XRenderPictFormat
*
templ
,
int
count
),(
dpy
,
mask
,
templ
,
count
),
return
)
SDL_X11_SYM
(
Picture
,
XRenderCreatePicture
,(
Display
*
dpy
,
Drawable
drawable
,
_Xconst
XRenderPictFormat
*
format
,
unsigned
long
valuemask
,
_Xconst
XRenderPictureAttributes
*
attributes
),(
dpy
,
drawable
,
format
,
valuemask
,
attributes
),
return
)
SDL_X11_SYM
(
void
,
XRenderFreePicture
,(
Display
*
dpy
,
Picture
picture
),(
dpy
,
picture
),
return
)
SDL_X11_SYM
(
void
,
XRenderChangePicture
,(
Display
*
dpy
,
Picture
picture
,
unsigned
long
valuemask
,
_Xconst
XRenderPictureAttributes
*
attributes
),(
dpy
,
picture
,
valuemask
,
attributes
),
return
)
SDL_X11_SYM
(
void
,
XRenderComposite
,(
Display
*
dpy
,
int
op
,
Picture
src
,
Picture
mask
,
Picture
dst
,
int
src_x
,
int
src_y
,
int
mask_x
,
int
mask_y
,
int
dst_x
,
int
dst_y
,
unsigned
int
width
,
unsigned
int
height
),(
dpy
,
op
,
src
,
mask
,
dst
,
src_x
,
src_y
,
mask_x
,
mask_y
,
dst_x
,
dst_y
,
width
,
height
),
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
,
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
)
SDL_X11_SYM
(
void
,
XRenderSetPictureFilter
,(
Display
*
dpy
,
Picture
picture
,
const
char
*
filter
,
XFixed
*
params
,
int
nparams
),(
dpy
,
picture
,
filter
,
params
,
nparams
),
return
)
#endif
#ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
SDL_X11_MODULE
(
XDAMAGE
)
SDL_X11_SYM
(
Bool
,
XDamageQueryExtension
,(
Display
*
dpy
,
int
*
event_base_return
,
int
*
error_base_return
),(
dpy
,
event_base_return
,
error_base_return
),
return
)
SDL_X11_SYM
(
Status
,
XDamageQueryVersion
,(
Display
*
dpy
,
int
*
major
,
int
*
minor
),(
dpy
,
major
,
minor
),
return
)
SDL_X11_SYM
(
Damage
,
XDamageCreate
,(
Display
*
dpy
,
Drawable
d
,
int
level
),(
dpy
,
d
,
level
),
return
)
SDL_X11_SYM
(
void
,
XDamageSubtract
,(
Display
*
dpy
,
Damage
damage
,
XserverRegion
repair
,
XserverRegion
parts
),(
dpy
,
damage
,
repair
,
parts
),
return
)
SDL_X11_SYM
(
void
,
XDamageDestroy
,(
Display
*
dpy
,
Damage
damage
),(
dpy
,
damage
),
return
)
#endif
#ifdef SDL_VIDEO_DRIVER_X11_XFIXES
SDL_X11_MODULE
(
XFIXES
)
SDL_X11_SYM
(
Bool
,
XFixesQueryExtension
,(
Display
*
dpy
,
int
*
event_base
,
int
*
error_base
),(
dpy
,
event_base
,
error_base
),
return
)
SDL_X11_SYM
(
Status
,
XFixesQueryVersion
,(
Display
*
dpy
,
int
*
major
,
int
*
minor
),(
dpy
,
major
,
minor
),
return
)
SDL_X11_SYM
(
void
,
XFixesSetGCClipRegion
,(
Display
*
dpy
,
GC
gc
,
int
clip_x
,
int
clip_y
,
XserverRegion
region
),(
dpy
,
gc
,
clip_x
,
clip_y
,
region
),
return
)
SDL_X11_SYM
(
void
,
XFixesSetPictureClipRegion
,(
Display
*
dpy
,
XID
picture
,
int
clip_x
,
int
clip_y
,
XserverRegion
region
),(
dpy
,
picture
,
clip_x
,
clip_y
,
region
),
return
)
#endif
/* *INDENT-ON* */
/* vi: set ts=4 sw=4 expandtab: */
src/video/x11/SDL_x11video.h
View file @
d8e7cebd
...
...
@@ -45,7 +45,15 @@
#if SDL_VIDEO_DRIVER_X11_SCRNSAVER
#include <X11/extensions/scrnsaver.h>
#endif
#if SDL_VIDEO_DRIVER_X11_XRENDER
#include <X11/extensions/Xrender.h>
#endif
#if SDL_VIDEO_DRIVER_X11_XDAMAGE
#include <X11/extensions/Xdamage.h>
#endif
#if SDL_VIDEO_DRIVER_X11_XFIXES
#include <X11/extensions/Xfixes.h>
#endif
#include "SDL_x11dyn.h"
#include "SDL_x11clipboard.h"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment