Make it clear that you can't mix 2D rendering and the window surface API

Also added functions to query and destroy the window surface so you can switch between modes if you want.

See https://github.com/pygame-community/pygame-ce/issues/2190 for more details.
This commit is contained in:
Sam Lantinga 2023-06-10 08:39:20 -07:00
parent 5490873daa
commit 281018f169
7 changed files with 154 additions and 957 deletions

View File

@ -1344,6 +1344,17 @@ extern DECLSPEC int SDLCALL SDL_RestoreWindow(SDL_Window *window);
*/
extern DECLSPEC int SDLCALL SDL_SetWindowFullscreen(SDL_Window *window, SDL_bool fullscreen);
/**
* Return whether the window has a surface associated with it.
*
* \returns SDL_TRUE if there is a surface associated with the window, or SDL_FALSE otherwise.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_GetWindowSurface
*/
extern DECLSPEC SDL_bool SDLCALL SDL_HasWindowSurface(SDL_Window *window);
/**
* Get the SDL surface associated with the window.
*
@ -1364,6 +1375,8 @@ extern DECLSPEC int SDLCALL SDL_SetWindowFullscreen(SDL_Window *window, SDL_bool
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_DestroyWindowSurface
* \sa SDL_HasWindowSurface
* \sa SDL_UpdateWindowSurface
* \sa SDL_UpdateWindowSurfaceRects
*/
@ -1410,6 +1423,20 @@ extern DECLSPEC int SDLCALL SDL_UpdateWindowSurface(SDL_Window *window);
*/
extern DECLSPEC int SDLCALL SDL_UpdateWindowSurfaceRects(SDL_Window *window, const SDL_Rect *rects, int numrects);
/**
* Destroy the surface associated with the window.
*
* \param window the window to update
* \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_GetWindowSurface
* \sa SDL_HasWindowSurface
*/
extern DECLSPEC int SDLCALL SDL_DestroyWindowSurface(SDL_Window *window);
/**
* Set a window's input grab mode.
*

View File

@ -864,6 +864,8 @@ SDL3_0.0.0 {
SDL_hid_get_input_report;
SDL_hid_get_device_info;
SDL_hid_get_report_descriptor;
SDL_HasWindowSurface;
SDL_DestroyWindowSurface;
# extra symbols go here (don't modify this line)
local: *;
};

View File

@ -890,3 +890,5 @@
#define SDL_hid_get_input_report SDL_hid_get_input_report_REAL
#define SDL_hid_get_device_info SDL_hid_get_device_info_REAL
#define SDL_hid_get_report_descriptor SDL_hid_get_report_descriptor_REAL
#define SDL_HasWindowSurface SDL_HasWindowSurface_REAL
#define SDL_DestroyWindowSurface SDL_DestroyWindowSurface_REAL

View File

@ -935,3 +935,5 @@ SDL_DYNAPI_PROC(int,SDL_vswprintf,(wchar_t *a, size_t b, const wchar_t *c, va_li
SDL_DYNAPI_PROC(int,SDL_hid_get_input_report,(SDL_hid_device *a, unsigned char *b, size_t c),(a,b,c),return)
SDL_DYNAPI_PROC(SDL_hid_device_info*,SDL_hid_get_device_info,(SDL_hid_device *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_hid_get_report_descriptor,(SDL_hid_device *a, unsigned char *b, size_t c),(a,b,c),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasWindowSurface,(SDL_Window *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_DestroyWindowSurface,(SDL_Window *a),(a),return)

View File

@ -822,6 +822,11 @@ SDL_Renderer *SDL_CreateRenderer(SDL_Window *window, const char *name, Uint32 fl
goto error;
}
if (SDL_HasWindowSurface(window)) {
SDL_SetError("Surface already associated with window");
goto error;
}
if (SDL_GetRenderer(window)) {
SDL_SetError("Renderer already associated with window");
goto error;

View File

@ -2148,12 +2148,7 @@ int SDL_RecreateWindow(SDL_Window *window, Uint32 flags)
}
/* Tear down the old native window */
if (window->surface) {
window->surface->flags &= ~SDL_DONTFREE;
SDL_DestroySurface(window->surface);
window->surface = NULL;
window->surface_valid = SDL_FALSE;
}
SDL_DestroyWindowSurface(window);
if (_this->checked_texture_framebuffer) { /* never checked? No framebuffer to destroy. Don't risk calling the wrong implementation. */
if (_this->DestroyWindowFramebuffer) {
@ -3053,16 +3048,19 @@ static SDL_Surface *SDL_CreateWindowFramebuffer(SDL_Window *window)
return SDL_CreateSurfaceFrom(pixels, w, h, pitch, format);
}
SDL_bool SDL_HasWindowSurface(SDL_Window *window)
{
CHECK_WINDOW_MAGIC(window, SDL_FALSE);
return window->surface ? SDL_TRUE : SDL_FALSE;
}
SDL_Surface *SDL_GetWindowSurface(SDL_Window *window)
{
CHECK_WINDOW_MAGIC(window, NULL);
if (!window->surface_valid) {
if (window->surface) {
window->surface->flags &= ~SDL_DONTFREE;
SDL_DestroySurface(window->surface);
window->surface = NULL;
}
SDL_DestroyWindowSurface(window);
window->surface = SDL_CreateWindowFramebuffer(window);
if (window->surface) {
window->surface_valid = SDL_TRUE;
@ -3122,6 +3120,19 @@ int SDL_SetWindowOpacity(SDL_Window *window, float opacity)
return retval;
}
int SDL_DestroyWindowSurface(SDL_Window *window)
{
CHECK_WINDOW_MAGIC(window, -1);
if (window->surface) {
window->surface->flags &= ~SDL_DONTFREE;
SDL_DestroySurface(window->surface);
window->surface = NULL;
window->surface_valid = SDL_FALSE;
}
return 0;
}
int SDL_GetWindowOpacity(SDL_Window *window, float *out_opacity)
{
CHECK_WINDOW_MAGIC(window, -1);
@ -3553,12 +3564,7 @@ void SDL_DestroyWindow(SDL_Window *window)
SDL_SetMouseFocus(NULL);
}
if (window->surface) {
window->surface->flags &= ~SDL_DONTFREE;
SDL_DestroySurface(window->surface);
window->surface = NULL;
window->surface_valid = SDL_FALSE;
}
SDL_DestroyWindowSurface(window);
if (_this->checked_texture_framebuffer) { /* never checked? No framebuffer to destroy. Don't risk calling the wrong implementation. */
if (_this->DestroyWindowFramebuffer) {

File diff suppressed because it is too large Load Diff