VirtualDisplay Screen Flicker - android

A while back I asked this question and #fadden was gracious enough to give me an answer. So, now I have a VirtualDisplay which is using an intermediary Surface that I create and when the SurfaceTexture that backs the Surface receives an onFrameAvailable call, I make OpenGL calls to put draw that texture to an EGLSurface which is created from the Surface generated by the MediaCodec. Phew.
All of this is running in a Service (so it sticks around in the background). It all works, but I'm having some screen flickering occasionally on some devices. The flickering does not carry through to the data sent to the MediaCodec so it seems to be an issue with just the screen. The flickering also causes the "soft buttons" on Nexus devices to disappear/reappear on Nexus devices (but even when the buttons are gone on screen, the soft buttons appear in the output of the MediaCodec.
If I swap out my intermediary Surface so that the VirtualDisplay just outputs to the MediaCodec's input Surface then the flicker happens significantly less (happened one time in 50 or so minutes vs. flickering a few times a second periodically). The flickering also seems to happen in certain apps more so than other apps (Google Maps is a good culprit) or when certain UI appears/disappears in apps.
Anyone have have any ideas on what could cause the flickering in this scenario and only one some devices (that I've seen)? I can post some source code if that would be helpful.
EDIT: So, I've found that, on my Nexus 5x at least, if I go to "Developer Options" and enable "Disable HW Overlays" (the text says "Always use GPU for screen compositing") that the screen flicker goes away. Obviously this is a workaround, but I'd like to fix the issue programatically if at all possible.

Related

FrameBuffer texture breaks after changing device language

I am happily using libgdx for an android game application.
At a specific point in the game, I use a FrameBuffer object to render the screen onto, and then use its attached color texture for rendering that to the screen (to be able to render a half-transparent screen with full-color rectangular zones).
The documentation for FrameBuffer says:
FrameBuffers are managed. In case of an OpenGL context loss, which only happens on Android when a user switches to another application or receives an incoming call, the framebuffer will be automatically recreated.
And that works perfectly, I can switch to other applications, put the device in sleep mode, go back to the application and everything including the framebuffer is working as usual.
The problem begins when I try and change the device's language when the application is running (using the android settings menu).
After I change the language to something else, the framebuffer attached texture becomes completely black (either the rendering to it fails or its rendering to the screen does).
The incredible thing is that, even if I restart the application (i.e. the application reaches its onDestroy() method and exits), the problem does NOT go away, and it does only when I kill the application process from the task manager.
I probably could solve this by adding a System.exit(0) inside the onDestroy() method, but does anyone have an idea about what exactly happens when I change the device language?
I cannot think of any possible relation between that and the framebuffer object state (the other textures are working as usual!), if anyone could enlight me it would be greatly appreciated.

How to fix intermittent/jerky android paint updates

(I tried to stuff the question with keywords in case someone else has this issue - I couldn't find much help.)
I have a custom View in Android that contains an LED bargraph that displays levels received via socket communication. It's basically just a clipped image. The higher the level, the less clipped the image is.
When I update the level and then invalidate the View, some devices seem to "collect" multiple updates and render them in chunks. The screen visibly hesitates for say 1/10th of a second, then rapidly paints multiple frames, and then hesitates again. It looks like it's overwhelmed and dropping frames.
However, when changing another UI control on the screen, the LED bargraph paints much more frequently and smoothly. I'm thinking Android is trying to help me by "collecting" multiple invalidations and then doing them all at once. Perhaps by manipulating controls, I'm "increasing" my frame rate simply by giving it "more to do" so it delays less between actual paints.
Unlike animation (with smooth transitions) I want to show the absolute latest value as quickly as possible. My data samples aren't faster than 10-20fps anyway.
Is there an easy way to "force" a paint at certain points, or is this a limit of how Views work? Should I be implementing this in a SurfaceView instead? (I have not played with that yet... want advice first.) Thanks in advance for suggestions.
(Later that same day...)
Update: I found a page in the Docs that does suggest implementing my widget as a SurfaceView is the way to go:
http://developer.android.com/guide/topics/graphics/2d-graphics.html
(An hour after that...)
SurfaceView seems overkill for what I want to do. The best-practice method is to "own" the whole canvas, but I have already developed the rest of my controls and layouts and they work well. It must be possible to get some better performance with what I have, especially since interacting with the UI makes the redraw speed satisfactory.
It turns out SurfaceView was the way to go. I was benchmarking on an older phone which didn't help. (The frame rate using a standard View was fine on an ASUS eeePad). I had to throw away some code, but the end result is smoother and faster with SurfaceView. Further, I was able to re-use more code than I expected and actually dramatically simplified my multitouch handling code (since everything I want to touch is in the same SurfaceView.
FYI: I'm still only getting about 15fps on Droid X, but half of the CPU load appears to be data packet processing. The eeePad is doing almost 40fps now -- and my data rate is only 20 samples/sec.
So... a win I guess. I want the Droid X to run better, but it flies on a real tablet.

Camera on Android Example

I want to write an activity that:
Shows the camera preview (viewfinder), and has a "capture" button.
When the "capture" button is pressed, takes a picture and returns it to the calling activity (setResult() & finish()).
Are there any complete examples out there that works on every device? A link to a simple open source application that takes pictures would be the ideal answer.
My research so far:
This is a common scenario, and there are many questions and tutorials on this.
There are two main approaches:
Use the android.provider.MediaStore.ACTION_IMAGE_CAPTURE event. See this question
Use the Camera API directly. See this example or this question (with lots of references).
Approach 1 would have been perfect, but the issue is that the intent is implemented differently on each device. On some devices it works well. However, on some devices you can take a picture but it is never returned to your app. On some devices nothing happens when you launch the intent. Typically it also saves the picture to the SD card, and requires the SD card to be present. The user interaction is also different on every device.
With approach 2 the issues is stability. I tried some examples, but I've managed to stop the camera from working (until a restart) on some devices and completely freeze another device. On another device the capture worked, but the preview stayed black.
I would have used ZXing as an example application (I work with it a lot), but it only uses the preview (viewfinder), and doesn't take any pictures. I also found that on some devices, ZXing did not automatically adjust the white balance when the lighting conditions changed, while the native camera app did it properly (not sure if this can be fixed).
Update:
For a while I used the camera API directly. This gives more control (custom UI, etc), but I would not recommend it to anyone. I would work on 90% of devices, but every now and again a new device would be released, with a different problem.
Some of the problems I've encountered:
Handling autofocus
Handling flash
Supporting devices with a front camera, back camera or both
Each device has a different combination of screen resolution, preview resolutions (doesn't always match the screen resolution) and picture resolutions.
So in general, I'd not recommend going this route at all, unless there is no other way. After two years I dumped by custom code and switched back to the Intent-based approach. Since then I've had much less trouble. The issues I've had with the Intent-based approach in the past was probably just my own incompetence.
If you really need to go this route, I've heard it's much easier if you only support devices with Android 4.0+.
With approach 2 the issues is stability. I tried some examples, but I've managed to stop the camera from working (until a restart) on some devices and completely freeze another device. On another device the capture worked, but the preview stayed black.
Either there is a bug in the examples or there is a compatibility issue with the devices.
The example that CommonsWare gave works well. The example works when using it as-is, but here are the issues I ran into when modifying it for my use case:
Never take a second picture before the first picture has completed, in other words PictureCallback.onPictureTaken() has been called. The CommonsWare example uses the inPreview flag for this purpose.
Make sure that your SurfaceView is full-screen. If you want a smaller preview you might need to change the preview size selection logic, otherwise the preview might not fit into the SurfaceView on some devices. Some devices only support a full-screen preview size, so keeping it full-screen is the simplest solution.
To add more components to the preview screen, FrameLayout works well in my experience. I started by using a LinearLayout to add text above the preview, but that broke rule #2. When using a FrameLayout to add components on top of the preview, you don't have any issues with the preview resolution.
I also posted a minor issue relating to Camera.open() on GitHub.
"the recommended way to access the camera is to open Camera on a separate thread". Otherwise, Camera.open() can take a while and might bog down the UI thread.
"Callbacks will be invoked on the event thread open(int) was called from". That's why to achieve best performance with camera preview callbacks (e.g. to encode them in a low-latency video for live communication), I recommend to open camera in a new HandlerThread, as shown here.

OpenGL goes green on tablets

Description:
My OpenGL game runs fine on phones. However, after a couple of seconds of running on a tablet the 3D rendering goes all green. The 2D overlays (gl) are mostly fine.
This might be triggered by rotation, I can't be sure; no access to a tablet.
A user kindly recording it happening, which I have posted online:
http://www.youtube.com/watch?v=DRfDM673TRA
Questions:
Has anyone seen this before, or know of a possible cause/cure?
Also, can anyone confirm this is is still happening? (BB Rally Lite is free).
Other info:
The game is locked into landscape mode so I wouldn't expect it to do anything on rotation.
Update:
This was a bug in my code.
Tablets have a different default orientation,
which was triggering conditional (bugged) code that never got run on a phone.
The green screen was a result of the bug causing the model's matrix to contain nan (or inf, I can't recall).
If you suffer from a green screen I suggest you start by looking at your matrices.

Android: Frame rate drops in landscape mode

I am trying out the (latest) Android SDK, and noticed some strange behavior.
I've written a skeletal SurfaceView app: Activity, SurfaceView and a rendering thread. It doesn't actually do any painting, and only writes out the framerate to logcat once a second. When it runs in portrait mode, I get around 60 fps. However, when I flip it to landscape the framerate drops to about 30 fps.
I have also tested it on the LunarLender sample, and got similiar results. All of the testing are done on the emulator, since I don't have a physical device.
What's it all about? I can't seem to find any mentioning to this on Google, have anyone else experienced that? Is it just an emulator quirk or does it apply to physical hardware too?
Guessing here- in landscape mode, is there extra "blank" space on either side of the rendered content? If so there could be an effective increase in the amount of processing just to paint the screen. Don't know if that should account for a 50% decrease in framerate, but it's possible.
Another guess- landscape mode may be deliberately throttled because it's intended primarily for video viewing. No reason to go up to 60fps for 30fps content. Configuration?

Categories

Resources