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.

Bug: 71538967
Change-Id: Ic7b31bbd07a22b8df47fccb2024b3415ab3a559b
CRs-fixed: 2165926
Acked-by:  Saurabh Shah <saurshah@codeaurora.org>
This commit is contained in:
Naseer Ahmed 2018-01-24 19:06:23 -05:00 committed by Adrian Salido
parent 0a489f6722
commit c9bb61606f
2 changed files with 8 additions and 15 deletions

View File

@ -1090,8 +1090,8 @@ HWC2::Error HWCDisplay::GetHdrCapabilities(uint32_t *out_num_types, int32_t *out
HWC2::Error HWCDisplay::CommitLayerStack(void) {
if (shutdown_pending_ || layer_set_.empty()) {
return HWC2::Error::None;
if (skip_validate_ && !CanSkipValidate()) {
validated_ = false;
}
if (!validated_) {
@ -1099,10 +1099,9 @@ HWC2::Error HWCDisplay::CommitLayerStack(void) {
return HWC2::Error::NotValidated;
}
if (skip_validate_ && !CanSkipValidate()) {
DLOGV_IF(kTagCompManager, "Cannot skip validate on display: %d", id_);
validated_ = false;
return HWC2::Error::NotValidated;
if (shutdown_pending_ || layer_set_.empty()) {
return HWC2::Error::None;
}
DumpInputBuffers();
@ -1189,8 +1188,11 @@ HWC2::Error HWCDisplay::PostCommitLayerStack(int32_t *out_retire_fence) {
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
@ -1210,8 +1212,6 @@ HWC2::Error HWCDisplay::PostCommitLayerStack(int32_t *out_retire_fence) {
geometry_changes_ = GeometryChanges::kNone;
flush_ = false;
ClearRequestFlags();
return status;
}
@ -1845,12 +1845,6 @@ void HWCDisplay::CloseAcquireFds() {
}
}
void HWCDisplay::ClearRequestFlags() {
for (Layer *layer : layer_stack_.layers) {
layer->request.flags = {};
}
}
std::string HWCDisplay::Dump() {
std::ostringstream os;
os << "-------------------------------" << std::endl;

View File

@ -238,7 +238,6 @@ class HWCDisplay : public DisplayEventHandler {
bool IsLayerUpdating(const Layer *layer);
uint32_t SanitizeRefreshRate(uint32_t req_refresh_rate);
virtual void CloseAcquireFds();
virtual void ClearRequestFlags();
virtual void GetUnderScanConfig() { }
enum {