[Ozone-DRM] Cache CTM, DEGAMMA and GAMMA and apply them on commit
Cache the properties and apply them on commit on DRM Atomic. This works
around the need to waste a vsync interval to applying the atomic
properties.
BUG=839487
TEST=Ran unittests
Change-Id: I23a300d98648c5f7dff86019c8f8b9cb11129fb8
Reviewed-on: https://chromium-review.googlesource.com/1108561
Commit-Queue: Daniel Nicoara <dnicoara@chromium.org>
Reviewed-by: Daniele Castagna <dcastagna@chromium.org>
Cr-Commit-Position: refs/heads/master@{#578356}
diff --git a/ui/ozone/platform/drm/BUILD.gn b/ui/ozone/platform/drm/BUILD.gn
index 567ffa04..1550f531 100644
--- a/ui/ozone/platform/drm/BUILD.gn
+++ b/ui/ozone/platform/drm/BUILD.gn
@@ -8,6 +8,13 @@
visibility = [ "//ui/ozone/*" ]
+declare_args() {
+ # Enables commiting of CRTC properties on page flip events.
+ # This is not enabled by default because of a bug on Intel:
+ # https://crbug.com/854753
+ drm_commit_properties_on_page_flip = false
+}
+
source_set("gbm") {
sources = [
"client_native_pixmap_factory_gbm.cc",
@@ -161,6 +168,10 @@
public_configs = [ "//third_party/khronos:khronos_headers" ]
defines = [ "OZONE_IMPLEMENTATION" ]
+
+ if (drm_commit_properties_on_page_flip) {
+ defines += [ "COMMIT_PROPERTIES_ON_PAGE_FLIP" ]
+ }
}
source_set("gbm_unittests") {
@@ -194,4 +205,8 @@
"//ui/ozone/common",
"//ui/ozone/common/linux",
]
+
+ if (drm_commit_properties_on_page_flip) {
+ defines = [ "COMMIT_PROPERTIES_ON_PAGE_FLIP" ]
+ }
}
diff --git a/ui/ozone/platform/drm/gpu/drm_gpu_util.cc b/ui/ozone/platform/drm/gpu/drm_gpu_util.cc
index 1924b6e..518916c 100644
--- a/ui/ozone/platform/drm/gpu/drm_gpu_util.cc
+++ b/ui/ozone/platform/drm/gpu/drm_gpu_util.cc
@@ -30,6 +30,24 @@
return false;
}
+bool AddPropertyIfValid(drmModeAtomicReq* property_set,
+ uint32_t object_id,
+ const DrmDevice::Property& property) {
+ if (!property.id)
+ return true;
+
+ int ret = drmModeAtomicAddProperty(property_set, object_id, property.id,
+ property.value);
+ if (ret < 0) {
+ LOG(ERROR) << "Failed to set property object_id=" << object_id
+ << " property_id=" << property.id
+ << " property_value=" << property.value << " error=" << -ret;
+ return false;
+ }
+
+ return true;
+}
+
ScopedDrmColorLutPtr CreateLutBlob(
const std::vector<display::GammaRampRGBEntry>& source) {
TRACE_EVENT0("drm", "CreateLutBlob");
diff --git a/ui/ozone/platform/drm/gpu/drm_gpu_util.h b/ui/ozone/platform/drm/gpu/drm_gpu_util.h
index e138ef8..1972bef 100644
--- a/ui/ozone/platform/drm/gpu/drm_gpu_util.h
+++ b/ui/ozone/platform/drm/gpu/drm_gpu_util.h
@@ -16,6 +16,11 @@
const std::string& name,
DrmDevice::Property* property);
+// If the |property| has a valid ID add it to the |property_set| request.
+bool AddPropertyIfValid(drmModeAtomicReq* property_set,
+ uint32_t object_id,
+ const DrmDevice::Property& property);
+
// Transforms the gamma ramp entries into the drm_color_lut format.
ScopedDrmColorLutPtr CreateLutBlob(
const std::vector<display::GammaRampRGBEntry>& source);
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_atomic.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_atomic.cc
index b1ab4c1..0a041d8 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane_atomic.cc
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_atomic.cc
@@ -5,6 +5,7 @@
#include "ui/ozone/platform/drm/gpu/hardware_display_plane_atomic.h"
#include "ui/ozone/platform/drm/gpu/drm_device.h"
+#include "ui/ozone/platform/drm/gpu/drm_gpu_util.h"
namespace ui {
namespace {
@@ -41,21 +42,6 @@
return 0;
}
-bool AddProperty(drmModeAtomicReqPtr property_set,
- uint32_t object_id,
- const DrmDevice::Property& property) {
- int ret = drmModeAtomicAddProperty(property_set, object_id, property.id,
- property.value);
- if (ret < 0) {
- LOG(ERROR) << "Failed to set property object_id=" << object_id
- << " property_id=" << property.id
- << " property_value=" << property.value << " error=" << -ret;
- return false;
- }
-
- return true;
-}
-
} // namespace
HardwareDisplayPlaneAtomic::HardwareDisplayPlaneAtomic(uint32_t id)
@@ -101,29 +87,30 @@
properties_.src_h.value = src_rect.height();
bool plane_set_succeeded =
- AddProperty(property_set, id_, properties_.crtc_id) &&
- AddProperty(property_set, id_, properties_.crtc_x) &&
- AddProperty(property_set, id_, properties_.crtc_y) &&
- AddProperty(property_set, id_, properties_.crtc_w) &&
- AddProperty(property_set, id_, properties_.crtc_h) &&
- AddProperty(property_set, id_, properties_.fb_id) &&
- AddProperty(property_set, id_, properties_.src_x) &&
- AddProperty(property_set, id_, properties_.src_y) &&
- AddProperty(property_set, id_, properties_.src_w) &&
- AddProperty(property_set, id_, properties_.src_h);
+ AddPropertyIfValid(property_set, id_, properties_.crtc_id) &&
+ AddPropertyIfValid(property_set, id_, properties_.crtc_x) &&
+ AddPropertyIfValid(property_set, id_, properties_.crtc_y) &&
+ AddPropertyIfValid(property_set, id_, properties_.crtc_w) &&
+ AddPropertyIfValid(property_set, id_, properties_.crtc_h) &&
+ AddPropertyIfValid(property_set, id_, properties_.fb_id) &&
+ AddPropertyIfValid(property_set, id_, properties_.src_x) &&
+ AddPropertyIfValid(property_set, id_, properties_.src_y) &&
+ AddPropertyIfValid(property_set, id_, properties_.src_w) &&
+ AddPropertyIfValid(property_set, id_, properties_.src_h);
if (properties_.rotation.id) {
properties_.rotation.value =
OverlayTransformToDrmRotationPropertyValue(transform);
- plane_set_succeeded = plane_set_succeeded &&
- AddProperty(property_set, id_, properties_.rotation);
+ plane_set_succeeded =
+ plane_set_succeeded &&
+ AddPropertyIfValid(property_set, id_, properties_.rotation);
}
if (properties_.in_fence_fd.id && in_fence_fd >= 0) {
properties_.in_fence_fd.value = in_fence_fd;
plane_set_succeeded =
plane_set_succeeded &&
- AddProperty(property_set, id_, properties_.in_fence_fd);
+ AddPropertyIfValid(property_set, id_, properties_.in_fence_fd);
}
if (!plane_set_succeeded) {
@@ -140,7 +127,7 @@
return false;
properties_.plane_ctm.value = ctm_blob_id;
- return AddProperty(property_set, id_, properties_.plane_ctm);
+ return AddPropertyIfValid(property_set, id_, properties_.plane_ctm);
}
} // namespace ui
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
index 10da4f49..b33793726 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
@@ -43,6 +43,12 @@
HardwareDisplayPlaneList::PageFlipInfo::~PageFlipInfo() {
}
+HardwareDisplayPlaneManager::CrtcState::CrtcState() = default;
+
+HardwareDisplayPlaneManager::CrtcState::~CrtcState() = default;
+
+HardwareDisplayPlaneManager::CrtcState::CrtcState(CrtcState&&) = default;
+
HardwareDisplayPlaneManager::HardwareDisplayPlaneManager() : drm_(nullptr) {
}
@@ -59,7 +65,7 @@
drm_->SetCapability(DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
#endif
- if (!InitializeCrtcProperties(drm))
+ if (!InitializeCrtcState(drm))
return false;
if (!InitializePlanes(drm))
@@ -95,8 +101,8 @@
}
int HardwareDisplayPlaneManager::LookupCrtcIndex(uint32_t crtc_id) const {
- for (size_t i = 0; i < crtc_properties_.size(); ++i)
- if (crtc_properties_[i].id == crtc_id)
+ for (size_t i = 0; i < crtc_state_.size(); ++i)
+ if (crtc_state_[i].properties.id == crtc_id)
return i;
return -1;
}
@@ -234,16 +240,16 @@
const int crtc_index = LookupCrtcIndex(crtc_id);
DCHECK_GE(crtc_index, 0);
- CrtcProperties* crtc_props = &crtc_properties_[crtc_index];
+ CrtcState* crtc_state = &crtc_state_[crtc_index];
ScopedDrmColorCtmPtr ctm_blob_data = CreateCTMBlob(color_matrix);
- if (!crtc_props->ctm.id)
+ if (!crtc_state->properties.ctm.id)
return SetColorCorrectionOnAllCrtcPlanes(crtc_id, std::move(ctm_blob_data));
- ScopedDrmPropertyBlob ctm_prop =
+ crtc_state->ctm_blob =
drm_->CreatePropertyBlob(ctm_blob_data.get(), sizeof(drm_color_ctm));
- crtc_props->ctm.value = ctm_prop->id();
- return CommitColorMatrix(*crtc_props);
+ crtc_state->properties.ctm.value = crtc_state->ctm_blob->id();
+ return CommitColorMatrix(crtc_state->properties);
}
bool HardwareDisplayPlaneManager::SetGammaCorrection(
@@ -256,7 +262,8 @@
return false;
}
- CrtcProperties* crtc_props = &crtc_properties_[crtc_index];
+ CrtcState* crtc_state = &crtc_state_[crtc_index];
+ CrtcProperties* crtc_props = &crtc_state->properties;
if (!degamma_lut.empty() &&
(!crtc_props->degamma_lut.id || !crtc_props->degamma_lut_size.id))
@@ -279,21 +286,20 @@
ScopedDrmColorLutPtr gamma_blob_data =
CreateLutBlob(ResampleLut(gamma_lut, crtc_props->gamma_lut_size.value));
- ScopedDrmPropertyBlob degamma_prop, gamma_prop;
if (degamma_blob_data) {
- degamma_prop = drm_->CreatePropertyBlob(
+ crtc_state->degamma_lut_blob = drm_->CreatePropertyBlob(
degamma_blob_data.get(),
sizeof(drm_color_lut) * crtc_props->degamma_lut_size.value);
- crtc_props->degamma_lut.value = degamma_prop->id();
+ crtc_props->degamma_lut.value = crtc_state->degamma_lut_blob->id();
} else {
crtc_props->degamma_lut.value = 0;
}
if (gamma_blob_data) {
- gamma_prop = drm_->CreatePropertyBlob(
+ crtc_state->gamma_lut_blob = drm_->CreatePropertyBlob(
gamma_blob_data.get(),
sizeof(drm_color_lut) * crtc_props->gamma_lut_size.value);
- crtc_props->gamma_lut.value = gamma_prop->id();
+ crtc_props->gamma_lut.value = crtc_state->gamma_lut_blob->id();
} else {
crtc_props->gamma_lut.value = 0;
}
@@ -301,7 +307,7 @@
return CommitGammaCorrection(*crtc_props);
}
-bool HardwareDisplayPlaneManager::InitializeCrtcProperties(DrmDevice* drm) {
+bool HardwareDisplayPlaneManager::InitializeCrtcState(DrmDevice* drm) {
ScopedDrmResourcesPtr resources(drm->GetResources());
if (!resources) {
PLOG(ERROR) << "Failed to get resources.";
@@ -311,30 +317,34 @@
unsigned int num_crtcs_with_out_fence_ptr = 0;
for (int i = 0; i < resources->count_crtcs; ++i) {
- CrtcProperties p{};
- p.id = resources->crtcs[i];
+ CrtcState state;
+ state.properties.id = resources->crtcs[i];
ScopedDrmObjectPropertyPtr props(
drm->GetObjectProperties(resources->crtcs[i], DRM_MODE_OBJECT_CRTC));
if (!props) {
- PLOG(ERROR) << "Failed to get CRTC properties for crtc_id=" << p.id;
+ PLOG(ERROR) << "Failed to get CRTC properties for crtc_id="
+ << state.properties.id;
continue;
}
// These properties are optional. If they don't exist we can tell by the
// invalid ID.
- GetDrmPropertyForName(drm, props.get(), "CTM", &p.ctm);
- GetDrmPropertyForName(drm, props.get(), "GAMMA_LUT", &p.gamma_lut);
+ GetDrmPropertyForName(drm, props.get(), "CTM", &state.properties.ctm);
+ GetDrmPropertyForName(drm, props.get(), "GAMMA_LUT",
+ &state.properties.gamma_lut);
GetDrmPropertyForName(drm, props.get(), "GAMMA_LUT_SIZE",
- &p.gamma_lut_size);
- GetDrmPropertyForName(drm, props.get(), "DEGAMMA_LUT", &p.degamma_lut);
+ &state.properties.gamma_lut_size);
+ GetDrmPropertyForName(drm, props.get(), "DEGAMMA_LUT",
+ &state.properties.degamma_lut);
GetDrmPropertyForName(drm, props.get(), "DEGAMMA_LUT_SIZE",
- &p.degamma_lut_size);
- GetDrmPropertyForName(drm, props.get(), "OUT_FENCE_PTR", &p.out_fence_ptr);
+ &state.properties.degamma_lut_size);
+ GetDrmPropertyForName(drm, props.get(), "OUT_FENCE_PTR",
+ &state.properties.out_fence_ptr);
- num_crtcs_with_out_fence_ptr += (p.out_fence_ptr.id != 0);
+ num_crtcs_with_out_fence_ptr += (state.properties.out_fence_ptr.id != 0);
- crtc_properties_.push_back(p);
+ crtc_state_.emplace_back(std::move(state));
}
// Check that either all or none of the crtcs support the OUT_FENCE_PTR
@@ -342,7 +352,7 @@
// out-fence set when we perform a commit involving the problematic
// crtcs.
if (num_crtcs_with_out_fence_ptr != 0 &&
- num_crtcs_with_out_fence_ptr != crtc_properties_.size()) {
+ num_crtcs_with_out_fence_ptr != crtc_state_.size()) {
LOG(ERROR) << "Only some of the crtcs support the OUT_FENCE_PTR property";
return false;
}
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
index ec54ede..e60ddb68 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
@@ -143,7 +143,23 @@
DrmDevice::Property out_fence_ptr;
};
- bool InitializeCrtcProperties(DrmDevice* drm);
+ struct CrtcState {
+ CrtcState();
+ ~CrtcState();
+ CrtcState(CrtcState&&);
+
+ CrtcProperties properties = {};
+
+ // Cached blobs for the properties since the CRTC properties are applied on
+ // the next page flip and we need to keep the properties valid until then.
+ ScopedDrmPropertyBlob ctm_blob;
+ ScopedDrmPropertyBlob gamma_lut_blob;
+ ScopedDrmPropertyBlob degamma_lut_blob;
+
+ DISALLOW_COPY_AND_ASSIGN(CrtcState);
+ };
+
+ bool InitializeCrtcState(DrmDevice* drm);
virtual bool InitializePlanes(DrmDevice* drm) = 0;
@@ -188,7 +204,7 @@
bool has_universal_planes_ = false;
std::vector<std::unique_ptr<HardwareDisplayPlane>> planes_;
- std::vector<CrtcProperties> crtc_properties_;
+ std::vector<CrtcState> crtc_state_;
std::vector<uint32_t> supported_formats_;
DISALLOW_COPY_AND_ASSIGN(HardwareDisplayPlaneManager);
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc
index 3852840..ad365ad 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc
@@ -17,6 +17,7 @@
#include "ui/ozone/platform/drm/common/drm_util.h"
#include "ui/ozone/platform/drm/gpu/crtc_controller.h"
#include "ui/ozone/platform/drm/gpu/drm_device.h"
+#include "ui/ozone/platform/drm/gpu/drm_gpu_util.h"
#include "ui/ozone/platform/drm/gpu/hardware_display_plane_atomic.h"
#include "ui/ozone/platform/drm/gpu/page_flip_request.h"
#include "ui/ozone/platform/drm/gpu/scanout_buffer.h"
@@ -81,6 +82,23 @@
crtcs.push_back(atomic_plane->crtc());
}
+#if defined(COMMIT_PROPERTIES_ON_PAGE_FLIP)
+ drmModeAtomicReqPtr request = plane_list->atomic_property_set.get();
+
+ // Apply all CRTC properties in the page-flip so we don't block the swap chain
+ // for a vsync.
+ // TODO(dnicoara): See if we can apply these properties async using
+ // DRM_MODE_ATOMIC_ASYNC_UPDATE flag when committing.
+ for (auto* const crtc : crtcs) {
+ int idx = LookupCrtcIndex(crtc->crtc());
+ AddPropertyIfValid(request, crtc->crtc(),
+ crtc_state_[idx].properties.degamma_lut);
+ AddPropertyIfValid(request, crtc->crtc(),
+ crtc_state_[idx].properties.gamma_lut);
+ AddPropertyIfValid(request, crtc->crtc(), crtc_state_[idx].properties.ctm);
+ }
+#endif
+
if (test_only) {
for (HardwareDisplayPlane* plane : plane_list->plane_list) {
plane->set_in_use(false);
@@ -254,6 +272,8 @@
bool HardwareDisplayPlaneManagerAtomic::CommitColorMatrix(
const CrtcProperties& crtc_props) {
+ DCHECK(crtc_props.ctm.id);
+#if !defined(COMMIT_PROPERTIES_ON_PAGE_FLIP)
ScopedDrmAtomicReqPtr property_set(drmModeAtomicAlloc());
int ret = drmModeAtomicAddProperty(property_set.get(), crtc_props.id,
crtc_props.ctm.id, crtc_props.ctm.value);
@@ -268,12 +288,15 @@
// TODO(dnicoara): Should cache these values locally and aggregate them with
// the page flip event otherwise this "steals" a vsync to apply the property.
return drm_->CommitProperties(property_set.get(), 0, 0, nullptr);
+#else
+ return true;
+#endif
}
bool HardwareDisplayPlaneManagerAtomic::CommitGammaCorrection(
const CrtcProperties& crtc_props) {
DCHECK(crtc_props.degamma_lut.id || crtc_props.gamma_lut.id);
-
+#if !defined(COMMIT_PROPERTIES_ON_PAGE_FLIP)
ScopedDrmAtomicReqPtr property_set(drmModeAtomicAlloc());
if (crtc_props.degamma_lut.id) {
int ret = drmModeAtomicAddProperty(property_set.get(), crtc_props.id,
@@ -303,6 +326,9 @@
// TODO(dnicoara): Should cache these values locally and aggregate them with
// the page flip event otherwise this "steals" a vsync to apply the property.
return drm_->CommitProperties(property_set.get(), 0, 0, nullptr);
+#else
+ return true;
+#endif
}
bool HardwareDisplayPlaneManagerAtomic::AddOutFencePtrProperties(
@@ -317,7 +343,8 @@
for (auto* crtc : crtcs) {
const auto crtc_index = LookupCrtcIndex(crtc->crtc());
DCHECK_GE(crtc_index, 0);
- const auto out_fence_ptr_id = crtc_properties_[crtc_index].out_fence_ptr.id;
+ const auto out_fence_ptr_id =
+ crtc_state_[crtc_index].properties.out_fence_ptr.id;
if (out_fence_ptr_id > 0) {
out_fence_fds->push_back(base::ScopedFD());
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc
index 5871d9a..1eb3c57 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc
@@ -150,8 +150,8 @@
// https://crbug.com/464085: if driver reports no primary planes for a crtc,
// create a dummy plane for which we can assign exactly one overlay.
if (!has_universal_planes_) {
- for (size_t i = 0; i < crtc_properties_.size(); ++i) {
- uint32_t id = crtc_properties_[i].id - 1;
+ for (size_t i = 0; i < crtc_state_.size(); ++i) {
+ uint32_t id = crtc_state_[i].properties.id - 1;
if (std::find_if(
planes_.begin(), planes_.end(),
[id](const std::unique_ptr<HardwareDisplayPlane>& plane) {
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc
index 52517e0..4d14e58 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc
@@ -48,9 +48,17 @@
HardwareDisplayPlaneManagerTest() {}
void InitializeDrmState(size_t crtc_count, size_t planes_per_crtc);
+
+ uint64_t GetObjectPropertyValue(uint32_t object_id,
+ uint32_t object_type,
+ const std::string& property_name);
+ uint64_t GetCrtcPropertyValue(uint32_t crtc,
+ const std::string& property_name);
uint64_t GetPlanePropertyValue(uint32_t plane,
const std::string& property_name);
+ void PerformPageFlip(size_t crtc_idx, ui::HardwareDisplayPlaneList* state);
+
void SetUp() override;
protected:
@@ -141,17 +149,47 @@
property_names_.insert({kOutFencePtrPropId, "OUT_FENCE_PTR"});
}
-uint64_t HardwareDisplayPlaneManagerTest::GetPlanePropertyValue(
- uint32_t plane,
+void HardwareDisplayPlaneManagerTest::PerformPageFlip(
+ size_t crtc_idx,
+ ui::HardwareDisplayPlaneList* state) {
+ ui::DrmOverlayPlaneList assigns;
+ ui::CrtcController crtc(fake_drm_, crtc_properties_[crtc_idx].id, 0);
+ scoped_refptr<ui::MockScanoutBuffer> xrgb_buffer =
+ new ui::MockScanoutBuffer(kDefaultBufferSize);
+ assigns.push_back(ui::DrmOverlayPlane(xrgb_buffer, nullptr));
+ fake_drm_->plane_manager()->BeginFrame(state);
+ ASSERT_TRUE(fake_drm_->plane_manager()->AssignOverlayPlanes(
+ state, assigns, crtc_properties_[crtc_idx].id, &crtc));
+ scoped_refptr<ui::PageFlipRequest> page_flip_request =
+ base::MakeRefCounted<ui::PageFlipRequest>(base::TimeDelta());
+ ASSERT_TRUE(
+ fake_drm_->plane_manager()->Commit(state, page_flip_request, nullptr));
+}
+
+uint64_t HardwareDisplayPlaneManagerTest::GetObjectPropertyValue(
+ uint32_t object_id,
+ uint32_t object_type,
const std::string& property_name) {
ui::DrmDevice::Property p{};
ui::ScopedDrmObjectPropertyPtr properties(
- fake_drm_->GetObjectProperties(plane, DRM_MODE_OBJECT_PLANE));
+ fake_drm_->GetObjectProperties(object_id, object_type));
EXPECT_TRUE(ui::GetDrmPropertyForName(fake_drm_.get(), properties.get(),
property_name, &p));
return p.value;
}
+uint64_t HardwareDisplayPlaneManagerTest::GetCrtcPropertyValue(
+ uint32_t crtc,
+ const std::string& property_name) {
+ return GetObjectPropertyValue(crtc, DRM_MODE_OBJECT_CRTC, property_name);
+}
+
+uint64_t HardwareDisplayPlaneManagerTest::GetPlanePropertyValue(
+ uint32_t plane,
+ const std::string& property_name) {
+ return GetObjectPropertyValue(plane, DRM_MODE_OBJECT_PLANE, property_name);
+}
+
using HardwareDisplayPlaneManagerLegacyTest = HardwareDisplayPlaneManagerTest;
using HardwareDisplayPlaneManagerAtomicTest = HardwareDisplayPlaneManagerTest;
@@ -450,10 +488,18 @@
EXPECT_TRUE(fake_drm_->plane_manager()->SetColorMatrix(
crtc_properties_[0].id, std::vector<float>(9)));
- if (use_atomic_)
+ if (use_atomic_) {
+ ui::HardwareDisplayPlaneList state;
+ PerformPageFlip(/*crtc_idx=*/0, &state);
+#if defined(COMMIT_PROPERTIES_ON_PAGE_FLIP)
EXPECT_EQ(1, fake_drm_->get_commit_count());
- else
+#else
+ EXPECT_EQ(2, fake_drm_->get_commit_count());
+#endif
+ EXPECT_NE(0u, GetCrtcPropertyValue(crtc_properties_[0].id, "CTM"));
+ } else {
EXPECT_EQ(1, fake_drm_->get_set_object_property_count());
+ }
}
TEST_P(HardwareDisplayPlaneManagerTest, SetColorMatrix_ErrorEmptyCtm) {
@@ -464,10 +510,14 @@
EXPECT_FALSE(
fake_drm_->plane_manager()->SetColorMatrix(crtc_properties_[0].id, {}));
- if (use_atomic_)
- EXPECT_EQ(0, fake_drm_->get_commit_count());
- else
+ if (use_atomic_) {
+ ui::HardwareDisplayPlaneList state;
+ PerformPageFlip(/*crtc_idx=*/0, &state);
+ EXPECT_EQ(1, fake_drm_->get_commit_count());
+ EXPECT_EQ(0u, GetCrtcPropertyValue(crtc_properties_[0].id, "CTM"));
+ } else {
EXPECT_EQ(0, fake_drm_->get_set_object_property_count());
+ }
}
TEST_P(HardwareDisplayPlaneManagerTest, SetGammaCorrection_MissingDegamma) {
@@ -478,10 +528,14 @@
EXPECT_FALSE(fake_drm_->plane_manager()->SetGammaCorrection(
crtc_properties_[0].id, {{0, 0, 0}}, {}));
- if (use_atomic_)
- EXPECT_EQ(0, fake_drm_->get_commit_count());
- else
+ if (use_atomic_) {
+ ui::HardwareDisplayPlaneList state;
+ PerformPageFlip(/*crtc_idx=*/0, &state);
+ // Page flip should succeed even if the properties failed to be updated.
+ EXPECT_EQ(1, fake_drm_->get_commit_count());
+ } else {
EXPECT_EQ(0, fake_drm_->get_set_object_property_count());
+ }
crtc_properties_[0].properties.push_back(
{.id = kDegammaLutSizePropId, .value = 1});
@@ -490,10 +544,14 @@
EXPECT_FALSE(fake_drm_->plane_manager()->SetGammaCorrection(
crtc_properties_[0].id, {{0, 0, 0}}, {}));
- if (use_atomic_)
- EXPECT_EQ(0, fake_drm_->get_commit_count());
- else
+ if (use_atomic_) {
+ ui::HardwareDisplayPlaneList state;
+ PerformPageFlip(/*crtc_idx=*/0, &state);
+ // Page flip should succeed even if the properties failed to be updated.
+ EXPECT_EQ(2, fake_drm_->get_commit_count());
+ } else {
EXPECT_EQ(0, fake_drm_->get_set_object_property_count());
+ }
}
TEST_P(HardwareDisplayPlaneManagerTest, SetGammaCorrection_MissingGamma) {
@@ -503,11 +561,15 @@
property_names_, use_atomic_);
EXPECT_FALSE(fake_drm_->plane_manager()->SetGammaCorrection(
- crtc_properties_[0].id, {{0, 0, 0}}, {}));
- if (use_atomic_)
- EXPECT_EQ(0, fake_drm_->get_commit_count());
- else
+ crtc_properties_[0].id, {}, {{0, 0, 0}}));
+ if (use_atomic_) {
+ ui::HardwareDisplayPlaneList state;
+ PerformPageFlip(/*crtc_idx=*/0, &state);
+ // Page flip should succeed even if the properties failed to be updated.
+ EXPECT_EQ(1, fake_drm_->get_commit_count());
+ } else {
EXPECT_EQ(0, fake_drm_->get_set_object_property_count());
+ }
crtc_properties_[0].properties.push_back(
{.id = kGammaLutSizePropId, .value = 1});
@@ -516,17 +578,21 @@
EXPECT_FALSE(fake_drm_->plane_manager()->SetGammaCorrection(
crtc_properties_[0].id, {}, {{0, 0, 0}}));
- if (use_atomic_)
- EXPECT_EQ(0, fake_drm_->get_commit_count());
- else
+ if (use_atomic_) {
+ ui::HardwareDisplayPlaneList state;
+ PerformPageFlip(/*crtc_idx=*/0, &state);
+ // Page flip should succeed even if the properties failed to be updated.
+ EXPECT_EQ(2, fake_drm_->get_commit_count());
+ } else {
EXPECT_EQ(0, fake_drm_->get_set_object_property_count());
+ }
fake_drm_->set_legacy_gamma_ramp_expectation(true);
EXPECT_TRUE(fake_drm_->plane_manager()->SetGammaCorrection(
crtc_properties_[0].id, {}, {{0, 0, 0}}));
// Going through the legacy API, so we shouldn't commit anything.
if (use_atomic_)
- EXPECT_EQ(0, fake_drm_->get_commit_count());
+ EXPECT_EQ(2, fake_drm_->get_commit_count());
else
EXPECT_EQ(0, fake_drm_->get_set_object_property_count());
}
@@ -551,20 +617,37 @@
fake_drm_->InitializeState(crtc_properties_, plane_properties_,
property_names_, use_atomic_);
+ ui::HardwareDisplayPlaneList state;
// Check that we reset the properties correctly.
EXPECT_TRUE(fake_drm_->plane_manager()->SetGammaCorrection(
crtc_properties_[0].id, {}, {}));
- if (use_atomic_)
+ if (use_atomic_) {
+ PerformPageFlip(/*crtc_idx=*/0, &state);
+#if defined(COMMIT_PROPERTIES_ON_PAGE_FLIP)
EXPECT_EQ(1, fake_drm_->get_commit_count());
- else
+#else
+ EXPECT_EQ(2, fake_drm_->get_commit_count());
+#endif
+ EXPECT_EQ(0u, GetCrtcPropertyValue(crtc_properties_[0].id, "GAMMA_LUT"));
+ EXPECT_EQ(0u, GetCrtcPropertyValue(crtc_properties_[0].id, "DEGAMMA_LUT"));
+ } else {
EXPECT_EQ(2, fake_drm_->get_set_object_property_count());
+ }
EXPECT_TRUE(fake_drm_->plane_manager()->SetGammaCorrection(
crtc_properties_[0].id, {{0, 0, 0}}, {{0, 0, 0}}));
- if (use_atomic_)
+ if (use_atomic_) {
+ PerformPageFlip(/*crtc_idx=*/0, &state);
+#if defined(COMMIT_PROPERTIES_ON_PAGE_FLIP)
EXPECT_EQ(2, fake_drm_->get_commit_count());
- else
+#else
+ EXPECT_EQ(4, fake_drm_->get_commit_count());
+#endif
+ EXPECT_NE(0u, GetCrtcPropertyValue(crtc_properties_[0].id, "GAMMA_LUT"));
+ EXPECT_NE(0u, GetCrtcPropertyValue(crtc_properties_[0].id, "DEGAMMA_LUT"));
+ } else {
EXPECT_EQ(4, fake_drm_->get_set_object_property_count());
+ }
}
TEST_P(HardwareDisplayPlaneManagerAtomicTest,
diff --git a/ui/ozone/platform/drm/gpu/mock_drm_device.cc b/ui/ozone/platform/drm/gpu/mock_drm_device.cc
index 7e1d70a..7b0845a 100644
--- a/ui/ozone/platform/drm/gpu/mock_drm_device.cc
+++ b/ui/ozone/platform/drm/gpu/mock_drm_device.cc
@@ -404,10 +404,12 @@
request->items[i].value));
}
- if (!page_flip_request)
+ if (page_flip_request)
+ callbacks_.push(page_flip_request->AddPageFlip());
+
+ if (flags & DRM_MODE_ATOMIC_TEST_ONLY)
return true;
- callbacks_.push(page_flip_request->AddPageFlip());
// Only update values if not testing.
for (uint32_t i = 0; i < request->cursor; ++i) {
EXPECT_TRUE(UpdateProperty(request->items[i].object_id,