Skip to content

Commit ac7c2dd

Browse files
committed
Enable partial rendering with Skia's software renderer by default
1 parent a4ff057 commit ac7c2dd

File tree

3 files changed

+42
-36
lines changed

3 files changed

+42
-36
lines changed

api/rs/slint/tests/partial_renderer.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,9 @@ struct SkiaTestWindow {
7272
impl SkiaTestWindow {
7373
fn new() -> Rc<Self> {
7474
let render_buffer = Rc::new(SkiaTestSoftwareBuffer::default());
75-
let mut renderer = SkiaRenderer::new_with_surface(Box::new(
75+
let renderer = SkiaRenderer::new_with_surface(Box::new(
7676
i_slint_renderer_skia::software_surface::SoftwareSurface::from(render_buffer.clone()),
7777
));
78-
i_slint_renderer_skia::SkiaRendererExt::enable_partial_rendering(&mut renderer);
7978
Rc::new_cyclic(|w: &Weak<Self>| Self {
8079
window: slint::Window::new(w.clone()),
8180
renderer,

internal/renderers/skia/lib.rs

+37-34
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,25 @@ enum DirtyRegionDebugMode {
9696
Log,
9797
}
9898

99-
fn create_partial_renderer_state() -> (Option<PartialRenderingState>, DirtyRegionDebugMode) {
100-
let dirty_region_debug_mode = match std::env::var("SLINT_SKIA_PARTIAL_RENDERING").as_deref() {
101-
Ok("visualize") => DirtyRegionDebugMode::Visualize,
102-
Ok("log") => DirtyRegionDebugMode::Log,
103-
Ok(_) => DirtyRegionDebugMode::NoDebug,
104-
_ => return (None, DirtyRegionDebugMode::NoDebug),
105-
};
106-
107-
(Some(PartialRenderingState::default()), dirty_region_debug_mode)
99+
impl Default for DirtyRegionDebugMode {
100+
fn default() -> Self {
101+
match std::env::var("SLINT_SKIA_PARTIAL_RENDERING").as_deref() {
102+
Ok("visualize") => DirtyRegionDebugMode::Visualize,
103+
Ok("log") => DirtyRegionDebugMode::Log,
104+
_ => DirtyRegionDebugMode::NoDebug,
105+
}
106+
}
107+
}
108+
109+
fn create_partial_renderer_state(
110+
maybe_surface: Option<&dyn Surface>,
111+
) -> Option<PartialRenderingState> {
112+
maybe_surface
113+
.map_or_else(
114+
|| std::env::var("SLINT_SKIA_PARTIAL_RENDERING").as_deref().is_ok(),
115+
|surface| surface.use_partial_rendering(),
116+
)
117+
.then(|| PartialRenderingState::default())
108118
}
109119

110120
/// Use the SkiaRenderer when implementing a custom Slint platform where you deliver events to
@@ -132,7 +142,6 @@ pub struct SkiaRenderer {
132142

133143
impl Default for SkiaRenderer {
134144
fn default() -> Self {
135-
let (partial_rendering_state, dirty_region_debug_mode) = create_partial_renderer_state();
136145
Self {
137146
maybe_window_adapter: Default::default(),
138147
rendering_notifier: Default::default(),
@@ -143,8 +152,8 @@ impl Default for SkiaRenderer {
143152
surface: Default::default(),
144153
surface_factory: create_default_surface,
145154
pre_present_callback: Default::default(),
146-
partial_rendering_state,
147-
dirty_region_debug_mode,
155+
partial_rendering_state: create_partial_renderer_state(None),
156+
dirty_region_debug_mode: Default::default(),
148157
dirty_region_history: Default::default(),
149158
}
150159
}
@@ -154,7 +163,6 @@ impl SkiaRenderer {
154163
#[cfg(skia_backend_software)]
155164
/// Creates a new SkiaRenderer that will always use Skia's software renderer.
156165
pub fn default_software() -> Self {
157-
let (partial_rendering_state, dirty_region_debug_mode) = create_partial_renderer_state();
158166
Self {
159167
maybe_window_adapter: Default::default(),
160168
rendering_notifier: Default::default(),
@@ -173,16 +181,15 @@ impl SkiaRenderer {
173181
.map(|r| Box::new(r) as Box<dyn Surface>)
174182
},
175183
pre_present_callback: Default::default(),
176-
partial_rendering_state,
177-
dirty_region_debug_mode,
184+
partial_rendering_state: PartialRenderingState::default().into(),
185+
dirty_region_debug_mode: Default::default(),
178186
dirty_region_history: Default::default(),
179187
}
180188
}
181189

182190
#[cfg(not(target_os = "ios"))]
183191
/// Creates a new SkiaRenderer that will always use Skia's OpenGL renderer.
184192
pub fn default_opengl() -> Self {
185-
let (partial_rendering_state, dirty_region_debug_mode) = create_partial_renderer_state();
186193
Self {
187194
maybe_window_adapter: Default::default(),
188195
rendering_notifier: Default::default(),
@@ -201,16 +208,15 @@ impl SkiaRenderer {
201208
.map(|r| Box::new(r) as Box<dyn Surface>)
202209
},
203210
pre_present_callback: Default::default(),
204-
partial_rendering_state,
205-
dirty_region_debug_mode,
211+
partial_rendering_state: create_partial_renderer_state(None),
212+
dirty_region_debug_mode: Default::default(),
206213
dirty_region_history: Default::default(),
207214
}
208215
}
209216

210217
#[cfg(target_vendor = "apple")]
211218
/// Creates a new SkiaRenderer that will always use Skia's Metal renderer.
212219
pub fn default_metal() -> Self {
213-
let (partial_rendering_state, dirty_region_debug_mode) = create_partial_renderer_state();
214220
Self {
215221
maybe_window_adapter: Default::default(),
216222
rendering_notifier: Default::default(),
@@ -229,16 +235,15 @@ impl SkiaRenderer {
229235
.map(|r| Box::new(r) as Box<dyn Surface>)
230236
},
231237
pre_present_callback: Default::default(),
232-
partial_rendering_state,
233-
dirty_region_debug_mode,
238+
partial_rendering_state: create_partial_renderer_state(None),
239+
dirty_region_debug_mode: Default::default(),
234240
dirty_region_history: Default::default(),
235241
}
236242
}
237243

238244
#[cfg(skia_backend_vulkan)]
239245
/// Creates a new SkiaRenderer that will always use Skia's Vulkan renderer.
240246
pub fn default_vulkan() -> Self {
241-
let (partial_rendering_state, dirty_region_debug_mode) = create_partial_renderer_state();
242247
Self {
243248
maybe_window_adapter: Default::default(),
244249
rendering_notifier: Default::default(),
@@ -257,16 +262,15 @@ impl SkiaRenderer {
257262
.map(|r| Box::new(r) as Box<dyn Surface>)
258263
},
259264
pre_present_callback: Default::default(),
260-
partial_rendering_state,
261-
dirty_region_debug_mode,
265+
partial_rendering_state: create_partial_renderer_state(None),
266+
dirty_region_debug_mode: Default::default(),
262267
dirty_region_history: Default::default(),
263268
}
264269
}
265270

266271
#[cfg(target_family = "windows")]
267272
/// Creates a new SkiaRenderer that will always use Skia's Direct3D renderer.
268273
pub fn default_direct3d() -> Self {
269-
let (partial_rendering_state, dirty_region_debug_mode) = create_partial_renderer_state();
270274
Self {
271275
maybe_window_adapter: Default::default(),
272276
rendering_notifier: Default::default(),
@@ -285,8 +289,8 @@ impl SkiaRenderer {
285289
.map(|r| Box::new(r) as Box<dyn Surface>)
286290
},
287291
pre_present_callback: Default::default(),
288-
partial_rendering_state,
289-
dirty_region_debug_mode,
292+
partial_rendering_state: create_partial_renderer_state(None),
293+
dirty_region_debug_mode: Default::default(),
290294
dirty_region_history: Default::default(),
291295
}
292296
}
@@ -307,7 +311,7 @@ impl SkiaRenderer {
307311

308312
/// Creates a new renderer with the given surface trait implementation.
309313
pub fn new_with_surface(surface: Box<dyn Surface + 'static>) -> Self {
310-
let (partial_rendering_state, dirty_region_debug_mode) = create_partial_renderer_state();
314+
let partial_rendering_state = create_partial_renderer_state(Some(surface.as_ref())).into();
311315
Self {
312316
maybe_window_adapter: Default::default(),
313317
rendering_notifier: Default::default(),
@@ -321,7 +325,7 @@ impl SkiaRenderer {
321325
},
322326
pre_present_callback: Default::default(),
323327
partial_rendering_state,
324-
dirty_region_debug_mode,
328+
dirty_region_debug_mode: Default::default(),
325329
dirty_region_history: Default::default(),
326330
}
327331
}
@@ -966,6 +970,10 @@ pub trait Surface {
966970
) -> Result<(), i_slint_core::platform::PlatformError>;
967971
fn bits_per_pixel(&self) -> Result<u8, PlatformError>;
968972

973+
fn use_partial_rendering(&self) -> bool {
974+
false
975+
}
976+
969977
/// Implementations should return self to allow upcasting.
970978
fn as_any(&self) -> &dyn core::any::Any {
971979
&()
@@ -980,8 +988,6 @@ pub trait SkiaRendererExt {
980988
surface_size: PhysicalWindowSize,
981989
post_render_cb: Option<&dyn Fn(&mut dyn ItemRenderer)>,
982990
) -> Result<(), i_slint_core::platform::PlatformError>;
983-
/// Remove this when partial rendering becomes enabled by default.
984-
fn enable_partial_rendering(&mut self);
985991
}
986992

987993
impl SkiaRendererExt for SkiaRenderer {
@@ -999,7 +1005,4 @@ impl SkiaRendererExt for SkiaRenderer {
9991005
post_render_cb,
10001006
)
10011007
}
1002-
fn enable_partial_rendering(&mut self) {
1003-
self.partial_rendering_state = Some(PartialRenderingState::default())
1004-
}
10051008
}

internal/renderers/skia/software_surface.rs

+4
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,10 @@ impl super::Surface for SoftwareSurface {
190190
fn bits_per_pixel(&self) -> Result<u8, i_slint_core::platform::PlatformError> {
191191
Ok(24)
192192
}
193+
194+
fn use_partial_rendering(&self) -> bool {
195+
true
196+
}
193197
}
194198

195199
impl<T: RenderBuffer + 'static> From<T> for SoftwareSurface {

0 commit comments

Comments
 (0)