Sync to Android frame rate

Hi Folks (and pardon me if I'm not on topic)-

I'm looking for a way to synchronize some code activity to the Android display frame rate. It's a short bit of code that will simply set the color of a small display region, nothing more. Is there some sort of method or hook that I can exploit for this purpose?

I can use a timer running at very fast intervals successfully but the rendering appears to suffer from aliasing with the frame rate. For example, my frame rate is 60 Hz so if I set the timer interval to 1/60 seconds, the appearance is non-uniform. I can't set the timer to exactly

16.666 msec and even if I could, I'd still see aliasing.

Thanks - JJS

Reply to
John Speth
Loading thread data ...

I'll answer my own question, partially that is. It appears one solution is to use the Choreographer class which provides a way to hook a callback function into the frame rate. Below is the code. It executes but the timing is sloppy.

I can time the calls to doFrame() using System.nanoTime(). A little testing shows me the timing of calls to doFrame() is not uniform (ranging from 12 msec to 20 msec, expecting about 16 msec). The callback argument is rock steady (about 16 msec) which makes me think it's a value that is computed at initialization time.

It's a solution but it's not doing what I wanted because the callback is not timing precisely enough. Still seeking advice, thank you.

JJS

///////////////////////////////////////////////////////////////

private FrameCallback frameCallback = null; private boolean frameCallbackPending = false;

public void armVSyncHandler() { if(!frameCallbackPending) { frameCallbackPending = true; if(frameCallback == null) { frameCallback = new FrameCallback() { @Override public void doFrame(long frameTimeNanos) { frameCallbackPending = false;

// Do some work here

armVSyncHandler(); } }; } Choreographer.getInstance().postFrameCallback(frameCallback); } }

Reply to
John Speth

I know nothing about Android, but it seems to me there should be a graphics library that provides this sort of functionality. I would think your code would provide a buffer of data to be presented to the screen and a graphics call would hand it to the graphic processor which in turn copies that buffer in a highly synchronized manner.

Trying to run user code synchronized to the frame update would be difficult to say the least.

--

Rick C
Reply to
rickman

There is, it's called SurfaceFlinger. Though you might want to use higher levels of the graphics stack because you may need further layers of compositing (eg controls on top of the image):

formatting link

Theo

Reply to
Theo Markettos

Looks right, but complicated. I didn't see anything that would provide the synchronization the OP is looking for but I can't believe it wouldn't be there. That would be required for glitch-less display updates which we know happens.

--

Rick C
Reply to
rickman

Thanks, Theo. That looks like it's worth some experimentation.

JJS

Reply to
John Speth

Update: I ran this code on a newer and probably faster phone (Samsung Galaxy Grand Prime). It seems to work like I wanted (no aliasing). I conclude the original phone (ZTE X752C) was way short of compute capacity.

JJS

Reply to
John Speth

If all you're doing is filling the screen with colour and you need to buy a faster phone, it feels something is wrong.

For one thing, if that is the intended application (rather than a reduced test case of some other application) you should be using the GPU to do it and take basically no CPU time.

Theo

Reply to
Theo Markettos

You're right, Theo. The application is a custom device that mates to a phone display and needs to receive signals, phone to custom device. Communication is one way and contains very little data (a few bytes per message). I think I can signal a photo-transistor in the custom device by switching a region of the screen as the comm channel. I'm weighing the trade-off of going deep and stepping around the Android graphics SW or playing nicely with it. The alternative is a costlier but much more reliable BLE comm.

JJS

Reply to
John Speth

I'd have thought you make two buffers, one white the other black. Then you alternately tell it to composite one or other. You'll likely get a one-frame lag but, unless your phone is utterly ancient (< Android 4.0), the GPU will render it for you. Think of it as 'playing a

60Hz movie' but with only two images to choose from, that you never change pixels inside.

If you're trying to colour in pixels from Java it's going to be a lot slower - because each one has to reach down the graphics stack, and that's all CPU side.

Theo

Reply to
Theo Markettos

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.