Merge branch 'master' into worktree-spot-removal
# Conflicts: # docs/traceability.md
This commit is contained in:
+23
-2
@@ -2439,8 +2439,29 @@ impl DevelopSession {
|
||||
// in `AdjustPass`'s texture descriptor — so a failure here is a
|
||||
// descriptor that drifted, not anything the caller did. Say that,
|
||||
// rather than surfacing "InvalidUsage" to a photographer.
|
||||
slint::Image::try_from(texture.clone())
|
||||
.map_err(|e| format!("the render target is not importable by the compositor: {e}"))
|
||||
#[cfg(not(target_os = "android"))]
|
||||
{
|
||||
slint::Image::try_from(texture.clone())
|
||||
.map_err(|e| format!("the render target is not importable by the compositor: {e}"))
|
||||
}
|
||||
|
||||
// Android draws with Skia over OpenGL and cannot sample a
|
||||
// `wgpu::Texture`, so the frame comes back through memory. See
|
||||
// `crate::shared_gpu`'s Android arm for why that is the trade on this
|
||||
// platform. The pass still runs on the GPU; only this last hop does not.
|
||||
#[cfg(target_os = "android")]
|
||||
{
|
||||
let _ = texture;
|
||||
let (rgba, w, h) = self
|
||||
.adjust
|
||||
.export_pixels()
|
||||
.map_err(|e| format!("reading the rendered frame back: {e}"))?;
|
||||
let mut buf = slint::SharedPixelBuffer::<slint::Rgba8Pixel>::new(w, h);
|
||||
let wanted = (w as usize) * (h as usize) * 4;
|
||||
let src = &rgba[..wanted.min(rgba.len())];
|
||||
buf.make_mut_bytes()[..src.len()].copy_from_slice(src);
|
||||
Ok(slint::Image::from_rgba8(buf))
|
||||
}
|
||||
}
|
||||
|
||||
/// TRACES: FR-DSP-7
|
||||
|
||||
@@ -741,6 +741,7 @@ enum PointsUpdate {
|
||||
///
|
||||
/// `None` means develop is unavailable and the viewer falls back to embedded
|
||||
/// previews — the same degradation as a machine with no adapter at all.
|
||||
#[cfg(not(target_os = "android"))]
|
||||
fn shared_gpu() -> Option<dr_gpu::GpuContext> {
|
||||
let shared = match pollster::block_on(dr_gpu::GpuContext::new_shared()) {
|
||||
Ok(shared) => shared,
|
||||
@@ -781,6 +782,45 @@ fn shared_gpu() -> Option<dr_gpu::GpuContext> {
|
||||
Some(ctx)
|
||||
}
|
||||
|
||||
/// TRACES: FR-DSP-1 | AC-8
|
||||
/// Open the compute device on Android — and do **not** give it to Slint.
|
||||
///
|
||||
/// # Why this platform is different
|
||||
///
|
||||
/// The desktop version above exists so one `wgpu::Texture` can be written by
|
||||
/// the adjust pass and sampled by the compositor without a round-trip. That
|
||||
/// requires Slint to be drawing with wgpu, and on Android drawing with wgpu
|
||||
/// means drawing on wgpu's Vulkan swapchain — which hardcodes
|
||||
/// `preTransform = IDENTITY` (gfx-rs/wgpu#3345).
|
||||
///
|
||||
/// On a tablet whose panel is mounted landscape, portrait then presents an
|
||||
/// unrotated buffer, every present returns `VK_SUBOPTIMAL_KHR`, and the frames
|
||||
/// arrive torn. Measured on the device: portrait sits on `composition=CLIENT`
|
||||
/// with `bufferTransform=ROT_270`, landscape on `composition=DEVICE` with
|
||||
/// `ROT_180`, and only portrait tore. Taking Slint off wgpu — it then uses
|
||||
/// Skia over OpenGL, where the driver owns the rotation — fixed it.
|
||||
///
|
||||
/// # What it costs, and why that is the right trade here
|
||||
///
|
||||
/// Without a shared device the display path needs a readback:
|
||||
/// `AdjustPass::export_pixels` instead of `Image::try_from(texture)`. That is
|
||||
/// the transfer ARCH §6.1 and AC-8 exist to avoid, and it is still the better
|
||||
/// bargain on this platform — the alternative is not a faster develop view, it
|
||||
/// is a torn one, in the orientation a tablet is mostly held in.
|
||||
///
|
||||
/// The compute passes are untouched: demosaic and adjust still run on the GPU,
|
||||
/// on this device. Only the last hop to the screen goes through memory.
|
||||
#[cfg(target_os = "android")]
|
||||
fn shared_gpu() -> Option<dr_gpu::GpuContext> {
|
||||
match pollster::block_on(dr_gpu::GpuContext::new_headless()) {
|
||||
Ok(ctx) => Some(ctx),
|
||||
Err(e) => {
|
||||
log::warn!("no GPU for the develop passes: {e}");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// TRACES: M-13 | M-14
|
||||
/// Build and run the viewer.
|
||||
pub fn run(paths: Vec<PathBuf>) -> Result<()> {
|
||||
|
||||
Reference in New Issue
Block a user