| Summary: | Rotation breaks SDL2 rendering on Android | ||
|---|---|---|---|
| Product: | SDL | Reporter: | Jonny D <grimfang4> |
| Component: | video | Assignee: | Gabriel Jacobo <gabomdq> |
| Status: | ASSIGNED --- | QA Contact: | Sam Lantinga <slouken> |
| Severity: | normal | ||
| Priority: | P2 | CC: | denis, gabomdq |
| Version: | HG 2.0 | ||
| Hardware: | ARM | ||
| OS: | Android (All) | ||
| Attachments: | naive fix | ||
Actually I think the problem lies elsewhere... Looking at the SDL_WindowEventID enums: SDL_WINDOWEVENT_RESIZED, /**< Window has been resized to data1xdata2 */ SDL_WINDOWEVENT_SIZE_CHANGED, /**< The window size has changed, either as a result of an API call or through the system or user changing the window size. */ Android_SetScreenResolution emits the SDL_WINDOWEVENT_RESIZED, which in theory (if the windows dimensions are different to the current ones) makes SDL_SendWindowEvent emit a SDL_WINDOWEVENT_SIZE_CHANGED which is what actually updates the viewport.w/viewport.h in SDL_RendererEventWatch from SDL_render.c When SDL_WINDOWEVENT_RESIZED is fired, SDL_RendererEventWatch attempts to center the viewport (temporarily...but why? And also why temporarily update the backup viewport when it's not really in use?) based on the old viewport size and the new size, and it sets everything right when SDL_WINDOWEVENT_SIZE_CHANGED comes (which AFAICT is right away). So, the question is...does SDL_WINDOWEVENT_SIZE_CHANGED fire? If not, can you tell why? The events seem to fire properly. A working workaround for this is to call SDL_GL_SwapWindow(window) when receiving SDL_WINDOWEVENT_SIZE_CHANGED and ignore SDL_WINDOWEVENT_RESIZED (to avoid duplicate redraws). So the bug seems to sit somewhere between video/android/SDL_androidgl.c and render/opengles2/SDL_render_gles2.c. |
Created attachment 1137 [details] naive fix The viewport width and height are not being updated when the device is rotated. This makes the centering code in SDL_render.c (around line 119) try to center x and y using incompatible dimensions (e.g. (portrait_w - landscape_w)/2). The result is a large offset of the entire viewport (which is very bad, obviously). As an example... Start with portrait. Viewport: (0,0,480,800) Rotate to landscape. Viewport: (0,0,800,480) Rotate back to portrait. Viewport: (-160,160,480,800) The centering code uses: viewport.y = (h - viewport.h)/2; which is: 160 = (800-480)/2; ...because viewport.h was not updated to portrait before the render event callback. I'm not sure of the proper fix... I can make it work by setting the viewport to the incoming w and h, but I don't know about cases where the viewport dims are intentionally different than the window dims. Also, there's the if(renderer->target) case that I'm not sure of. I'm attaching a patch for this, but it needs a more experienced look-over.