OSDN Git Service

Clean up handling of VR surface updates.
authorCorey Tabaka <eieio@google.com>
Fri, 1 Sep 2017 03:01:15 +0000 (20:01 -0700)
committerCorey Tabaka <eieio@google.com>
Fri, 1 Sep 2017 23:52:00 +0000 (16:52 -0700)
- Fix bug where adding a new hardware layer causes existing single-
  buffered surface layers to unlatch their buffer.
- Rename variables holding Composer pointers from hidl to composer
  to improve readability.
- Remove the arbitrary hardware layer limit, moving responsibility
  for efficient use of hardware layers to the VR display manager.

Bug: 64987282
Bug: 64756801
Test: Build system for multiple devices and manually test operation.
Change-Id: I8f05ca83830f62e15b18cd52df3014432c887681

libs/vr/libvrflinger/display_service.cpp
libs/vr/libvrflinger/hardware_composer.cpp
libs/vr/libvrflinger/hardware_composer.h

index f350762..0019acc 100644 (file)
@@ -351,17 +351,9 @@ DisplayService::GetVisibleDisplaySurfaces() const {
 
 void DisplayService::UpdateActiveDisplaySurfaces() {
   auto visible_surfaces = GetVisibleDisplaySurfaces();
-
-  std::sort(visible_surfaces.begin(), visible_surfaces.end(),
-            [](const std::shared_ptr<DisplaySurface>& a,
-               const std::shared_ptr<DisplaySurface>& b) {
-              return a->z_order() < b->z_order();
-            });
-
   ALOGD_IF(TRACE,
            "DisplayService::UpdateActiveDisplaySurfaces: %zd visible surfaces",
            visible_surfaces.size());
-
   hardware_composer_.SetDisplaySurfaces(std::move(visible_surfaces));
 }
 
index 3418d65..d595896 100644 (file)
@@ -85,9 +85,6 @@ bool SetThreadPolicy(const std::string& scheduler_class,
 
 }  // anonymous namespace
 
-// HardwareComposer static data;
-constexpr size_t HardwareComposer::kMaxHardwareLayers;
-
 HardwareComposer::HardwareComposer()
     : initialized_(false), request_display_callback_(nullptr) {}
 
@@ -98,7 +95,7 @@ HardwareComposer::~HardwareComposer(void) {
 }
 
 bool HardwareComposer::Initialize(
-    Hwc2::Composer* hidl, RequestDisplayCallback request_display_callback) {
+    Hwc2::Composer* composer, RequestDisplayCallback request_display_callback) {
   if (initialized_) {
     ALOGE("HardwareComposer::Initialize: already initialized.");
     return false;
@@ -109,7 +106,7 @@ bool HardwareComposer::Initialize(
   HWC::Error error = HWC::Error::None;
 
   Hwc2::Config config;
-  error = hidl->getActiveConfig(HWC_DISPLAY_PRIMARY, &config);
+  error = composer->getActiveConfig(HWC_DISPLAY_PRIMARY, &config);
 
   if (error != HWC::Error::None) {
     ALOGE("HardwareComposer: Failed to get current display config : %d",
@@ -117,7 +114,7 @@ bool HardwareComposer::Initialize(
     return false;
   }
 
-  error = GetDisplayMetrics(hidl, HWC_DISPLAY_PRIMARY, config,
+  error = GetDisplayMetrics(composer, HWC_DISPLAY_PRIMARY, config,
                             &native_display_metrics_);
 
   if (error != HWC::Error::None) {
@@ -140,6 +137,9 @@ bool HardwareComposer::Initialize(
   display_transform_ = HWC_TRANSFORM_NONE;
   display_metrics_ = native_display_metrics_;
 
+  // Setup the display metrics used by all Layer instances.
+  Layer::SetDisplayMetrics(native_display_metrics_);
+
   post_thread_event_fd_.Reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
   LOG_ALWAYS_FATAL_IF(
       !post_thread_event_fd_,
@@ -198,9 +198,10 @@ void HardwareComposer::UpdatePostThreadState(PostThreadStateType state,
 }
 
 void HardwareComposer::OnPostThreadResumed() {
-  hidl_.reset(new Hwc2::Composer(false));
-  hidl_callback_ = new ComposerCallback;
-  hidl_->registerCallback(hidl_callback_);
+  composer_.reset(new Hwc2::Composer(false));
+  composer_callback_ = new ComposerCallback;
+  composer_->registerCallback(composer_callback_);
+  Layer::SetComposer(composer_.get());
 
   EnableVsync(true);
 
@@ -217,19 +218,15 @@ void HardwareComposer::OnPostThreadResumed() {
 
 void HardwareComposer::OnPostThreadPaused() {
   retire_fence_fds_.clear();
-  display_surfaces_.clear();
-
-  for (size_t i = 0; i < kMaxHardwareLayers; ++i) {
-    layers_[i].Reset();
-  }
-  active_layer_count_ = 0;
+  layers_.clear();
 
-  if (hidl_) {
+  if (composer_) {
     EnableVsync(false);
   }
 
-  hidl_callback_ = nullptr;
-  hidl_.reset(nullptr);
+  composer_callback_ = nullptr;
+  composer_.reset(nullptr);
+  Layer::SetComposer(nullptr);
 
   // Trigger target-specific performance mode change.
   property_set(kDvrPerformanceProperty, "idle");
@@ -239,21 +236,21 @@ HWC::Error HardwareComposer::Validate(hwc2_display_t display) {
   uint32_t num_types;
   uint32_t num_requests;
   HWC::Error error =
-      hidl_->validateDisplay(display, &num_types, &num_requests);
+      composer_->validateDisplay(display, &num_types, &num_requests);
 
   if (error == HWC2_ERROR_HAS_CHANGES) {
     // TODO(skiazyk): We might need to inspect the requested changes first, but
     // so far it seems like we shouldn't ever hit a bad state.
     // error = hwc2_funcs_.accept_display_changes_fn_(hardware_composer_device_,
     //                                               display);
-    error = hidl_->acceptDisplayChanges(display);
+    error = composer_->acceptDisplayChanges(display);
   }
 
   return error;
 }
 
 HWC::Error HardwareComposer::EnableVsync(bool enabled) {
-  return hidl_->setVsyncEnabled(
+  return composer_->setVsyncEnabled(
       HWC_DISPLAY_PRIMARY,
       (Hwc2::IComposerClient::Vsync)(enabled ? HWC2_VSYNC_ENABLE
                                              : HWC2_VSYNC_DISABLE));
@@ -261,7 +258,7 @@ HWC::Error HardwareComposer::EnableVsync(bool enabled) {
 
 HWC::Error HardwareComposer::Present(hwc2_display_t display) {
   int32_t present_fence;
-  HWC::Error error = hidl_->presentDisplay(display, &present_fence);
+  HWC::Error error = composer_->presentDisplay(display, &present_fence);
 
   // According to the documentation, this fence is signaled at the time of
   // vsync/DMA for physical displays.
@@ -275,21 +272,21 @@ HWC::Error HardwareComposer::Present(hwc2_display_t display) {
   return error;
 }
 
-HWC::Error HardwareComposer::GetDisplayAttribute(Hwc2::Composer* hidl,
+HWC::Error HardwareComposer::GetDisplayAttribute(Hwc2::Composer* composer,
                                                  hwc2_display_t display,
                                                  hwc2_config_t config,
                                                  hwc2_attribute_t attribute,
                                                  int32_t* out_value) const {
-  return hidl->getDisplayAttribute(
+  return composer->getDisplayAttribute(
       display, config, (Hwc2::IComposerClient::Attribute)attribute, out_value);
 }
 
 HWC::Error HardwareComposer::GetDisplayMetrics(
-    Hwc2::Composer* hidl, hwc2_display_t display, hwc2_config_t config,
+    Hwc2::Composer* composer, hwc2_display_t display, hwc2_config_t config,
     HWCDisplayMetrics* out_metrics) const {
   HWC::Error error;
 
-  error = GetDisplayAttribute(hidl, display, config, HWC2_ATTRIBUTE_WIDTH,
+  error = GetDisplayAttribute(composer, display, config, HWC2_ATTRIBUTE_WIDTH,
                               &out_metrics->width);
   if (error != HWC::Error::None) {
     ALOGE(
@@ -298,7 +295,7 @@ HWC::Error HardwareComposer::GetDisplayMetrics(
     return error;
   }
 
-  error = GetDisplayAttribute(hidl, display, config, HWC2_ATTRIBUTE_HEIGHT,
+  error = GetDisplayAttribute(composer, display, config, HWC2_ATTRIBUTE_HEIGHT,
                               &out_metrics->height);
   if (error != HWC::Error::None) {
     ALOGE(
@@ -307,7 +304,7 @@ HWC::Error HardwareComposer::GetDisplayMetrics(
     return error;
   }
 
-  error = GetDisplayAttribute(hidl, display, config,
+  error = GetDisplayAttribute(composer, display, config,
                               HWC2_ATTRIBUTE_VSYNC_PERIOD,
                               &out_metrics->vsync_period_ns);
   if (error != HWC::Error::None) {
@@ -317,7 +314,7 @@ HWC::Error HardwareComposer::GetDisplayMetrics(
     return error;
   }
 
-  error = GetDisplayAttribute(hidl, display, config, HWC2_ATTRIBUTE_DPI_X,
+  error = GetDisplayAttribute(composer, display, config, HWC2_ATTRIBUTE_DPI_X,
                               &out_metrics->dpi.x);
   if (error != HWC::Error::None) {
     ALOGE(
@@ -326,7 +323,7 @@ HWC::Error HardwareComposer::GetDisplayMetrics(
     return error;
   }
 
-  error = GetDisplayAttribute(hidl, display, config, HWC2_ATTRIBUTE_DPI_Y,
+  error = GetDisplayAttribute(composer, display, config, HWC2_ATTRIBUTE_DPI_Y,
                               &out_metrics->dpi.y);
   if (error != HWC::Error::None) {
     ALOGE(
@@ -349,10 +346,10 @@ std::string HardwareComposer::Dump() {
          << std::endl;
 
   stream << "Post thread resumed: " << post_thread_resumed_ << std::endl;
-  stream << "Active layers:       " << active_layer_count_ << std::endl;
+  stream << "Active layers:       " << layers_.size() << std::endl;
   stream << std::endl;
 
-  for (size_t i = 0; i < active_layer_count_; i++) {
+  for (size_t i = 0; i < layers_.size(); i++) {
     stream << "Layer " << i << ":";
     stream << " type=" << layers_[i].GetCompositionType().to_string();
     stream << " surface_id=" << layers_[i].GetSurfaceId();
@@ -363,7 +360,7 @@ std::string HardwareComposer::Dump() {
 
   if (post_thread_resumed_) {
     stream << "Hardware Composer Debug Info:" << std::endl;
-    stream << hidl_->dumpDebugInfo();
+    stream << composer_->dumpDebugInfo();
   }
 
   return stream.str();
@@ -373,8 +370,8 @@ void HardwareComposer::PostLayers() {
   ATRACE_NAME("HardwareComposer::PostLayers");
 
   // Setup the hardware composer layers with current buffers.
-  for (size_t i = 0; i < active_layer_count_; i++) {
-    layers_[i].Prepare();
+  for (auto& layer : layers_) {
+    layer.Prepare();
   }
 
   HWC::Error error = Validate(HWC_DISPLAY_PRIMARY);
@@ -408,8 +405,8 @@ void HardwareComposer::PostLayers() {
              "Warning: dropping a frame to catch up with HWC (pending = %zd)",
              retire_fence_fds_.size());
 
-    for (size_t i = 0; i < active_layer_count_; i++) {
-      layers_[i].Drop();
+    for (auto& layer : layers_) {
+      layer.Drop();
     }
     return;
   } else {
@@ -419,7 +416,7 @@ void HardwareComposer::PostLayers() {
   }
 
 #if TRACE > 1
-  for (size_t i = 0; i < active_layer_count_; i++) {
+  for (size_t i = 0; i < layers_.size(); i++) {
     ALOGI("HardwareComposer::PostLayers: layer=%zu buffer_id=%d composition=%s",
           i, layers_[i].GetBufferId(),
           layers_[i].GetCompositionType().to_string().c_str());
@@ -435,18 +432,18 @@ void HardwareComposer::PostLayers() {
 
   std::vector<Hwc2::Layer> out_layers;
   std::vector<int> out_fences;
-  error = hidl_->getReleaseFences(HWC_DISPLAY_PRIMARY, &out_layers,
-                                  &out_fences);
+  error = composer_->getReleaseFences(HWC_DISPLAY_PRIMARY, &out_layers,
+                                      &out_fences);
   ALOGE_IF(error != HWC::Error::None,
            "HardwareComposer::PostLayers: Failed to get release fences: %s",
            error.to_string().c_str());
 
-  // Perform post-frame bookkeeping. Unused layers are a no-op.
+  // Perform post-frame bookkeeping.
   uint32_t num_elements = out_layers.size();
   for (size_t i = 0; i < num_elements; ++i) {
-    for (size_t j = 0; j < active_layer_count_; ++j) {
-      if (layers_[j].GetLayerHandle() == out_layers[i]) {
-        layers_[j].Finish(out_fences[i]);
+    for (auto& layer : layers_) {
+      if (layer.GetLayerHandle() == out_layers[i]) {
+        layer.Finish(out_fences[i]);
       }
     }
   }
@@ -618,12 +615,12 @@ int HardwareComposer::ReadWaitPPState() {
 // vsync already passed since the last call, returns the latest vsync timestamp
 // instead of blocking.
 int HardwareComposer::WaitForVSync(int64_t* timestamp) {
-  int error = PostThreadPollInterruptible(
-      hidl_callback_->GetVsyncEventFd(), POLLIN, /*timeout_ms*/ 1000);
+  int error = PostThreadPollInterruptible(composer_callback_->GetVsyncEventFd(),
+                                          POLLIN, /*timeout_ms*/ 1000);
   if (error == kPostThreadInterrupted || error < 0) {
     return error;
   } else {
-    *timestamp = hidl_callback_->GetVsyncTime();
+    *timestamp = composer_callback_->GetVsyncTime();
     return 0;
   }
 }
@@ -827,38 +824,60 @@ bool HardwareComposer::UpdateLayerConfig() {
 
   ATRACE_NAME("UpdateLayerConfig_HwLayers");
 
-  display_surfaces_.clear();
+  // Sort the new direct surface list by z-order to determine the relative order
+  // of the surfaces. This relative order is used for the HWC z-order value to
+  // insulate VrFlinger and HWC z-order semantics from each other.
+  std::sort(surfaces.begin(), surfaces.end(), [](const auto& a, const auto& b) {
+    return a->z_order() < b->z_order();
+  });
 
-  Layer* target_layer;
-  size_t layer_index;
-  for (layer_index = 0;
-       layer_index < std::min(surfaces.size(), kMaxHardwareLayers);
-       layer_index++) {
+  // Prepare a new layer stack, pulling in layers from the previous
+  // layer stack that are still active and updating their attributes.
+  std::vector<Layer> layers;
+  size_t layer_index = 0;
+  for (const auto& surface : surfaces) {
     // The bottom layer is opaque, other layers blend.
     HWC::BlendMode blending =
         layer_index == 0 ? HWC::BlendMode::None : HWC::BlendMode::Coverage;
-    layers_[layer_index].Setup(surfaces[layer_index], native_display_metrics_,
-                               hidl_.get(), blending,
-                               display_transform_, HWC::Composition::Device,
-                               layer_index);
-    display_surfaces_.push_back(surfaces[layer_index]);
-  }
 
-  // Clear unused layers.
-  for (size_t i = layer_index; i < kMaxHardwareLayers; i++)
-    layers_[i].Reset();
+    // Try to find a layer for this surface in the set of active layers.
+    auto search =
+        std::lower_bound(layers_.begin(), layers_.end(), surface->surface_id());
+    const bool found = search != layers_.end() &&
+                       search->GetSurfaceId() == surface->surface_id();
+    if (found) {
+      // Update the attributes of the layer that may have changed.
+      search->SetBlending(blending);
+      search->SetZOrder(layer_index);  // Relative z-order.
+
+      // Move the existing layer to the new layer set and remove the empty layer
+      // object from the current set.
+      layers.push_back(std::move(*search));
+      layers_.erase(search);
+    } else {
+      // Insert a layer for the new surface.
+      layers.emplace_back(surface, blending, display_transform_,
+                          HWC::Composition::Device, layer_index);
+    }
 
-  active_layer_count_ = layer_index;
-  ALOGD_IF(TRACE, "HardwareComposer::UpdateLayerConfig: %zd active layers",
-           active_layer_count_);
+    ALOGI_IF(
+        TRACE,
+        "HardwareComposer::UpdateLayerConfig: layer_index=%zu surface_id=%d",
+        layer_index, layers[layer_index].GetSurfaceId());
+
+    layer_index++;
+  }
+
+  // Sort the new layer stack by ascending surface id.
+  std::sort(layers.begin(), layers.end());
 
-  // Any surfaces left over could not be assigned a hardware layer and will
-  // not be displayed.
-  ALOGW_IF(surfaces.size() != display_surfaces_.size(),
-           "HardwareComposer::UpdateLayerConfig: More surfaces than layers: "
-           "pending_surfaces=%zu display_surfaces=%zu",
-           surfaces.size(), display_surfaces_.size());
+  // Replace the previous layer set with the new layer set. The destructor of
+  // the previous set will clean up the remaining Layers that are not moved to
+  // the new layer set.
+  layers_ = std::move(layers);
 
+  ALOGD_IF(TRACE, "HardwareComposer::UpdateLayerConfig: %zd active layers",
+           layers_.size());
   return true;
 }
 
@@ -920,13 +939,15 @@ int64_t HardwareComposer::ComposerCallback::GetVsyncTime() {
   return return_val;
 }
 
+Hwc2::Composer* Layer::composer_{nullptr};
+HWCDisplayMetrics Layer::display_metrics_{0, 0, {0, 0}, 0};
+
 void Layer::Reset() {
-  if (hidl_ != nullptr && hardware_composer_layer_) {
-    hidl_->destroyLayer(HWC_DISPLAY_PRIMARY, hardware_composer_layer_);
+  if (hardware_composer_layer_) {
+    composer_->destroyLayer(HWC_DISPLAY_PRIMARY, hardware_composer_layer_);
     hardware_composer_layer_ = 0;
   }
 
-  hidl_ = nullptr;
   z_order_ = 0;
   blending_ = HWC::BlendMode::None;
   transform_ = HWC::Transform::None;
@@ -935,38 +956,52 @@ void Layer::Reset() {
   source_ = EmptyVariant{};
   acquire_fence_.Close();
   surface_rect_functions_applied_ = false;
+  pending_visibility_settings_ = true;
 }
 
-void Layer::Setup(const std::shared_ptr<DirectDisplaySurface>& surface,
-                  const HWCDisplayMetrics& display_metrics,
-                  Hwc2::Composer* hidl, HWC::BlendMode blending,
-                  HWC::Transform transform, HWC::Composition composition_type,
-                  size_t z_order) {
-  Reset();
-  hidl_ = hidl;
-  z_order_ = z_order;
-  blending_ = blending;
-  transform_ = transform;
-  composition_type_ = HWC::Composition::Invalid;
-  target_composition_type_ = composition_type;
-  source_ = SourceSurface{surface};
-  CommonLayerSetup(display_metrics);
+Layer::Layer(const std::shared_ptr<DirectDisplaySurface>& surface,
+             HWC::BlendMode blending, HWC::Transform transform,
+             HWC::Composition composition_type, size_t z_order)
+    : z_order_{z_order},
+      blending_{blending},
+      transform_{transform},
+      target_composition_type_{composition_type},
+      source_{SourceSurface{surface}} {
+  CommonLayerSetup();
 }
 
-void Layer::Setup(const std::shared_ptr<IonBuffer>& buffer,
-                  const HWCDisplayMetrics& display_metrics,
-                  Hwc2::Composer* hidl, HWC::BlendMode blending,
-                  HWC::Transform transform, HWC::Composition composition_type,
-                  size_t z_order) {
-  Reset();
-  hidl_ = hidl;
-  z_order_ = z_order;
-  blending_ = blending;
-  transform_ = transform;
-  composition_type_ = HWC::Composition::Invalid;
-  target_composition_type_ = composition_type;
-  source_ = SourceBuffer{buffer};
-  CommonLayerSetup(display_metrics);
+Layer::Layer(const std::shared_ptr<IonBuffer>& buffer, HWC::BlendMode blending,
+             HWC::Transform transform, HWC::Composition composition_type,
+             size_t z_order)
+    : z_order_{z_order},
+      blending_{blending},
+      transform_{transform},
+      target_composition_type_{composition_type},
+      source_{SourceBuffer{buffer}} {
+  CommonLayerSetup();
+}
+
+Layer::~Layer() { Reset(); }
+
+Layer::Layer(Layer&& other) { *this = std::move(other); }
+
+Layer& Layer::operator=(Layer&& other) {
+  if (this != &other) {
+    Reset();
+    using std::swap;
+    swap(hardware_composer_layer_, other.hardware_composer_layer_);
+    swap(z_order_, other.z_order_);
+    swap(blending_, other.blending_);
+    swap(transform_, other.transform_);
+    swap(composition_type_, other.composition_type_);
+    swap(target_composition_type_, other.target_composition_type_);
+    swap(source_, other.source_);
+    swap(acquire_fence_, other.acquire_fence_);
+    swap(surface_rect_functions_applied_,
+         other.surface_rect_functions_applied_);
+    swap(pending_visibility_settings_, other.pending_visibility_settings_);
+  }
+  return *this;
 }
 
 void Layer::UpdateBuffer(const std::shared_ptr<IonBuffer>& buffer) {
@@ -974,8 +1009,19 @@ void Layer::UpdateBuffer(const std::shared_ptr<IonBuffer>& buffer) {
     std::get<SourceBuffer>(source_) = {buffer};
 }
 
-void Layer::SetBlending(HWC::BlendMode blending) { blending_ = blending; }
-void Layer::SetZOrder(size_t z_order) { z_order_ = z_order; }
+void Layer::SetBlending(HWC::BlendMode blending) {
+  if (blending_ != blending) {
+    blending_ = blending;
+    pending_visibility_settings_ = true;
+  }
+}
+
+void Layer::SetZOrder(size_t z_order) {
+  if (z_order_ != z_order) {
+    z_order_ = z_order;
+    pending_visibility_settings_ = true;
+  }
+}
 
 IonBuffer* Layer::GetBuffer() {
   struct Visitor {
@@ -986,18 +1032,35 @@ IonBuffer* Layer::GetBuffer() {
   return source_.Visit(Visitor{});
 }
 
-void Layer::UpdateLayerSettings(const HWCDisplayMetrics& display_metrics) {
-  if (!IsLayerSetup()) {
-    ALOGE(
-        "HardwareComposer::Layer::UpdateLayerSettings: Attempt to update "
-        "unused Layer!");
-    return;
+void Layer::UpdateVisibilitySettings() {
+  if (pending_visibility_settings_) {
+    pending_visibility_settings_ = false;
+
+    HWC::Error error;
+    hwc2_display_t display = HWC_DISPLAY_PRIMARY;
+
+    error = composer_->setLayerBlendMode(
+        display, hardware_composer_layer_,
+        blending_.cast<Hwc2::IComposerClient::BlendMode>());
+    ALOGE_IF(error != HWC::Error::None,
+             "Layer::UpdateLayerSettings: Error setting layer blend mode: %s",
+             error.to_string().c_str());
+
+    error =
+        composer_->setLayerZOrder(display, hardware_composer_layer_, z_order_);
+    ALOGE_IF(error != HWC::Error::None,
+             "Layer::UpdateLayerSettings: Error setting z_ order: %s",
+             error.to_string().c_str());
   }
+}
 
+void Layer::UpdateLayerSettings() {
   HWC::Error error;
   hwc2_display_t display = HWC_DISPLAY_PRIMARY;
 
-  error = hidl_->setLayerCompositionType(
+  UpdateVisibilitySettings();
+
+  error = composer_->setLayerCompositionType(
       display, hardware_composer_layer_,
       composition_type_.cast<Hwc2::IComposerClient::Composition>());
   ALOGE_IF(
@@ -1005,48 +1068,37 @@ void Layer::UpdateLayerSettings(const HWCDisplayMetrics& display_metrics) {
       "Layer::UpdateLayerSettings: Error setting layer composition type: %s",
       error.to_string().c_str());
 
-  error = hidl_->setLayerBlendMode(
-      display, hardware_composer_layer_,
-      blending_.cast<Hwc2::IComposerClient::BlendMode>());
-  ALOGE_IF(error != HWC::Error::None,
-           "Layer::UpdateLayerSettings: Error setting layer blend mode: %s",
-           error.to_string().c_str());
-
   // TODO(eieio): Use surface attributes or some other mechanism to control
   // the layer display frame.
-  error = hidl_->setLayerDisplayFrame(
+  error = composer_->setLayerDisplayFrame(
       display, hardware_composer_layer_,
-      {0, 0, display_metrics.width, display_metrics.height});
+      {0, 0, display_metrics_.width, display_metrics_.height});
   ALOGE_IF(error != HWC::Error::None,
            "Layer::UpdateLayerSettings: Error setting layer display frame: %s",
            error.to_string().c_str());
 
-  error = hidl_->setLayerVisibleRegion(
+  error = composer_->setLayerVisibleRegion(
       display, hardware_composer_layer_,
-      {{0, 0, display_metrics.width, display_metrics.height}});
+      {{0, 0, display_metrics_.width, display_metrics_.height}});
   ALOGE_IF(error != HWC::Error::None,
            "Layer::UpdateLayerSettings: Error setting layer visible region: %s",
            error.to_string().c_str());
 
-  error = hidl_->setLayerPlaneAlpha(display, hardware_composer_layer_, 1.0f);
+  error =
+      composer_->setLayerPlaneAlpha(display, hardware_composer_layer_, 1.0f);
   ALOGE_IF(error != HWC::Error::None,
            "Layer::UpdateLayerSettings: Error setting layer plane alpha: %s",
            error.to_string().c_str());
-
-  error = hidl_->setLayerZOrder(display, hardware_composer_layer_, z_order_);
-  ALOGE_IF(error != HWC::Error::None,
-           "Layer::UpdateLayerSettings: Error setting z_ order: %s",
-           error.to_string().c_str());
 }
 
-void Layer::CommonLayerSetup(const HWCDisplayMetrics& display_metrics) {
+void Layer::CommonLayerSetup() {
   HWC::Error error =
-      hidl_->createLayer(HWC_DISPLAY_PRIMARY, &hardware_composer_layer_);
-  ALOGE_IF(
-      error != HWC::Error::None,
-      "Layer::CommonLayerSetup: Failed to create layer on primary display: %s",
-      error.to_string().c_str());
-  UpdateLayerSettings(display_metrics);
+      composer_->createLayer(HWC_DISPLAY_PRIMARY, &hardware_composer_layer_);
+  ALOGE_IF(error != HWC::Error::None,
+           "Layer::CommonLayerSetup: Failed to create layer on primary "
+           "display: %s",
+           error.to_string().c_str());
+  UpdateLayerSettings();
 }
 
 void Layer::Prepare() {
@@ -1058,19 +1110,23 @@ void Layer::Prepare() {
     std::tie(right, bottom, handle, acquire_fence_) = source.Acquire();
   });
 
-  // When a layer is first setup there may be some time before the first buffer
-  // arrives. Setup the HWC layer as a solid color to stall for time until the
-  // first buffer arrives. Once the first buffer arrives there will always be a
-  // buffer for the frame even if it is old.
+  // Update any visibility (blending, z-order) changes that occurred since
+  // last prepare.
+  UpdateVisibilitySettings();
+
+  // When a layer is first setup there may be some time before the first
+  // buffer arrives. Setup the HWC layer as a solid color to stall for time
+  // until the first buffer arrives. Once the first buffer arrives there will
+  // always be a buffer for the frame even if it is old.
   if (!handle.get()) {
     if (composition_type_ == HWC::Composition::Invalid) {
       composition_type_ = HWC::Composition::SolidColor;
-      hidl_->setLayerCompositionType(
+      composer_->setLayerCompositionType(
           HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
           composition_type_.cast<Hwc2::IComposerClient::Composition>());
       Hwc2::IComposerClient::Color layer_color = {0, 0, 0, 0};
-      hidl_->setLayerColor(HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
-                           layer_color);
+      composer_->setLayerColor(HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
+                               layer_color);
     } else {
       // The composition type is already set. Nothing else to do until a
       // buffer arrives.
@@ -1078,15 +1134,15 @@ void Layer::Prepare() {
   } else {
     if (composition_type_ != target_composition_type_) {
       composition_type_ = target_composition_type_;
-      hidl_->setLayerCompositionType(
+      composer_->setLayerCompositionType(
           HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
           composition_type_.cast<Hwc2::IComposerClient::Composition>());
     }
 
     HWC::Error error{HWC::Error::None};
-    error = hidl_->setLayerBuffer(HWC_DISPLAY_PRIMARY,
-                                  hardware_composer_layer_, 0, handle,
-                                  acquire_fence_.Get());
+    error =
+        composer_->setLayerBuffer(HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
+                                  0, handle, acquire_fence_.Get());
 
     ALOGE_IF(error != HWC::Error::None,
              "Layer::Prepare: Error setting layer buffer: %s",
@@ -1095,9 +1151,9 @@ void Layer::Prepare() {
     if (!surface_rect_functions_applied_) {
       const float float_right = right;
       const float float_bottom = bottom;
-      error = hidl_->setLayerSourceCrop(HWC_DISPLAY_PRIMARY,
-                                        hardware_composer_layer_,
-                                        {0, 0, float_right, float_bottom});
+      error = composer_->setLayerSourceCrop(HWC_DISPLAY_PRIMARY,
+                                            hardware_composer_layer_,
+                                            {0, 0, float_right, float_bottom});
 
       ALOGE_IF(error != HWC::Error::None,
                "Layer::Prepare: Error setting layer source crop: %s",
index fc0efee..550e687 100644 (file)
@@ -52,10 +52,7 @@ struct HWCDisplayMetrics {
 // source supplying buffers for the layer's contents.
 class Layer {
  public:
-  Layer() {}
-
-  // Releases any shared pointers and fence handles held by this instance.
-  void Reset();
+  Layer() = default;
 
   // Sets up the layer to use a display surface as its content source. The Layer
   // automatically handles ACQUIRE/RELEASE phases for the surface's buffer train
@@ -66,10 +63,9 @@ class Layer {
   // |composition_type| receives either HWC_FRAMEBUFFER for most layers or
   // HWC_FRAMEBUFFER_TARGET (unless you know what you are doing).
   // |index| is the index of this surface in the DirectDisplaySurface array.
-  void Setup(const std::shared_ptr<DirectDisplaySurface>& surface,
-             const HWCDisplayMetrics& display_metrics, Hwc2::Composer* hidl,
-             HWC::BlendMode blending, HWC::Transform transform,
-             HWC::Composition composition_type, size_t z_roder);
+  Layer(const std::shared_ptr<DirectDisplaySurface>& surface,
+        HWC::BlendMode blending, HWC::Transform transform,
+        HWC::Composition composition_type, size_t z_roder);
 
   // Sets up the layer to use a direct buffer as its content source. No special
   // handling of the buffer is performed; responsibility for updating or
@@ -79,10 +75,17 @@ class Layer {
   // |transform| receives HWC_TRANSFORM_* values.
   // |composition_type| receives either HWC_FRAMEBUFFER for most layers or
   // HWC_FRAMEBUFFER_TARGET (unless you know what you are doing).
-  void Setup(const std::shared_ptr<IonBuffer>& buffer,
-             const HWCDisplayMetrics& display_metrics, Hwc2::Composer* hidl,
-             HWC::BlendMode blending, HWC::Transform transform,
-             HWC::Composition composition_type, size_t z_order);
+  Layer(const std::shared_ptr<IonBuffer>& buffer, HWC::BlendMode blending,
+        HWC::Transform transform, HWC::Composition composition_type,
+        size_t z_order);
+
+  Layer(Layer&&);
+  Layer& operator=(Layer&&);
+
+  ~Layer();
+
+  // Releases any shared pointers and fence handles held by this instance.
+  void Reset();
 
   // Layers that use a direct IonBuffer should call this each frame to update
   // which buffer will be used for the next PostLayers.
@@ -117,9 +120,6 @@ class Layer {
   HWC::Layer GetLayerHandle() const { return hardware_composer_layer_; }
   bool IsLayerSetup() const { return !source_.empty(); }
 
-  // Applies all of the settings to this layer using the hwc functions
-  void UpdateLayerSettings(const HWCDisplayMetrics& display_metrics);
-
   int GetSurfaceId() const {
     int surface_id = -1;
     pdx::rpc::IfAnyOf<SourceSurface>::Call(
@@ -138,10 +138,41 @@ class Layer {
     return buffer_id;
   }
 
+  // Compares Layers by surface id.
+  bool operator<(const Layer& other) const {
+    return GetSurfaceId() < other.GetSurfaceId();
+  }
+  bool operator<(int surface_id) const {
+    return GetSurfaceId() < surface_id;
+  }
+
+  // Sets the composer instance used by all Layer instances.
+  static void SetComposer(Hwc2::Composer* composer) { composer_ = composer; }
+
+  // Sets the display metrics used by all Layer instances.
+  static void SetDisplayMetrics(HWCDisplayMetrics display_metrics) {
+    display_metrics_ = display_metrics;
+  }
+
  private:
-  void CommonLayerSetup(const HWCDisplayMetrics& display_metrics);
+  void CommonLayerSetup();
+
+  // Applies all of the settings to this layer using the hwc functions
+  void UpdateLayerSettings();
 
-  Hwc2::Composer* hidl_ = nullptr;
+  // Applies visibility settings that may have changed.
+  void UpdateVisibilitySettings();
+
+  // Composer instance shared by all instances of Layer. This must be set
+  // whenever a new instance of the Composer is created. This may be set to
+  // nullptr as long as there are no instances of Layer that might need to use
+  // it.
+  static Hwc2::Composer* composer_;
+
+  // Display metrics shared by all instances of Layer. This must be set at least
+  // once during VrFlinger initialization and is expected to remain constant
+  // thereafter.
+  static HWCDisplayMetrics display_metrics_;
 
   // The hardware composer layer and metrics to use during the prepare cycle.
   hwc2_layer_t hardware_composer_layer_ = 0;
@@ -235,6 +266,7 @@ class Layer {
 
   pdx::LocalHandle acquire_fence_;
   bool surface_rect_functions_applied_ = false;
+  bool pending_visibility_settings_ = true;
 
   Layer(const Layer&) = delete;
   void operator=(const Layer&) = delete;
@@ -254,14 +286,10 @@ class HardwareComposer {
   using VSyncCallback = std::function<void(int, int64_t, int64_t, uint32_t)>;
   using RequestDisplayCallback = std::function<void(bool)>;
 
-  // Since there is no universal way to query the number of hardware layers,
-  // just set it to 4 for now.
-  static constexpr size_t kMaxHardwareLayers = 4;
-
   HardwareComposer();
   ~HardwareComposer();
 
-  bool Initialize(Hwc2::Composer* hidl,
+  bool Initialize(Hwc2::Composer* composer,
                   RequestDisplayCallback request_display_callback);
 
   bool IsInitialized() const { return initialized_; }
@@ -299,11 +327,11 @@ class HardwareComposer {
   void OnDeletedGlobalBuffer(DvrGlobalBufferKey key);
 
  private:
-  HWC::Error GetDisplayAttribute(Hwc2::Composer* hidl, hwc2_display_t display,
-                                 hwc2_config_t config,
+  HWC::Error GetDisplayAttribute(Hwc2::Composer* composer,
+                                 hwc2_display_t display, hwc2_config_t config,
                                  hwc2_attribute_t attributes,
                                  int32_t* out_value) const;
-  HWC::Error GetDisplayMetrics(Hwc2::Composer* hidl, hwc2_display_t display,
+  HWC::Error GetDisplayMetrics(Hwc2::Composer* composer, hwc2_display_t display,
                                hwc2_config_t config,
                                HWCDisplayMetrics* out_metrics) const;
 
@@ -319,6 +347,7 @@ class HardwareComposer {
                                    int64_t timestamp) override;
     const pdx::LocalHandle& GetVsyncEventFd() const;
     int64_t GetVsyncTime();
+
    private:
     std::mutex vsync_mutex_;
     pdx::LocalHandle vsync_event_fd_;
@@ -356,8 +385,7 @@ class HardwareComposer {
   // the case of a timeout. If we're interrupted, kPostThreadInterrupted will be
   // returned.
   int PostThreadPollInterruptible(const pdx::LocalHandle& event_fd,
-                                  int requested_events,
-                                  int timeout_ms);
+                                  int requested_events, int timeout_ms);
 
   // WaitForVSync and SleepUntil are blocking calls made on the post thread that
   // can be interrupted by a control thread. If interrupted, these calls return
@@ -386,8 +414,8 @@ class HardwareComposer {
 
   bool initialized_;
 
-  std::unique_ptr<Hwc2::Composer> hidl_;
-  sp<ComposerCallback> hidl_callback_;
+  std::unique_ptr<Hwc2::Composer> composer_;
+  sp<ComposerCallback> composer_callback_;
   RequestDisplayCallback request_display_callback_;
 
   // Display metrics of the physical display.
@@ -403,13 +431,9 @@ class HardwareComposer {
   // thread and read by the post thread.
   std::vector<std::shared_ptr<DirectDisplaySurface>> pending_surfaces_;
 
-  // The surfaces displayed by the post thread. Used exclusively by the post
-  // thread.
-  std::vector<std::shared_ptr<DirectDisplaySurface>> display_surfaces_;
-
-  // Layer array for handling buffer flow into hardware composer layers.
-  std::array<Layer, kMaxHardwareLayers> layers_;
-  size_t active_layer_count_ = 0;
+  // Layer set for handling buffer flow into hardware composer layers. This
+  // vector must be sorted by surface_id in ascending order.
+  std::vector<Layer> layers_;
 
   // Handler to hook vsync events outside of this class.
   VSyncCallback vsync_callback_;
@@ -419,8 +443,8 @@ class HardwareComposer {
   std::thread post_thread_;
 
   // Post thread state machine and synchronization primitives.
-  PostThreadStateType post_thread_state_{
-      PostThreadState::Idle | PostThreadState::Suspended};
+  PostThreadStateType post_thread_state_{PostThreadState::Idle |
+                                         PostThreadState::Suspended};
   std::atomic<bool> post_thread_quiescent_{true};
   bool post_thread_resumed_{false};
   pdx::LocalHandle post_thread_event_fd_;