This is for corner cases where a multi-window app is activated and wants to
make a decision about where focus should go.
This patch came from Unreal Engine 4's fork of SDL, compliments of Epic Games.
Adam M.
When setting a texture alpha mod other than 255 and also specifying a flip mode in the software renderer, the rendering fails. When the texture has an alpha channel, it becomes invisible when flipped. When the texture does not have an alpha channel, it is flipped but the colors are wrong: the alpha mod makes the texture darker rather than more translucent.
0) Initialize a software renderer.
1) Load 16-bit 565 or 32-bit texture.
2) Set texture blend mode to BLEND.
3) Set texture alpha mod to 150.
4) Draw the texture flipped horizontally and/or vertically.
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.
Adam M.
Okay, here is the problem, I think.
During the first blit, RLEAlphaSurface is called to do RLE conversion of the RGBA source into a format allowing it "to be quickly alpha-blittable onto dest". Since the destination is the screen, it has no alpha channel. RLEAlphaSurface calls copy_opaque(dst, src + runstart, len, sf, df) (where copy_opaque is copy_32), which has this code:
SDL_RLEaccel.c:984:
RGBA_FROM_8888(*src, sfmt, r, g, b, a);
PIXEL_FROM_RGBA(*d, dfmt, r, g, b, a);
On the first line, it reads the source pixel 0xFFFFFFFF. The second line drops the alpha value (because dfmt for the screen has no alpha channel) and writes 0x00FFFFFF. Later, when the RLE conversion is being undone, uncopy_32 is called, which has the following code:
SDL_RLEaccel.c:1001:
Uint32 pixel = *s++;
RGB_FROM_PIXEL(pixel, sfmt, r, g, b);
a = pixel >> 24;
PIXEL_FROM_RGBA(*dst, dfmt, r, g, b, a);
However, the the alpha channel has already been dropped by copy_opaque (= copy_32), so pixel = 0x00FFFFFF and 'a' becomes 0. Thus, all opaque pixels lose their alpha channel when being unRLE'd. (I don't know what happens to pixels with alpha from 1-254, but they should be checked too.)
So, that seems to be the problem, but I'm not sure what the solution should be. Since opaque pixels have alpha == 255, I'm thinking to create another uncopy function for opaque pixels that simply uses 255 for alpha.
However, there may be other problems here. For translucent pixels, uncopy_32 assumes the alpha channel is stored in the upper 8 bits, but copy_32 doesn't store it there. Instead, it stores it in whatever location is appropriate for the destination surface. Isn't one of their behaviors incorrect, given the other? I'm not sure which to change, however.
For translucent pixels, it seems that the blit function uses do_blend, which is the BLIT_TRANSL_888 macro, which also assumes alpha is in top 8 bits. It has the comment "we have made sure the alpha is stored in the top 8 bits...", but it seems that's not true (copy_32 doesn't make sure the alpha goes there).
Perhaps the correct fix is to make copy_32 put the alpha there, but then that seems to require that RLE conversion be limited to destination surfaces that don't use the upper 8 bits. However, looking further, it seems that has already been done: if (masksum != 0x00ffffff) return -1; /* requires unused high byte */
Sylvain
When using API 21 and running on an old device (android < 5.0 ?) some function are missing.
functions are (at least) : signal, sigemptyset, atof, stpcpy (strcat and strcpy), srand, rand.
Very few modifications on SDL to get this working :
on SDL
======
Undefine android configuration :
HAVE_SIGNAL
HAVE_SIGACTION
HAVE_ATOF
In "SDL_systrhead.c", comment out the few block of lines with "sigemptyset".
Android.mk:
remove the compilation of "test" directory because it contains a few rand/srand calls
Also, there are more discussions about this in internet :
https://groups.google.com/forum/#!topic/android-ndk/RjO9WmG9pfEhttp://stackoverflow.com/questions/25475055/android-ndk-load-library-cannot-locate-srand
Sylvain
http://developer.android.com/reference/android/view/InputDevice.html
int SOURCE_CLASS_JOYSTICK Constant Value: 16 (0x00000010)
int SOURCE_JOYSTICK Constant Value: 16777232 (0x01000010)
int SOURCE_KEYBOARD Constant Value: 257 (0x00000101)
int SOURCE_GAMEPAD Constant Value: 1025 (0x00000401)
int SOURCE_DPAD Constant Value: 513 (0x00000201)
I have an a PC keyboard that I connect to an android device.
The issue is that "arrow" keys gets lost.
More explanation:
This device gets detected twice by the java "pollInputDevices()" both as SOURCE_KEYBOARD and as a composite (0x1000311 == SOURCE_JOYSTICK | SOURCE_KEYBOARD | SOURCE_DPAD).
Because of being a SOURCE_CLASS_JOYSTICK, only the second entry is registered, and I opened it.
When I press one arrow key, the java method "onKey(...)" is called.
The Source "event.getSource()" is "SOURCE_KEYBOARD", so it enters this conditions :
if ( (event.getSource() & InputDevice.SOURCE_GAMEPAD) != 0 ||
(event.getSource() & InputDevice.SOURCE_DPAD) != 0 ) {
And then, it enters :
SDLActivity.onNativePadDown() (native code in "SDL_sysjoystick.c")
Since the "arrows" are viewed as "D-PAD", it gets translated :
int button = keycode_to_SDL(keycode);
But the android-java "event.getDeviceId()" is wrong: this is the one from the Keyboard, and not the one from the Joystick that I have opened.
So I don't get them through the Joystick interface.
And since, the keycode has been translated, it returns 0 and assume it was consumed.
So I lost the key in the function "Android_OnPadDown()"
Notice, It won't happen with other normal "letters" keys because they does not get translated by "keycode_to_SDL", so "Android_OnPadDown()" returns -1.
And then java code send the keys to "SDLActivity.onNativeKeyDown()".
Possible patch on "Android_OnPadDown" and also "Android_OnPadUp" (and maybe other functons):
85 int
186 Android_OnPadDown(int device_id, int keycode)
187 {
188 SDL_joylist_item *item;
189 int button = keycode_to_SDL(keycode);
190 if (button >= 0) {
191 item = JoystickByDeviceId(device_id);
192 if (item && item->joystick) {
193 SDL_PrivateJoystickButton(item->joystick, button , SDL_PRESSED);
194 }
+ else return -1;
195 return 0;
196 }
197
198 return -1;
199 }
It would allow the java caller function to send the key to "SDLActivity.onNativeKeyDown();"
Another solution, would be to replace:
if ( (event.getSource() & InputDevice.SOURCE_GAMEPAD) != 0 ||
(event.getSource() & InputDevice.SOURCE_DPAD) != 0 ) {
by
if ( (event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0)
Because only "SOURCE_CLASS_JOYSTICK" devices are registered/opened.
Sylvain
I have an android device to which I try to connect the google virtual remote application.
https://play.google.com/store/apps/details?id=com.google.android.tv.remote
The java method "pollInputDevices()" detects it as an input source 0x701 which is (SOURCE_KEYBOARD | SOURCE_GAMEPAD | SOURCE_DPAD).
It it not added because it does not AND-bitwise with "SOURCE_CLASS_JOYSTICK".
It's only a virtual DPAD and it works when checking also with SOURCE_CLASS_BUTTON
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.
Martin Gerhardy
Not sure - but I think there might be a logic flaw in SDL_SetWindowGrab.
The problem here is that this modifies the window flags and e.g. sets
SDL_WINDOW_INPUT_GRABBED - but the _this->grabbed_window pointer is not
yet set.
Then in SDL_UpdateWindowGrab the _this->grabbed_window pointer is only
set if the function pointer _this->SetWindowGrab is not NULL. But if
this is NULL, the _this->grabbed_window pointer is never set, but every
future call to any of the grab functions include an assert for:
SDL_assert(!_this->grabbed_window || ((_this->grabbed_window->flags &
SDL_WINDOW_INPUT_GRABBED) != 0));
That means the first call works, the second always fails and triggers
the assert.
Magnus Bjerke Vik
This causes issues when for instance using the joystick API to make an Android phone rotate an object by rotating the phone. When the absolute value of an axis reported by android is larger than earth gravity, SDL will overflow the Sint16 value used for joystick axes, causing sporadic movements when close to the gravity. Just holding the phone so that e.g. Y points directly upwards will make it unstable, and even more if you just tap the phone gently from below (increasing the acceleration).
More detailed: SDLActivity gets the accelerometer values in onSensorChanged and divides each axis by earth gravity. SDL_SYS_JoystickUpdate takes each of the axis values, multiplies them by 32767.0 (largest Sint16), and the casts them to Sint16. From this you can see that any value from Android that exceeds earth gravity will overflow the joystick axis.
A fix is to clamp the values so that they won't overflow the Sint16.
Simon Deschenes
My build system still shows warning as errors.
The first warning says that the member named instances can never be false (or NULL) as it is a static array, and we should check for instances[index] which we do anyway.
Ozkan Sezer
pthread/SDL_syssem.c requires _GNU_SOURCE predefined (like SDL_sysmutex.c),
otherwise sem_timedwait() prototype might not be available to it. Problem
seen with glibc-2.3.4.
If the allocation of an SDL_Touch failed, the number of touch devices was still
increased. Later access of the SDL_Touch would then have dereferenced the NULL.