Merge "sdm: Fix incorrect permission on hw_info.cpp" into display.lnx.3.0-dev
diff --git a/sdm/include/private/color_params.h b/sdm/include/private/color_params.h
index e7f779a..9eb5d79 100644
--- a/sdm/include/private/color_params.h
+++ b/sdm/include/private/color_params.h
@@ -48,6 +48,8 @@
   kEnterQDCMMode = BITMAP(3),
   kExitQDCMMode = BITMAP(4),
   kSetPanelBrightness = BITMAP(5),
+  kEnableFrameCapture = BITMAP(6),
+  kDisableFrameCapture = BITMAP(7),
   kNoAction = BITMAP(31),
 };
 
@@ -141,6 +143,21 @@
     return ret;
   }
 
+  DisplayError CreatePayloadBytes(uint8_t *output, uint32_t size_in_bytes) {
+    DisplayError ret = kErrorNone;
+
+    payload = new uint8_t[size_in_bytes]();
+    if (!payload) {
+      ret = kErrorMemory;
+      output = NULL;
+    } else {
+      this->size = size_in_bytes;
+      output = payload;
+      own_payload = true;
+    }
+    return ret;
+  }
+
   inline void DestroyPayload() {
     if (payload && own_payload) {
       delete[] payload;
@@ -153,6 +170,34 @@
   }
 };
 
+struct PPRectInfo {
+  uint32_t width;
+  uint32_t height;
+  int32_t x;
+  int32_t y;
+};
+
+typedef enum {
+  PP_PIXEL_FORMAT_NONE = 0,
+  PP_PIXEL_FORMAT_RGB_888,
+  PP_PIXEL_FORMAT_RGB_2101010,
+  PP_PIXEL_FORMAT_MAX,
+  PP_PIXEL_FORMAT_FORCE32BIT = 0x7FFFFFFF,
+} PPPixelFormats;
+
+struct PPFrameCaptureInputParams {
+  PPRectInfo rect;
+  PPPixelFormats out_pix_format;
+  uint32_t flags;
+};
+
+struct PPFrameCaptureData {
+  PPFrameCaptureInputParams input_params;
+  uint8_t *buffer;
+  uint32_t buffer_stride;
+  uint32_t buffer_size;
+};
+
 struct SDEGamutCfg {
   static const int kGamutTableNum = 4;
   static const int kGamutScaleoffTableNum = 3;
@@ -413,7 +458,7 @@
   }
 
   inline Locker &GetLocker(void) { return locker_; }
-
+  inline PPFrameCaptureData *GetFrameCaptureData(void) { return &frame_capture_data; }
   // Once all features are consumed, destroy/release all TFeatureInfo<T> on the list,
   // then clear dirty_ flag and return the lock to the TFeatureInfo<T> producer.
   void Reset();
@@ -429,6 +474,7 @@
   Locker locker_;
   PPFeatureInfo *feature_[kMaxNumPPFeatures];  // reference to TFeatureInfo<T>.
   uint32_t next_idx_ = 0;
+  PPFrameCaptureData frame_capture_data;
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/hwc/hwc_color_manager.cpp b/sdm/libs/hwc/hwc_color_manager.cpp
index 15270d5..27115b5 100644
--- a/sdm/libs/hwc/hwc_color_manager.cpp
+++ b/sdm/libs/hwc/hwc_color_manager.cpp
@@ -348,6 +348,82 @@
   return ret;
 }
 
+int HWCColorManager::SetFrameCapture(void *params, bool enable, HWCDisplay *hwc_display) {
+  SCOPE_LOCK(locker_);
+  int ret = 0;
+
+  PPFrameCaptureData *frame_capture_data = reinterpret_cast<PPFrameCaptureData*>(params);
+
+  if (enable) {
+    std::memset(&buffer_info, 0x00, sizeof(buffer_info));
+    hwc_display->GetFrameBufferResolution(&buffer_info.buffer_config.width,
+                                          &buffer_info.buffer_config.height);
+    if (frame_capture_data->input_params.out_pix_format == PP_PIXEL_FORMAT_RGB_888) {
+      buffer_info.buffer_config.format = kFormatRGB888;
+    } else if (frame_capture_data->input_params.out_pix_format == PP_PIXEL_FORMAT_RGB_2101010) {
+      // TODO(user): Complete the implementation
+      DLOGE("RGB 10-bit format NOT supported");
+      return -EFAULT;
+    } else {
+      DLOGE("Pixel-format: %d NOT support.", frame_capture_data->input_params.out_pix_format);
+      return -EFAULT;
+    }
+
+    buffer_info.buffer_config.buffer_count = 1;
+    buffer_info.alloc_buffer_info.fd = -1;
+    buffer_info.alloc_buffer_info.stride = 0;
+    buffer_info.alloc_buffer_info.size = 0;
+
+    buffer_allocator_ = new HWCBufferAllocator();
+    if (buffer_allocator_ == NULL) {
+      DLOGE("Memory allocation for buffer_allocator_ FAILED");
+      return -ENOMEM;
+    }
+
+    ret = buffer_allocator_->AllocateBuffer(&buffer_info);
+    if (ret != 0) {
+      DLOGE("Buffer allocation failed. ret: %d", ret);
+      delete[] buffer_allocator_;
+      buffer_allocator_ = NULL;
+      return -ENOMEM;
+    } else {
+      void *buffer = mmap(NULL, buffer_info.alloc_buffer_info.size,
+                          PROT_READ|PROT_WRITE,
+                          MAP_SHARED, buffer_info.alloc_buffer_info.fd, 0);
+
+      if (buffer == MAP_FAILED) {
+        DLOGE("mmap failed. err = %d", errno);
+        frame_capture_data->buffer = NULL;
+        ret = buffer_allocator_->FreeBuffer(&buffer_info);
+        delete[] buffer_allocator_;
+        buffer_allocator_ = NULL;
+        return -EFAULT;
+      } else {
+        frame_capture_data->buffer = reinterpret_cast<uint8_t *>(buffer);
+        frame_capture_data->buffer_stride = buffer_info.alloc_buffer_info.stride;
+        frame_capture_data->buffer_size = buffer_info.alloc_buffer_info.size;
+      }
+      // TODO(user): Call HWC interface to provide the buffer and rectangle information
+    }
+  } else {
+    if (frame_capture_data->buffer != NULL) {
+      if (munmap(frame_capture_data->buffer, buffer_info.alloc_buffer_info.size) != 0) {
+        DLOGE("munmap failed. err = %d", errno);
+      }
+    }
+    if (buffer_allocator_ != NULL) {
+      std::memset(frame_capture_data, 0x00, sizeof(PPFrameCaptureData));
+      ret = buffer_allocator_->FreeBuffer(&buffer_info);
+      if (ret != 0) {
+        DLOGE("FreeBuffer failed. ret = %d", ret);
+      }
+      delete[] buffer_allocator_;
+      buffer_allocator_ = NULL;
+    }
+  }
+  return ret;
+}
+
 const HWCQDCMModeManager::ActiveFeatureCMD HWCQDCMModeManager::kActiveFeatureCMD[] = {
     HWCQDCMModeManager::ActiveFeatureCMD("cabl:on", "cabl:off", "cabl:status", "running"),
     HWCQDCMModeManager::ActiveFeatureCMD("ad:on", "ad:off", "ad:query:status", "running"),
diff --git a/sdm/libs/hwc/hwc_color_manager.h b/sdm/libs/hwc/hwc_color_manager.h
index cb80b48..2541e21 100644
--- a/sdm/libs/hwc/hwc_color_manager.h
+++ b/sdm/libs/hwc/hwc_color_manager.h
@@ -117,6 +117,7 @@
   int SetSolidFill(const void *params, bool enable, HWCDisplay *hwc_display);
   bool SolidFillLayersPrepare(hwc_display_contents_1_t **displays, HWCDisplay *hwc_display);
   bool SolidFillLayersSet(hwc_display_contents_1_t **displays, HWCDisplay *hwc_display);
+  int SetFrameCapture(void *params, bool enable, HWCDisplay *hwc_display);
 
  protected:
   int CreateSolidFillLayers(HWCDisplay *hwc_display);
@@ -134,6 +135,8 @@
   bool solid_fill_enable_ = false;
   PPColorFillParams solid_fill_params_;
   hwc_display_contents_1_t *solid_fill_layers_ = NULL;
+  HWCBufferAllocator *buffer_allocator_ = NULL;
+  BufferInfo buffer_info;
   Locker locker_;
 };
 
diff --git a/sdm/libs/hwc/hwc_session.cpp b/sdm/libs/hwc/hwc_session.cpp
index b8891bd..129b605 100644
--- a/sdm/libs/hwc/hwc_session.cpp
+++ b/sdm/libs/hwc/hwc_session.cpp
@@ -1168,6 +1168,15 @@
       if (HWC_DISPLAY_PRIMARY == display_id)
         ret = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(*brightness_value);
       break;
+    case kEnableFrameCapture:
+      ret = color_mgr_->SetFrameCapture(pending_action.params,
+                                        true, hwc_display_[HWC_DISPLAY_PRIMARY]);
+      hwc_procs_->invalidate(hwc_procs_);
+      break;
+    case kDisableFrameCapture:
+      ret = color_mgr_->SetFrameCapture(pending_action.params,
+                                        false, hwc_display_[HWC_DISPLAY_PRIMARY]);
+      break;
     case kNoAction:
       break;
     default: