Fixed bug 2774 - Android: screen distorted in Landscape after background/foreground
authorSam Lantinga <slouken@libsdl.org>
Tue, 16 Jun 2015 22:16:35 -0700
changeset 9749a1b920bc870d
parent 9748 ea643fcc1b12
child 9750 f6567f77f663
Fixed bug 2774 - Android: screen distorted in Landscape after background/foreground

Sylvain

With a Landscape application.
Going to background with Home Key, then foreground.
The screen is distorted.

This has been reported by Samsung. It happens on S5 and Samsung Alpha, see the video attached.

I have captured the following logcat:

V/SDL (20549): onResume()
V/SDL (20549): surfaceCreated()
V/SDL (20549): surfaceChanged()
V/SDL (20549): pixel format RGB_565
V/SDL (20549): Window size:1920x1080
I/SDL (20549): SDL_Android_Init()
I/SDL (20549): SDL_Android_Init() finished!
V/SDL (20549): SDL audio: opening device
V/SDL (20549): SDL audio: wanted stereo 16-bit 22.05kHz, 256 frames buffer
V/SDL (20549): SDL audio: got stereo 16-bit 22.05kHz, 1764 frames buffer
V/SDL (20549): onWindowFocusChanged(): true
V/SDL (20549): onWindowFocusChanged(): false
V/SDL (20549): onPause()
V/SDL (20549): nativePause()
V/SDL (20549): surfaceDestroyed()

Background / Foreground

V/SDL (20549): onResume()
V/SDL (20549): surfaceCreated()
V/SDL (20549): surfaceChanged()
V/SDL (20549): pixel format RGB_565
V/SDL (20549): Window size:1080x1920
V/SDL (20549): surfaceChanged()
V/SDL (20549): pixel format RGB_565
V/SDL (20549): Window size:1920x1080
V/SDL (20549): onWindowFocusChanged(): true
V/SDL (20549): nativeResume()



This seems to be related to the fact that I have in "AndroidManifest.xml":
android:configChanges="..."
Because of the fields: "orientation" and also "screenSize".


I have looked for another way to solve the issue. Discarding the "surfaceChanged" call, based on the "requestedOrientation" and the new Orientation. It seems to be better.


On my failing test case, the first "surfaceChanged()" is discarded. Sometimes the "focusChanged()" might appear between the two "surfaceChanged()", while the surface is not yet ready. Thus, discarding also the "nativeResume()".

So, for robustness, a call to "nativeResume()" is added at the end of "surfaceChanged()".

Some update:

1/ First I tried, to discard the surface using the current orientation (rather than width / heigh). -> that solve the issue sometimes, but not always.

2/ Samsung Certification now accepts my application that were previously failing.

3/ I personally now owns a Samsung S5, and was able to solve the issue on my side.

4/ I now use the patch and get no complaints from my users. (but I admit, nobody seemed to be complaining before neither...).

5/ I have added a v2 because of a new smart-phone called "Black Berry Passport" that has a square screen of 1440x1440. This screen has a "status bar" so the resolution is in fact : 1440x1308. (as reported by "surfaceChanged").

Problem is: the portrait resolution is in fact a Landscape!

So the "v1" patch is always discarding the "surface" of BlackBerry Passport. Which is terribly bad.


Hence, I added the "v2" patch not to discard the surface when aspect ratio is < 1.20. (BB 1440/1308 is : 1.1009). Which seems fair.
android-project/src/org/libsdl/app/SDLActivity.java
     1.1 --- a/android-project/src/org/libsdl/app/SDLActivity.java	Tue Jun 16 20:28:21 2015 +0200
     1.2 +++ b/android-project/src/org/libsdl/app/SDLActivity.java	Tue Jun 16 22:16:35 2015 -0700
     1.3 @@ -27,6 +27,7 @@
     1.4  import android.graphics.drawable.Drawable;
     1.5  import android.media.*;
     1.6  import android.hardware.*;
     1.7 +import android.content.pm.ActivityInfo;
     1.8  
     1.9  /**
    1.10      SDL Activity
    1.11 @@ -1062,6 +1063,42 @@
    1.12          SDLActivity.onNativeResize(width, height, sdlFormat, mDisplay.getRefreshRate());
    1.13          Log.v("SDL", "Window size: " + width + "x" + height);
    1.14  
    1.15 + 
    1.16 +        boolean skip = false;
    1.17 +        int requestedOrientation = SDLActivity.mSingleton.getRequestedOrientation();
    1.18 +
    1.19 +        if (requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
    1.20 +        {
    1.21 +            // Accept any
    1.22 +        }
    1.23 +        else if (requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
    1.24 +        {
    1.25 +            if (mWidth > mHeight) {
    1.26 +               skip = true;
    1.27 +            }
    1.28 +        } else if (requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
    1.29 +            if (mWidth < mHeight) {
    1.30 +               skip = true;
    1.31 +            }
    1.32 +        }
    1.33 +
    1.34 +        // Special Patch for Square Resolution: Black Berry Passport
    1.35 +        if (skip) {
    1.36 +           double min = Math.min(mWidth, mHeight);
    1.37 +           double max = Math.max(mWidth, mHeight);
    1.38 +           
    1.39 +           if (max / min < 1.20) {
    1.40 +              Log.v("SDL", "Don't skip on such aspect-ratio. Could be a square resolution.");
    1.41 +              skip = false;
    1.42 +           }
    1.43 +        }
    1.44 +
    1.45 +        if (skip) {
    1.46 +           Log.v("SDL", "Skip .. Surface is not ready.");
    1.47 +           return;
    1.48 +        }
    1.49 +
    1.50 +
    1.51          // Set mIsSurfaceReady to 'true' *before* making a call to handleResume
    1.52          SDLActivity.mIsSurfaceReady = true;
    1.53          SDLActivity.onNativeSurfaceChanged();
    1.54 @@ -1093,6 +1130,10 @@
    1.55              }, "SDLThreadListener");
    1.56              SDLActivity.mSDLThread.start();
    1.57          }
    1.58 +
    1.59 +        if (SDLActivity.mHasFocus) {
    1.60 +            SDLActivity.handleResume();
    1.61 +        }
    1.62      }
    1.63  
    1.64      // unused