Fix automatic Picture in Picture after session handoffs (#195)

Preserve session readiness for automatic picture in picture
This commit is contained in:
Kurt Himebauch authored and GitHub committed 2026-10-04 04:24:25 +00:00
1 parent 9e54e094fb
commit 5da3cf673c
3 files changed
+12 -5

No files matched your search

+9 -4
View File
@@ -836,6 +836,7 @@ int sc_layer_present_ahb(AHardwareBuffer *ahb, int w, int h, int acquire_fd, voi
apply_geometry(tx, l, r); apply_frame_rate(tx, l); apply_colour(tx, l, color);
api.txApply(tx); api.txDelete(tx);
}
vkp_signal_first_frame();
return 0;
}
ASurfaceTransaction *tx = api.txCreate();
@@ -863,7 +864,10 @@ int sc_layer_present_ahb(AHardwareBuffer *ahb, int w, int h, int acquire_fd, voi
l->cur_slot = -1;
l->cur_token = token;
if (!l->shown) { l->shown = 1; banner_log("layer", "%s: layer shown", l->name); }
if (!l->first_logged) { l->first_logged = 1; vkp_signal_first_frame(); }
/* The notification is re-armed for each session; the layer and its logging flag can
* outlive it. Let the notification's own one-shot decide whether to fire. */
if (!l->first_logged) l->first_logged = 1;
vkp_signal_first_frame();
if (color && color->dataspace) banner_color_frame_shown(color, BANNER_HDR_ZERO_COPY, ahb_format);
return 0;
unavailable:
@@ -891,8 +895,8 @@ int sc_layer_present(struct vkp_image *src, int scene_w, int scene_h, const stru
banner_log("layer", "presenting %dx%d game frames on their own SurfaceControl layer (%s pool, %d buffers); "
"HUD and pointer stay Android views above it", sw, sh,
l->pool_modifier == MOD_QCOM_COMPRESSED ? "UBWC" : "linear", l->pool_n);
vkp_signal_first_frame();
}
vkp_signal_first_frame();
return 0;
}
@@ -915,8 +919,8 @@ int sc_layer_present_pass(const struct vkp_draw *draws, int n, int scene_w, int
banner_log("layer", "presenting %dx%d frames on their own SurfaceControl layer (%s pool, %d buffers); "
"HUD and pointer stay Android views above it", rw, rh,
l->pool_modifier == MOD_QCOM_COMPRESSED ? "UBWC" : "linear", l->pool_n);
vkp_signal_first_frame();
}
vkp_signal_first_frame();
return 0;
}
@@ -971,7 +975,8 @@ int sc_layer_present_hdr_scene(const struct vkp_draw *draws, int n, const struct
cov[0] ? ", " : "", cov);
}
}
if (!l->first_logged) { l->first_logged = 1; vkp_signal_first_frame(); }
if (!l->first_logged) l->first_logged = 1;
vkp_signal_first_frame();
return 0;
}
@@ -907,7 +907,6 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
// whole process, so the second Play after a session ended used to re-attach the Surface,
// start nothing, and leave the loading panel counting up over a dead session.
if (!SessionState.running) {
CompositorHost.newSession()
SessionEvents.transition(SessionPhase.STARTING_GUEST, "guest.starting")
SessionService.start(
this, intent.getStringExtra(SessionService.EXTRA_MODE) ?: SessionService.MODE_STEAM,
@@ -217,6 +217,9 @@ class SessionService : Service() {
SessionState.firstFrameSeen = false
SessionState.guestPid = -1
SessionEvents.transition(SessionPhase.STARTING_GUEST, "service.started", mapOf("mode" to SessionState.mode))
// Re-arm after clearing readiness: a retained picture can present between the activity's
// start request and this callback, and that notice must not be erased by the reset above.
com.droiddeck.launcher.wayland.CompositorHost.newSession()
// This session's number, claimed here and not when its process starts: the session it
// replaces can report its own exit in the gap between the two, and that exit must not
// be taken as this one's.