mirror of
https://github.com/screentinker/screentinker.git
synced 2026-08-13 22:03:13 -06:00
Reported as one or two frames of the OUTGOING photo after every transition, before the incoming one appears. Three things conspired, all at the moment the wipe ends. The overlay is a translucent SurfaceView with setZOrderOnTop(true) and a clear colour of (0,0,0,0). onDrawFrame() cleared unconditionally, before testing whether there was anything to draw. finish() left RENDERMODE_CONTINUOUSLY on and only POSTED the content swap and the hide to the main thread, so the GL thread got at least one more frame in first: it cleared to fully transparent while the overlay was still visible, showing straight through to the ImageView — which still held the previous photo, because the swap had not run yet. Not a black flash; a see-through one. The same clear ran on the failed/hard-cut path. So: clear only when a frame is actually going to be drawn over it, and stop the render loop in finish() on the GL thread rather than waiting for the main thread to park the overlay. What stays on screen is then the wipe's final frame, which is the destination image, and it is correct to leave it there. That still left the hand-off itself racing. Hiding a Z-ordered SurfaceView is a SurfaceFlinger transaction that is not synchronised with the app drawing the newly mounted bitmap, so the hide can land a vsync before the paint and uncover the old photo anyway. The overlay now lingers briefly before parking. It costs nothing to look at — both layers are showing the same picture — and it removes the race rather than narrowing it. Measured on the panel with 64x36 frame classification over screen recordings: the old photo reappeared after 1 of 4 wipes before, 0 of 14 after the first two changes. That sampling runs through a virtual display and cannot see every composited frame, so it bounds the problem rather than proving absence — hence closing the last gap by construction instead of by measurement. The web player never had this: it calls mount() and then hides the canvas synchronously in one task, so both land in the same paint. |
||
|---|---|---|
| .. | ||
| java/com/remotedisplay/player | ||
| res | ||
| AndroidManifest.xml | ||