it: verify that surface damage damages connector
This commit is contained in:
parent
8a5f1e1e37
commit
f45cbed53b
4 changed files with 133 additions and 2 deletions
|
|
@ -27,7 +27,7 @@ use {
|
|||
state::State,
|
||||
udmabuf::Udmabuf,
|
||||
utils::{
|
||||
clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt,
|
||||
clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt, numcell::NumCell,
|
||||
on_change::OnChange, oserror::OsError, syncqueue::SyncQueue,
|
||||
},
|
||||
video::{
|
||||
|
|
@ -84,6 +84,7 @@ impl TestBackend {
|
|||
events: Default::default(),
|
||||
feedback: Default::default(),
|
||||
idle: Default::default(),
|
||||
damage_calls: NumCell::new(0),
|
||||
});
|
||||
let default_mouse = Rc::new(TestBackendMouse {
|
||||
common: TestInputDeviceCommon {
|
||||
|
|
@ -318,6 +319,7 @@ pub struct TestConnector {
|
|||
pub events: OnChange<ConnectorEvent>,
|
||||
pub feedback: CloneCell<Option<Rc<DrmFeedback>>>,
|
||||
pub idle: TEEH<bool>,
|
||||
pub damage_calls: NumCell<u32>,
|
||||
}
|
||||
|
||||
impl Connector for TestConnector {
|
||||
|
|
@ -338,7 +340,7 @@ impl Connector for TestConnector {
|
|||
}
|
||||
|
||||
fn damage(&self) {
|
||||
// nothing
|
||||
self.damage_calls.fetch_add(1);
|
||||
}
|
||||
|
||||
fn drm_dev(&self) -> Option<DrmDeviceId> {
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ mod t0045_content_type;
|
|||
mod t0046_buffer_release;
|
||||
mod t0047_surface_damage;
|
||||
mod t0048_frame_callback;
|
||||
mod t0049_surface_damage_backend;
|
||||
|
||||
pub trait TestCase: Sync {
|
||||
fn name(&self) -> &'static str;
|
||||
|
|
@ -146,5 +147,6 @@ pub fn tests() -> Vec<&'static dyn TestCase> {
|
|||
t0046_buffer_release,
|
||||
t0047_surface_damage,
|
||||
t0048_frame_callback,
|
||||
t0049_surface_damage_backend,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ use {
|
|||
format::XRGB8888,
|
||||
ifs::wl_output::OutputId,
|
||||
it::{test_backend::TestConnector, test_error::TestResult, testrun::TestRun},
|
||||
utils::numcell::NumCell,
|
||||
video::drm::ConnectorType,
|
||||
},
|
||||
std::rc::Rc,
|
||||
|
|
@ -35,6 +36,7 @@ async fn test(run: Rc<TestRun>) -> TestResult {
|
|||
events: Default::default(),
|
||||
feedback: Default::default(),
|
||||
idle: Default::default(),
|
||||
damage_calls: NumCell::new(0),
|
||||
});
|
||||
let new_monitor_info = MonitorInfo {
|
||||
modes: vec![],
|
||||
|
|
|
|||
125
src/it/tests/t0049_surface_damage_backend.rs
Normal file
125
src/it/tests/t0049_surface_damage_backend.rs
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
use {
|
||||
crate::it::{test_error::TestResult, testrun::TestRun},
|
||||
std::rc::Rc,
|
||||
};
|
||||
|
||||
testcase!();
|
||||
|
||||
/// Test that committing damage on a visible surface causes the backend connector to be damaged.
|
||||
/// This test verifies that surface damage triggers backend connector damage tracking AND
|
||||
/// that the frontend actually calls into the backend connector's damage method,
|
||||
/// ensuring the rendering pipeline knows when to update the display.
|
||||
async fn test(run: Rc<TestRun>) -> TestResult {
|
||||
run.backend.install_default()?;
|
||||
let client = run.create_client().await?;
|
||||
|
||||
// Get connector for tracking backend damage state
|
||||
let connector_id = run.backend.default_connector.id;
|
||||
let connector_data = run.state.connectors.get(&connector_id).unwrap();
|
||||
|
||||
// Create a visible window with mapped surface
|
||||
let window = client.create_window().await?;
|
||||
let buffer = client
|
||||
.spbm
|
||||
.create_buffer(crate::theme::Color::from_srgb(0, 255, 0))?;
|
||||
window.surface.attach(buffer.id)?;
|
||||
window.map().await?;
|
||||
client.sync().await;
|
||||
|
||||
// Test 1: Ensure initially the backend is not damaged
|
||||
connector_data.damaged.set(false);
|
||||
run.backend.default_connector.damage_calls.set(0);
|
||||
tassert!(!connector_data.damaged.get());
|
||||
tassert_eq!(run.backend.default_connector.damage_calls.get(), 0);
|
||||
|
||||
// Test 2: Add surface damage and commit - this should trigger backend connector damage
|
||||
window.surface.damage(10, 10, 50, 50)?;
|
||||
window.surface.commit()?;
|
||||
client.sync().await;
|
||||
|
||||
// Critical test: Verify the backend connector is now damaged AND the backend method was called
|
||||
tassert!(connector_data.damaged.get());
|
||||
tassert!(run.backend.default_connector.damage_calls.get() > 0);
|
||||
|
||||
// Test 3: Reset damage state and test buffer damage
|
||||
connector_data.damaged.set(false);
|
||||
let previous_calls = run.backend.default_connector.damage_calls.get();
|
||||
tassert!(!connector_data.damaged.get());
|
||||
|
||||
// Add buffer damage and commit - this should also trigger backend connector damage
|
||||
window.surface.damage_buffer(0, 0, 1, 1)?; // Damage entire 1x1 buffer
|
||||
window.surface.commit()?;
|
||||
client.sync().await;
|
||||
|
||||
// Verify the backend connector is damaged again AND more backend calls were made
|
||||
tassert!(connector_data.damaged.get());
|
||||
tassert!(run.backend.default_connector.damage_calls.get() > previous_calls);
|
||||
|
||||
// Test 4: Test that invisible surfaces do not trigger backend damage
|
||||
let invisible_surface = client.comp.create_surface().await?;
|
||||
let invisible_buffer = client
|
||||
.spbm
|
||||
.create_buffer(crate::theme::Color::from_srgb(255, 255, 0))?;
|
||||
invisible_surface.attach(invisible_buffer.id)?;
|
||||
invisible_surface.commit()?; // Initial commit to attach buffer
|
||||
client.sync().await;
|
||||
|
||||
// Reset damage state
|
||||
connector_data.damaged.set(false);
|
||||
let invisible_calls_before = run.backend.default_connector.damage_calls.get();
|
||||
tassert!(!connector_data.damaged.get());
|
||||
|
||||
// Add damage to invisible surface and commit
|
||||
invisible_surface.damage(20, 20, 30, 30)?;
|
||||
invisible_surface.commit()?;
|
||||
client.sync().await;
|
||||
|
||||
// Invisible surface damage should NOT trigger backend connector damage or backend calls
|
||||
tassert!(!connector_data.damaged.get());
|
||||
tassert_eq!(
|
||||
run.backend.default_connector.damage_calls.get(),
|
||||
invisible_calls_before
|
||||
);
|
||||
|
||||
// Test 5: Test multiple damage areas on visible surface
|
||||
connector_data.damaged.set(false);
|
||||
let multi_calls_before = run.backend.default_connector.damage_calls.get();
|
||||
tassert!(!connector_data.damaged.get());
|
||||
|
||||
// Add multiple damage rectangles to visible surface
|
||||
window.surface.damage(5, 5, 10, 10)?;
|
||||
window.surface.damage(25, 25, 15, 15)?;
|
||||
window.surface.damage_buffer(0, 0, 1, 1)?;
|
||||
window.surface.commit()?;
|
||||
client.sync().await;
|
||||
|
||||
// Multiple damage areas on visible surface should trigger backend connector damage and calls
|
||||
tassert!(connector_data.damaged.get());
|
||||
tassert!(run.backend.default_connector.damage_calls.get() > multi_calls_before);
|
||||
|
||||
// Test 6: Test that damage without commit does not trigger backend damage
|
||||
connector_data.damaged.set(false);
|
||||
let no_commit_calls_before = run.backend.default_connector.damage_calls.get();
|
||||
tassert!(!connector_data.damaged.get());
|
||||
|
||||
// Add damage but don't commit
|
||||
window.surface.damage(40, 40, 20, 20)?;
|
||||
client.sync().await;
|
||||
|
||||
// Damage without commit should NOT trigger backend connector damage or backend calls
|
||||
tassert!(!connector_data.damaged.get());
|
||||
tassert_eq!(
|
||||
run.backend.default_connector.damage_calls.get(),
|
||||
no_commit_calls_before
|
||||
);
|
||||
|
||||
// Now commit the pending damage
|
||||
window.surface.commit()?;
|
||||
client.sync().await;
|
||||
|
||||
// After commit, backend connector should be damaged and backend called
|
||||
tassert!(connector_data.damaged.get());
|
||||
tassert!(run.backend.default_connector.damage_calls.get() > no_commit_calls_before);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue