sdm: Fixes for HWC2
- Return HWC2::Error::HasChanges from Validate(), when the
composition types changes compared to requested.
- Reset release_fence_fd after pushing to queue so that it
doesn't get pushed again.
- Clear dirty and visible regions on every call to set them.
- Maintain client requested and SDM selected comp types.
Change-Id: Iff2a52c99a15cdbfccc4c0206f3958d0a2eb1642
Crs-fixed: 1023408
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index f687731..233306c 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -332,6 +332,8 @@
// TODO(user): Add blit target layers
for (auto hwc_layer : layer_set_) {
Layer *layer = hwc_layer->GetSDMLayer();
+ // set default composition as GPU for SDM
+ layer->composition = kCompositionGPU;
if (swap_interval_zero_) {
if (layer->input_buffer->acquire_fence_fd >= 0) {
@@ -708,18 +710,24 @@
if (!needs_fb_refresh && composition == kCompositionGPU) {
composition = kCompositionSDE;
}
- HWC2::Composition current_hwc_composition = hwc_layer->GetCompositionType();
+ HWC2::Composition requested_composition = hwc_layer->GetClientRequestedCompositionType();
// Convert the SDM layer composition to HWC2 type
hwc_layer->SetComposition(composition);
- // Update the changes list only if the HWC2 comp type changed from the previous cycle
- if (current_hwc_composition != hwc_layer->GetCompositionType()) {
- layer_changes_[hwc_layer->GetId()] = hwc_layer->GetCompositionType();
+ HWC2::Composition device_composition = hwc_layer->GetDeviceSelectedCompositionType();
+ // Update the changes list only if the requested composition is different from SDM comp type
+ // TODO(user): Take Care of other comptypes(BLIT)
+ if (requested_composition != device_composition) {
+ layer_changes_[hwc_layer->GetId()] = device_composition;
}
}
*out_num_types = UINT32(layer_changes_.size());
*out_num_requests = UINT32(layer_requests_.size());
validated_ = true;
- return HWC2::Error::None;
+ if (*out_num_types > 0) {
+ return HWC2::Error::HasChanges;
+ } else {
+ return HWC2::Error::None;
+ }
}
HWC2::Error HWCDisplay::AcceptDisplayChanges() {
@@ -731,6 +739,10 @@
HWC2::Error HWCDisplay::GetChangedCompositionTypes(uint32_t *out_num_elements,
hwc2_layer_t *out_layers, int32_t *out_types) {
+ if (!validated_) {
+ DLOGW("Display is not validated");
+ return HWC2::Error::NotValidated;
+ }
*out_num_elements = UINT32(layer_changes_.size());
if (out_layers != nullptr && out_types != nullptr) {
int i = 0;
@@ -846,6 +858,7 @@
layer_buffer->release_fence_fd = -1;
} else if (layer->composition != kCompositionGPU) {
hwc_layer->PushReleaseFence(layer_buffer->release_fence_fd);
+ layer_buffer->release_fence_fd = -1;
}
}
@@ -1568,7 +1581,10 @@
os << "-------------------------------" << std::endl;
os << "layer_id: " << layer->GetId() << std::endl;
os << "\tz: " << layer->GetZ() << std::endl;
- os << "\tcomposition: " << to_string(layer->GetCompositionType()).c_str() << std::endl;
+ os << "\tclient(SF) composition: " <<
+ to_string(layer->GetClientRequestedCompositionType()).c_str() << std::endl;
+ os << "\tdevice(SDM) composition: " <<
+ to_string(layer->GetDeviceSelectedCompositionType()).c_str() << std::endl;
os << "\tplane_alpha: " << std::to_string(sdm_layer->plane_alpha).c_str() << std::endl;
os << "\tformat: " << GetFormatString(sdm_layer->input_buffer->format) << std::endl;
os << "\tbuffer_id: " << std::hex << "0x" << sdm_layer->input_buffer->buffer_id << std::dec
diff --git a/sdm/libs/hwc2/hwc_layers.cpp b/sdm/libs/hwc2/hwc_layers.cpp
index 2591898..dd43dbb 100644
--- a/sdm/libs/hwc2/hwc_layers.cpp
+++ b/sdm/libs/hwc2/hwc_layers.cpp
@@ -89,6 +89,7 @@
HWC2::Error HWCLayer::SetLayerSurfaceDamage(hwc_region_t damage) {
auto num_dirty_rects = damage.numRects;
+ layer_->dirty_regions.clear();
if (num_dirty_rects > 0) {
for (uint32_t i = 0; i <= damage.numRects; i++) {
LayerRect rect;
@@ -128,7 +129,7 @@
HWC2::Error HWCLayer::SetLayerCompositionType(HWC2::Composition type) {
layer_->flags = {}; // Reset earlier flags
- composition_ = type; // Used to compute changes
+ client_requested_ = type;
switch (type) {
case HWC2::Composition::Client:
layer_->flags.skip = true;
@@ -213,6 +214,7 @@
HWC2::Error HWCLayer::SetLayerVisibleRegion(hwc_region_t visible) {
auto num_dirty_rects = visible.numRects;
+ layer_->visible_regions.clear();
if (num_dirty_rects > 0) {
for (uint32_t i = 0; i <= visible.numRects; i++) {
LayerRect rect;
@@ -490,24 +492,26 @@
return frame_rate;
}
-void HWCLayer::SetComposition(const LayerComposition &source) {
- auto composition = HWC2::Composition::Invalid;
- switch (source) {
+void HWCLayer::SetComposition(const LayerComposition &sdm_composition) {
+ auto hwc_composition = HWC2::Composition::Invalid;
+ switch (sdm_composition) {
case kCompositionGPU:
- composition = HWC2::Composition::Client;
+ hwc_composition = HWC2::Composition::Client;
break;
case kCompositionHWCursor:
- composition = HWC2::Composition::Cursor;
+ hwc_composition = HWC2::Composition::Cursor;
break;
default:
- composition = HWC2::Composition::Device;
+ hwc_composition = HWC2::Composition::Device;
break;
}
// Update solid fill composition
- if (layer_->composition == kCompositionSDE && layer_->flags.solid_fill != 0) {
- composition = HWC2::Composition::SolidColor;
+ if (sdm_composition == kCompositionSDE && layer_->flags.solid_fill != 0) {
+ hwc_composition = HWC2::Composition::SolidColor;
}
- composition_ = composition;
+ device_selected_ = hwc_composition;
+
+ return;
}
void HWCLayer::PushReleaseFence(int32_t fence) {
release_fences_.push(fence);
diff --git a/sdm/libs/hwc2/hwc_layers.h b/sdm/libs/hwc2/hwc_layers.h
index 1026ff2..56e0336 100644
--- a/sdm/libs/hwc2/hwc_layers.h
+++ b/sdm/libs/hwc2/hwc_layers.h
@@ -70,8 +70,9 @@
HWC2::Error SetLayerTransform(HWC2::Transform transform);
HWC2::Error SetLayerVisibleRegion(hwc_region_t visible);
HWC2::Error SetLayerZOrder(uint32_t z);
- void SetComposition(const LayerComposition &source);
- HWC2::Composition GetCompositionType() { return composition_; }
+ void SetComposition(const LayerComposition &sdm_composition);
+ HWC2::Composition GetClientRequestedCompositionType() { return client_requested_; }
+ HWC2::Composition GetDeviceSelectedCompositionType() { return device_selected_; }
uint32_t GetGeometryChanges() { return geometry_changes_; }
void ResetGeometryChanges() { geometry_changes_ = GeometryChanges::kNone; }
void PushReleaseFence(int32_t fence);
@@ -85,7 +86,10 @@
static std::atomic<hwc2_layer_t> next_id_;
std::queue<int32_t> release_fences_;
- HWC2::Composition composition_ = HWC2::Composition::Device;
+ // Composition requested by client(SF)
+ HWC2::Composition client_requested_ = HWC2::Composition::Device;
+ // Composition selected by SDM
+ HWC2::Composition device_selected_ = HWC2::Composition::Device;
uint32_t geometry_changes_ = GeometryChanges::kNone;
void SetRect(const hwc_rect_t &source, LayerRect *target);
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index 28e0206..c0d3081 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -571,7 +571,7 @@
}
// If validate fails, cancel the sequence lock so that other operations
// (such as Dump or SetPowerMode) may succeed without blocking on the condition
- if (status != HWC2::Error::None) {
+ if (status == HWC2::Error::BadDisplay) {
SEQUENCE_CANCEL_SCOPE_LOCK(locker_);
}
return INT32(status);