feat: enhance resizable virtual display handling and improve resize quality

This commit is contained in:
Reynaldo San Juan 2025-09-13 19:16:10 +02:00
parent ddaa33538a
commit 3ef31a1f58
4 changed files with 34 additions and 47 deletions

View file

@ -541,6 +541,11 @@ sc_input_manager_process_key(struct sc_input_manager *im,
if (shift) {
reset_video(im);
} else {
// Disable MOD+R rotation in resizable virtual display mode
if (im->screen->resizable_new_display) {
LOGI("MOD+R rotation disabled in resizable virtual display mode");
return;
}
rotate_device(im);
}
}

View file

@ -251,45 +251,8 @@ event_watcher(void *data, SDL_Event *event) {
assert(screen->video);
if (event->type == SDL_WINDOWEVENT
&& event->window.event == SDL_WINDOWEVENT_RESIZED) {
int width = event->window.data1;
int height = event->window.data2;
if (screen->resizable_new_display) {
if ((!sizes_are_close(width, screen->last_window_width, 2) || !sizes_are_close(height, screen->last_window_height, 2)) &&
!screen->initial_setup && !screen->content_driven_resize) {
screen->last_window_width = width;
screen->last_window_height = height;
// --- Resize diferido ---
screen->pending_resize_width = width;
screen->pending_resize_height = height;
if (screen->resize_timer) {
SDL_RemoveTimer(screen->resize_timer);
}
screen->resize_timer = SDL_AddTimer(RESIZE_FINISHED_DELAY, resize_timer_callback, screen);
// --- Fin resize diferido ---
sc_screen_render(screen, true);
} else if (screen->initial_setup) {
LOGD("[RESIZED] Initial setup resize ignored: %dx%d", width, height);
sc_screen_render(screen, true);
} else if (screen->content_driven_resize) {
LOGD("[RESIZED] Content-driven resize ignored: %dx%d", width, height);
sc_screen_render(screen, true);
}
} else {
// Modo normal
if (screen->content_driven_resize) {
LOGD("[RESIZED] Content-driven resize, solo render");
sc_screen_render(screen, true);
return 0;
}
if (screen->initial_setup) {
LOGD("[RESIZED] Initial setup, solo render");
sc_screen_render(screen, true);
return 0;
}
LOGD("[RESIZED] User resize detected: %dx%d", width, height);
sc_screen_render(screen, true);
sc_screen_send_resize_display(screen, width, height);
}
// Only handle rendering for the workaround, resize logic should be handled elsewhere
sc_screen_render(screen, true);
}
return 0;
}
@ -924,8 +887,18 @@ sc_screen_handle_event(struct sc_screen *screen, const SDL_Event *event) {
screen->last_window_width = w;
screen->last_window_height = h;
// --- Resize diferido ---
screen->pending_resize_width = w;
screen->pending_resize_height = h;
// Round to multiple of 8 to match server-side rounding and avoid quality degradation
int rounded_w = (w + 4) & ~7; // Round to nearest multiple of 8
int rounded_h = (h + 4) & ~7; // Round to nearest multiple of 8
// Resize window to rounded dimensions to maintain quality
if (rounded_w != w || rounded_h != h) {
SDL_SetWindowSize(screen->window, rounded_w, rounded_h);
LOGD("Window resized to rounded dimensions: %dx%d (from %dx%d)", rounded_w, rounded_h, w, h);
}
screen->pending_resize_width = rounded_w;
screen->pending_resize_height = rounded_h;
if (screen->resize_timer) {
SDL_RemoveTimer(screen->resize_timer);
}
@ -1084,7 +1057,10 @@ static Uint32 resize_timer_callback(Uint32 interval, void *param) {
LOGD("Ignoring invalid resize: %dx%d", width, height);
return 0;
}
LOGD("[RESIZE_FINISHED] Notifying display resize: %dx%d", width, height);
sc_screen_send_resize_display(screen, width, height);
// Round to multiple of 8 to match server-side rounding and avoid quality degradation
int rounded_w = (width + 4) & ~7; // Round to nearest multiple of 8
int rounded_h = (height + 4) & ~7; // Round to nearest multiple of 8
LOGD("[RESIZE_FINISHED] Notifying display resize: %dx%d (rounded from %dx%d)", rounded_w, rounded_h, width, height);
sc_screen_send_resize_display(screen, rounded_w, rounded_h);
return 0;
}

View file

@ -313,6 +313,7 @@ public class Controller implements AsyncProcessor, VirtualDisplayListener {
break;
case ControlMessage.TYPE_ROTATE_DEVICE:
Device.rotateDevice(getActionDisplayId());
// The virtual display resize will be handled by the main display monitor
break;
case ControlMessage.TYPE_UHID_CREATE:
getUhidManager().open(msg.getId(), msg.getVendorId(), msg.getProductId(), msg.getText(), msg.getData());

View file

@ -295,14 +295,19 @@ public class NewDisplayCapture extends SurfaceCapture {
// Ensure DPI is within valid range (Android requires DPI >= 1)
newDpi = Math.max(1, newDpi);
// Resize the virtual display
virtualDisplay.resize(newWidth, newHeight, newDpi);
// Round to multiple of 8 to avoid quality degradation from encoding constraints
Size roundedSize = new Size(newWidth, newHeight).round8();
int roundedWidth = roundedSize.getWidth();
int roundedHeight = roundedSize.getHeight();
// Resize the virtual display with rounded dimensions
virtualDisplay.resize(roundedWidth, roundedHeight, newDpi);
// Update our internal state
displaySize = new Size(newWidth, newHeight);
displaySize = new Size(roundedWidth, roundedHeight);
dpi = newDpi;
Ln.i("Resized display to: " + newWidth + "x" + newHeight + "/" + newDpi);
Ln.i("Resized display to: " + roundedWidth + "x" + roundedHeight + "/" + newDpi + " (rounded from " + newWidth + "x" + newHeight + ")");
// Trigger a reconfiguration
invalidate();