Merge "hwc: Add support to disable animation on WFD(GPU)"
diff --git a/composer/gl_layer_stitch_impl.cpp b/composer/gl_layer_stitch_impl.cpp
index 709f190..e37ce62 100644
--- a/composer/gl_layer_stitch_impl.cpp
+++ b/composer/gl_layer_stitch_impl.cpp
@@ -208,10 +208,10 @@
   DTRACE_SCOPED();
   // Enable scissor test.
   GL(glEnable(GL_SCISSOR_TEST));
-  GL(glClearColor(0, 0, 0, 0));
-  GL(glClear(GL_COLOR_BUFFER_BIT));
   GL(glScissor(scissor_rect.left, scissor_rect.top, scissor_rect.right - scissor_rect.left,
                scissor_rect.bottom - scissor_rect.top));
+  GL(glClearColor(0, 0, 0, 0));
+  GL(glClear(GL_COLOR_BUFFER_BIT));
 }
 
 void GLLayerStitchImpl::InitContext() {
diff --git a/composer/hwc_display.h b/composer/hwc_display.h
index e6c1c8d..13d713a 100644
--- a/composer/hwc_display.h
+++ b/composer/hwc_display.h
@@ -535,6 +535,7 @@
   LayerRect window_rect_ = {};
   bool windowed_display_ = false;
   uint32_t active_refresh_rate_ = 0;
+  bool animating_ = false;
 
  private:
   void DumpInputBuffers(void);
@@ -546,7 +547,6 @@
   DisplayClass display_class_;
   uint32_t geometry_changes_ = GeometryChanges::kNone;
   uint32_t geometry_changes_on_doze_suspend_ = GeometryChanges::kNone;
-  bool animating_ = false;
   int null_display_mode_ = 0;
   DisplayValidateState validate_state_ = kNormalValidate;
   bool fast_path_enabled_ = true;
diff --git a/composer/hwc_display_virtual_gpu.cpp b/composer/hwc_display_virtual_gpu.cpp
index 8a249cf..854e442 100644
--- a/composer/hwc_display_virtual_gpu.cpp
+++ b/composer/hwc_display_virtual_gpu.cpp
@@ -43,6 +43,8 @@
   // Calls into SDM need to be dropped. Create Null Display interface.
   display_intf_ = new DisplayNull();
 
+  disable_animation_ = Debug::IsExtAnimDisabled();
+
   return HWCDisplayVirtual::Init();
 }
 
@@ -78,7 +80,7 @@
   layer_requests_.clear();
 
   // Mark all layers to GPU if there is no need to bypass.
-  bool needs_gpu_bypass = NeedsGPUBypass();
+  bool needs_gpu_bypass = NeedsGPUBypass() || FreezeScreen();
   for (auto hwc_layer : layer_set_) {
     auto layer = hwc_layer->GetSDMLayer();
     layer->composition = needs_gpu_bypass ? kCompositionSDE : kCompositionGPU;
@@ -220,5 +222,25 @@
   }
 }
 
+bool HWCDisplayVirtualGPU::FreezeScreen() {
+  if (!disable_animation_) {
+    return false;
+  }
+
+  bool freeze_screen = false;
+  if (animating_ && !animation_in_progress_) {
+    // Start of animation. GPU comp is needed.
+    animation_in_progress_ = true;
+  } else if (!animating_ && animation_in_progress_) {
+    // End of animation. Start composing.
+    animation_in_progress_ = false;
+  } else if (animating_ && animation_in_progress_) {
+    // Animation in progress...
+    freeze_screen = true;
+  }
+
+  return freeze_screen;
+}
+
 }  // namespace sdm
 
diff --git a/composer/hwc_display_virtual_gpu.h b/composer/hwc_display_virtual_gpu.h
index a39d168..b3ff0b8 100644
--- a/composer/hwc_display_virtual_gpu.h
+++ b/composer/hwc_display_virtual_gpu.h
@@ -68,6 +68,7 @@
   virtual HWC2::Error Validate(uint32_t *out_num_types, uint32_t *out_num_requests);
   virtual HWC2::Error Present(shared_ptr<Fence> *out_retire_fence);
   virtual HWC2::Error SetOutputBuffer(buffer_handle_t buf, shared_ptr<Fence> release_fence);
+  virtual bool FreezeScreen();
 
  private:
   // SyncTask methods.
@@ -76,6 +77,9 @@
 
   SyncTask<ColorConvertTaskCode> color_convert_task_;
   GLColorConvert *gl_color_convert_;
+
+  bool disable_animation_ = false;
+  bool animation_in_progress_ = false;
 };
 
 }  // namespace sdm