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
9c126183
Commit
9c126183
authored
Feb 01, 2011
by
Sam Lantinga
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Removed partially functional renderers
--HG-- extra : rebase_source : 3fc2560c02393bf9e7c46360fc24f2585c9409be
parent
886e9476
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
0 additions
and
3600 deletions
+0
-3600
SDL_VS2005.vcproj
VisualC/SDL/SDL_VS2005.vcproj
+0
-8
SDL_VS2008.vcproj
VisualC/SDL/SDL_VS2008.vcproj
+0
-8
SDL_VS2010.vcxproj
VisualC/SDL/SDL_VS2010.vcxproj
+0
-2
configure.in
configure.in
+0
-18
SDL_config.h.in
include/SDL_config.h.in
+0
-2
SDL_config_macosx.h
include/SDL_config_macosx.h
+0
-3
SDL_config_windows.h
include/SDL_config_windows.h
+0
-3
SDL_gdirender.c
src/video/windows/SDL_gdirender.c
+0
-1129
SDL_gdirender.h
src/video/windows/SDL_gdirender.h
+0
-30
SDL_windowsvideo.c
src/video/windows/SDL_windowsvideo.c
+0
-3
SDL_x11render.c
src/video/x11/SDL_x11render.c
+0
-2360
SDL_x11render.h
src/video/x11/SDL_x11render.h
+0
-30
SDL_x11video.c
src/video/x11/SDL_x11video.c
+0
-4
No files found.
VisualC/SDL/SDL_VS2005.vcproj
View file @
9c126183
...
@@ -855,14 +855,6 @@
...
@@ -855,14 +855,6 @@
RelativePath=
"..\..\src\video\SDL_gamma.c"
RelativePath=
"..\..\src\video\SDL_gamma.c"
>
>
</File>
</File>
<File
RelativePath=
"..\..\src\video\windows\SDL_gdirender.c"
>
</File>
<File
RelativePath=
"..\..\src\video\windows\SDL_gdirender.h"
>
</File>
<File
<File
RelativePath=
"..\..\src\events\SDL_gesture.c"
RelativePath=
"..\..\src\events\SDL_gesture.c"
>
>
...
...
VisualC/SDL/SDL_VS2008.vcproj
View file @
9c126183
...
@@ -842,14 +842,6 @@
...
@@ -842,14 +842,6 @@
RelativePath=
"..\..\src\video\SDL_gamma.c"
RelativePath=
"..\..\src\video\SDL_gamma.c"
>
>
</File>
</File>
<File
RelativePath=
"..\..\src\video\windows\SDL_gdirender.c"
>
</File>
<File
RelativePath=
"..\..\src\video\windows\SDL_gdirender.h"
>
</File>
<File
<File
RelativePath=
"..\..\src\events\SDL_gesture.c"
RelativePath=
"..\..\src\events\SDL_gesture.c"
>
>
...
...
VisualC/SDL/SDL_VS2010.vcxproj
View file @
9c126183
...
@@ -296,7 +296,6 @@ echo #define SDL_REVISION "hg-0:baadf00d" >"$(ProjectDir)\..\..\include\SDL_r
...
@@ -296,7 +296,6 @@ echo #define SDL_REVISION "hg-0:baadf00d" >"$(ProjectDir)\..\..\include\SDL_r
<ClInclude
Include=
"..\..\src\SDL_error_c.h"
/>
<ClInclude
Include=
"..\..\src\SDL_error_c.h"
/>
<ClInclude
Include=
"..\..\src\events\SDL_events_c.h"
/>
<ClInclude
Include=
"..\..\src\events\SDL_events_c.h"
/>
<ClInclude
Include=
"..\..\src\SDL_fatal.h"
/>
<ClInclude
Include=
"..\..\src\SDL_fatal.h"
/>
<ClInclude
Include=
"..\..\src\video\windows\SDL_gdirender.h"
/>
<ClInclude
Include=
"..\..\src\video\SDL_glesfuncs.h"
/>
<ClInclude
Include=
"..\..\src\video\SDL_glesfuncs.h"
/>
<ClInclude
Include=
"..\..\src\video\SDL_glfuncs.h"
/>
<ClInclude
Include=
"..\..\src\video\SDL_glfuncs.h"
/>
<ClInclude
Include=
"..\..\src\joystick\SDL_joystick_c.h"
/>
<ClInclude
Include=
"..\..\src\joystick\SDL_joystick_c.h"
/>
...
@@ -401,7 +400,6 @@ echo #define SDL_REVISION "hg-0:baadf00d" >"$(ProjectDir)\..\..\include\SDL_r
...
@@ -401,7 +400,6 @@ echo #define SDL_REVISION "hg-0:baadf00d" >"$(ProjectDir)\..\..\include\SDL_r
<ClCompile
Include=
"..\..\src\SDL_fatal.c"
/>
<ClCompile
Include=
"..\..\src\SDL_fatal.c"
/>
<ClCompile
Include=
"..\..\src\video\SDL_fillrect.c"
/>
<ClCompile
Include=
"..\..\src\video\SDL_fillrect.c"
/>
<ClCompile
Include=
"..\..\src\video\SDL_gamma.c"
/>
<ClCompile
Include=
"..\..\src\video\SDL_gamma.c"
/>
<ClCompile
Include=
"..\..\src\video\windows\SDL_gdirender.c"
/>
<ClCompile
Include=
"..\..\src\stdlib\SDL_getenv.c"
/>
<ClCompile
Include=
"..\..\src\stdlib\SDL_getenv.c"
/>
<ClCompile
Include=
"..\..\src\haptic\SDL_haptic.c"
/>
<ClCompile
Include=
"..\..\src\haptic\SDL_haptic.c"
/>
<ClCompile
Include=
"..\..\src\stdlib\SDL_iconv.c"
/>
<ClCompile
Include=
"..\..\src\stdlib\SDL_iconv.c"
/>
...
...
configure.in
View file @
9c126183
...
@@ -1322,12 +1322,6 @@ AC_HELP_STRING([--enable-video-x11-xdamage-xfixes], [enable X11 Xdamage and Xfix
...
@@ -1322,12 +1322,6 @@ AC_HELP_STRING([--enable-video-x11-xdamage-xfixes], [enable X11 Xdamage and Xfix
AC_DEFINE(SDL_VIDEO_DRIVER_X11_XDAMAGE)
AC_DEFINE(SDL_VIDEO_DRIVER_X11_XDAMAGE)
AC_DEFINE(SDL_VIDEO_DRIVER_X11_XFIXES)
AC_DEFINE(SDL_VIDEO_DRIVER_X11_XFIXES)
fi
fi
AC_ARG_ENABLE(render-x11,
AC_HELP_STRING([--enable-render-x11], [enable the X11 render driver [[default=yes]]]),
, enable_render_x11=yes)
if test x$enable_render_x11 = xyes; then
AC_DEFINE(SDL_VIDEO_RENDER_X11)
fi
fi
fi
fi
fi
}
}
...
@@ -2351,12 +2345,6 @@ case "$host" in
...
@@ -2351,12 +2345,6 @@ case "$host" in
AC_DEFINE(SDL_VIDEO_DRIVER_WINDOWS)
AC_DEFINE(SDL_VIDEO_DRIVER_WINDOWS)
SOURCES="$SOURCES $srcdir/src/video/windows/*.c"
SOURCES="$SOURCES $srcdir/src/video/windows/*.c"
have_video=yes
have_video=yes
AC_ARG_ENABLE(render-gdi,
AC_HELP_STRING([--enable-render-gdi], [enable the GDI render driver [[default=yes]]]),
, enable_render_gdi=yes)
if test x$enable_render_gdi = xyes; then
AC_DEFINE(SDL_VIDEO_RENDER_GDI)
fi
AC_ARG_ENABLE(render-gapi,
AC_ARG_ENABLE(render-gapi,
AC_HELP_STRING([--enable-render-gapi], [enable the GAPI/RAWFRAMEBUFFER render driver [[default=yes]]]),
AC_HELP_STRING([--enable-render-gapi], [enable the GAPI/RAWFRAMEBUFFER render driver [[default=yes]]]),
, enable_render_gapi=yes)
, enable_render_gapi=yes)
...
@@ -2457,12 +2445,6 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau
...
@@ -2457,12 +2445,6 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau
AC_DEFINE(SDL_VIDEO_DRIVER_WINDOWS)
AC_DEFINE(SDL_VIDEO_DRIVER_WINDOWS)
SOURCES="$SOURCES $srcdir/src/video/windows/*.c"
SOURCES="$SOURCES $srcdir/src/video/windows/*.c"
have_video=yes
have_video=yes
AC_ARG_ENABLE(render-gdi,
AC_HELP_STRING([--enable-render-gdi], [enable the GDI render driver [[default=yes]]]),
, enable_render_gdi=yes)
if test x$enable_render_gdi = xyes; then
AC_DEFINE(SDL_VIDEO_RENDER_GDI)
fi
AC_ARG_ENABLE(render-d3d,
AC_ARG_ENABLE(render-d3d,
AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[default=yes]]]),
AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[default=yes]]]),
, enable_render_d3d=yes)
, enable_render_d3d=yes)
...
...
include/SDL_config.h.in
View file @
9c126183
...
@@ -285,10 +285,8 @@
...
@@ -285,10 +285,8 @@
#undef SDL_VIDEO_DRIVER_X11_XSHAPE
#undef SDL_VIDEO_DRIVER_X11_XSHAPE
#undef SDL_VIDEO_RENDER_D3D
#undef SDL_VIDEO_RENDER_D3D
#undef SDL_VIDEO_RENDER_GDI
#undef SDL_VIDEO_RENDER_OGL
#undef SDL_VIDEO_RENDER_OGL
#undef SDL_VIDEO_RENDER_OGL_ES
#undef SDL_VIDEO_RENDER_OGL_ES
#undef SDL_VIDEO_RENDER_X11
#undef SDL_VIDEO_RENDER_GAPI
#undef SDL_VIDEO_RENDER_GAPI
#undef SDL_VIDEO_RENDER_DDRAW
#undef SDL_VIDEO_RENDER_DDRAW
...
...
include/SDL_config_macosx.h
View file @
9c126183
...
@@ -151,9 +151,6 @@
...
@@ -151,9 +151,6 @@
#ifndef SDL_VIDEO_RENDER_OGL
#ifndef SDL_VIDEO_RENDER_OGL
#define SDL_VIDEO_RENDER_OGL 1
#define SDL_VIDEO_RENDER_OGL 1
#endif
#endif
#ifndef SDL_VIDEO_RENDER_X11
#define SDL_VIDEO_RENDER_X11 1
#endif
/* Enable OpenGL support */
/* Enable OpenGL support */
#ifndef SDL_VIDEO_OPENGL
#ifndef SDL_VIDEO_OPENGL
...
...
include/SDL_config_windows.h
View file @
9c126183
...
@@ -187,9 +187,6 @@ typedef unsigned int uintptr_t;
...
@@ -187,9 +187,6 @@ typedef unsigned int uintptr_t;
#define SDL_VIDEO_RENDER_D3D 1
#define SDL_VIDEO_RENDER_D3D 1
#endif
#endif
#endif
#endif
#ifndef SDL_VIDEO_RENDER_GDI
#define SDL_VIDEO_RENDER_GDI 1
#endif
/* Enable OpenGL support */
/* Enable OpenGL support */
#ifndef _WIN32_WCE
#ifndef _WIN32_WCE
...
...
src/video/windows/SDL_gdirender.c
deleted
100644 → 0
View file @
886e9476
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
#if SDL_VIDEO_RENDER_GDI
#include "SDL_windowsvideo.h"
#include "../SDL_rect_c.h"
#include "../SDL_yuv_sw_c.h"
#include "../SDL_alphamult.h"
#ifdef _WIN32_WCE
#define NO_GETDIBBITS 1
#endif
/* GDI renderer implementation */
static
SDL_Renderer
*
GDI_CreateRenderer
(
SDL_Window
*
window
,
Uint32
flags
);
static
int
GDI_DisplayModeChanged
(
SDL_Renderer
*
renderer
);
static
int
GDI_CreateTexture
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
);
static
int
GDI_QueryTexturePixels
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
,
void
**
pixels
,
int
*
pitch
);
static
int
GDI_SetTexturePalette
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
,
const
SDL_Color
*
colors
,
int
firstcolor
,
int
ncolors
);
static
int
GDI_GetTexturePalette
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
,
SDL_Color
*
colors
,
int
firstcolor
,
int
ncolors
);
static
int
GDI_SetTextureAlphaMod
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
);
static
int
GDI_SetTextureBlendMode
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
);
static
int
GDI_SetTextureScaleMode
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
);
static
int
GDI_UpdateTexture
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
,
const
SDL_Rect
*
rect
,
const
void
*
pixels
,
int
pitch
);
static
int
GDI_LockTexture
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
,
const
SDL_Rect
*
rect
,
int
markDirty
,
void
**
pixels
,
int
*
pitch
);
static
void
GDI_UnlockTexture
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
);
static
int
GDI_SetDrawBlendMode
(
SDL_Renderer
*
renderer
);
static
int
GDI_RenderDrawPoints
(
SDL_Renderer
*
renderer
,
const
SDL_Point
*
points
,
int
count
);
static
int
GDI_RenderDrawLines
(
SDL_Renderer
*
renderer
,
const
SDL_Point
*
points
,
int
count
);
static
int
GDI_RenderDrawRects
(
SDL_Renderer
*
renderer
,
const
SDL_Rect
**
rects
,
int
count
);
static
int
GDI_RenderFillRects
(
SDL_Renderer
*
renderer
,
const
SDL_Rect
**
rects
,
int
count
);
static
int
GDI_RenderCopy
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
,
const
SDL_Rect
*
srcrect
,
const
SDL_Rect
*
dstrect
);
static
int
GDI_RenderReadPixels
(
SDL_Renderer
*
renderer
,
const
SDL_Rect
*
rect
,
Uint32
format
,
void
*
pixels
,
int
pitch
);
static
int
GDI_RenderWritePixels
(
SDL_Renderer
*
renderer
,
const
SDL_Rect
*
rect
,
Uint32
format
,
const
void
*
pixels
,
int
pitch
);
static
void
GDI_RenderPresent
(
SDL_Renderer
*
renderer
);
static
void
GDI_DestroyTexture
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
);
static
void
GDI_DestroyRenderer
(
SDL_Renderer
*
renderer
);
SDL_RenderDriver
GDI_RenderDriver
=
{
GDI_CreateRenderer
,
{
"gdi"
,
(
SDL_RENDERER_SINGLEBUFFER
|
SDL_RENDERER_PRESENTCOPY
|
SDL_RENDERER_PRESENTFLIP2
|
SDL_RENDERER_PRESENTFLIP3
|
SDL_RENDERER_PRESENTDISCARD
|
SDL_RENDERER_ACCELERATED
),
(
SDL_TEXTUREMODULATE_NONE
|
SDL_TEXTUREMODULATE_ALPHA
),
(
SDL_BLENDMODE_NONE
|
SDL_BLENDMODE_MASK
),
(
SDL_SCALEMODE_NONE
|
SDL_SCALEMODE_FAST
),
14
,
{
SDL_PIXELFORMAT_INDEX8
,
SDL_PIXELFORMAT_RGB555
,
SDL_PIXELFORMAT_RGB565
,
SDL_PIXELFORMAT_RGB888
,
SDL_PIXELFORMAT_BGR888
,
SDL_PIXELFORMAT_ARGB8888
,
SDL_PIXELFORMAT_RGBA8888
,
SDL_PIXELFORMAT_ABGR8888
,
SDL_PIXELFORMAT_BGRA8888
,
SDL_PIXELFORMAT_YV12
,
SDL_PIXELFORMAT_IYUV
,
SDL_PIXELFORMAT_YUY2
,
SDL_PIXELFORMAT_UYVY
,
SDL_PIXELFORMAT_YVYU
},
0
,
0
}
};
typedef
struct
{
HWND
hwnd
;
HDC
window_hdc
;
HDC
render_hdc
;
HDC
memory_hdc
;
HDC
current_hdc
;
#ifndef NO_GETDIBBITS
LPBITMAPINFO
bmi
;
#endif
HBITMAP
hbm
[
3
];
int
current_hbm
;
SDL_DirtyRectList
dirty
;
SDL_bool
makedirty
;
}
GDI_RenderData
;
typedef
struct
{
SDL_SW_YUVTexture
*
yuv
;
Uint32
format
;
HPALETTE
hpal
;
HBITMAP
hbm
;
void
*
pixels
;
int
pitch
;
SDL_bool
premultiplied
;
}
GDI_TextureData
;
static
void
UpdateYUVTextureData
(
SDL_Texture
*
texture
)
{
GDI_TextureData
*
data
=
(
GDI_TextureData
*
)
texture
->
driverdata
;
SDL_Rect
rect
;
rect
.
x
=
0
;
rect
.
y
=
0
;
rect
.
w
=
texture
->
w
;
rect
.
h
=
texture
->
h
;
SDL_SW_CopyYUVToRGB
(
data
->
yuv
,
&
rect
,
data
->
format
,
texture
->
w
,
texture
->
h
,
data
->
pixels
,
data
->
pitch
);
}
void
GDI_AddRenderDriver
(
_THIS
)
{
int
i
;
for
(
i
=
0
;
i
<
_this
->
num_displays
;
++
i
)
{
SDL_AddRenderDriver
(
&
_this
->
displays
[
i
],
&
GDI_RenderDriver
);
}
}
SDL_Renderer
*
GDI_CreateRenderer
(
SDL_Window
*
window
,
Uint32
flags
)
{
SDL_WindowData
*
windowdata
=
(
SDL_WindowData
*
)
window
->
driverdata
;
SDL_Renderer
*
renderer
;
GDI_RenderData
*
data
;
#ifndef NO_GETDIBBITS
int
bmi_size
;
HBITMAP
hbm
;
#endif
int
i
,
n
;
renderer
=
(
SDL_Renderer
*
)
SDL_calloc
(
1
,
sizeof
(
*
renderer
));
if
(
!
renderer
)
{
SDL_OutOfMemory
();
return
NULL
;
}
data
=
(
GDI_RenderData
*
)
SDL_calloc
(
1
,
sizeof
(
*
data
));
if
(
!
data
)
{
GDI_DestroyRenderer
(
renderer
);
SDL_OutOfMemory
();
return
NULL
;
}
windowdata
->
videodata
->
render
=
RENDER_GDI
;
renderer
->
DisplayModeChanged
=
GDI_DisplayModeChanged
;
renderer
->
CreateTexture
=
GDI_CreateTexture
;
renderer
->
QueryTexturePixels
=
GDI_QueryTexturePixels
;
renderer
->
SetTexturePalette
=
GDI_SetTexturePalette
;
renderer
->
GetTexturePalette
=
GDI_GetTexturePalette
;
renderer
->
SetTextureAlphaMod
=
GDI_SetTextureAlphaMod
;
renderer
->
SetTextureBlendMode
=
GDI_SetTextureBlendMode
;
renderer
->
SetTextureScaleMode
=
GDI_SetTextureScaleMode
;
renderer
->
UpdateTexture
=
GDI_UpdateTexture
;
renderer
->
LockTexture
=
GDI_LockTexture
;
renderer
->
UnlockTexture
=
GDI_UnlockTexture
;
renderer
->
SetDrawBlendMode
=
GDI_SetDrawBlendMode
;
renderer
->
RenderDrawPoints
=
GDI_RenderDrawPoints
;
renderer
->
RenderDrawLines
=
GDI_RenderDrawLines
;
renderer
->
RenderDrawRects
=
GDI_RenderDrawRects
;
renderer
->
RenderFillRects
=
GDI_RenderFillRects
;
renderer
->
RenderCopy
=
GDI_RenderCopy
;
renderer
->
RenderReadPixels
=
GDI_RenderReadPixels
;
renderer
->
RenderWritePixels
=
GDI_RenderWritePixels
;
renderer
->
RenderPresent
=
GDI_RenderPresent
;
renderer
->
DestroyTexture
=
GDI_DestroyTexture
;
renderer
->
DestroyRenderer
=
GDI_DestroyRenderer
;
renderer
->
info
=
GDI_RenderDriver
.
info
;
renderer
->
window
=
window
;
renderer
->
driverdata
=
data
;
renderer
->
info
.
flags
=
SDL_RENDERER_ACCELERATED
;
data
->
hwnd
=
windowdata
->
hwnd
;
data
->
window_hdc
=
windowdata
->
hdc
;
data
->
render_hdc
=
CreateCompatibleDC
(
data
->
window_hdc
);
data
->
memory_hdc
=
CreateCompatibleDC
(
data
->
window_hdc
);
#ifndef NO_GETDIBBITS
/* Fill in the compatible bitmap info */
bmi_size
=
sizeof
(
BITMAPINFOHEADER
)
+
256
*
sizeof
(
RGBQUAD
);
data
->
bmi
=
(
LPBITMAPINFO
)
SDL_calloc
(
1
,
bmi_size
);
if
(
!
data
->
bmi
)
{
GDI_DestroyRenderer
(
renderer
);
SDL_OutOfMemory
();
return
NULL
;
}
data
->
bmi
->
bmiHeader
.
biSize
=
sizeof
(
BITMAPINFOHEADER
);
hbm
=
CreateCompatibleBitmap
(
data
->
window_hdc
,
1
,
1
);
GetDIBits
(
data
->
window_hdc
,
hbm
,
0
,
1
,
NULL
,
data
->
bmi
,
DIB_RGB_COLORS
);
GetDIBits
(
data
->
window_hdc
,
hbm
,
0
,
1
,
NULL
,
data
->
bmi
,
DIB_RGB_COLORS
);
DeleteObject
(
hbm
);
#endif
if
(
flags
&
SDL_RENDERER_SINGLEBUFFER
)
{
renderer
->
info
.
flags
|=
(
SDL_RENDERER_SINGLEBUFFER
|
SDL_RENDERER_PRESENTCOPY
);
n
=
0
;
}
else
if
(
flags
&
SDL_RENDERER_PRESENTFLIP2
)
{
renderer
->
info
.
flags
|=
SDL_RENDERER_PRESENTFLIP2
;
n
=
2
;
}
else
if
(
flags
&
SDL_RENDERER_PRESENTFLIP3
)
{
renderer
->
info
.
flags
|=
SDL_RENDERER_PRESENTFLIP3
;
n
=
3
;
}
else
{
renderer
->
info
.
flags
|=
SDL_RENDERER_PRESENTCOPY
;
n
=
1
;
}
for
(
i
=
0
;
i
<
n
;
++
i
)
{
data
->
hbm
[
i
]
=
CreateCompatibleBitmap
(
data
->
window_hdc
,
window
->
w
,
window
->
h
);
if
(
!
data
->
hbm
[
i
])
{
GDI_DestroyRenderer
(
renderer
);
WIN_SetError
(
"CreateCompatibleBitmap()"
);
return
NULL
;
}
}
if
(
n
>
0
)
{
SelectObject
(
data
->
render_hdc
,
data
->
hbm
[
0
]);
data
->
current_hdc
=
data
->
render_hdc
;
data
->
makedirty
=
SDL_TRUE
;
}
else
{
data
->
current_hdc
=
data
->
window_hdc
;
data
->
makedirty
=
SDL_FALSE
;
}
data
->
current_hbm
=
0
;
#ifdef _WIN32_WCE
// check size for GDI fullscreen and rotate
if
((
window
->
flags
&
SDL_WINDOW_FULLSCREEN
)
&&
GetSystemMetrics
(
SM_CXSCREEN
)
!=
GetSystemMetrics
(
SM_CYSCREEN
)
&&
((
GetSystemMetrics
(
SM_CXSCREEN
)
<
GetSystemMetrics
(
SM_CYSCREEN
)
&&
window
->
w
>
window
->
h
)
||
(
GetSystemMetrics
(
SM_CXSCREEN
)
>
GetSystemMetrics
(
SM_CYSCREEN
)
&&
window
->
w
<
window
->
h
)))
{
int
orientation
=
WINCE_GetDMOrientation
();
switch
(
orientation
)
{
case
DMDO_0
:
orientation
=
DMDO_90
;
break
;
case
DMDO_270
:
orientation
=
DMDO_180
;
break
;
case
DMDO_90
:
orientation
=
DMDO_0
;
break
;
case
DMDO_180
:
orientation
=
DMDO_270
;
break
;
default:
GDI_DestroyRenderer
(
renderer
);
return
NULL
;
}
if
(
0
>
WINCE_SetDMOrientation
(
orientation
))
{
GDI_DestroyRenderer
(
renderer
);
return
NULL
;
}
}
#endif
return
renderer
;
}
static
int
GDI_DisplayModeChanged
(
SDL_Renderer
*
renderer
)
{
GDI_RenderData
*
data
=
(
GDI_RenderData
*
)
renderer
->
driverdata
;
SDL_Window
*
window
=
renderer
->
window
;
int
i
,
n
;
if
(
renderer
->
info
.
flags
&
SDL_RENDERER_SINGLEBUFFER
)
{
n
=
0
;
}
else
if
(
renderer
->
info
.
flags
&
SDL_RENDERER_PRESENTFLIP2
)
{
n
=
2
;
}
else
if
(
renderer
->
info
.
flags
&
SDL_RENDERER_PRESENTFLIP3
)
{
n
=
3
;
}
else
{
n
=
1
;
}
for
(
i
=
0
;
i
<
n
;
++
i
)
{
if
(
data
->
hbm
[
i
])
{
DeleteObject
(
data
->
hbm
[
i
]);
data
->
hbm
[
i
]
=
NULL
;
}
}
for
(
i
=
0
;
i
<
n
;
++
i
)
{
data
->
hbm
[
i
]
=
CreateCompatibleBitmap
(
data
->
window_hdc
,
window
->
w
,
window
->
h
);
if
(
!
data
->
hbm
[
i
])
{
WIN_SetError
(
"CreateCompatibleBitmap()"
);
return
-
1
;
}
}
if
(
n
>
0
)
{
SelectObject
(
data
->
render_hdc
,
data
->
hbm
[
0
]);
}
data
->
current_hbm
=
0
;
return
0
;
}
static
HBITMAP
GDI_CreateDIBSection
(
HDC
hdc
,
int
w
,
int
h
,
int
pitch
,
Uint32
format
,
HPALETTE
*
hpal
,
void
**
pixels
)
{
int
bmi_size
;
LPBITMAPINFO
bmi
;
bmi_size
=
sizeof
(
BITMAPINFOHEADER
)
+
256
*
sizeof
(
RGBQUAD
);
bmi
=
(
LPBITMAPINFO
)
SDL_calloc
(
1
,
bmi_size
);
if
(
!
bmi
)
{
SDL_OutOfMemory
();
return
NULL
;
}
bmi
->
bmiHeader
.
biSize
=
sizeof
(
BITMAPINFOHEADER
);
bmi
->
bmiHeader
.
biWidth
=
w
;
bmi
->
bmiHeader
.
biHeight
=
-
h
;
/* topdown bitmap */
bmi
->
bmiHeader
.
biPlanes
=
1
;
bmi
->
bmiHeader
.
biSizeImage
=
h
*
pitch
;
bmi
->
bmiHeader
.
biXPelsPerMeter
=
0
;
bmi
->
bmiHeader
.
biYPelsPerMeter
=
0
;
bmi
->
bmiHeader
.
biClrUsed
=
0
;
bmi
->
bmiHeader
.
biClrImportant
=
0
;
bmi
->
bmiHeader
.
biBitCount
=
SDL_BYTESPERPIXEL
(
format
)
*
8
;
if
(
SDL_ISPIXELFORMAT_INDEXED
(
format
))
{
bmi
->
bmiHeader
.
biCompression
=
BI_RGB
;
if
(
hpal
)
{
int
i
,
ncolors
;
LOGPALETTE
*
palette
;
ncolors
=
(
1
<<
SDL_BITSPERPIXEL
(
format
));
palette
=
(
LOGPALETTE
*
)
SDL_malloc
(
sizeof
(
*
palette
)
+
ncolors
*
sizeof
(
PALETTEENTRY
));
if
(
!
palette
)
{
SDL_free
(
bmi
);
SDL_OutOfMemory
();
return
NULL
;
}
palette
->
palVersion
=
0x300
;
palette
->
palNumEntries
=
ncolors
;
for
(
i
=
0
;
i
<
ncolors
;
++
i
)
{
palette
->
palPalEntry
[
i
].
peRed
=
0xFF
;
palette
->
palPalEntry
[
i
].
peGreen
=
0xFF
;
palette
->
palPalEntry
[
i
].
peBlue
=
0xFF
;
palette
->
palPalEntry
[
i
].
peFlags
=
0
;
}
*
hpal
=
CreatePalette
(
palette
);
SDL_free
(
palette
);
}
}
else
{
int
bpp
;
Uint32
Rmask
,
Gmask
,
Bmask
,
Amask
;
bmi
->
bmiHeader
.
biCompression
=
BI_BITFIELDS
;
SDL_PixelFormatEnumToMasks
(
format
,
&
bpp
,
&
Rmask
,
&
Gmask
,
&
Bmask
,
&
Amask
);
((
Uint32
*
)
bmi
->
bmiColors
)[
0
]
=
Rmask
;
((
Uint32
*
)
bmi
->
bmiColors
)[
1
]
=
Gmask
;
((
Uint32
*
)
bmi
->
bmiColors
)[
2
]
=
Bmask
;
if
(
hpal
)
{
*
hpal
=
NULL
;
}
}
return
CreateDIBSection
(
hdc
,
bmi
,
DIB_RGB_COLORS
,
pixels
,
NULL
,
0
);
}
static
int
GDI_CreateTexture
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
)
{
GDI_RenderData
*
renderdata
=
(
GDI_RenderData
*
)
renderer
->
driverdata
;
SDL_Window
*
window
=
renderer
->
window
;
SDL_VideoDisplay
*
display
=
window
->
display
;
GDI_TextureData
*
data
;
data
=
(
GDI_TextureData
*
)
SDL_calloc
(
1
,
sizeof
(
*
data
));
if
(
!
data
)
{
SDL_OutOfMemory
();
return
-
1
;
}
texture
->
driverdata
=
data
;
if
(
SDL_ISPIXELFORMAT_FOURCC
(
texture
->
format
))
{
data
->
yuv
=
SDL_SW_CreateYUVTexture
(
texture
->
format
,
texture
->
w
,
texture
->
h
);
if
(
!
data
->
yuv
)
{
return
-
1
;
}
data
->
format
=
display
->
current_mode
.
format
;
}
else
{
data
->
format
=
texture
->
format
;
}
data
->
pitch
=
(
texture
->
w
*
SDL_BYTESPERPIXEL
(
data
->
format
));
if
(
data
->
yuv
||
texture
->
access
==
SDL_TEXTUREACCESS_STREAMING
||
texture
->
format
!=
display
->
current_mode
.
format
)
{
data
->
hbm
=
GDI_CreateDIBSection
(
renderdata
->
memory_hdc
,
texture
->
w
,
texture
->
h
,
data
->
pitch
,
data
->
format
,
&
data
->
hpal
,
&
data
->
pixels
);
}
else
{
data
->
hbm
=
CreateCompatibleBitmap
(
renderdata
->
window_hdc
,
texture
->
w
,
texture
->
h
);
}
if
(
!
data
->
hbm
)
{
WIN_SetError
(
"Couldn't create bitmap"
);
return
-
1
;
}
return
0
;
}
static
int
GDI_QueryTexturePixels
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
,
void
**
pixels
,
int
*
pitch
)
{
GDI_TextureData
*
data
=
(
GDI_TextureData
*
)
texture
->
driverdata
;
if
(
data
->
yuv
)
{
return
SDL_SW_QueryYUVTexturePixels
(
data
->
yuv
,
pixels
,
pitch
);
}
else
{
*
pixels
=
data
->
pixels
;
*
pitch
=
data
->
pitch
;
return
0
;
}
}
static
int
GDI_SetTexturePalette
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
,
const
SDL_Color
*
colors
,
int
firstcolor
,
int
ncolors
)
{
GDI_RenderData
*
renderdata
=
(
GDI_RenderData
*
)
renderer
->
driverdata
;
GDI_TextureData
*
data
=
(
GDI_TextureData
*
)
texture
->
driverdata
;
if
(
data
->
yuv
)
{
SDL_SetError
(
"YUV textures don't have a palette"
);
return
-
1
;
}
else
{
PALETTEENTRY
entries
[
256
];
int
i
;
for
(
i
=
0
;
i
<
ncolors
;
++
i
)
{
entries
[
i
].
peRed
=
colors
[
i
].
r
;
entries
[
i
].
peGreen
=
colors
[
i
].
g
;
entries
[
i
].
peBlue
=
colors
[
i
].
b
;
entries
[
i
].
peFlags
=
0
;
}
if
(
!
SetPaletteEntries
(
data
->
hpal
,
firstcolor
,
ncolors
,
entries
))
{
WIN_SetError
(
"SetPaletteEntries()"
);
return
-
1
;
}
return
0
;
}
}
static
int
GDI_GetTexturePalette
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
,
SDL_Color
*
colors
,
int
firstcolor
,
int
ncolors
)
{
GDI_TextureData
*
data
=
(
GDI_TextureData
*
)
texture
->
driverdata
;
if
(
data
->
yuv
)
{
SDL_SetError
(
"YUV textures don't have a palette"
);
return
-
1
;
}
else
{
PALETTEENTRY
entries
[
256
];
int
i
;
if
(
!
GetPaletteEntries
(
data
->
hpal
,
firstcolor
,
ncolors
,
entries
))
{
WIN_SetError
(
"GetPaletteEntries()"
);
return
-
1
;
}
for
(
i
=
0
;
i
<
ncolors
;
++
i
)
{
colors
[
i
].
r
=
entries
[
i
].
peRed
;
colors
[
i
].
g
=
entries
[
i
].
peGreen
;
colors
[
i
].
b
=
entries
[
i
].
peBlue
;
}
return
0
;
}
}
static
int
GDI_SetTextureAlphaMod
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
)
{
return
0
;
}
static
int
GDI_SetTextureBlendMode
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
)
{
GDI_TextureData
*
data
=
(
GDI_TextureData
*
)
texture
->
driverdata
;
switch
(
texture
->
blendMode
)
{
case
SDL_BLENDMODE_NONE
:
if
(
data
->
premultiplied
)
{
/* Crap, we've lost the original pixel data... *sigh* */
}
return
0
;
#ifndef _WIN32_WCE
/* WinCE has no alphablend */
case
SDL_BLENDMODE_MASK
:
case
SDL_BLENDMODE_BLEND
:
if
(
!
data
->
premultiplied
&&
data
->
pixels
)
{
switch
(
texture
->
format
)
{
case
SDL_PIXELFORMAT_ARGB8888
:
SDL_PreMultiplyAlphaARGB8888
(
texture
->
w
,
texture
->
h
,
(
Uint32
*
)
data
->
pixels
,
data
->
pitch
);
data
->
premultiplied
=
SDL_TRUE
;
break
;
case
SDL_PIXELFORMAT_RGBA8888
:
SDL_PreMultiplyAlphaRGBA8888
(
texture
->
w
,
texture
->
h
,
(
Uint32
*
)
data
->
pixels
,
data
->
pitch
);
data
->
premultiplied
=
SDL_TRUE
;
break
;
case
SDL_PIXELFORMAT_ABGR8888
:
SDL_PreMultiplyAlphaABGR8888
(
texture
->
w
,
texture
->
h
,
(
Uint32
*
)
data
->
pixels
,
data
->
pitch
);
data
->
premultiplied
=
SDL_TRUE
;
break
;
case
SDL_PIXELFORMAT_BGRA8888
:
SDL_PreMultiplyAlphaBGRA8888
(
texture
->
w
,
texture
->
h
,
(
Uint32
*
)
data
->
pixels
,
data
->
pitch
);
data
->
premultiplied
=
SDL_TRUE
;
break
;
}
}
return
0
;
#endif
default:
SDL_Unsupported
();
texture
->
blendMode
=
SDL_BLENDMODE_NONE
;
return
-
1
;
}
}
static
int
GDI_SetTextureScaleMode
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
)
{
switch
(
texture
->
scaleMode
)
{
case
SDL_SCALEMODE_NONE
:
case
SDL_SCALEMODE_FAST
:
return
0
;
case
SDL_SCALEMODE_SLOW
:
case
SDL_SCALEMODE_BEST
:
SDL_Unsupported
();
texture
->
scaleMode
=
SDL_SCALEMODE_FAST
;
return
-
1
;
default:
SDL_Unsupported
();
texture
->
scaleMode
=
SDL_SCALEMODE_NONE
;
return
-
1
;
}
return
0
;
}
static
int
GDI_UpdateTexture
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
,
const
SDL_Rect
*
rect
,
const
void
*
pixels
,
int
pitch
)
{
GDI_TextureData
*
data
=
(
GDI_TextureData
*
)
texture
->
driverdata
;
if
(
data
->
yuv
)
{
if
(
SDL_SW_UpdateYUVTexture
(
data
->
yuv
,
rect
,
pixels
,
pitch
)
<
0
)
{
return
-
1
;
}
UpdateYUVTextureData
(
texture
);
return
0
;
}
else
{
GDI_RenderData
*
renderdata
=
(
GDI_RenderData
*
)
renderer
->
driverdata
;
if
(
data
->
pixels
)
{
Uint8
*
src
,
*
dst
;
int
row
;
size_t
length
;
src
=
(
Uint8
*
)
pixels
;
dst
=
(
Uint8
*
)
data
->
pixels
+
rect
->
y
*
data
->
pitch
+
rect
->
x
*
SDL_BYTESPERPIXEL
(
texture
->
format
);
length
=
rect
->
w
*
SDL_BYTESPERPIXEL
(
texture
->
format
);
for
(
row
=
0
;
row
<
rect
->
h
;
++
row
)
{
SDL_memcpy
(
dst
,
src
,
length
);
src
+=
pitch
;
dst
+=
data
->
pitch
;
}
if
(
data
->
premultiplied
)
{
Uint32
*
pixels
=
(
Uint32
*
)
data
->
pixels
+
rect
->
y
*
(
data
->
pitch
/
4
)
+
rect
->
x
;
switch
(
texture
->
format
)
{
case
SDL_PIXELFORMAT_ARGB8888
:
SDL_PreMultiplyAlphaARGB8888
(
rect
->
w
,
rect
->
h
,
pixels
,
data
->
pitch
);
break
;
case
SDL_PIXELFORMAT_RGBA8888
:
SDL_PreMultiplyAlphaRGBA8888
(
rect
->
w
,
rect
->
h
,
pixels
,
data
->
pitch
);
break
;
case
SDL_PIXELFORMAT_ABGR8888
:
SDL_PreMultiplyAlphaABGR8888
(
rect
->
w
,
rect
->
h
,
pixels
,
data
->
pitch
);
break
;
case
SDL_PIXELFORMAT_BGRA8888
:
SDL_PreMultiplyAlphaBGRA8888
(
rect
->
w
,
rect
->
h
,
pixels
,
data
->
pitch
);
break
;
}
}
}
else
if
(
rect
->
w
==
texture
->
w
&&
pitch
==
data
->
pitch
)
{
#ifndef NO_GETDIBBITS
if
(
!
SetDIBits
(
renderdata
->
window_hdc
,
data
->
hbm
,
rect
->
y
,
rect
->
h
,
pixels
,
renderdata
->
bmi
,
DIB_RGB_COLORS
))
{
WIN_SetError
(
"SetDIBits()"
);
return
-
1
;
}
#else
SDL_SetError
(
"FIXME: Update Texture"
);
return
-
1
;
#endif
}
else
{
SDL_SetError
(
"FIXME: Need to allocate temporary memory and do GetDIBits() followed by SetDIBits(), since we can only set blocks of scanlines at a time"
);
return
-
1
;
}
return
0
;
}
}
static
int
GDI_LockTexture
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
,
const
SDL_Rect
*
rect
,
int
markDirty
,
void
**
pixels
,
int
*
pitch
)
{
GDI_TextureData
*
data
=
(
GDI_TextureData
*
)
texture
->
driverdata
;
if
(
data
->
yuv
)
{
return
SDL_SW_LockYUVTexture
(
data
->
yuv
,
rect
,
markDirty
,
pixels
,
pitch
);
}
else
if
(
data
->
pixels
)
{
#ifndef _WIN32_WCE
/* WinCE has no GdiFlush */
GdiFlush
();
#endif
*
pixels
=
(
void
*
)
((
Uint8
*
)
data
->
pixels
+
rect
->
y
*
data
->
pitch
+
rect
->
x
*
SDL_BYTESPERPIXEL
(
texture
->
format
));
*
pitch
=
data
->
pitch
;
return
0
;
}
else
{
SDL_SetError
(
"No pixels available"
);
return
-
1
;
}
}
static
void
GDI_UnlockTexture
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
)
{
GDI_TextureData
*
data
=
(
GDI_TextureData
*
)
texture
->
driverdata
;
if
(
data
->
yuv
)
{
SDL_SW_UnlockYUVTexture
(
data
->
yuv
);
UpdateYUVTextureData
(
texture
);
}
}
static
int
GDI_SetDrawBlendMode
(
SDL_Renderer
*
renderer
)
{
switch
(
renderer
->
blendMode
)
{
case
SDL_BLENDMODE_NONE
:
return
0
;
default:
SDL_Unsupported
();
renderer
->
blendMode
=
SDL_BLENDMODE_NONE
;
return
-
1
;
}
}
static
int
GDI_RenderDrawPoints
(
SDL_Renderer
*
renderer
,
const
SDL_Point
*
points
,
int
count
)
{
GDI_RenderData
*
data
=
(
GDI_RenderData
*
)
renderer
->
driverdata
;
int
i
;
COLORREF
color
;
if
(
data
->
makedirty
)
{
/* Get the smallest rectangle that contains everything */
SDL_Window
*
window
=
renderer
->
window
;
SDL_Rect
rect
;
rect
.
x
=
0
;
rect
.
y
=
0
;
rect
.
w
=
window
->
w
;
rect
.
h
=
window
->
h
;
if
(
!
SDL_EnclosePoints
(
points
,
count
,
&
rect
,
&
rect
))
{
/* Nothing to draw */
return
0
;
}
SDL_AddDirtyRect
(
&
data
->
dirty
,
&
rect
);
}
color
=
RGB
(
renderer
->
r
,
renderer
->
g
,
renderer
->
b
);
for
(
i
=
0
;
i
<
count
;
++
i
)
{
SetPixel
(
data
->
current_hdc
,
points
[
i
].
x
,
points
[
i
].
y
,
color
);
}
return
0
;
}
static
int
GDI_RenderDrawLines
(
SDL_Renderer
*
renderer
,
const
SDL_Point
*
points
,
int
count
)
{
GDI_RenderData
*
data
=
(
GDI_RenderData
*
)
renderer
->
driverdata
;
HPEN
pen
;
BOOL
status
;
if
(
data
->
makedirty
)
{
/* Get the smallest rectangle that contains everything */
SDL_Window
*
window
=
renderer
->
window
;
SDL_Rect
clip
,
rect
;
clip
.
x
=
0
;
clip
.
y
=
0
;
clip
.
w
=
window
->
w
;
clip
.
h
=
window
->
h
;
SDL_EnclosePoints
(
points
,
count
,
NULL
,
&
rect
);
if
(
!
SDL_IntersectRect
(
&
rect
,
&
clip
,
&
rect
))
{
/* Nothing to draw */
return
0
;
}
SDL_AddDirtyRect
(
&
data
->
dirty
,
&
rect
);
}
/* Should we cache the pen? .. it looks like GDI does for us. :) */
pen
=
CreatePen
(
PS_SOLID
,
1
,
RGB
(
renderer
->
r
,
renderer
->
g
,
renderer
->
b
));
SelectObject
(
data
->
current_hdc
,
pen
);
{
LPPOINT
p
=
SDL_stack_alloc
(
POINT
,
count
);
int
i
;
for
(
i
=
0
;
i
<
count
;
++
i
)
{
p
[
i
].
x
=
points
[
i
].
x
;
p
[
i
].
y
=
points
[
i
].
y
;
}
status
=
Polyline
(
data
->
current_hdc
,
p
,
count
);
SDL_stack_free
(
p
);
}
DeleteObject
(
pen
);
/* Need to close the endpoint of the line */
if
(
points
[
0
].
x
!=
points
[
count
-
1
].
x
||
points
[
0
].
y
!=
points
[
count
-
1
].
y
)
{
SetPixel
(
data
->
current_hdc
,
points
[
count
-
1
].
x
,
points
[
count
-
1
].
y
,
RGB
(
renderer
->
r
,
renderer
->
g
,
renderer
->
b
));
}
if
(
!
status
)
{
WIN_SetError
(
"Polyline()"
);
return
-
1
;
}
return
0
;
}
static
int
GDI_RenderDrawRects
(
SDL_Renderer
*
renderer
,
const
SDL_Rect
**
rects
,
int
count
)
{
GDI_RenderData
*
data
=
(
GDI_RenderData
*
)
renderer
->
driverdata
;
HPEN
pen
;
POINT
vertices
[
5
];
int
i
,
status
=
1
;
if
(
data
->
makedirty
)
{
SDL_Window
*
window
=
renderer
->
window
;
SDL_Rect
clip
,
rect
;
clip
.
x
=
0
;
clip
.
y
=
0
;
clip
.
w
=
window
->
w
;
clip
.
h
=
window
->
h
;
for
(
i
=
0
;
i
<
count
;
++
i
)
{
if
(
SDL_IntersectRect
(
rects
[
i
],
&
clip
,
&
rect
))
{
SDL_AddDirtyRect
(
&
data
->
dirty
,
&
rect
);
}
}
}
/* Should we cache the pen? .. it looks like GDI does for us. :) */
pen
=
CreatePen
(
PS_SOLID
,
1
,
RGB
(
renderer
->
r
,
renderer
->
g
,
renderer
->
b
));
SelectObject
(
data
->
current_hdc
,
pen
);
for
(
i
=
0
;
i
<
count
;
++
i
)
{
const
SDL_Rect
*
rect
=
rects
[
i
];
vertices
[
0
].
x
=
rect
->
x
;
vertices
[
0
].
y
=
rect
->
y
;
vertices
[
1
].
x
=
rect
->
x
+
rect
->
w
-
1
;
vertices
[
1
].
y
=
rect
->
y
;
vertices
[
2
].
x
=
rect
->
x
+
rect
->
w
-
1
;
vertices
[
2
].
y
=
rect
->
y
+
rect
->
h
-
1
;
vertices
[
3
].
x
=
rect
->
x
;
vertices
[
3
].
y
=
rect
->
y
+
rect
->
h
-
1
;
vertices
[
4
].
x
=
rect
->
x
;
vertices
[
4
].
y
=
rect
->
y
;
status
&=
Polyline
(
data
->
current_hdc
,
vertices
,
5
);
}
DeleteObject
(
pen
);
if
(
!
status
)
{
WIN_SetError
(
"Polyline()"
);
return
-
1
;
}
return
0
;
}
static
int
GDI_RenderFillRects
(
SDL_Renderer
*
renderer
,
const
SDL_Rect
**
rects
,
int
count
)
{
GDI_RenderData
*
data
=
(
GDI_RenderData
*
)
renderer
->
driverdata
;
RECT
rc
;
HBRUSH
brush
;
int
i
,
status
=
1
;
if
(
data
->
makedirty
)
{
SDL_Window
*
window
=
renderer
->
window
;
SDL_Rect
clip
,
rect
;
clip
.
x
=
0
;
clip
.
y
=
0
;
clip
.
w
=
window
->
w
;
clip
.
h
=
window
->
h
;
for
(
i
=
0
;
i
<
count
;
++
i
)
{
if
(
SDL_IntersectRect
(
rects
[
i
],
&
clip
,
&
rect
))
{
SDL_AddDirtyRect
(
&
data
->
dirty
,
&
rect
);
}
}
}
/* Should we cache the brushes? .. it looks like GDI does for us. :) */
brush
=
CreateSolidBrush
(
RGB
(
renderer
->
r
,
renderer
->
g
,
renderer
->
b
));
SelectObject
(
data
->
current_hdc
,
brush
);
for
(
i
=
0
;
i
<
count
;
++
i
)
{
const
SDL_Rect
*
rect
=
rects
[
i
];
rc
.
left
=
rect
->
x
;
rc
.
top
=
rect
->
y
;
rc
.
right
=
rect
->
x
+
rect
->
w
;
rc
.
bottom
=
rect
->
y
+
rect
->
h
;
status
&=
FillRect
(
data
->
current_hdc
,
&
rc
,
brush
);
}
DeleteObject
(
brush
);
if
(
!
status
)
{
WIN_SetError
(
"FillRect()"
);
return
-
1
;
}
return
0
;
}
static
int
GDI_RenderCopy
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
,
const
SDL_Rect
*
srcrect
,
const
SDL_Rect
*
dstrect
)
{
GDI_RenderData
*
data
=
(
GDI_RenderData
*
)
renderer
->
driverdata
;
GDI_TextureData
*
texturedata
=
(
GDI_TextureData
*
)
texture
->
driverdata
;
if
(
data
->
makedirty
)
{
SDL_AddDirtyRect
(
&
data
->
dirty
,
dstrect
);
}
SelectObject
(
data
->
memory_hdc
,
texturedata
->
hbm
);
if
(
texturedata
->
hpal
)
{
SelectPalette
(
data
->
memory_hdc
,
texturedata
->
hpal
,
TRUE
);
RealizePalette
(
data
->
memory_hdc
);
}
if
(
texture
->
blendMode
&
(
SDL_BLENDMODE_MASK
|
SDL_BLENDMODE_BLEND
))
{
#ifdef _WIN32_WCE
SDL_SetError
(
"Texture has blendmode not supported under WinCE"
);
return
-
1
;
#else
BLENDFUNCTION
blendFunc
=
{
AC_SRC_OVER
,
0
,
texture
->
a
,
AC_SRC_ALPHA
};
if
(
!
AlphaBlend
(
data
->
current_hdc
,
dstrect
->
x
,
dstrect
->
y
,
dstrect
->
w
,
dstrect
->
h
,
data
->
memory_hdc
,
srcrect
->
x
,
srcrect
->
y
,
srcrect
->
w
,
srcrect
->
h
,
blendFunc
))
{
WIN_SetError
(
"AlphaBlend()"
);
return
-
1
;
}
#endif
}
else
{
if
(
srcrect
->
w
==
dstrect
->
w
&&
srcrect
->
h
==
dstrect
->
h
)
{
if
(
!
BitBlt
(
data
->
current_hdc
,
dstrect
->
x
,
dstrect
->
y
,
dstrect
->
w
,
srcrect
->
h
,
data
->
memory_hdc
,
srcrect
->
x
,
srcrect
->
y
,
SRCCOPY
))
{
WIN_SetError
(
"BitBlt()"
);
return
-
1
;
}
}
else
{
if
(
!
StretchBlt
(
data
->
current_hdc
,
dstrect
->
x
,
dstrect
->
y
,
dstrect
->
w
,
dstrect
->
h
,
data
->
memory_hdc
,
srcrect
->
x
,
srcrect
->
y
,
srcrect
->
w
,
srcrect
->
h
,
SRCCOPY
))
{
WIN_SetError
(
"StretchBlt()"
);
return
-
1
;
}
}
}
return
0
;
}
static
int
GDI_RenderReadPixels
(
SDL_Renderer
*
renderer
,
const
SDL_Rect
*
rect
,
Uint32
format
,
void
*
pixels
,
int
pitch
)
{
GDI_RenderData
*
renderdata
=
(
GDI_RenderData
*
)
renderer
->
driverdata
;
SDL_Window
*
window
=
renderer
->
window
;
SDL_VideoDisplay
*
display
=
window
->
display
;
struct
{
HBITMAP
hbm
;
void
*
pixels
;
int
pitch
;
Uint32
format
;
}
data
;
data
.
format
=
display
->
current_mode
.
format
;
data
.
pitch
=
(
rect
->
w
*
SDL_BYTESPERPIXEL
(
data
.
format
));
data
.
hbm
=
GDI_CreateDIBSection
(
renderdata
->
memory_hdc
,
rect
->
w
,
rect
->
h
,
data
.
pitch
,
data
.
format
,
NULL
,
&
data
.
pixels
);
if
(
!
data
.
hbm
)
{
WIN_SetError
(
"Couldn't create bitmap"
);
return
-
1
;
}
SelectObject
(
renderdata
->
memory_hdc
,
data
.
hbm
);
if
(
!
BitBlt
(
renderdata
->
memory_hdc
,
0
,
0
,
rect
->
w
,
rect
->
h
,
renderdata
->
current_hdc
,
rect
->
x
,
rect
->
y
,
SRCCOPY
))
{
WIN_SetError
(
"BitBlt()"
);
DeleteObject
(
data
.
hbm
);
return
-
1
;
}
SDL_ConvertPixels
(
rect
->
w
,
rect
->
h
,
data
.
format
,
data
.
pixels
,
data
.
pitch
,
format
,
pixels
,
pitch
);
DeleteObject
(
data
.
hbm
);
return
0
;
}
static
int
GDI_RenderWritePixels
(
SDL_Renderer
*
renderer
,
const
SDL_Rect
*
rect
,
Uint32
format
,
const
void
*
pixels
,
int
pitch
)
{
GDI_RenderData
*
renderdata
=
(
GDI_RenderData
*
)
renderer
->
driverdata
;
SDL_Window
*
window
=
renderer
->
window
;
SDL_VideoDisplay
*
display
=
window
->
display
;
struct
{
HBITMAP
hbm
;
void
*
pixels
;
int
pitch
;
Uint32
format
;
}
data
;
data
.
format
=
display
->
current_mode
.
format
;
data
.
pitch
=
(
rect
->
w
*
SDL_BYTESPERPIXEL
(
data
.
format
));
data
.
hbm
=
GDI_CreateDIBSection
(
renderdata
->
memory_hdc
,
rect
->
w
,
rect
->
h
,
data
.
pitch
,
data
.
format
,
NULL
,
&
data
.
pixels
);
if
(
!
data
.
hbm
)
{
WIN_SetError
(
"Couldn't create bitmap"
);
return
-
1
;
}
SDL_ConvertPixels
(
rect
->
w
,
rect
->
h
,
format
,
pixels
,
pitch
,
data
.
format
,
data
.
pixels
,
data
.
pitch
);
SelectObject
(
renderdata
->
memory_hdc
,
data
.
hbm
);
if
(
!
BitBlt
(
renderdata
->
current_hdc
,
rect
->
x
,
rect
->
y
,
rect
->
w
,
rect
->
h
,
renderdata
->
memory_hdc
,
0
,
0
,
SRCCOPY
))
{
WIN_SetError
(
"BitBlt()"
);
DeleteObject
(
data
.
hbm
);
return
-
1
;
}
DeleteObject
(
data
.
hbm
);
return
0
;
}
static
void
GDI_RenderPresent
(
SDL_Renderer
*
renderer
)
{
GDI_RenderData
*
data
=
(
GDI_RenderData
*
)
renderer
->
driverdata
;
SDL_DirtyRect
*
dirty
;
/* Send the data to the display */
if
(
!
(
renderer
->
info
.
flags
&
SDL_RENDERER_SINGLEBUFFER
))
{
for
(
dirty
=
data
->
dirty
.
list
;
dirty
;
dirty
=
dirty
->
next
)
{
const
SDL_Rect
*
rect
=
&
dirty
->
rect
;
BitBlt
(
data
->
window_hdc
,
rect
->
x
,
rect
->
y
,
rect
->
w
,
rect
->
h
,
data
->
render_hdc
,
rect
->
x
,
rect
->
y
,
SRCCOPY
);
}
SDL_ClearDirtyRects
(
&
data
->
dirty
);
}
/* Update the flipping chain, if any */
if
(
renderer
->
info
.
flags
&
SDL_RENDERER_PRESENTFLIP2
)
{
data
->
current_hbm
=
(
data
->
current_hbm
+
1
)
%
2
;
SelectObject
(
data
->
render_hdc
,
data
->
hbm
[
data
->
current_hbm
]);
}
else
if
(
renderer
->
info
.
flags
&
SDL_RENDERER_PRESENTFLIP3
)
{
data
->
current_hbm
=
(
data
->
current_hbm
+
1
)
%
3
;
SelectObject
(
data
->
render_hdc
,
data
->
hbm
[
data
->
current_hbm
]);
}
}
static
void
GDI_DestroyTexture
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
)
{
GDI_TextureData
*
data
=
(
GDI_TextureData
*
)
texture
->
driverdata
;
if
(
!
data
)
{
return
;
}
if
(
data
->
yuv
)
{
SDL_SW_DestroyYUVTexture
(
data
->
yuv
);
}
if
(
data
->
hpal
)
{
DeleteObject
(
data
->
hpal
);
}
if
(
data
->
hbm
)
{
DeleteObject
(
data
->
hbm
);
}
SDL_free
(
data
);
texture
->
driverdata
=
NULL
;
}
static
void
GDI_DestroyRenderer
(
SDL_Renderer
*
renderer
)
{
GDI_RenderData
*
data
=
(
GDI_RenderData
*
)
renderer
->
driverdata
;
int
i
;
if
(
data
)
{
DeleteDC
(
data
->
render_hdc
);
DeleteDC
(
data
->
memory_hdc
);
#ifndef NO_GETDIBBITS
if
(
data
->
bmi
)
{
SDL_free
(
data
->
bmi
);
}
#endif
for
(
i
=
0
;
i
<
SDL_arraysize
(
data
->
hbm
);
++
i
)
{
if
(
data
->
hbm
[
i
])
{
DeleteObject
(
data
->
hbm
[
i
]);
}
}
SDL_FreeDirtyRects
(
&
data
->
dirty
);
SDL_free
(
data
);
}
SDL_free
(
renderer
);
}
#endif
/* SDL_VIDEO_RENDER_GDI */
/* vi: set ts=4 sw=4 expandtab: */
src/video/windows/SDL_gdirender.h
deleted
100644 → 0
View file @
886e9476
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
/* SDL surface based renderer implementation */
#if SDL_VIDEO_RENDER_GDI
extern
void
GDI_AddRenderDriver
(
_THIS
);
#endif
/* vi: set ts=4 sw=4 expandtab: */
src/video/windows/SDL_windowsvideo.c
View file @
9c126183
...
@@ -225,9 +225,6 @@ WIN_VideoInit(_THIS)
...
@@ -225,9 +225,6 @@ WIN_VideoInit(_THIS)
#if SDL_VIDEO_RENDER_DDRAW
#if SDL_VIDEO_RENDER_DDRAW
DDRAW_AddRenderDriver
(
_this
);
DDRAW_AddRenderDriver
(
_this
);
#endif
#endif
#if SDL_VIDEO_RENDER_GDI
GDI_AddRenderDriver
(
_this
);
#endif
#if SDL_VIDEO_RENDER_GAPI
#if SDL_VIDEO_RENDER_GAPI
WINCE_AddRenderDriver
(
_this
);
WINCE_AddRenderDriver
(
_this
);
#endif
#endif
...
...
src/video/x11/SDL_x11render.c
deleted
100644 → 0
View file @
886e9476
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
#if SDL_VIDEO_RENDER_X11
#include <limits.h>
/* For INT_MIN and INT_MAX */
#include "SDL_x11video.h"
#include "SDL_x11render.h"
#include "../SDL_rect_c.h"
#include "../SDL_pixels_c.h"
#include "../SDL_yuv_sw_c.h"
/* X11 renderer implementation */
static
SDL_Renderer
*
X11_CreateRenderer
(
SDL_Window
*
window
,
Uint32
flags
);
static
int
X11_DisplayModeChanged
(
SDL_Renderer
*
renderer
);
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
,
SDL_Texture
*
texture
);
static
int
X11_UpdateTexture
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
,
const
SDL_Rect
*
rect
,
const
void
*
pixels
,
int
pitch
);
static
int
X11_LockTexture
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
,
const
SDL_Rect
*
rect
,
int
markDirty
,
void
**
pixels
,
int
*
pitch
);
static
void
X11_UnlockTexture
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
);
static
int
X11_SetDrawBlendMode
(
SDL_Renderer
*
renderer
);
static
int
X11_RenderDrawPoints
(
SDL_Renderer
*
renderer
,
const
SDL_Point
*
points
,
int
count
);
static
int
X11_RenderDrawLines
(
SDL_Renderer
*
renderer
,
const
SDL_Point
*
points
,
int
count
);
static
int
X11_RenderDrawRects
(
SDL_Renderer
*
renderer
,
const
SDL_Rect
**
rects
,
int
count
);
static
int
X11_RenderFillRects
(
SDL_Renderer
*
renderer
,
const
SDL_Rect
**
rects
,
int
count
);
static
int
X11_RenderCopy
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
,
const
SDL_Rect
*
srcrect
,
const
SDL_Rect
*
dstrect
);
static
int
X11_RenderReadPixels
(
SDL_Renderer
*
renderer
,
const
SDL_Rect
*
rect
,
Uint32
format
,
void
*
pixels
,
int
pitch
);
static
int
X11_RenderWritePixels
(
SDL_Renderer
*
renderer
,
const
SDL_Rect
*
rect
,
Uint32
format
,
const
void
*
pixels
,
int
pitch
);
static
void
X11_RenderPresent
(
SDL_Renderer
*
renderer
);
static
void
X11_DestroyTexture
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
);
static
void
X11_DestroyRenderer
(
SDL_Renderer
*
renderer
);
SDL_RenderDriver
X11_RenderDriver
=
{
X11_CreateRenderer
,
{
"x11"
,
(
SDL_RENDERER_SINGLEBUFFER
|
SDL_RENDERER_PRESENTCOPY
|
SDL_RENDERER_PRESENTFLIP2
|
SDL_RENDERER_PRESENTFLIP3
|
SDL_RENDERER_PRESENTDISCARD
|
SDL_RENDERER_ACCELERATED
),
SDL_TEXTUREMODULATE_NONE
,
SDL_BLENDMODE_NONE
,
SDL_SCALEMODE_NONE
,
0
,
{
0
},
0
,
0
}
};
typedef
struct
{
Display
*
display
;
int
screen
;
Visual
*
visual
;
int
depth
;
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
;
GC
gc
;
SDL_DirtyRectList
dirty
;
SDL_bool
makedirty
;
}
X11_RenderData
;
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 */
XShmSegmentInfo
shminfo
;
#endif
XImage
*
scaling_image
;
void
*
pixels
;
int
pitch
;
}
X11_TextureData
;
#ifndef NO_SHARED_MEMORY
/* Shared memory error handler routine */
static
int
shm_error
;
static
int
(
*
X_handler
)
(
Display
*
,
XErrorEvent
*
)
=
NULL
;
static
int
shm_errhandler
(
Display
*
d
,
XErrorEvent
*
e
)
{
if
(
e
->
error_code
==
BadAccess
)
{
shm_error
=
True
;
return
(
0
);
}
else
{
return
(
X_handler
(
d
,
e
));
}
}
#endif
/* ! NO_SHARED_MEMORY */
static
void
UpdateYUVTextureData
(
SDL_Texture
*
texture
)
{
X11_TextureData
*
data
=
(
X11_TextureData
*
)
texture
->
driverdata
;
SDL_Rect
rect
;
rect
.
x
=
0
;
rect
.
y
=
0
;
rect
.
w
=
texture
->
w
;
rect
.
h
=
texture
->
h
;
SDL_SW_CopyYUVToRGB
(
data
->
yuv
,
&
rect
,
data
->
format
,
texture
->
w
,
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
;
}
if
(
*
major
!=
0
||
*
minor
<
10
)
{
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
;
}
if
(
*
major
<
2
)
{
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
;
info
->
texture_formats
[
info
->
num_texture_formats
++
]
=
SDL_PIXELFORMAT_YV12
;
info
->
texture_formats
[
info
->
num_texture_formats
++
]
=
SDL_PIXELFORMAT_IYUV
;
info
->
texture_formats
[
info
->
num_texture_formats
++
]
=
SDL_PIXELFORMAT_YUY2
;
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
;
/* Convert each XRenderPictFormat into appropriate
* SDLPixelFormatEnum. */
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
;
}
/* Update the capabilities of the renderer. */
info
->
blend_modes
|=
(
SDL_BLENDMODE_BLEND
|
SDL_BLENDMODE_ADD
|
SDL_BLENDMODE_MOD
|
SDL_BLENDMODE_MASK
);
info
->
scale_modes
|=
(
SDL_SCALEMODE_FAST
|
SDL_SCALEMODE_SLOW
|
SDL_SCALEMODE_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
);
}
}
SDL_Renderer
*
X11_CreateRenderer
(
SDL_Window
*
window
,
Uint32
flags
)
{
SDL_VideoDisplay
*
display
=
window
->
display
;
SDL_DisplayData
*
displaydata
=
(
SDL_DisplayData
*
)
display
->
driverdata
;
SDL_WindowData
*
windowdata
=
(
SDL_WindowData
*
)
window
->
driverdata
;
SDL_Renderer
*
renderer
;
X11_RenderData
*
data
;
XGCValues
gcv
;
gcv
.
graphics_exposures
=
False
;
int
i
,
n
;
int
bpp
;
Uint32
Rmask
,
Gmask
,
Bmask
,
Amask
;
renderer
=
(
SDL_Renderer
*
)
SDL_calloc
(
1
,
sizeof
(
*
renderer
));
if
(
!
renderer
)
{
SDL_OutOfMemory
();
return
NULL
;
}
data
=
(
X11_RenderData
*
)
SDL_calloc
(
1
,
sizeof
(
*
data
));
if
(
!
data
)
{
X11_DestroyRenderer
(
renderer
);
SDL_OutOfMemory
();
return
NULL
;
}
data
->
display
=
windowdata
->
videodata
->
display
;
data
->
screen
=
displaydata
->
screen
;
data
->
visual
=
displaydata
->
visual
;
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
;
renderer
->
LockTexture
=
X11_LockTexture
;
renderer
->
UnlockTexture
=
X11_UnlockTexture
;
renderer
->
SetDrawBlendMode
=
X11_SetDrawBlendMode
;
renderer
->
RenderDrawPoints
=
X11_RenderDrawPoints
;
renderer
->
RenderDrawLines
=
X11_RenderDrawLines
;
renderer
->
RenderDrawRects
=
X11_RenderDrawRects
;
renderer
->
RenderFillRects
=
X11_RenderFillRects
;
renderer
->
RenderCopy
=
X11_RenderCopy
;
renderer
->
RenderReadPixels
=
X11_RenderReadPixels
;
renderer
->
RenderWritePixels
=
X11_RenderWritePixels
;
renderer
->
RenderPresent
=
X11_RenderPresent
;
renderer
->
DestroyTexture
=
X11_DestroyTexture
;
renderer
->
DestroyRenderer
=
X11_DestroyRenderer
;
renderer
->
info
=
X11_RenderDriver
.
info
;
renderer
->
window
=
window
;
renderer
->
driverdata
=
data
;
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
))
{
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
);
if
(
!
data
->
stencil
)
{
SDL_SetError
(
"XCreatePixmap() failed."
);
return
NULL
;
}
/* Create the GC for the clip mask. */
data
->
stencil_gc
=
XCreateGC
(
data
->
display
,
data
->
stencil
,
GCGraphicsExposures
,
&
gcv
);
/* Set the GC parameters. */
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
);
/* Create an XRender Picture for the clip mask. */
data
->
stencil_pict
=
XRenderCreatePicture
(
data
->
display
,
data
->
stencil
,
XRenderFindStandardFormat
(
data
->
display
,
PictStandardARGB32
),
0
,
NULL
);
if
(
!
data
->
stencil_pict
)
{
SDL_SetError
(
"XRenderCreatePicture() failed."
);
return
NULL
;
}
#ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
if
(
data
->
use_xdamage
)
{
data
->
stencil_damage
=
XDamageCreate
(
data
->
display
,
data
->
stencil
,
XDamageReportNonEmpty
);
if
(
!
data
->
stencil_damage
)
{
SDL_SetError
(
"XDamageCreate() failed."
);
return
NULL
;
}
XDamageSubtract
(
data
->
display
,
data
->
stencil_damage
,
None
,
data
->
stencil_parts
);
}
#endif
/* Create a brush pixmap for the color being
* drawn at any given time. */
data
->
brush
=
XCreatePixmap
(
data
->
display
,
data
->
xwindow
,
1
,
1
,
32
);
if
(
!
data
->
brush
)
{
SDL_SetError
(
"XCreatePixmap() failed."
);
return
NULL
;
}
/* Set some parameters for the brush. */
XRenderPictureAttributes
brush_attr
;
brush_attr
.
repeat
=
RepeatNormal
;
/* Create an XRender Picture for the brush
* with the above parameters. */
data
->
brush_pict
=
XRenderCreatePicture
(
data
->
display
,
data
->
brush
,
XRenderFindStandardFormat
(
data
->
display
,
PictStandardARGB32
),
CPRepeat
,
&
brush_attr
);
if
(
!
data
->
brush_pict
)
{
SDL_SetError
(
"XRenderCreatePicture() failed."
);
return
NULL
;
}
// FIXME: Is the following necessary?
/* 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
);
n
=
0
;
}
else
if
(
flags
&
SDL_RENDERER_PRESENTFLIP2
)
{
renderer
->
info
.
flags
|=
SDL_RENDERER_PRESENTFLIP2
;
n
=
2
;
}
else
if
(
flags
&
SDL_RENDERER_PRESENTFLIP3
)
{
renderer
->
info
.
flags
|=
SDL_RENDERER_PRESENTFLIP3
;
n
=
3
;
}
else
{
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
)
{
#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
])
{
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
;
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
/* When using XRender the drawable format
* is not the same as the screen format. */
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
->
drawable
,
GCGraphicsExposures
,
&
gcv
);
if
(
!
data
->
gc
)
{
X11_DestroyRenderer
(
renderer
);
SDL_SetError
(
"XCreateGC() failed"
);
return
NULL
;
}
return
renderer
;
}
static
int
X11_DisplayModeChanged
(
SDL_Renderer
*
renderer
)
{
X11_RenderData
*
data
=
(
X11_RenderData
*
)
renderer
->
driverdata
;
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
);
if
(
!
data
->
xwindow_pict_fmt
)
{
SDL_SetError
(
"XRenderFindVisualFormat() failed."
);
return
-
1
;
}
data
->
xwindow_pict
=
XRenderCreatePicture
(
data
->
display
,
data
->
xwindow
,
data
->
xwindow_pict_fmt
,
0
,
NULL
);
if
(
!
data
->
xwindow_pict
)
{
SDL_SetError
(
"XRenderCreatePicture() failed."
);
return
-
1
;
}
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
);
data
->
stencil
=
XCreatePixmap
(
data
->
display
,
data
->
xwindow
,
window
->
w
,
window
->
h
,
32
);
if
(
!
data
->
stencil
)
{
SDL_SetError
(
"XCreatePixmap() failed."
);
return
-
1
;
}
XRenderFreePicture
(
data
->
display
,
data
->
stencil_pict
);
data
->
stencil_pict
=
XRenderCreatePicture
(
data
->
display
,
data
->
stencil
,
XRenderFindStandardFormat
(
data
->
display
,
PictStandardARGB32
),
0
,
NULL
);
if
(
!
data
->
stencil_pict
)
{
SDL_SetError
(
"XRenderCreatePicture() failed."
);
return
-
1
;
}
#ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
if
(
data
->
use_xdamage
)
{
XDamageDestroy
(
data
->
display
,
data
->
stencil_damage
);
data
->
stencil_damage
=
XDamageCreate
(
data
->
display
,
data
->
stencil
,
XDamageReportNonEmpty
);
if
(
!
data
->
stencil_damage
)
{
SDL_SetError
(
"XDamageCreate() failed."
);
return
-
1
;
}
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
)
{
n
=
2
;
}
else
if
(
renderer
->
info
.
flags
&
SDL_RENDERER_PRESENTFLIP3
)
{
n
=
3
;
}
else
{
n
=
1
;
}
for
(
i
=
0
;
i
<
n
;
++
i
)
{
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
)
{
#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
)
{
X11_RenderData
*
renderdata
=
(
X11_RenderData
*
)
renderer
->
driverdata
;
SDL_Window
*
window
=
renderer
->
window
;
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
);
if
(
!
data
->
yuv
)
{
return
-
1
;
}
data
->
format
=
display
->
current_mode
.
format
;
}
else
{
#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
;
}
if
(
data
->
yuv
||
texture
->
access
==
SDL_TEXTUREACCESS_STREAMING
)
{
#ifndef NO_SHARED_MEMORY
XShmSegmentInfo
*
shminfo
=
&
data
->
shminfo
;
shm_error
=
True
;
if
(
SDL_X11_HAVE_SHM
)
{
data
->
image
=
XShmCreateImage
(
renderdata
->
display
,
data
->
visual
,
data
->
depth
,
ZPixmap
,
NULL
,
shminfo
,
texture
->
w
,
texture
->
h
);
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
)
{
shminfo
->
shmaddr
=
NULL
;
}
if
(
!
data
->
image
)
#endif
/* not NO_SHARED_MEMORY */
{
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
;
}
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
;
}
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
;
}
}
data
->
pitch
=
data
->
image
->
bytes_per_line
;
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
renderdata
->
use_xrender
&&
!
data
->
yuv
)
{
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
(
"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
;
}
// FIXME: Is the following required?
/* Set the default blending and scaling modes. */
texture
->
blendMode
=
SDL_BLENDMODE_NONE
;
texture
->
scaleMode
=
SDL_SCALEMODE_NONE
;
data
->
blend_op
=
PictOpSrc
;
data
->
filter
=
NULL
;
}
#endif
return
0
;
}
static
int
X11_QueryTexturePixels
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
,
void
**
pixels
,
int
*
pitch
)
{
X11_TextureData
*
data
=
(
X11_TextureData
*
)
texture
->
driverdata
;
if
(
data
->
yuv
)
{
return
SDL_SW_QueryYUVTexturePixels
(
data
->
yuv
,
pixels
,
pitch
);
}
else
{
*
pixels
=
data
->
pixels
;
*
pitch
=
data
->
pitch
;
return
0
;
}
}
static
int
X11_SetTextureRGBAMod
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
)
{
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
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
;
}
#else
SDL_Unsupported
();
return
-
1
;
#endif
}
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
;
}
}
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_SCALEMODE_NONE
:
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
renderdata
->
use_xrender
)
{
data
->
filter
=
NULL
;
}
#endif
return
0
;
case
SDL_SCALEMODE_FAST
:
/* We can sort of fake it for streaming textures */
if
(
data
->
yuv
||
texture
->
access
==
SDL_TEXTUREACCESS_STREAMING
)
{
return
0
;
}
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
renderdata
->
use_xrender
)
{
data
->
filter
=
FilterFast
;
return
0
;
}
case
SDL_SCALEMODE_SLOW
:
if
(
renderdata
->
use_xrender
)
{
data
->
filter
=
FilterGood
;
return
0
;
}
case
SDL_SCALEMODE_BEST
:
if
(
renderdata
->
use_xrender
)
{
data
->
filter
=
FilterBest
;
return
0
;
}
#endif
/* Fall through to unsupported case */
default:
SDL_Unsupported
();
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
renderdata
->
use_xrender
)
{
texture
->
scaleMode
=
SDL_SCALEMODE_NONE
;
data
->
filter
=
NULL
;
}
else
#endif
texture
->
scaleMode
=
SDL_SCALEMODE_NONE
;
return
-
1
;
}
return
0
;
}
static
int
X11_UpdateTexture
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
,
const
SDL_Rect
*
rect
,
const
void
*
pixels
,
int
pitch
)
{
X11_TextureData
*
data
=
(
X11_TextureData
*
)
texture
->
driverdata
;
if
(
data
->
yuv
)
{
if
(
SDL_SW_UpdateYUVTexture
(
data
->
yuv
,
rect
,
pixels
,
pitch
)
<
0
)
{
return
-
1
;
}
UpdateYUVTextureData
(
texture
);
return
0
;
}
else
{
X11_RenderData
*
renderdata
=
(
X11_RenderData
*
)
renderer
->
driverdata
;
if
(
data
->
pixels
)
{
Uint8
*
src
,
*
dst
;
int
row
;
size_t
length
;
src
=
(
Uint8
*
)
pixels
;
dst
=
(
Uint8
*
)
data
->
pixels
+
rect
->
y
*
data
->
pitch
+
rect
->
x
*
SDL_BYTESPERPIXEL
(
texture
->
format
);
length
=
rect
->
w
*
SDL_BYTESPERPIXEL
(
texture
->
format
);
for
(
row
=
0
;
row
<
rect
->
h
;
++
row
)
{
SDL_memcpy
(
dst
,
src
,
length
);
src
+=
pitch
;
dst
+=
data
->
pitch
;
}
}
else
{
data
->
image
->
width
=
rect
->
w
;
data
->
image
->
height
=
rect
->
h
;
data
->
image
->
data
=
(
char
*
)
pixels
;
data
->
image
->
bytes_per_line
=
pitch
;
XPutImage
(
renderdata
->
display
,
data
->
pixmap
,
data
->
gc
,
data
->
image
,
0
,
0
,
rect
->
x
,
rect
->
y
,
rect
->
w
,
rect
->
h
);
}
return
0
;
}
}
static
int
X11_LockTexture
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
,
const
SDL_Rect
*
rect
,
int
markDirty
,
void
**
pixels
,
int
*
pitch
)
{
X11_TextureData
*
data
=
(
X11_TextureData
*
)
texture
->
driverdata
;
if
(
data
->
yuv
)
{
return
SDL_SW_LockYUVTexture
(
data
->
yuv
,
rect
,
markDirty
,
pixels
,
pitch
);
}
else
if
(
data
->
pixels
)
{
*
pixels
=
(
void
*
)
((
Uint8
*
)
data
->
pixels
+
rect
->
y
*
data
->
pitch
+
rect
->
x
*
SDL_BYTESPERPIXEL
(
texture
->
format
));
*
pitch
=
data
->
pitch
;
return
0
;
}
else
{
SDL_SetError
(
"No pixels available"
);
return
-
1
;
}
}
static
void
X11_UnlockTexture
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
)
{
X11_TextureData
*
data
=
(
X11_TextureData
*
)
texture
->
driverdata
;
if
(
data
->
yuv
)
{
SDL_SW_UnlockYUVTexture
(
data
->
yuv
);
UpdateYUVTextureData
(
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
();
#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
;
}
}
static
Uint32
renderdrawcolor
(
SDL_Renderer
*
renderer
,
int
premult
)
{
X11_RenderData
*
data
=
(
X11_RenderData
*
)
renderer
->
driverdata
;
Uint8
r
=
renderer
->
r
;
Uint8
g
=
renderer
->
g
;
Uint8
b
=
renderer
->
b
;
Uint8
a
=
renderer
->
a
;
if
(
premult
)
return
SDL_MapRGBA
(
&
data
->
format
,
((
int
)
r
*
(
int
)
a
)
/
255
,
((
int
)
g
*
(
int
)
a
)
/
255
,
((
int
)
b
*
(
int
)
a
)
/
255
,
255
);
else
return
SDL_MapRGBA
(
&
data
->
format
,
r
,
g
,
b
,
a
);
}
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
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
;
}
#endif
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
;
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
;
/* Get the smallest rectangle that contains everything */
rect
.
x
=
0
;
rect
.
y
=
0
;
rect
.
w
=
window
->
w
;
rect
.
h
=
window
->
h
;
if
(
!
SDL_EnclosePoints
(
points
,
count
,
&
rect
,
&
rect
))
{
/* Nothing to draw */
return
0
;
}
SDL_AddDirtyRect
(
&
data
->
dirty
,
&
rect
);
}
{
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
}
#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
)
{
/* 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
,
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
}
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
;
}
static
int
X11_RenderDrawLines
(
SDL_Renderer
*
renderer
,
const
SDL_Point
*
points
,
int
count
)
{
X11_RenderData
*
data
=
(
X11_RenderData
*
)
renderer
->
driverdata
;
SDL_Window
*
window
=
renderer
->
window
;
SDL_Rect
clip
;
unsigned
long
foreground
;
XPoint
*
xpoints
,
*
xpoint
;
int
i
,
xcount
;
int
minx
,
miny
;
int
maxx
,
maxy
;
clip
.
x
=
0
;
clip
.
y
=
0
;
clip
.
w
=
window
->
w
;
clip
.
h
=
window
->
h
;
{
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
;
}
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
;
}
/* We need to clip the line segments joined by this point */
if
(
xcount
>
0
)
{
int
x1
=
xpoint
[
-
1
].
x
;
int
y1
=
xpoint
[
-
1
].
y
;
int
x2
=
x
;
int
y2
=
y
;
if
(
SDL_IntersectRectAndLine
(
&
clip
,
&
x1
,
&
y1
,
&
x2
,
&
y2
))
{
if
(
x2
<
minx
)
{
minx
=
x2
;
}
else
if
(
x2
>
maxx
)
{
maxx
=
x2
;
}
if
(
y2
<
miny
)
{
miny
=
y2
;
}
else
if
(
y2
>
maxy
)
{
maxy
=
y2
;
}
xpoint
->
x
=
(
short
)
x2
;
xpoint
->
y
=
(
short
)
y2
;
++
xpoint
;
++
xcount
;
}
XDrawLines
(
data
->
display
,
drawable
,
gc
,
xpoints
,
xcount
,
CoordModeOrigin
);
if
(
xpoints
[
0
].
x
!=
x2
||
xpoints
[
0
].
y
!=
y2
)
{
XDrawPoint
(
data
->
display
,
drawable
,
gc
,
x2
,
y2
);
}
if
(
data
->
makedirty
)
{
SDL_Rect
rect
;
rect
.
x
=
minx
;
rect
.
y
=
miny
;
rect
.
w
=
(
maxx
-
minx
)
+
1
;
rect
.
h
=
(
maxy
-
miny
)
+
1
;
SDL_AddDirtyRect
(
&
data
->
dirty
,
&
rect
);
}
xpoint
=
xpoints
;
xcount
=
0
;
minx
=
INT_MAX
;
miny
=
INT_MAX
;
maxx
=
INT_MIN
;
maxy
=
INT_MIN
;
}
if
(
i
<
(
count
-
1
))
{
int
x1
=
x
;
int
y1
=
y
;
int
x2
=
points
[
i
+
1
].
x
;
int
y2
=
points
[
i
+
1
].
y
;
if
(
SDL_IntersectRectAndLine
(
&
clip
,
&
x1
,
&
y1
,
&
x2
,
&
y2
))
{
if
(
x1
<
minx
)
{
minx
=
x1
;
}
else
if
(
x1
>
maxx
)
{
maxx
=
x1
;
}
if
(
y1
<
miny
)
{
miny
=
y1
;
}
else
if
(
y1
>
maxy
)
{
maxy
=
y1
;
}
xpoint
->
x
=
(
short
)
x1
;
xpoint
->
y
=
(
short
)
y1
;
++
xpoint
;
++
xcount
;
}
}
}
if
(
xcount
>
1
)
{
int
x2
=
xpoint
[
-
1
].
x
;
int
y2
=
xpoint
[
-
1
].
y
;
XDrawLines
(
data
->
display
,
drawable
,
gc
,
xpoints
,
xcount
,
CoordModeOrigin
);
if
(
xpoints
[
0
].
x
!=
x2
||
xpoints
[
0
].
y
!=
y2
)
{
XDrawPoint
(
data
->
display
,
drawable
,
gc
,
x2
,
y2
);
}
if
(
data
->
makedirty
)
{
SDL_Rect
rect
;
rect
.
x
=
minx
;
rect
.
y
=
miny
;
rect
.
w
=
(
maxx
-
minx
)
+
1
;
rect
.
h
=
(
maxy
-
miny
)
+
1
;
SDL_AddDirtyRect
(
&
data
->
dirty
,
&
rect
);
}
}
}
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
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
);
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
;
}
static
int
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
;
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
;
{
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
);
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
}
#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
}
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
;
}
static
int
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
;
clip
.
x
=
0
;
clip
.
y
=
0
;
clip
.
w
=
window
->
w
;
clip
.
h
=
window
->
h
;
int
i
,
xcount
;
XRectangle
*
xrects
,
*
xrect
;
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
;
xrect
->
height
=
(
unsigned
short
)
rect
.
h
;
++
xrect
;
++
xcount
;
if
(
data
->
makedirty
)
{
SDL_AddDirtyRect
(
&
data
->
dirty
,
&
rect
);
}
}
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
data
->
use_xrender
)
{
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
(
xrects
);
return
0
;
}
static
int
X11_RenderCopy
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
,
const
SDL_Rect
*
srcrect
,
const
SDL_Rect
*
dstrect
)
{
X11_RenderData
*
data
=
(
X11_RenderData
*
)
renderer
->
driverdata
;
X11_TextureData
*
texturedata
=
(
X11_TextureData
*
)
texture
->
driverdata
;
if
(
data
->
makedirty
)
{
SDL_AddDirtyRect
(
&
data
->
dirty
,
dstrect
);
}
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
if
(
data
->
use_xrender
&&
!
texturedata
->
yuv
)
{
if
(
texture
->
access
==
SDL_TEXTUREACCESS_STREAMING
)
{
#ifndef NO_SHARED_MEMORY
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
);
}
Picture
src
,
mask
;
XRenderPictureAttributes
attr
;
const
SDL_Rect
*
mrect
;
/* mrect is the rectangular area of the mask
* picture that is aligned with the source. */
if
(
texture
->
modMode
==
SDL_TEXTUREMODULATE_NONE
)
{
src
=
texturedata
->
picture
;
}
else
{
src
=
texturedata
->
modulated_picture
;
}
if
(
texture
->
blendMode
==
SDL_BLENDMODE_NONE
)
{
mask
=
None
;
mrect
=
srcrect
;
}
else
if
(
texture
->
blendMode
==
SDL_BLENDMODE_MOD
)
{
/* SDL_BLENDMODE_MOD requires a temporary buffer
* i.e. stencil_pict */
mask
=
data
->
stencil_pict
;
mrect
=
dstrect
;
}
else
{
/* This trick allows on-the-fly multiplication
* of the src color channels with it's alpha
* channel. */
mask
=
src
;
mrect
=
srcrect
;
}
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
);
}
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
{
/* The transformation is from the dst to src picture. */
double
xscale
=
((
double
)
srcrect
->
w
)
/
dstrect
->
w
;
double
yscale
=
((
double
)
srcrect
->
h
)
/
dstrect
->
h
;
XTransform
xform
=
{{
{
XDoubleToFixed
(
xscale
),
XDoubleToFixed
(
0
),
XDoubleToFixed
(
0
)},
{
XDoubleToFixed
(
0
),
XDoubleToFixed
(
yscale
),
XDoubleToFixed
(
0
)},
{
XDoubleToFixed
(
0
),
XDoubleToFixed
(
0
),
XDoubleToFixed
(
1
)}}};
XRenderSetPictureTransform
(
data
->
display
,
src
,
&
xform
);
/* Black magic follows. */
if
(
texture
->
blendMode
==
SDL_BLENDMODE_MOD
)
{
/* Copy the dst to a temp buffer. */
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
);
/* Set the compnent alpha flag on the temp buffer. */
attr
.
component_alpha
=
True
;
XRenderChangePicture
(
data
->
display
,
data
->
stencil_pict
,
CPComponentAlpha
,
&
attr
);
}
/* Set the picture filter only if a scaling mode is set. */
if
(
texture
->
scaleMode
!=
SDL_SCALEMODE_NONE
)
{
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
);
/* Set the texture transformation back to the identity matrix. */
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
);
}
/* Reset the component alpha flag only when
* the blending mode is SDL_BLENDMODE_MOD. */
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
)
{
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
);
}
}
else
if
(
texturedata
->
yuv
||
texture
->
access
==
SDL_TEXTUREACCESS_STREAMING
)
{
SDL_Surface
src
,
dst
;
SDL_PixelFormat
fmt
;
SDL_Rect
rect
;
XImage
*
image
=
texturedata
->
scaling_image
;
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
;
}
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
;
}
}
/* 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
);
}
}
return
0
;
}
static
int
X11_RenderReadPixels
(
SDL_Renderer
*
renderer
,
const
SDL_Rect
*
rect
,
Uint32
format
,
void
*
pixels
,
int
pitch
)
{
X11_RenderData
*
data
=
(
X11_RenderData
*
)
renderer
->
driverdata
;
SDL_Window
*
window
=
renderer
->
window
;
SDL_VideoDisplay
*
display
=
window
->
display
;
Uint32
screen_format
=
display
->
current_mode
.
format
;
XImage
*
image
;
image
=
XGetImage
(
data
->
display
,
data
->
drawable
,
rect
->
x
,
rect
->
y
,
rect
->
w
,
rect
->
h
,
AllPlanes
,
ZPixmap
);
SDL_ConvertPixels
(
rect
->
w
,
rect
->
h
,
screen_format
,
image
->
data
,
image
->
bytes_per_line
,
format
,
pixels
,
pitch
);
XDestroyImage
(
image
);
return
0
;
}
static
int
X11_RenderWritePixels
(
SDL_Renderer
*
renderer
,
const
SDL_Rect
*
rect
,
Uint32
format
,
const
void
*
pixels
,
int
pitch
)
{
X11_RenderData
*
data
=
(
X11_RenderData
*
)
renderer
->
driverdata
;
SDL_Window
*
window
=
renderer
->
window
;
SDL_VideoDisplay
*
display
=
window
->
display
;
Uint32
screen_format
=
display
->
current_mode
.
format
;
XImage
*
image
;
void
*
image_pixels
;
int
image_pitch
;
image_pitch
=
rect
->
w
*
SDL_BYTESPERPIXEL
(
screen_format
);
image_pixels
=
SDL_malloc
(
rect
->
h
*
image_pitch
);
if
(
!
image_pixels
)
{
SDL_OutOfMemory
();
return
-
1
;
}
image
=
XCreateImage
(
data
->
display
,
data
->
visual
,
data
->
depth
,
ZPixmap
,
0
,
image_pixels
,
rect
->
w
,
rect
->
h
,
SDL_BYTESPERPIXEL
(
screen_format
)
*
8
,
image_pitch
);
if
(
!
image
)
{
SDL_SetError
(
"XCreateImage() failed"
);
return
-
1
;
}
SDL_ConvertPixels
(
rect
->
w
,
rect
->
h
,
format
,
pixels
,
pitch
,
screen_format
,
image
->
data
,
image
->
bytes_per_line
);
XPutImage
(
data
->
display
,
data
->
drawable
,
data
->
gc
,
image
,
0
,
0
,
rect
->
x
,
rect
->
y
,
rect
->
w
,
rect
->
h
);
image
->
data
=
NULL
;
XDestroyImage
(
image
);
SDL_free
(
image_pixels
);
return
0
;
}
static
void
X11_RenderPresent
(
SDL_Renderer
*
renderer
)
{
X11_RenderData
*
data
=
(
X11_RenderData
*
)
renderer
->
driverdata
;
SDL_DirtyRect
*
dirty
;
/* Send the data to the display */
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
);
}
XSync
(
data
->
display
,
False
);
/* Update the flipping chain, if any */
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
}
}
static
void
X11_DestroyTexture
(
SDL_Renderer
*
renderer
,
SDL_Texture
*
texture
)
{
X11_RenderData
*
renderdata
=
(
X11_RenderData
*
)
renderer
->
driverdata
;
X11_TextureData
*
data
=
(
X11_TextureData
*
)
texture
->
driverdata
;
if
(
!
data
)
{
return
;
}
if
(
data
->
yuv
)
{
SDL_SW_DestroyYUVTexture
(
data
->
yuv
);
}
if
(
data
->
pixmap
!=
None
)
{
XFreePixmap
(
renderdata
->
display
,
data
->
pixmap
);
}
if
(
data
->
image
)
{
data
->
image
->
data
=
NULL
;
XDestroyImage
(
data
->
image
);
}
#ifndef NO_SHARED_MEMORY
if
(
data
->
shminfo
.
shmaddr
)
{
XShmDetach
(
renderdata
->
display
,
&
data
->
shminfo
);
XSync
(
renderdata
->
display
,
False
);
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
);
data
->
scaling_image
->
data
=
NULL
;
XDestroyImage
(
data
->
scaling_image
);
}
if
(
data
->
pixels
)
{
SDL_free
(
data
->
pixels
);
}
SDL_free
(
data
);
texture
->
driverdata
=
NULL
;
}
static
void
X11_DestroyRenderer
(
SDL_Renderer
*
renderer
)
{
X11_RenderData
*
data
=
(
X11_RenderData
*
)
renderer
->
driverdata
;
int
i
;
if
(
data
)
{
for
(
i
=
0
;
i
<
SDL_arraysize
(
data
->
pixmaps
);
++
i
)
{
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
);
}
SDL_free
(
renderer
);
}
#endif
/* SDL_VIDEO_RENDER_X11 */
/* vi: set ts=4 sw=4 expandtab: */
src/video/x11/SDL_x11render.h
deleted
100644 → 0
View file @
886e9476
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
/* SDL surface based renderer implementation */
#if SDL_VIDEO_RENDER_X11
extern
void
X11_AddRenderDriver
(
_THIS
);
#endif
/* vi: set ts=4 sw=4 expandtab: */
src/video/x11/SDL_x11video.c
View file @
9c126183
...
@@ -350,10 +350,6 @@ X11_VideoInit(_THIS)
...
@@ -350,10 +350,6 @@ X11_VideoInit(_THIS)
return
-
1
;
return
-
1
;
}
}
#if SDL_VIDEO_RENDER_X11
X11_AddRenderDriver
(
_this
);
#endif
if
(
X11_InitKeyboard
(
_this
)
!=
0
)
{
if
(
X11_InitKeyboard
(
_this
)
!=
0
)
{
return
-
1
;
return
-
1
;
}
}
...
...
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