hwc: Fix request flag reset and Present() bailout
The ClearRequestFlags() method iterates over layer_stack_ instead of
layer_set_. This causes a use-after-free since DestroyLayer() removes
layer from layer_set_ only. Besides that, the method need not be
virtual and has a redundant loop. This change removes the
ClearRequestFlags() method and clears flags in an existing loop.
Present() bails out if layer_set_ is empty or a shutdown is pending.
Since layers could have been destroyed before Present(), ideally
bailing out on re-validation has a higher priority over the rest.
Change-Id: Ic7b31bbd07a22b8df47fccb2024b3415ab3a559b
CRs-fixed: 2165926
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index 0c48b05..0ce1f1e 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -1214,10 +1214,6 @@
HWC2::Error HWCDisplay::CommitLayerStack(void) {
- if (shutdown_pending_ || layer_set_.empty()) {
- return HWC2::Error::None;
- }
-
if (skip_validate_ && !CanSkipValidate()) {
validated_ = false;
}
@@ -1227,6 +1223,10 @@
return HWC2::Error::NotValidated;
}
+ if (shutdown_pending_ || layer_set_.empty()) {
+ return HWC2::Error::None;
+ }
+
DumpInputBuffers();
if (!flush_) {
@@ -1316,8 +1316,11 @@
close(layer_buffer->acquire_fence_fd);
layer_buffer->acquire_fence_fd = -1;
}
+
+ layer->request.flags = {};
}
+ client_target_->GetSDMLayer()->request.flags = {};
*out_retire_fence = -1;
if (!flush_) {
// if swapinterval property is set to 0 then close and reset the list retire fence
@@ -1337,8 +1340,6 @@
geometry_changes_ = GeometryChanges::kNone;
flush_ = false;
- ClearRequestFlags();
-
return status;
}
@@ -2016,12 +2017,6 @@
return display_class_;
}
-void HWCDisplay::ClearRequestFlags() {
- for (Layer *layer : layer_stack_.layers) {
- layer->request.flags = {};
- }
-}
-
std::string HWCDisplay::Dump() {
std::ostringstream os;
os << "\n------------HWC----------------\n";
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index 263b69f..c251944 100644
--- a/sdm/libs/hwc2/hwc_display.h
+++ b/sdm/libs/hwc2/hwc_display.h
@@ -249,7 +249,6 @@
bool IsSurfaceUpdated(const std::vector<LayerRect> &dirty_regions);
bool IsLayerUpdating(const Layer *layer);
uint32_t SanitizeRefreshRate(uint32_t req_refresh_rate);
- virtual void ClearRequestFlags();
virtual void GetUnderScanConfig() { }
enum {