OSDN Git Service

Cache DisplayPlaneState.
authorKalyan Kondapally <kalyan.kondapally@intel.com>
Sat, 23 Dec 2017 03:36:12 +0000 (19:36 -0800)
committerKalyan Kondapally <kalyan.kondapally@intel.com>
Sun, 24 Dec 2017 00:07:26 +0000 (16:07 -0800)
This patch adds support to cache relevant private data, instead
of having to manually track it for every frame. This simplifies
lot of things like keeping track of any new surfaces when commit
has failed for that frame, display rect changes etc. Also, this
avoids redundant copies of plane state every frame.

Jira: None.
Test: No flicker seen while moving between different views.
Signed-off-by: Kalyan Kondapally <kalyan.kondapally@intel.com>
common/compositor/nativesurface.cpp
common/compositor/nativesurface.h
common/display/displayplanemanager.cpp
common/display/displayplanestate.cpp
common/display/displayplanestate.h
common/display/displayqueue.cpp
common/display/displayqueue.h

index 658066a..40cf006 100644 (file)
@@ -81,15 +81,12 @@ void NativeSurface::SetSurfaceAge(uint32_t value) {
   surface_age_ = value;
 }
 
-void NativeSurface::SetPlaneTarget(DisplayPlaneState &plane, uint32_t gpu_fd) {
+void NativeSurface::SetPlaneTarget(const DisplayPlaneState &plane,
+                                   uint32_t gpu_fd) {
   const HwcRect<int> &display_rect = plane.GetDisplayFrame();
   surface_damage_ = display_rect;
   last_surface_damage_ = surface_damage_;
-  ResetDisplayFrame(plane.GetDisplayFrame());
-  ResetSourceCrop(plane.GetSourceCrop());
   layer_.UsePlaneScalar(plane.IsUsingPlaneScalar());
-
-  plane.SetOverlayLayer(&layer_);
   in_use_ = true;
   clear_surface_ = true;
   surface_age_ = 0;
index d1ac4af..a1b1455 100644 (file)
@@ -84,7 +84,7 @@ class NativeSurface {
     return clear_surface_;
   }
 
-  void SetPlaneTarget(DisplayPlaneState& plane, uint32_t gpu_fd);
+  void SetPlaneTarget(const DisplayPlaneState& plane, uint32_t gpu_fd);
 
   // Resets DisplayFrame, SurfaceDamage to display_frame.
   void ResetDisplayFrame(const HwcRect<int>& display_frame);
index 6f9c04a..8a97c17 100644 (file)
@@ -194,7 +194,7 @@ bool DisplayPlaneManager::ValidateLayers(
         bool force_buffer = false;
         if (is_video && last_plane.GetSourceLayers().size() > 1 &&
             last_plane.GetOffScreenTarget()) {
-          last_plane.ReleaseSurfaces();
+          last_plane.ReleaseSurfaces(false);
           force_buffer = true;
         }
 
@@ -307,16 +307,16 @@ void DisplayPlaneManager::PreparePlaneForCursor(DisplayPlaneState *plane,
     SetOffScreenPlaneTarget(*plane);
   }
 
-  std::vector<CompositionRegion> &comp_regions = plane->GetCompositionRegion();
-  std::vector<CompositionRegion>().swap(comp_regions);
-  const std::vector<NativeSurface *> &surfaces = plane->GetSurfaces();
-  size_t size = surfaces.size();
-  const HwcRect<int> &current_rect = plane->GetDisplayFrame();
-  for (size_t i = 0; i < size; i++) {
-    surfaces.at(i)->ResetDisplayFrame(current_rect);
+  // If Last frame surface is re-cycled and surfaces are
+  // less than 3, make sure we have the offscreen surface
+  // which is not in queued to be onscreen yet.
+  if (plane->SurfaceRecycled() && (plane->GetSurfaces().size() < 3)) {
+    SetOffScreenPlaneTarget(*plane);
+  } else {
+    plane->SwapSurfaceIfNeeded();
   }
 
-  plane->SwapSurfaceIfNeeded();
+  plane->RefreshSurfaces(true);
 }
 
 bool DisplayPlaneManager::ValidateCursorLayer(
@@ -409,18 +409,12 @@ void DisplayPlaneManager::ValidateForDisplayScaling(
     DisplayPlaneState &last_plane, std::vector<OverlayPlane> &commit_planes,
     OverlayLayer *current_layer, bool ignore_format) {
   size_t total_layers = last_plane.GetSourceLayers().size();
-  const std::vector<NativeSurface *> &surfaces = last_plane.GetSurfaces();
-  size_t size = surfaces.size();
 
   if (last_plane.IsUsingPlaneScalar()) {
     last_plane.UsePlaneScalar(false);
     current_layer->UsePlaneScalar(false);
     last_plane.ResetSourceRectToDisplayFrame();
-    const HwcRect<float> &current_rect = last_plane.GetSourceCrop();
-    for (size_t i = 0; i < size; i++) {
-      surfaces.at(i)->ResetSourceCrop(current_rect);
-      surfaces.at(i)->GetLayer()->UsePlaneScalar(false);
-    }
+    last_plane.RefreshSurfaces(false);
   }
 
   // TODO: Handle case where all layers to be compoisted have same scaling
@@ -491,10 +485,7 @@ void DisplayPlaneManager::ValidateForDisplayScaling(
   // we can take advantage of scalars attached to this plane.
   const HwcRect<float> &crop = current_layer->GetSourceCrop();
   last_plane.SetSourceCrop(crop);
-  for (size_t i = 0; i < size; i++) {
-    surfaces.at(i)->ResetSourceCrop(crop);
-    surfaces.at(i)->GetLayer()->UsePlaneScalar(true);
-  }
+  last_plane.RefreshSurfaces(false);
 
   OverlayPlane &last_overlay_plane = commit_planes.back();
   last_overlay_plane.layer = last_plane.GetOverlayLayer();
@@ -504,11 +495,7 @@ void DisplayPlaneManager::ValidateForDisplayScaling(
                     last_plane.GetOffScreenTarget()->GetLayer(), commit_planes);
   if (fall_back) {
     last_plane.ResetSourceRectToDisplayFrame();
-    const HwcRect<float> &current_rect = last_plane.GetSourceCrop();
-    for (size_t i = 0; i < size; i++) {
-      surfaces.at(i)->ResetSourceCrop(current_rect);
-      surfaces.at(i)->GetLayer()->UsePlaneScalar(false);
-    }
+    last_plane.RefreshSurfaces(false);
   } else {
     last_plane.UsePlaneScalar(true);
     current_layer->UsePlaneScalar(true);
index 96229dd..9575249 100644 (file)
 namespace hwcomposer {
 
 DisplayPlaneState::DisplayPlaneState(DisplayPlane *plane, OverlayLayer *layer,
-                                     uint32_t index)
-    : plane_(plane), layer_(layer) {
-  source_layers_.emplace_back(index);
-  display_frame_ = layer->GetDisplayFrame();
-  source_crop_ = layer->GetSourceCrop();
+                                     uint32_t index) {
+  private_data_ = std::make_shared<DisplayPlanePrivateState>();
+  private_data_->source_layers_.emplace_back(index);
+  private_data_->display_frame_ = layer->GetDisplayFrame();
+  private_data_->source_crop_ = layer->GetSourceCrop();
   if (layer->IsCursorLayer()) {
-    type_ = PlaneType::kCursor;
-    has_cursor_layer_ = true;
+    private_data_->type_ = DisplayPlanePrivateState::PlaneType::kCursor;
+    private_data_->has_cursor_layer_ = true;
   }
+
+  plane->SetInUse(true);
+  private_data_->plane_ = plane;
+  private_data_->layer_ = layer;
 }
 
 void DisplayPlaneState::CopyState(DisplayPlaneState &state) {
-  has_cursor_layer_ = state.has_cursor_layer_;
-  type_ = state.type_;
-  use_plane_scalar_ = state.use_plane_scalar_;
-  plane_ = state.plane_;
-  state_ = state.state_;
-  source_crop_ = state.source_crop_;
-  display_frame_ = state.display_frame_;
-  apply_effects_ = state.apply_effects_;
-  plane_->SetInUse(true);
+  private_data_ = state.private_data_;
   // We don't copy recycled_surface_ state as this
   // should be determined in DisplayQueue for every frame.
 }
 
 const HwcRect<int> &DisplayPlaneState::GetDisplayFrame() const {
-  return display_frame_;
+  return private_data_->display_frame_;
 }
 
 const HwcRect<float> &DisplayPlaneState::GetSourceCrop() const {
-  return source_crop_;
+  return private_data_->source_crop_;
 }
 
 void DisplayPlaneState::SetSourceCrop(const HwcRect<float> &crop) {
-  source_crop_ = crop;
+  private_data_->source_crop_ = crop;
 }
 
 void DisplayPlaneState::ResetSourceRectToDisplayFrame() {
-  source_crop_ = HwcRect<float>(display_frame_);
+  private_data_->source_crop_ = HwcRect<float>(private_data_->display_frame_);
 }
 
 void DisplayPlaneState::AddLayer(const OverlayLayer *layer) {
   const HwcRect<int> &display_frame = layer->GetDisplayFrame();
-  display_frame_.left = std::min(display_frame_.left, display_frame.left);
-  display_frame_.top = std::min(display_frame_.top, display_frame.top);
-  display_frame_.right = std::max(display_frame_.right, display_frame.right);
-  display_frame_.bottom = std::max(display_frame_.bottom, display_frame.bottom);
-
-  source_layers_.emplace_back(layer->GetZorder());
-
-  state_ = State::kRender;
-  has_cursor_layer_ = layer->IsCursorLayer();
-
-  if (source_layers_.size() == 1 && has_cursor_layer_) {
-    type_ = PlaneType::kCursor;
+  HwcRect<int> &target_display_frame = private_data_->display_frame_;
+  target_display_frame.left =
+      std::min(target_display_frame.left, display_frame.left);
+  target_display_frame.top =
+      std::min(target_display_frame.top, display_frame.top);
+  target_display_frame.right =
+      std::max(target_display_frame.right, display_frame.right);
+  target_display_frame.bottom =
+      std::max(target_display_frame.bottom, display_frame.bottom);
+
+  private_data_->source_layers_.emplace_back(layer->GetZorder());
+
+  private_data_->state_ = DisplayPlanePrivateState::State::kRender;
+  private_data_->has_cursor_layer_ = layer->IsCursorLayer();
+
+  if (private_data_->source_layers_.size() == 1 &&
+      private_data_->has_cursor_layer_) {
+    private_data_->type_ = DisplayPlanePrivateState::PlaneType::kCursor;
   } else {
     // TODO: Add checks for Video type once our
     // Media backend can support compositing more
     // than one layer together.
-    type_ = PlaneType::kNormal;
-    apply_effects_ = false;
+    private_data_->type_ = DisplayPlanePrivateState::PlaneType::kNormal;
+    private_data_->apply_effects_ = false;
   }
 
-  if (!use_plane_scalar_)
-    source_crop_ = HwcRect<float>(display_frame_);
-}
-
-// This API should be called only when Cursor layer is being
-// added, is part of layers displayed by plane or is being
-// removed in this frame. AddLayers should be used in all
-// other cases.
-void DisplayPlaneState::AddLayers(const std::vector<size_t> &source_layers,
-                                  const std::vector<OverlayLayer> &layers,
-                                  bool ignore_cursor_layer) {
-  if (ignore_cursor_layer) {
-    size_t lsize = layers.size();
-    size_t size = source_layers.size();
-    source_layers_.reserve(size);
-    has_cursor_layer_ = false;
-    bool initialized = false;
-    for (const size_t &index : source_layers) {
-      if (index >= lsize) {
-        continue;
-      }
-
-      const OverlayLayer &layer = layers.at(index);
-      const HwcRect<int> &df = layer.GetDisplayFrame();
-      if (!initialized) {
-        display_frame_ = df;
-        initialized = true;
-      } else {
-        display_frame_.left = std::min(display_frame_.left, df.left);
-        display_frame_.top = std::min(display_frame_.top, df.top);
-        display_frame_.right = std::max(display_frame_.right, df.right);
-        display_frame_.bottom = std::max(display_frame_.bottom, df.bottom);
-      }
-
-      source_layers_.emplace_back(index);
+  if (!private_data_->use_plane_scalar_)
+    private_data_->source_crop_ = HwcRect<float>(private_data_->display_frame_);
+}
+
+void DisplayPlaneState::ResetLayers(const std::vector<OverlayLayer> &layers,
+                                    bool *layers_changed) {
+  const std::vector<size_t> &current_layers = private_data_->source_layers_;
+  size_t lsize = layers.size();
+  size_t size = current_layers.size();
+  std::vector<size_t> source_layers;
+  source_layers.reserve(size);
+  private_data_->has_cursor_layer_ = false;
+  bool initialized = false;
+  HwcRect<int> target_display_frame;
+  bool removed = false;
+  for (const size_t &index : current_layers) {
+    if (index >= lsize) {
+      removed = true;
+      continue;
     }
 
-    if (!use_plane_scalar_)
-      source_crop_ = HwcRect<float>(display_frame_);
-  } else {
-    for (const int &index : source_layers) {
-      source_layers_.emplace_back(index);
+    const OverlayLayer &layer = layers.at(index);
+    if (layer.IsCursorLayer()) {
+      private_data_->has_cursor_layer_ = true;
+    }
+
+    const HwcRect<int> &df = layer.GetDisplayFrame();
+    if (!initialized) {
+      target_display_frame = df;
+      initialized = true;
+    } else {
+      target_display_frame.left = std::min(target_display_frame.left, df.left);
+      target_display_frame.top = std::min(target_display_frame.top, df.top);
+      target_display_frame.right =
+          std::max(target_display_frame.right, df.right);
+      target_display_frame.bottom =
+          std::max(target_display_frame.bottom, df.bottom);
     }
+
+    source_layers.emplace_back(index);
   }
+
+  private_data_->source_layers_.swap(source_layers);
+  private_data_->display_frame_ = target_display_frame;
+
+  if (!private_data_->use_plane_scalar_)
+    private_data_->source_crop_ = HwcRect<float>(target_display_frame);
+
+  if (private_data_->source_layers_.size() == 1 &&
+      private_data_->has_cursor_layer_) {
+    private_data_->type_ = DisplayPlanePrivateState::PlaneType::kCursor;
+  }
+
+  *layers_changed = removed;
 }
 
 void DisplayPlaneState::UpdateDisplayFrame(const HwcRect<int> &display_frame) {
-  display_frame_.left = std::min(display_frame_.left, display_frame.left);
-  display_frame_.top = std::min(display_frame_.top, display_frame.top);
-  display_frame_.right = std::max(display_frame_.right, display_frame.right);
-  display_frame_.bottom = std::max(display_frame_.bottom, display_frame.bottom);
+  HwcRect<int> &target_display_frame = private_data_->display_frame_;
+  target_display_frame.left =
+      std::min(target_display_frame.left, display_frame.left);
+  target_display_frame.top =
+      std::min(target_display_frame.top, display_frame.top);
+  target_display_frame.right =
+      std::max(target_display_frame.right, display_frame.right);
+  target_display_frame.bottom =
+      std::max(target_display_frame.bottom, display_frame.bottom);
 
-  if (!use_plane_scalar_)
-    source_crop_ = HwcRect<float>(display_frame_);
+  if (!private_data_->use_plane_scalar_)
+    private_data_->source_crop_ = HwcRect<float>(target_display_frame);
 }
 
 void DisplayPlaneState::ForceGPURendering() {
-  state_ = State::kRender;
+  private_data_->state_ = DisplayPlanePrivateState::State::kRender;
 }
 
 void DisplayPlaneState::SetOverlayLayer(const OverlayLayer *layer) {
-  layer_ = layer;
+  private_data_->layer_ = layer;
 }
 
 void DisplayPlaneState::ReUseOffScreenTarget() {
@@ -155,47 +172,28 @@ bool DisplayPlaneState::SurfaceRecycled() const {
 }
 
 const OverlayLayer *DisplayPlaneState::GetOverlayLayer() const {
-  return layer_;
+  return private_data_->layer_;
 }
 
 void DisplayPlaneState::SetOffScreenTarget(NativeSurface *target) {
-  surfaces_.emplace(surfaces_.begin(), target);
+  private_data_->layer_ = target->GetLayer();
+  target->ResetDisplayFrame(private_data_->display_frame_);
+  target->ResetSourceCrop(private_data_->source_crop_);
+  private_data_->surfaces_.emplace(private_data_->surfaces_.begin(), target);
+  recycled_surface_ = false;
 }
 
 NativeSurface *DisplayPlaneState::GetOffScreenTarget() const {
-  if (surfaces_.size() == 0) {
+  if (private_data_->surfaces_.size() == 0) {
     return NULL;
   }
 
-  return surfaces_.at(0);
+  return private_data_->surfaces_.at(0);
 }
 
-void DisplayPlaneState::TransferSurfaces(
-    const std::vector<NativeSurface *> &surfaces, bool swap_front_buffer) {
-  size_t size = surfaces.size();
-  source_layers_.reserve(size);
-  if (size < 3 || !swap_front_buffer) {
-    for (uint32_t i = 0; i < size; i++) {
-      surfaces_.emplace_back(surfaces.at(i));
-    }
-  } else {
-    // Lets make sure front buffer is now back in the list.
-    surfaces_.emplace_back(surfaces.at(1));
-    surfaces_.emplace_back(surfaces.at(2));
-    surfaces_.emplace_back(surfaces.at(0));
-  }
-
-  NativeSurface *surface = surfaces_.at(0);
-  surface->SetInUse(true);
-  SetOverlayLayer(surface->GetLayer());
-
-  if (surfaces_.size() == 3) {
-    surface_swapped_ = swap_front_buffer;
-  } else {
-    // We will be using an empty buffer, no need to
-    // swap buffer in this case.
-    surface_swapped_ = true;
-  }
+void DisplayPlaneState::SwapSurface() {
+  surface_swapped_ = false;
+  SwapSurfaceIfNeeded();
 }
 
 void DisplayPlaneState::SwapSurfaceIfNeeded() {
@@ -203,82 +201,106 @@ void DisplayPlaneState::SwapSurfaceIfNeeded() {
     return;
   }
 
-  std::vector<NativeSurface *> temp;
-  temp.reserve(surfaces_.size());
-  temp.emplace_back(surfaces_.at(1));
-  temp.emplace_back(surfaces_.at(2));
-  temp.emplace_back(surfaces_.at(0));
-  temp.swap(surfaces_);
+  size_t size = private_data_->surfaces_.size();
+
+  if (size == 3) {
+    std::vector<NativeSurface *> temp;
+    temp.reserve(size);
+    // Lets make sure front buffer is now back in the list.
+    temp.emplace_back(private_data_->surfaces_.at(1));
+    temp.emplace_back(private_data_->surfaces_.at(2));
+    temp.emplace_back(private_data_->surfaces_.at(0));
+    private_data_->surfaces_.swap(temp);
+  }
+
   surface_swapped_ = true;
-  NativeSurface *surface = surfaces_.at(0);
+  recycled_surface_ = false;
+  NativeSurface *surface = private_data_->surfaces_.at(0);
   surface->SetInUse(true);
-  SetOverlayLayer(surface->GetLayer());
+  private_data_->layer_ = surface->GetLayer();
 }
 
 const std::vector<NativeSurface *> &DisplayPlaneState::GetSurfaces() const {
-  return surfaces_;
+  return private_data_->surfaces_;
+}
+
+void DisplayPlaneState::ReleaseSurfaces(bool only_release) {
+  if (!only_release) {
+    for (NativeSurface *surface : private_data_->surfaces_) {
+      surface->SetInUse(false);
+    }
+  }
+
+  std::vector<NativeSurface *>().swap(private_data_->surfaces_);
 }
 
-void DisplayPlaneState::ReleaseSurfaces() {
-  for (NativeSurface *surface : surfaces_) {
-    surface->SetInUse(false);
+void DisplayPlaneState::RefreshSurfaces(bool clear_surface) {
+  const HwcRect<int> &target_display_frame = private_data_->display_frame_;
+  const HwcRect<float> &target_src_rect = private_data_->source_crop_;
+  bool use_scalar = private_data_->use_plane_scalar_;
+  for (NativeSurface *surface : private_data_->surfaces_) {
+    surface->ResetDisplayFrame(target_display_frame);
+    surface->ResetSourceCrop(target_src_rect);
+    surface->UpdateSurfaceDamage(target_src_rect, target_src_rect);
+    if (!surface->ClearSurface())
+      surface->SetClearSurface(clear_surface);
+    surface->GetLayer()->UsePlaneScalar(use_scalar);
   }
 
-  std::vector<NativeSurface *>().swap(surfaces_);
+  std::vector<CompositionRegion>().swap(private_data_->composition_region_);
 }
 
 DisplayPlane *DisplayPlaneState::GetDisplayPlane() const {
-  return plane_;
+  return private_data_->plane_;
 }
 
 const std::vector<size_t> &DisplayPlaneState::GetSourceLayers() const {
-  return source_layers_;
+  return private_data_->source_layers_;
 }
 
 std::vector<CompositionRegion> &DisplayPlaneState::GetCompositionRegion() {
-  return composition_region_;
+  return private_data_->composition_region_;
 }
 
-const std::vector<CompositionRegion> &DisplayPlaneState::GetCompositionRegion()
-    const {
-  return composition_region_;
+void DisplayPlaneState::ResetCompositionRegion() {
+  std::vector<CompositionRegion>().swap(private_data_->composition_region_);
 }
 
 bool DisplayPlaneState::IsCursorPlane() const {
-  return type_ == PlaneType::kCursor;
+  return private_data_->type_ == DisplayPlanePrivateState::PlaneType::kCursor;
 }
 
 bool DisplayPlaneState::HasCursorLayer() const {
-  return has_cursor_layer_;
+  return private_data_->has_cursor_layer_;
 }
 
 bool DisplayPlaneState::IsVideoPlane() const {
-  return type_ == PlaneType::kVideo;
+  return private_data_->type_ == DisplayPlanePrivateState::PlaneType::kVideo;
 }
 
 void DisplayPlaneState::SetVideoPlane() {
-  type_ = PlaneType::kVideo;
+  private_data_->type_ = DisplayPlanePrivateState::PlaneType::kVideo;
 }
 
 void DisplayPlaneState::UsePlaneScalar(bool enable) {
-  use_plane_scalar_ = enable;
+  private_data_->use_plane_scalar_ = enable;
 }
 
 bool DisplayPlaneState::IsUsingPlaneScalar() const {
-  return use_plane_scalar_;
+  return private_data_->use_plane_scalar_;
 }
 
 void DisplayPlaneState::SetApplyEffects(bool apply_effects) {
-  apply_effects_ = apply_effects;
+  private_data_->apply_effects_ = apply_effects;
   // Doesn't have any impact on planes which
   // are not meant for video purpose.
-  if (type_ != PlaneType::kVideo) {
-    apply_effects_ = false;
+  if (private_data_->type_ != DisplayPlanePrivateState::PlaneType::kVideo) {
+    private_data_->apply_effects_ = false;
   }
 }
 
 bool DisplayPlaneState::ApplyEffects() const {
-  return apply_effects_;
+  return private_data_->apply_effects_;
 }
 
 bool DisplayPlaneState::Scanout() const {
@@ -286,22 +308,22 @@ bool DisplayPlaneState::Scanout() const {
     return true;
   }
 
-  if (apply_effects_) {
+  if (private_data_->apply_effects_) {
     return false;
   }
 
-  return state_ == State::kScanout;
+  return private_data_->state_ == DisplayPlanePrivateState::State::kScanout;
 }
 
 bool DisplayPlaneState::NeedsOffScreenComposition() {
-  if (state_ == State::kRender)
+  if (private_data_->state_ == DisplayPlanePrivateState::State::kRender)
     return true;
 
   if (recycled_surface_) {
     return true;
   }
 
-  if (apply_effects_) {
+  if (private_data_->apply_effects_) {
     return true;
   }
 
index 96d1d6f..69e6a80 100644 (file)
@@ -50,13 +50,12 @@ class DisplayPlaneState {
 
   void AddLayer(const OverlayLayer *layer);
 
-  // This API should be called only when Cursor layer is being
-  // added, is part of layers displayed by plane or is being
-  // removed in this frame. AddLayers should be used in all
-  // other cases.
-  void AddLayers(const std::vector<size_t> &source_layers,
-                 const std::vector<OverlayLayer> &layers,
-                 bool ignore_cursor_layer);
+  // This API should be called only when source_layers being
+  // shown by this plane might be removed in this frame.
+  // layer_removed will be set to true in case layers
+  // associated with this plane are changed.
+  void ResetLayers(const std::vector<OverlayLayer> &layers,
+                   bool *layers_changed);
 
   // Updates Display frame rect of this plane to include
   // display_frame.
@@ -80,11 +79,9 @@ class DisplayPlaneState {
   // SetOffcreen Surface for this plane.
   void SetOffScreenTarget(NativeSurface *target);
 
-  // Moves surfaces to this plane. If swap_front_buffer
-  // is true we would swap the buffer first in surfaces to
-  // last.
-  void TransferSurfaces(const std::vector<NativeSurface *> &surfaces,
-                        bool swap_front_buffer);
+  // Put's current OffscreenSurface to back in the
+  // list.
+  void SwapSurface();
 
   const HwcRect<int> &GetDisplayFrame() const;
 
@@ -104,17 +101,27 @@ class DisplayPlaneState {
   // Marks all surfaces used by this plane as not in use
   // and removes surfaces from this plane. After this call
   // this plane will not have have any associated offscreen
-  // surfaces.
-  void ReleaseSurfaces();
+  // surfaces. If only_release is set to true than we dont
+  // change the use flag.
+  void ReleaseSurfaces(bool only_release);
+
+  // Updates all offscreen surfaces to have same display frame
+  // and source rect as displayplanestate. Also, resets
+  // composition region to null. Also updates if layer
+  // needs to use scalar or not depending on what
+  // IsUsingPlaneScalar returns.
+  void RefreshSurfaces(bool clear_surface);
 
   DisplayPlane *GetDisplayPlane() const;
 
   // Returns source layers for this plane.
   const std::vector<size_t> &GetSourceLayers() const;
 
+  // Returns composition region used by this plane.
   std::vector<CompositionRegion> &GetCompositionRegion();
 
-  const std::vector<CompositionRegion> &GetCompositionRegion() const;
+  // Resets composition region to null.
+  void ResetCompositionRegion();
 
   bool IsCursorPlane() const;
 
@@ -147,34 +154,44 @@ class DisplayPlaneState {
   bool NeedsOffScreenComposition();
 
  private:
-  enum class PlaneType : int32_t {
-    kCursor,  // Plane is compositing only Cursor.
-    kVideo,   // Plane is compositing only Media content.
-    kNormal   // Plane is compositing different types of content.
-  };
-
-  enum class State : int32_t {
-    kScanout,  // Scanout the layer directly.
-    kRender,   // Needs to render the contents to
-               // layer before scanning out.
+  class DisplayPlanePrivateState {
+   public:
+    enum class PlaneType : int32_t {
+      kCursor,  // Plane is compositing only Cursor.
+      kVideo,   // Plane is compositing only Media content.
+      kNormal   // Plane is compositing different types of content.
+    };
+
+    enum class State : int32_t {
+      kScanout,  // Scanout the layer directly.
+      kRender,   // Needs to render the contents to
+                 // layer before scanning out.
+    };
+
+    State state_ = State::kScanout;
+    DisplayPlane *plane_ = NULL;
+    const OverlayLayer *layer_ = NULL;
+    HwcRect<int> display_frame_;
+    HwcRect<float> source_crop_;
+    std::vector<size_t> source_layers_;
+    std::vector<CompositionRegion> composition_region_;
+
+    bool use_plane_scalar_ = false;
+    // Even if layer can be scanned out
+    // directly, post processing for
+    // applying video effects is needed.
+    bool apply_effects_ = false;
+    // This plane shows cursor.
+    bool has_cursor_layer_ = false;
+    // Any offscreen surfaces used by this
+    // plane.
+    std::vector<NativeSurface *> surfaces_;
+    PlaneType type_ = PlaneType::kNormal;
   };
 
-  State state_ = State::kScanout;
-  DisplayPlane *plane_ = NULL;
-  const OverlayLayer *layer_ = NULL;
-  HwcRect<int> display_frame_;
-  HwcRect<float> source_crop_;
-  std::vector<size_t> source_layers_;
-  std::vector<CompositionRegion> composition_region_;
   bool recycled_surface_ = false;
-  bool has_cursor_layer_ = false;
   bool surface_swapped_ = true;
-  bool use_plane_scalar_ = false;
-  bool apply_effects_ = false;  // Even if layer can be scanned out
-                                // directly, post processing for
-                                // applying video effects is needed.
-  std::vector<NativeSurface *> surfaces_;
-  PlaneType type_ = PlaneType::kNormal;
+  std::shared_ptr<DisplayPlanePrivateState> private_data_;
 };
 
 }  // namespace hwcomposer
index ac085c5..866121c 100644 (file)
@@ -131,19 +131,13 @@ void DisplayQueue::GetCachedLayers(const std::vector<OverlayLayer>& layers,
       continue;
     }
 
-    // We consider last_commit_failed_update_ state here. Displayplanemanager
-    // Tries to recycle free surfaces and it could have changed the rect of
-    // these surfaces during test commit. Let's make sure the rect is correct
-    // even in this case.
-    bool clear_surface = last_commit_failed_update_;
-    if (cursor_layer_removed && plane.HasCursorLayer()) {
-      clear_surface = true;
-    }
-
+    bool clear_surface = false;
     composition->emplace_back();
     DisplayPlaneState& last_plane = composition->back();
     last_plane.CopyState(plane);
-    last_plane.AddLayers(plane.GetSourceLayers(), layers, cursor_layer_removed);
+    if (cursor_layer_removed && plane.HasCursorLayer()) {
+      last_plane.ResetLayers(layers, &clear_surface);
+    }
 
     if (plane.NeedsOffScreenComposition()) {
       bool content_changed = false;
@@ -186,39 +180,24 @@ void DisplayQueue::GetCachedLayers(const std::vector<OverlayLayer>& layers,
         }
       }
 
-      if (update_rect) {
+      // If surfaces need to be cleared or rect is updated,
+      // let's make sure all surfaces are refreshed.
+      if (clear_surface || update_rect) {
         content_changed = true;
+        last_plane.RefreshSurfaces(clear_surface);
       }
 
-      // Let's make sure we swap the surface if content has changed or
-      // we need to clear the surface.
-      last_plane.TransferSurfaces(plane.GetSurfaces(),
-                                  content_changed || clear_surface);
-      const std::vector<NativeSurface*>& surfaces = last_plane.GetSurfaces();
-      size_t size = surfaces.size();
-      if (clear_surface || update_rect) {
-        content_changed = true;
-        const HwcRect<int>& current_rect = last_plane.GetDisplayFrame();
-        const HwcRect<float>& source_crop = last_plane.GetSourceCrop();
-        for (size_t i = 0; i < size; i++) {
-          surfaces.at(i)->ResetDisplayFrame(current_rect);
-          surfaces.at(i)->ResetSourceCrop(source_crop);
-        }
-      } else {
-        clear_surface = true;
+      // Let's make sure we swap the surface in case content has changed.
+      if (content_changed) {
+        last_plane.SwapSurface();
+      }
+
+      // Let's get the state from surface if it needs to be cleared.
+      if (!clear_surface) {
         NativeSurface* surface = last_plane.GetOffScreenTarget();
         if (surface) {
           clear_surface = surface->ClearSurface();
         }
-
-        if (!clear_surface) {
-          const std::vector<CompositionRegion>& comp_regions =
-              plane.GetCompositionRegion();
-          last_plane.GetCompositionRegion().assign(comp_regions.begin(),
-                                                   comp_regions.end());
-        } else {
-          content_changed = true;
-        }
       }
 
       if (content_changed) {
@@ -513,7 +492,6 @@ bool DisplayQueue::QueueUpdate(std::vector<HwcLayer*>& source_layers,
   }
 
   if (!composition_passed) {
-    IgnoreCompositionResults(current_composition_planes);
     last_commit_failed_update_ = true;
     return false;
   }
@@ -538,7 +516,6 @@ bool DisplayQueue::QueueUpdate(std::vector<HwcLayer*>& source_layers,
                        disable_ovelays, &fence);
 
   if (!composition_passed) {
-    IgnoreCompositionResults(current_composition_planes);
     last_commit_failed_update_ = true;
     return false;
   }
@@ -681,7 +658,7 @@ void DisplayQueue::ReleaseSurfacesAsNeeded(bool layers_validated) {
 
 void DisplayQueue::SetMediaEffectsState(
     bool apply_effects, const std::vector<OverlayLayer>& layers,
-    DisplayPlaneStateList& current_composition_planes) const {
+    DisplayPlaneStateList& current_composition_planes) {
   for (DisplayPlaneState& plane : current_composition_planes) {
     if (!plane.IsVideoPlane()) {
       continue;
@@ -699,7 +676,8 @@ void DisplayQueue::SetMediaEffectsState(
       // scanned out directly. In this case we will need to delete all
       // offscreen surfaces and set the right overlayer layer to the
       // plane.
-      plane.ReleaseSurfaces();
+      RecyclePreviousPlaneSurfaces();
+      plane.ReleaseSurfaces(true);
       const std::vector<size_t>& source = plane.GetSourceLayers();
       plane.SetOverlayLayer(&(layers.at(source.at(0))));
     }
@@ -777,13 +755,6 @@ void DisplayQueue::SaveOnScreenSurfaces(
   }
 }
 
-void DisplayQueue::IgnoreCompositionResults(
-    DisplayPlaneStateList& current_composition_planes) {
-  UpdateSurfaceInUse(false, current_composition_planes);
-  UpdateSurfaceInUse(true, previous_plane_state_);
-  ReleaseSurfaces();
-}
-
 void DisplayQueue::SetReleaseFenceToLayers(
     int32_t fence, std::vector<HwcLayer*>& source_layers) const {
   for (const DisplayPlaneState& plane : previous_plane_state_) {
index 917a1ad..bc6bcf3 100644 (file)
@@ -231,9 +231,9 @@ class DisplayQueue {
   void SetReleaseFenceToLayers(int32_t fence,
                                std::vector<HwcLayer*>& source_layers) const;
 
-  void SetMediaEffectsState(
-      bool apply_effects, const std::vector<OverlayLayer>& layers,
-      DisplayPlaneStateList& current_composition_planes) const;
+  void SetMediaEffectsState(bool apply_effects,
+                            const std::vector<OverlayLayer>& layers,
+                            DisplayPlaneStateList& current_composition_planes);
 
   void UpdateSurfaceInUse(bool in_use,
                           DisplayPlaneStateList& current_composition_planes);
@@ -241,9 +241,6 @@ class DisplayQueue {
   void SaveOnScreenSurfaces(DisplayPlaneStateList& current_composition_planes);
   void UpdateOnScreenSurfaces();
 
-  void IgnoreCompositionResults(
-      DisplayPlaneStateList& current_composition_planes);
-
   void ReleaseSurfaces();
   void ReleaseSurfacesAsNeeded(bool layers_validated);