Commit 36a7f285 authored by Roman Stratiienko's avatar Roman Stratiienko
Browse files

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: default avatarRoman Stratiienko <roman.o.stratiienko@globallogic.com>
parent 6ede4667
......@@ -716,7 +716,7 @@ HWC2::Error DrmHwcTwo::HwcDisplay::CreateComposition(bool test) {
// 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 @@ HWC2::Error DrmHwcTwo::HwcDisplay::SetActiveConfig(hwc2_config_t config) {
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::SetOutputBuffer(buffer_handle_t buffer,
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 @@ HWC2::Error DrmHwcTwo::HwcDisplay::SetPowerMode(int32_t mode_in) {
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;
......
......@@ -37,41 +37,11 @@ DrmDisplayComposition::DrmDisplayComposition(DrmCrtc *crtc, Planner *planner)
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::AddPlaneComposition(DrmCompositionPlane plane) {
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)
......
......@@ -32,13 +32,6 @@ namespace android {
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 @@ class DrmDisplayComposition {
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 @@ class DrmDisplayComposition {
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 @@ class DrmDisplayComposition {
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_;
};
......
......@@ -44,8 +44,7 @@ DrmDisplayCompositor::DrmDisplayCompositor()
: resource_manager_(nullptr),
display_(-1),
initialized_(false),
active_(false),
use_hw_overlays_(true) {
active_(false) {
}
DrmDisplayCompositor::~DrmDisplayCompositor() {
......@@ -205,43 +204,21 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp,
}
}
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 @@ void DrmDisplayCompositor::ClearDisplay() {
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 @@ int DrmDisplayCompositor::TestComposition(DrmDisplayComposition *composition) {
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
......@@ -44,8 +44,13 @@ class DrmDisplayCompositor {
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 @@ class DrmDisplayCompositor {
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 @@ class DrmDisplayCompositor {
std::unique_ptr<DrmDisplayComposition> active_composition_;
bool initialized_;
bool active_;
bool use_hw_overlays_;
bool active_{true}, active_changed_{true};
ModeState mode_;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment