Module damage

Module damage 

Source
Expand description

Helper for effective output damage tracking

§Why use this implementation

The OutputDamageTracker in combination with the RenderElement trait can help you to reduce resource consumption by tracking what elements have been damaged and only redraw the damaged parts on an output.

It does so by keeping track of the last used CommitCounter for all provided RenderElements and queries the element for new damage on each call to render_output or damage_output.

Additionally the damage tracker will automatically generate damage in the following situations:

  • Current geometry for elements entering the output
  • Current and last known geometry for moved elements (includes z-index changes)
  • Last known geometry for elements no longer present

Elements fully occluded by opaque regions as defined by elements higher in the stack are skipped. The actual action taken by the damage tracker can be inspected from the returned RenderElementStates.

You can initialize it with a static output by using OutputDamageTracker::new or allow it to track a specific Output with OutputDamageTracker::from_output.

See the renderer::element module for more information about how to use RenderElement.

§How to use it

use smithay::{
    backend::{
        allocator::Fourcc,
        renderer::{
            damage::OutputDamageTracker,
            element::{
                Kind,
                memory::{MemoryRenderBuffer, MemoryRenderBufferRenderElement},
            }
        },
    },
    utils::{Point, Transform},
};
use std::time::{Duration, Instant};

const WIDTH: i32 = 10;
const HEIGHT: i32 = 10;

// Initialize a new damage tracker for a static output
let mut damage_tracker = OutputDamageTracker::new((800, 600), 1.0, Transform::Normal);

// Initialize a buffer to render
let mut memory_buffer = MemoryRenderBuffer::new(Fourcc::Argb8888, (WIDTH, HEIGHT), 1, Transform::Normal, None);

let mut last_update = Instant::now();

loop {
    let now = Instant::now();
    if now.duration_since(last_update) >= Duration::from_secs(3) {
        let mut render_context = memory_buffer.render();

        render_context.draw(|_buffer| {
            // Update the changed parts of the buffer

            // Return the updated parts
            Result::<_, ()>::Ok(vec![Rectangle::from_size((WIDTH, HEIGHT).into())])
        });

        last_update = now;
    }

    // Create a render element from the buffer
    let location = Point::from((100.0, 100.0));
    let render_element =
        MemoryRenderBufferRenderElement::from_buffer(&mut renderer, location, &memory_buffer, None, None, None, Kind::Unspecified)
        .expect("Failed to upload memory to gpu");

    // Render the output
    damage_tracker
        .render_output(
            &mut renderer,
            &mut framebuffer,
            buffer_age,
            &[render_element],
            [0.8, 0.8, 0.9, 1.0],
        )
        .expect("failed to render the output");
}

Structs§

OutputDamageTracker
Damage tracker for a single output
RenderOutputResult
Represents the result from rendering the output

Enums§

Error
Errors thrown by OutputDamageTracker::render_output