Skip to content

cleanup texture cache #1064

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/backend/drm/compositor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2451,6 +2451,13 @@ where

match render_res {
Ok(render_output_result) => {
if render_output_result.damage.is_none() {
// if we receive no damage we can assume no rendering took place
// and we should trigger a cleanup of the renderer texture cache
// to prevent holding textures longer then necessary
let _ = renderer.cleanup_texture_cache();
}

for (id, state) in render_output_result.states.states.into_iter() {
// Skip the state for our fake elements
if self.overlay_plane_element_ids.contains_plane_id(&id) {
Expand Down Expand Up @@ -2532,6 +2539,11 @@ where
return Err(RenderFrameError::from(err));
}
}
} else {
// if we are constantly doing direct scan-out on the primary plane
// we have to cleanup the renderer texture cache as this would
// only happen implicit during rendering otherwise
let _ = renderer.cleanup_texture_cache();
}

let primary_plane_element = if render {
Expand Down
7 changes: 7 additions & 0 deletions src/backend/renderer/gles/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2116,6 +2116,13 @@ impl Renderer for GlesRenderer {
// block until the sync point has been reached
sync.wait().map_err(|_| GlesError::SyncInterrupted)
}

#[profiling::function]
fn cleanup_texture_cache(&mut self) -> Result<(), Self::Error> {
self.make_current()?;
self.cleanup();
Ok(())
}
}

/// Vertices for instanced rendering.
Expand Down
5 changes: 5 additions & 0 deletions src/backend/renderer/glow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,11 @@ impl Renderer for GlowRenderer {
fn wait(&mut self, sync: &sync::SyncPoint) -> Result<(), Self::Error> {
self.gl.wait(sync)
}

#[profiling::function]
fn cleanup_texture_cache(&mut self) -> Result<(), Self::Error> {
self.gl.cleanup_texture_cache()
}
}

impl<'frame> Frame for GlowFrame<'frame> {
Expand Down
14 changes: 14 additions & 0 deletions src/backend/renderer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ pub trait TextureMapping: Texture {
}

/// Helper trait for [`Renderer`], which defines a rendering api for a currently in-progress frame during [`Renderer::render`].
///
/// Dropping the [`Frame`] or explicitly calling [`Frame::finish`] will free any unused resources. If you need explicit control
/// over resource clean-up take a look at [`Renderer::cleanup_texture_cache`].
pub trait Frame {
/// Error type returned by the rendering operations of this renderer.
type Error: Error;
Expand Down Expand Up @@ -300,6 +303,17 @@ pub trait Renderer: fmt::Debug {

/// Wait for a [`SyncPoint`](sync::SyncPoint) to be signaled
fn wait(&mut self, sync: &sync::SyncPoint) -> Result<(), Self::Error>;

/// Forcibly clean up the renderer internal texture cache
///
/// Note: Resources used by the renderer will be implicitly cleaned-up after finishing
/// a [`Frame`] by either dropping the [`Frame`] or explicitly calling [`Frame::finish`].
/// This call can be used to clean-up resources in cases where either no [`Frame`] is used
/// at all to prevent resource pile-up or in case of only infrequent access to lower
/// system resource usage.
fn cleanup_texture_cache(&mut self) -> Result<(), Self::Error> {
Ok(())
}
}

/// Trait for renderers that support creating offscreen framebuffers to render into.
Expand Down
35 changes: 34 additions & 1 deletion src/backend/renderer/multigpu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1098,6 +1098,22 @@ where
fn wait(&mut self, sync: &sync::SyncPoint) -> Result<(), Self::Error> {
self.render.renderer_mut().wait(sync).map_err(Error::Render)
}

#[profiling::function]
fn cleanup_texture_cache(&mut self) -> Result<(), Self::Error> {
if let Some(target) = self.target.as_mut() {
target
.device
.renderer_mut()
.cleanup_texture_cache()
.map_err(Error::Target)?;
}
self.render
.renderer_mut()
.cleanup_texture_cache()
.map_err(Error::Render)?;
Ok(())
}
}

fn create_shared_dma_framebuffer<R, T: GraphicsApi>(
Expand Down Expand Up @@ -1224,6 +1240,10 @@ where
)
.map_err(Error::Target)?;
let sync = frame.finish().map_err(Error::Target)?;
render
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to clarify, why does this call cleanup_texture_cache() explicitly, even though the new docs say that Frame::finish() does it automatically?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The frame here is from the target, so the call to cleanup_texture_cache should clean-up the other renderer in this case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, thanks

.renderer_mut()
.cleanup_texture_cache()
.map_err(Error::Render)?;

return Ok(sync);
}
Expand Down Expand Up @@ -1275,6 +1295,10 @@ where
}

if mappings.is_empty() {
render
.renderer_mut()
.cleanup_texture_cache()
.map_err(Error::Render)?;
return Ok(sync::SyncPoint::signaled());
}

Expand Down Expand Up @@ -1319,9 +1343,18 @@ where
.map_err(Error::Target)?;
}
}
return frame.finish().map_err(Error::Target);
let sync = frame.finish().map_err(Error::Target)?;
render
.renderer_mut()
.cleanup_texture_cache()
.map_err(Error::Render)?;
return Ok(sync);
}

render
.renderer_mut()
.cleanup_texture_cache()
.map_err(Error::Render)?;
return Ok(sync);
}

Expand Down
5 changes: 5 additions & 0 deletions src/backend/renderer/pixman/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,11 @@ impl Renderer for PixmanRenderer {
fn wait(&mut self, sync: &SyncPoint) -> Result<(), Self::Error> {
sync.wait().map_err(|_| PixmanError::SyncInterrupted)
}

fn cleanup_texture_cache(&mut self) -> Result<(), Self::Error> {
self.cleanup();
Ok(())
}
}

impl ImportMem for PixmanRenderer {
Expand Down
Loading