mirror of https://github.com/libsdl-org/SDL
Handle DPI scaling in SDL_GetWindowSurface
Fixes DPI awareness of testdrawchessboard (previously, the surface was being created in points instead of pixels, resulting in the demo app only drawing in a corner of the screen on High-DPI displays) *_CreateWindowFramebuffer()/*_UpdateWindowFramebuffer(): are updated to use SDL_GetWindowSizeInPixels instead of SDL_GetWindowSize() or window->w/window->h. Most of the _CreateWindowFramebuffer backends are untested except for Windows. Fixes #7047
This commit is contained in:
parent
6d11515873
commit
67c91353e0
|
@ -1261,7 +1261,7 @@ extern DECLSPEC int SDLCALL SDL_UpdateWindowSurface(SDL_Window * window);
|
|||
*
|
||||
* \param window the window to update
|
||||
* \param rects an array of SDL_Rect structures representing areas of the
|
||||
* surface to copy
|
||||
* surface to copy, in pixels
|
||||
* \param numrects the number of rectangles
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
|
|
|
@ -90,7 +90,7 @@ static int SW_GetOutputSize(SDL_Renderer *renderer, int *w, int *h)
|
|||
}
|
||||
|
||||
if (renderer->window) {
|
||||
SDL_GetWindowSize(renderer->window, w, h);
|
||||
SDL_GetWindowSizeInPixels(renderer->window, w, h);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -203,6 +203,9 @@ static int SDL_CreateWindowTexture(SDL_VideoDevice *_this, SDL_Window *window, U
|
|||
SDL_RendererInfo info;
|
||||
SDL_WindowTextureData *data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA);
|
||||
int i;
|
||||
int w, h;
|
||||
|
||||
SDL_GetWindowSizeInPixels(window, &w, &h);
|
||||
|
||||
if (data == NULL) {
|
||||
SDL_Renderer *renderer = NULL;
|
||||
|
@ -280,7 +283,7 @@ static int SDL_CreateWindowTexture(SDL_VideoDevice *_this, SDL_Window *window, U
|
|||
|
||||
data->texture = SDL_CreateTexture(data->renderer, *format,
|
||||
SDL_TEXTUREACCESS_STREAMING,
|
||||
window->w, window->h);
|
||||
w, h);
|
||||
if (!data->texture) {
|
||||
/* codechecker_false_positive [Malloc] Static analyzer doesn't realize allocated `data` is saved to SDL_WINDOWTEXTUREDATA and not leaked here. */
|
||||
return -1; /* NOLINT(clang-analyzer-unix.Malloc) */
|
||||
|
@ -288,11 +291,11 @@ static int SDL_CreateWindowTexture(SDL_VideoDevice *_this, SDL_Window *window, U
|
|||
|
||||
/* Create framebuffer data */
|
||||
data->bytes_per_pixel = SDL_BYTESPERPIXEL(*format);
|
||||
data->pitch = (((window->w * data->bytes_per_pixel) + 3) & ~3);
|
||||
data->pitch = (((w * data->bytes_per_pixel) + 3) & ~3);
|
||||
|
||||
{
|
||||
/* Make static analysis happy about potential SDL_malloc(0) calls. */
|
||||
const size_t allocsize = (size_t)window->h * data->pitch;
|
||||
const size_t allocsize = (size_t)h * data->pitch;
|
||||
data->pixels = SDL_malloc((allocsize > 0) ? allocsize : 1);
|
||||
if (!data->pixels) {
|
||||
return SDL_OutOfMemory();
|
||||
|
@ -316,6 +319,9 @@ static int SDL_UpdateWindowTexture(SDL_VideoDevice *unused, SDL_Window *window,
|
|||
SDL_WindowTextureData *data;
|
||||
SDL_Rect rect;
|
||||
void *src;
|
||||
int w, h;
|
||||
|
||||
SDL_GetWindowSizeInPixels(window, &w, &h);
|
||||
|
||||
data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA);
|
||||
if (data == NULL || !data->texture) {
|
||||
|
@ -323,7 +329,7 @@ static int SDL_UpdateWindowTexture(SDL_VideoDevice *unused, SDL_Window *window,
|
|||
}
|
||||
|
||||
/* Update a single rect that contains subrects for best DMA performance */
|
||||
if (SDL_GetSpanEnclosingRect(window->w, window->h, numrects, rects, &rect)) {
|
||||
if (SDL_GetSpanEnclosingRect(w, h, numrects, rects, &rect)) {
|
||||
src = (void *)((Uint8 *)data->pixels +
|
||||
rect.y * data->pitch +
|
||||
rect.x * data->bytes_per_pixel);
|
||||
|
@ -2569,6 +2575,9 @@ static SDL_Surface *SDL_CreateWindowFramebuffer(SDL_Window *window)
|
|||
void *pixels = NULL;
|
||||
int pitch = 0;
|
||||
SDL_bool created_framebuffer = SDL_FALSE;
|
||||
int w, h;
|
||||
|
||||
SDL_GetWindowSizeInPixels(window, &w, &h);
|
||||
|
||||
/* This will switch the video backend from using a software surface to
|
||||
using a GPU texture through the 2D render API, if we think this would
|
||||
|
@ -2643,7 +2652,7 @@ static SDL_Surface *SDL_CreateWindowFramebuffer(SDL_Window *window)
|
|||
return window->surface;
|
||||
}
|
||||
|
||||
return SDL_CreateSurfaceFrom(pixels, window->w, window->h, pitch, format);
|
||||
return SDL_CreateSurfaceFrom(pixels, w, h, pitch, format);
|
||||
}
|
||||
|
||||
SDL_Surface *SDL_GetWindowSurface(SDL_Window *window)
|
||||
|
@ -2673,8 +2682,8 @@ int SDL_UpdateWindowSurface(SDL_Window *window)
|
|||
|
||||
full_rect.x = 0;
|
||||
full_rect.y = 0;
|
||||
full_rect.w = window->w;
|
||||
full_rect.h = window->h;
|
||||
SDL_GetWindowSizeInPixels(window, &full_rect.w, &full_rect.h);
|
||||
|
||||
return SDL_UpdateWindowSurfaceRects(window, &full_rect, 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ int SDL_DUMMY_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format,
|
|||
SDL_DUMMY_DestroyWindowFramebuffer(_this, window);
|
||||
|
||||
/* Create a new one */
|
||||
SDL_GetWindowSize(window, &w, &h);
|
||||
SDL_GetWindowSizeInPixels(window, &w, &h);
|
||||
surface = SDL_CreateSurface(w, h, surface_format);
|
||||
if (surface == NULL) {
|
||||
return -1;
|
||||
|
|
|
@ -39,7 +39,7 @@ int Emscripten_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format
|
|||
SDL_DestroySurface(surface);
|
||||
|
||||
/* Create a new one */
|
||||
SDL_GetWindowSize(window, &w, &h);
|
||||
SDL_GetWindowSizeInPixels(window, &w, &h);
|
||||
|
||||
surface = SDL_CreateSurface(w, h, surface_format);
|
||||
if (surface == NULL) {
|
||||
|
|
|
@ -69,7 +69,7 @@ SDL_FORCE_INLINE SDL_Surface *
|
|||
CreateNewWindowFramebuffer(SDL_Window *window)
|
||||
{
|
||||
int w, h;
|
||||
SDL_GetWindowSize(window, &w, &h);
|
||||
SDL_GetWindowSizeInPixels(window, &w, &h);
|
||||
return SDL_CreateSurface(w, h, FRAMEBUFFER_FORMAT);
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ int SDL_NGAGE_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format,
|
|||
SDL_NGAGE_DestroyWindowFramebuffer(_this, window);
|
||||
|
||||
/* Create a new one */
|
||||
SDL_GetWindowSize(window, &w, &h);
|
||||
SDL_GetWindowSizeInPixels(window, &w, &h);
|
||||
surface = SDL_CreateSurface(w, h, surface_format);
|
||||
if (surface == NULL) {
|
||||
return -1;
|
||||
|
|
|
@ -37,7 +37,7 @@ int SDL_OFFSCREEN_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *for
|
|||
SDL_OFFSCREEN_DestroyWindowFramebuffer(_this, window);
|
||||
|
||||
/* Create a new one */
|
||||
SDL_GetWindowSize(window, &w, &h);
|
||||
SDL_GetWindowSizeInPixels(window, &w, &h);
|
||||
surface = SDL_CreateSurface(w, h, surface_format);
|
||||
if (surface == NULL) {
|
||||
return -1;
|
||||
|
|
|
@ -39,6 +39,9 @@ int RISCOS_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, vo
|
|||
_kernel_swi_regs regs;
|
||||
SDL_DisplayMode mode;
|
||||
int size;
|
||||
int w, h;
|
||||
|
||||
SDL_GetWindowSizeInPixels(window, &w, &h);
|
||||
|
||||
/* Free the old framebuffer surface */
|
||||
RISCOS_DestroyWindowFramebuffer(_this, window);
|
||||
|
@ -54,10 +57,10 @@ int RISCOS_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, vo
|
|||
}
|
||||
|
||||
/* Calculate pitch */
|
||||
*pitch = (((window->w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3);
|
||||
*pitch = (((w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3);
|
||||
|
||||
/* Allocate the sprite area */
|
||||
size = sizeof(sprite_area) + sizeof(sprite_header) + ((*pitch) * window->h);
|
||||
size = sizeof(sprite_area) + sizeof(sprite_header) + ((*pitch) * h);
|
||||
driverdata->fb_area = SDL_malloc(size);
|
||||
if (!driverdata->fb_area) {
|
||||
return SDL_OutOfMemory();
|
||||
|
@ -73,8 +76,8 @@ int RISCOS_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, vo
|
|||
regs.r[1] = (int)driverdata->fb_area;
|
||||
regs.r[2] = (int)sprite_name;
|
||||
regs.r[3] = 0;
|
||||
regs.r[4] = window->w;
|
||||
regs.r[5] = window->h;
|
||||
regs.r[4] = w;
|
||||
regs.r[5] = h;
|
||||
regs.r[6] = sprite_mode;
|
||||
error = _kernel_swi(OS_SpriteOp, ®s, ®s);
|
||||
if (error != NULL) {
|
||||
|
|
|
@ -31,6 +31,9 @@ int WIN_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void
|
|||
size_t size;
|
||||
LPBITMAPINFO info;
|
||||
HBITMAP hbm;
|
||||
int w, h;
|
||||
|
||||
SDL_GetWindowSizeInPixels(window, &w, &h);
|
||||
|
||||
/* Free the old framebuffer surface */
|
||||
if (data->mdc) {
|
||||
|
@ -78,10 +81,10 @@ int WIN_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void
|
|||
}
|
||||
|
||||
/* Fill in the size information */
|
||||
*pitch = (((window->w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3);
|
||||
info->bmiHeader.biWidth = window->w;
|
||||
info->bmiHeader.biHeight = -window->h; /* negative for topdown bitmap */
|
||||
info->bmiHeader.biSizeImage = (DWORD)window->h * (*pitch);
|
||||
*pitch = (((w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3);
|
||||
info->bmiHeader.biWidth = w;
|
||||
info->bmiHeader.biHeight = -h; /* negative for topdown bitmap */
|
||||
info->bmiHeader.biSizeImage = (DWORD)h * (*pitch);
|
||||
|
||||
data->mdc = CreateCompatibleDC(data->hdc);
|
||||
data->hbm = CreateDIBSection(data->hdc, info, DIB_RGB_COLORS, pixels, NULL, 0);
|
||||
|
|
|
@ -55,6 +55,9 @@ int X11_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format,
|
|||
Display *display = data->videodata->display;
|
||||
XGCValues gcv;
|
||||
XVisualInfo vinfo;
|
||||
int w, h;
|
||||
|
||||
SDL_GetWindowSizeInPixels(window, &w, &h);
|
||||
|
||||
/* Free the old framebuffer surface */
|
||||
X11_DestroyWindowFramebuffer(_this, window);
|
||||
|
@ -77,14 +80,14 @@ int X11_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format,
|
|||
}
|
||||
|
||||
/* Calculate pitch */
|
||||
*pitch = (((window->w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3);
|
||||
*pitch = (((w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3);
|
||||
|
||||
/* Create the actual image */
|
||||
#ifndef NO_SHARED_MEMORY
|
||||
if (have_mitshm(display)) {
|
||||
XShmSegmentInfo *shminfo = &data->shminfo;
|
||||
|
||||
shminfo->shmid = shmget(IPC_PRIVATE, (size_t)window->h * (*pitch), IPC_CREAT | 0777);
|
||||
shminfo->shmid = shmget(IPC_PRIVATE, (size_t)h * (*pitch), IPC_CREAT | 0777);
|
||||
if (shminfo->shmid >= 0) {
|
||||
shminfo->shmaddr = (char *)shmat(shminfo->shmid, 0, 0);
|
||||
shminfo->readOnly = False;
|
||||
|
@ -108,7 +111,7 @@ int X11_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format,
|
|||
data->ximage = X11_XShmCreateImage(display, data->visual,
|
||||
vinfo.depth, ZPixmap,
|
||||
shminfo->shmaddr, shminfo,
|
||||
window->w, window->h);
|
||||
w, h);
|
||||
if (!data->ximage) {
|
||||
X11_XShmDetach(display, shminfo);
|
||||
X11_XSync(display, False);
|
||||
|
@ -124,14 +127,14 @@ int X11_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format,
|
|||
}
|
||||
#endif /* not NO_SHARED_MEMORY */
|
||||
|
||||
*pixels = SDL_malloc((size_t)window->h * (*pitch));
|
||||
*pixels = SDL_malloc((size_t)h * (*pitch));
|
||||
if (*pixels == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
data->ximage = X11_XCreateImage(display, data->visual,
|
||||
vinfo.depth, ZPixmap, 0, (char *)(*pixels),
|
||||
window->w, window->h, 32, 0);
|
||||
w, h, 32, 0);
|
||||
if (!data->ximage) {
|
||||
SDL_free(*pixels);
|
||||
return SDL_SetError("Couldn't create XImage");
|
||||
|
@ -147,6 +150,10 @@ int X11_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects
|
|||
Display *display = data->videodata->display;
|
||||
int i;
|
||||
int x, y, w, h;
|
||||
int window_w, window_h;
|
||||
|
||||
SDL_GetWindowSizeInPixels(window, &window_w, &window_h);
|
||||
|
||||
#ifndef NO_SHARED_MEMORY
|
||||
if (data->use_mitshm) {
|
||||
for (i = 0; i < numrects; ++i) {
|
||||
|
@ -167,11 +174,11 @@ int X11_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects
|
|||
y += h;
|
||||
h += rects[i].y;
|
||||
}
|
||||
if (x + w > window->w) {
|
||||
w = window->w - x;
|
||||
if (x + w > window_w) {
|
||||
w = window_w - x;
|
||||
}
|
||||
if (y + h > window->h) {
|
||||
h = window->h - y;
|
||||
if (y + h > window_h) {
|
||||
h = window_h - y;
|
||||
}
|
||||
|
||||
X11_XShmPutImage(display, data->xwindow, data->gc, data->ximage,
|
||||
|
@ -198,11 +205,11 @@ int X11_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects
|
|||
y += h;
|
||||
h += rects[i].y;
|
||||
}
|
||||
if (x + w > window->w) {
|
||||
w = window->w - x;
|
||||
if (x + w > window_w) {
|
||||
w = window_w - x;
|
||||
}
|
||||
if (y + h > window->h) {
|
||||
h = window->h - y;
|
||||
if (y + h > window_h) {
|
||||
h = window_h - y;
|
||||
}
|
||||
|
||||
X11_XPutImage(display, data->xwindow, data->gc, data->ximage,
|
||||
|
|
Loading…
Reference in New Issue