mirror of
				https://github.com/Ryujinx/SDL.git
				synced 2025-11-04 14:45:00 +00:00 
			
		
		
		
	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 (cherry picked from commit 67c91353e01f6f2c0cc80c17eeddbad6def7cb01)
This commit is contained in:
		
							parent
							
								
									3a5abee512
								
							
						
					
					
						commit
						76392f4fe1
					
				| 
						 | 
				
			
			@ -1342,7 +1342,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.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -91,7 +91,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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -219,6 +219,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;
 | 
			
		||||
| 
						 | 
				
			
			@ -301,7 +304,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) */
 | 
			
		||||
| 
						 | 
				
			
			@ -309,11 +312,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();
 | 
			
		||||
| 
						 | 
				
			
			@ -337,6 +340,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) {
 | 
			
		||||
| 
						 | 
				
			
			@ -344,7 +350,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);
 | 
			
		||||
| 
						 | 
				
			
			@ -2584,6 +2590,9 @@ static SDL_Surface *SDL_CreateWindowFramebuffer(SDL_Window *window)
 | 
			
		|||
    int bpp;
 | 
			
		||||
    Uint32 Rmask, Gmask, Bmask, Amask;
 | 
			
		||||
    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
 | 
			
		||||
| 
						 | 
				
			
			@ -2662,7 +2671,7 @@ static SDL_Surface *SDL_CreateWindowFramebuffer(SDL_Window *window)
 | 
			
		|||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return SDL_CreateRGBSurfaceFrom(pixels, window->w, window->h, bpp, pitch, Rmask, Gmask, Bmask, Amask);
 | 
			
		||||
    return SDL_CreateRGBSurfaceFrom(pixels, w, h, bpp, pitch, Rmask, Gmask, Bmask, Amask);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SDL_bool SDL_HasWindowSurface(SDL_Window *window)
 | 
			
		||||
| 
						 | 
				
			
			@ -2695,8 +2704,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_CreateRGBSurfaceWithFormat(0, w, h, 0, surface_format);
 | 
			
		||||
    if (surface == NULL) {
 | 
			
		||||
        return -1;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,7 +43,7 @@ int Emscripten_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format
 | 
			
		|||
 | 
			
		||||
    /* Create a new one */
 | 
			
		||||
    SDL_PixelFormatEnumToMasks(surface_format, &bpp, &Rmask, &Gmask, &Bmask, &Amask);
 | 
			
		||||
    SDL_GetWindowSize(window, &w, &h);
 | 
			
		||||
    SDL_GetWindowSizeInPixels(window, &w, &h);
 | 
			
		||||
 | 
			
		||||
    surface = SDL_CreateRGBSurface(0, w, h, bpp, Rmask, Gmask, Bmask, Amask);
 | 
			
		||||
    if (surface == NULL) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -71,7 +71,7 @@ CreateNewWindowFramebuffer(SDL_Window *window)
 | 
			
		|||
    int w, h, bpp;
 | 
			
		||||
    Uint32 Rmask, Gmask, Bmask, Amask;
 | 
			
		||||
    SDL_PixelFormatEnumToMasks(FRAMEBUFFER_FORMAT, &bpp, &Rmask, &Gmask, &Bmask, &Amask);
 | 
			
		||||
    SDL_GetWindowSize(window, &w, &h);
 | 
			
		||||
    SDL_GetWindowSizeInPixels(window, &w, &h);
 | 
			
		||||
    return SDL_CreateRGBSurface(0, w, h, bpp, Rmask, Gmask, Bmask, Amask);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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_CreateRGBSurfaceWithFormat(0, w, h, 0, 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_CreateRGBSurfaceWithFormat(0, w, h, 0, 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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -54,6 +54,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);
 | 
			
		||||
| 
						 | 
				
			
			@ -76,14 +79,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;
 | 
			
		||||
| 
						 | 
				
			
			@ -107,7 +110,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);
 | 
			
		||||
| 
						 | 
				
			
			@ -123,14 +126,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");
 | 
			
		||||
| 
						 | 
				
			
			@ -146,6 +149,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) {
 | 
			
		||||
| 
						 | 
				
			
			@ -166,11 +173,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,
 | 
			
		||||
| 
						 | 
				
			
			@ -197,11 +204,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 a new issue