Eric wing
Hi, I think I found a bug when using SDL_WINDOW_ALLOW_HIGHDPI with SDL_RenderSetLogicalSize on iOS. I use SDL_RenderSetLogicalSize for all my stuff. I just tried turning on SDL_WINDOW_ALLOW_HIGHDPI on iOS and suddenly all my touch/mouse positions are really broken/far-off-the-mark.
I actually don't have a real retina device (still) so I'm seeing this using the iOS simulator with a 6plus template.
Attached is a simple test program that can reproduce the problem. It uses RenderSetLogicalSize and draws some moving happy faces (to show the boundaries/space of the LogicalSize and that it is working correctly for that part).
When you click/touch, it will draw one more happy face where your button point is.
If you comment out SDL_WINDOW_ALLOW_HIGHDPI, everything works as expected. But if you compile with it in, the mouse coordinates seem really far off the mark. (Face appears far up and to the left.)
Alex Szpakowski on the mailing list suggests the problem is
"I believe this is a bug in SDL_Render?s platform-agnostic mouse coordinate scaling code. It assumes the units of the mouse coordinates are always in pixels, which isn?t the case where high-DPI is involved (regardless of whether iOS is used) ? they?re actually in ?DPI independent? coordinates (which matches the window size, but not the renderer output size)."
Additionally, if this is correct, the Mac under Retina is also probably affected too and "as well as any other platform SDL adds high-dpi support for in the future".
felix
Here's a snippet of SDL_DestroyRenderer from hg revision 10746:7540ff5d0e0e:
SDL_Texture *texture = NULL;
SDL_Texture *nexttexture = NULL;
/* ... */
for (texture = renderer->textures; texture; texture = nexttexture) {
nexttexture = texture->next;
SDL_DestroyTexture(texture);
}
SDL_DestroyTexture removes the texture from the linked list pointed to by the renderer and ends up calling SDL_DestroyTextureInternal, which contains this:
if (texture->native) {
SDL_DestroyTexture(texture->native);
}
If it happens that texture->native is an alias of nexttexture two stack frames up, SDL_DestroyRenderer will end up trying to destroy an already freed texture. I've had this very situation happen in dosemu2.
Bug introduced in revision 10650:a8253d439914, which has a somewhat ironic description of "Fixed all known static analysis bugs"...
D39 does not support negative viewport values which the current implementation relies on.
D3D11 does support negative viewport values so that will continue working.
Refer to Bug 2799.
Adam M.
When doing a rotated texture copy with the software renderer, where the angle is a multiple of 90 degrees, one or two edges of the image get cut off. This is because of the following line in sw_rotate.c:
if ((unsigned)dx < (unsigned)sw && (unsigned)dy < (unsigned)sh) {
which is effectively saying:
if (dx >= 0 && dx < src->w-1 && dy >= 0 && dy < src->h-1) {
As a result, it doesn't process pixels in the right column or bottom row of the source image (except when they're accessed as part of the bilinear filtering for nearby pixels). This causes it to look like the edges are cut off, and it's especially obvious with an exact multiple of 90 degrees.
Daniel
Seems like check of the visibility of renderer (renderer->hidden) is missing in SDL_RenderCopyEx.
In SDL_RenderCopy it should be done much earlier (after checking support for RenderCopyEx, line 1750).
Adam M.
There are three problems in the code that I see.
1. SW_RenderCopyEx enables a color key on surface_scaled even if the source surface didn't have a color key.
2. SW_RenderCopyEx doesn't copy blend mode, color mod, or alpha mod from src to surface_scaled.
3. When SDL_BlitScaled(src, srcrect, surface_scaled, &tmp_rect) is called, it blends the src pixels into surface_scaled instead of overwriting them (if src has blending, etc. enabled).
I've attached a patch that 1) fixes the three problems that I mentioned, 2) adds the requested performance improvement of using the regular blit function if no rotation or flipping is needed, 3) avoids cloning the source surface if no stretching is required, and simplifies the rotation code slightly.
Andreas Ragnerstam
I have two windows where one has a renderer where the logical size has been changed with SDL_RenderSetLogicalSize. When I get SDL_MOUSEMOTION events belonging to the non-scaled window these will have been scaled with the factor of the scaled window, which is not expected.
Adding some printf debugging to SDL_RendererEventWatch of SDL_render.c, where (event->type == SDL_MOUSEMOTION), I found that for every mouse motion SDL_RendererEventWatch is called twice and the event->motion.x and event.motion.y are set twice for the event, once for each renderer where only the last one set will be saved to the event struct. This will work fine if both renderers have the same scale, but otherwise the motion coordinates will be scaled for the renderer belonging to another window than the mouse was moved in.
I guess one solution would be to check that window == renderer->window for SDL_MOUSEMOTION events, similar to what is done for when SDL_WINDOWEVENT events.
I get the same error on both X11 and Windows.
The same problem also exists for SDL_MOUSEBUTTONDOWN and SDL_MOUSEBUTTONUP events.
The internal function SDL_EGL_LoadLibrary() did not delete and remove a mostly
uninitialized data structure if loading the library first failed. A later try to
use EGL then skipped initialization and assumed it was previously successful
because the data structure now already existed. This led to at least one crash
in the internal function SDL_EGL_ChooseConfig() because a NULL pointer was
dereferenced to make a call to eglBindAPI().
The expected use case is for games that are designed with multiple aspect ratios already in mind and leave optional margins on the edges of the game which won't hurt if they are cut off.
An example use case is a game is designed for wide-screen/16:9, but then wants to deploy on an iPad which is 4:3. Normally, SDL will letterbox, which will shrink things and result in wasted space. But the designer already thought about 4:3 and designed the edges of the game so they could be cut off without any functional loss. So rather than wasting space with letterboxing, "overscan" mode will zoom the rendering to fill up the entire screen. Parts on the edges will be drawn offscreen, but since the game was already designed with this in mind, it is fine. The end result is the iPad (4:3) experience is much better since it feels like a game designed for that screen aspect ratio.
This patch introduces a new SDL_hint: SDL_HINT_RENDER_LOGICAL_SIZE_MODE.
Valid values are "letterbox" or "0" for letterboxing and "overscan" or "1" for overscan.
The default mode is letterbox to preserve existing behavior.
// Example usage:
SDL_SetHint(SDL_HINT_RENDER_LOGICAL_SIZE_MODE, "overscan");
SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH, SCREEN_HEIGHT);
An existing hint lets apps that don't need the timer resolution changed avoid
this, to save battery, etc, but this fixes several problems in timing, audio
callbacks not firing fast enough, etc.
Fixes Bugzilla #2944.