drm_hwcomposer: Rework display Mode Setting and DPMS handling
1. Remove DPMS logic. As stated in KMS kernel docs: CRTC "activate"
property was implemented as a simplified atomic replacement of DPMS.
And kernel internally will just update "activate" on DPMS setting.
2. Add SetDisplayActivate(bool state) method to compositor class,
which is now replacement for SetDpmsMode().
3. Move mode settings out of DrmComposition class to DrmCompositor class.
From now on DrmComposition describes only layer-to-plane composition
as it should be.
Signed-off-by: Roman Stratiienko <roman.o.stratiienko@globallogic.com>
diff --git a/DrmHwcTwo.cpp b/DrmHwcTwo.cpp
index 6ec8b31..071f3bf 100644
--- a/DrmHwcTwo.cpp
+++ b/DrmHwcTwo.cpp
@@ -716,7 +716,7 @@
// TODO(nobody): Don't always assume geometry changed
int ret = composition->SetLayers(composition_layers.data(),
- composition_layers.size(), true);
+ composition_layers.size());
if (ret) {
ALOGE("Failed to set layers in the composition ret=%d", ret);
return HWC2::Error::BadLayer;
@@ -793,15 +793,13 @@
return HWC2::Error::BadConfig;
}
- auto composition = std::make_unique<DrmDisplayComposition>(crtc_,
- planner_.get());
- int ret = composition->SetDisplayMode(*mode);
- if (ret) {
+ if (!compositor_.SetDisplayMode(*mode)) {
return HWC2::Error::BadConfig;
}
- ret = compositor_.ApplyComposition(std::move(composition));
- if (ret) {
- ALOGE("Failed to queue dpms composition on %d", ret);
+ int err = compositor_.ApplyComposition(
+ compositor_.CreateInitializedComposition());
+ if (err != 0) {
+ ALOGE("Failed to queue mode changing commit %d", err);
return HWC2::Error::BadConfig;
}
@@ -883,14 +881,13 @@
HWC2::Error DrmHwcTwo::HwcDisplay::SetPowerMode(int32_t mode_in) {
supported(__func__);
- uint64_t dpms_value = 0;
auto mode = static_cast<HWC2::PowerMode>(mode_in);
switch (mode) {
case HWC2::PowerMode::Off:
- dpms_value = DRM_MODE_DPMS_OFF;
+ compositor_.SetDisplayActive(false);
break;
case HWC2::PowerMode::On:
- dpms_value = DRM_MODE_DPMS_ON;
+ compositor_.SetDisplayActive(true);
break;
case HWC2::PowerMode::Doze:
case HWC2::PowerMode::DozeSuspend:
@@ -900,10 +897,8 @@
return HWC2::Error::BadParameter;
};
- auto composition = std::make_unique<DrmDisplayComposition>(crtc_,
- planner_.get());
- composition->SetDpmsMode(dpms_value);
- int ret = compositor_.ApplyComposition(std::move(composition));
+ int ret = compositor_.ApplyComposition(
+ compositor_.CreateInitializedComposition());
if (ret) {
ALOGE("Failed to apply the dpms composition ret=%d", ret);
return HWC2::Error::BadParameter;
diff --git a/compositor/DrmDisplayComposition.cpp b/compositor/DrmDisplayComposition.cpp
index c0fbba0..cd95267 100644
--- a/compositor/DrmDisplayComposition.cpp
+++ b/compositor/DrmDisplayComposition.cpp
@@ -37,41 +37,11 @@
planner_(planner) {
}
-bool DrmDisplayComposition::validate_composition_type(DrmCompositionType des) {
- return type_ == DRM_COMPOSITION_TYPE_EMPTY || type_ == des;
-}
-
-int DrmDisplayComposition::SetLayers(DrmHwcLayer *layers, size_t num_layers,
- bool geometry_changed) {
- if (!validate_composition_type(DRM_COMPOSITION_TYPE_FRAME))
- return -EINVAL;
-
- geometry_changed_ = geometry_changed;
-
+int DrmDisplayComposition::SetLayers(DrmHwcLayer *layers, size_t num_layers) {
for (size_t layer_index = 0; layer_index < num_layers; layer_index++) {
layers_.emplace_back(std::move(layers[layer_index]));
}
- type_ = DRM_COMPOSITION_TYPE_FRAME;
- return 0;
-}
-
-int DrmDisplayComposition::SetDpmsMode(uint32_t dpms_mode) {
- if (!validate_composition_type(DRM_COMPOSITION_TYPE_DPMS))
- return -EINVAL;
- dpms_mode_ = dpms_mode;
- type_ = DRM_COMPOSITION_TYPE_DPMS;
- return 0;
-}
-
-int DrmDisplayComposition::SetDisplayMode(const DrmMode &display_mode) {
- if (!validate_composition_type(DRM_COMPOSITION_TYPE_MODESET)) {
- ALOGE("SetDisplayMode() Failed to validate composition type");
- return -EINVAL;
- }
- display_mode_ = display_mode;
- dpms_mode_ = DRM_MODE_DPMS_ON;
- type_ = DRM_COMPOSITION_TYPE_MODESET;
return 0;
}
@@ -87,9 +57,6 @@
int DrmDisplayComposition::Plan(std::vector<DrmPlane *> *primary_planes,
std::vector<DrmPlane *> *overlay_planes) {
- if (type_ != DRM_COMPOSITION_TYPE_FRAME)
- return 0;
-
std::map<size_t, DrmHwcLayer *> to_composite;
for (size_t i = 0; i < layers_.size(); ++i)
diff --git a/compositor/DrmDisplayComposition.h b/compositor/DrmDisplayComposition.h
index bbac0af..7b7e668 100644
--- a/compositor/DrmDisplayComposition.h
+++ b/compositor/DrmDisplayComposition.h
@@ -32,13 +32,6 @@
class Importer;
class Planner;
-enum DrmCompositionType {
- DRM_COMPOSITION_TYPE_EMPTY,
- DRM_COMPOSITION_TYPE_FRAME,
- DRM_COMPOSITION_TYPE_DPMS,
- DRM_COMPOSITION_TYPE_MODESET,
-};
-
class DrmCompositionPlane {
public:
enum class Type : int32_t {
@@ -86,11 +79,9 @@
DrmDisplayComposition(DrmCrtc *crtc, Planner *planner);
~DrmDisplayComposition() = default;
- int SetLayers(DrmHwcLayer *layers, size_t num_layers, bool geometry_changed);
+ int SetLayers(DrmHwcLayer *layers, size_t num_layers);
int AddPlaneComposition(DrmCompositionPlane plane);
int AddPlaneDisable(DrmPlane *plane);
- int SetDpmsMode(uint32_t dpms_mode);
- int SetDisplayMode(const DrmMode &display_mode);
int Plan(std::vector<DrmPlane *> *primary_planes,
std::vector<DrmPlane *> *overlay_planes);
@@ -103,22 +94,6 @@
return composition_planes_;
}
- bool geometry_changed() const {
- return geometry_changed_;
- }
-
- DrmCompositionType type() const {
- return type_;
- }
-
- uint32_t dpms_mode() const {
- return dpms_mode_;
- }
-
- const DrmMode &display_mode() const {
- return display_mode_;
- }
-
DrmCrtc *crtc() const {
return crtc_;
}
@@ -130,16 +105,9 @@
UniqueFd out_fence_;
private:
- bool validate_composition_type(DrmCompositionType desired);
-
DrmCrtc *crtc_ = NULL;
Planner *planner_ = NULL;
- DrmCompositionType type_ = DRM_COMPOSITION_TYPE_EMPTY;
- uint32_t dpms_mode_ = DRM_MODE_DPMS_ON;
- DrmMode display_mode_;
-
- bool geometry_changed_ = true;
std::vector<DrmHwcLayer> layers_;
std::vector<DrmCompositionPlane> composition_planes_;
};
diff --git a/compositor/DrmDisplayCompositor.cpp b/compositor/DrmDisplayCompositor.cpp
index 576c533..a8f8d62 100644
--- a/compositor/DrmDisplayCompositor.cpp
+++ b/compositor/DrmDisplayCompositor.cpp
@@ -44,8 +44,7 @@
: resource_manager_(nullptr),
display_(-1),
initialized_(false),
- active_(false),
- use_hw_overlays_(true) {
+ active_(false) {
}
DrmDisplayCompositor::~DrmDisplayCompositor() {
@@ -205,43 +204,21 @@
}
}
- if (!test_only && mode_.blob) {
- /* TODO: Add dpms to the pset when the kernel supports it */
- ret = ApplyDpms(display_comp);
- if (ret) {
- ALOGE("Failed to apply DPMS after modeset %d\n", ret);
- return ret;
+ if (!test_only) {
+ if (mode_.blob) {
+ connector->set_active_mode(mode_.mode);
+ mode_.old_blob = std::move(mode_.blob);
}
+ active_changed_ = false;
- connector->set_active_mode(mode_.mode);
- mode_.old_blob = std::move(mode_.blob);
- }
-
- if (crtc->out_fence_ptr_property()) {
- display_comp->out_fence_ = UniqueFd((int)out_fences[crtc->pipe()]);
+ if (crtc->out_fence_ptr_property()) {
+ display_comp->out_fence_ = UniqueFd((int)out_fences[crtc->pipe()]);
+ }
}
return ret;
}
-int DrmDisplayCompositor::ApplyDpms(DrmDisplayComposition *display_comp) {
- DrmDevice *drm = resource_manager_->GetDrmDevice(display_);
- DrmConnector *conn = drm->GetConnectorForDisplay(display_);
- if (!conn) {
- ALOGE("Failed to get DrmConnector for display %d", display_);
- return -ENODEV;
- }
-
- const DrmProperty &prop = conn->dpms_property();
- int ret = drmModeConnectorSetProperty(drm->fd(), conn->id(), prop.id(),
- display_comp->dpms_mode());
- if (ret) {
- ALOGE("Failed to set DPMS property for connector %d", conn->id());
- return ret;
- }
- return 0;
-}
-
auto DrmDisplayCompositor::CreateModeBlob(const DrmMode &mode)
-> DrmModeUserPropertyBlobUnique {
struct drm_mode_modeinfo drm_mode {};
@@ -262,59 +239,20 @@
active_composition_.reset(nullptr);
}
-void DrmDisplayCompositor::ApplyFrame(
- std::unique_ptr<DrmDisplayComposition> composition, int status) {
- int ret = status;
-
- if (!ret) {
- ret = CommitFrame(composition.get(), false);
- }
+int DrmDisplayCompositor::ApplyComposition(
+ std::unique_ptr<DrmDisplayComposition> composition) {
+ int ret = CommitFrame(composition.get(), false);
if (ret) {
ALOGE("Composite failed for display %d", display_);
// Disable the hw used by the last active composition. This allows us to
// signal the release fences from that composition to avoid hanging.
ClearDisplay();
- return;
+ return ret;
}
- active_composition_.swap(composition);
-}
-
-int DrmDisplayCompositor::ApplyComposition(
- std::unique_ptr<DrmDisplayComposition> composition) {
- int ret = 0;
- switch (composition->type()) {
- case DRM_COMPOSITION_TYPE_FRAME:
- if (composition->geometry_changed()) {
- // Send the composition to the kernel to ensure we can commit it. This
- // is just a test, it won't actually commit the frame.
- ret = CommitFrame(composition.get(), true);
- if (ret) {
- ALOGE("Commit test failed for display %d, FIXME", display_);
- return ret;
- }
- }
-
- ApplyFrame(std::move(composition), ret);
- break;
- case DRM_COMPOSITION_TYPE_DPMS:
- active_ = (composition->dpms_mode() == DRM_MODE_DPMS_ON);
- ret = ApplyDpms(composition.get());
- if (ret)
- ALOGE("Failed to apply dpms for display %d", display_);
- return ret;
- case DRM_COMPOSITION_TYPE_MODESET:
- mode_.mode = composition->display_mode();
- mode_.blob = CreateModeBlob(mode_.mode);
- if (!mode_.blob) {
- ALOGE("Failed to create mode blob for display %d", display_);
- return -EINVAL;
- }
- return 0;
- default:
- ALOGE("Unknown composition type %d", composition->type());
- return -EINVAL;
+ if (composition) {
+ active_composition_.swap(composition);
}
return ret;
@@ -324,4 +262,10 @@
return CommitFrame(composition, true);
}
+auto DrmDisplayCompositor::SetDisplayMode(const DrmMode &display_mode) -> bool {
+ mode_.mode = display_mode;
+ mode_.blob = CreateModeBlob(mode_.mode);
+ return !!mode_.blob;
+}
+
} // namespace android
diff --git a/compositor/DrmDisplayCompositor.h b/compositor/DrmDisplayCompositor.h
index 3227e12..e76abf7 100644
--- a/compositor/DrmDisplayCompositor.h
+++ b/compositor/DrmDisplayCompositor.h
@@ -44,8 +44,13 @@
std::unique_ptr<DrmDisplayComposition> CreateInitializedComposition() const;
int ApplyComposition(std::unique_ptr<DrmDisplayComposition> composition);
int TestComposition(DrmDisplayComposition *composition);
- int Composite();
void ClearDisplay();
+ auto SetDisplayMode(const DrmMode &display_mode) -> bool;
+ auto SetDisplayActive(bool state) -> void {
+ active_ = state;
+ active_changed_ = true;
+ }
+
UniqueFd TakeOutFence() {
if (!active_composition_) {
return UniqueFd();
@@ -65,12 +70,8 @@
DrmDisplayCompositor(const DrmDisplayCompositor &) = delete;
int CommitFrame(DrmDisplayComposition *display_comp, bool test_only);
- int ApplyDpms(DrmDisplayComposition *display_comp);
int DisablePlanes(DrmDisplayComposition *display_comp);
- void ApplyFrame(std::unique_ptr<DrmDisplayComposition> composition,
- int status);
-
auto CreateModeBlob(const DrmMode &mode) -> DrmModeUserPropertyBlobUnique;
ResourceManager *resource_manager_;
@@ -79,8 +80,7 @@
std::unique_ptr<DrmDisplayComposition> active_composition_;
bool initialized_;
- bool active_;
- bool use_hw_overlays_;
+ bool active_{true}, active_changed_{true};
ModeState mode_;