sde: Add support for video playback with SDE.

1. Set the video and secure flag of the layer buffer flag properly.
2. Normalize the crop rectangle of the layer to even values.
3. Handle one pixel downscale usecase, as MDP hardware dont support it.
4. Set the hint flag for each layer qualified for SDE compoisition to
   notify surfaceflinger to clear the layers destination region in FB.

Change-Id: I20239e79db3ea90e0d4fdcb6953b8b70d703b4fc
diff --git a/displayengine/libs/core/hw_framebuffer.cpp b/displayengine/libs/core/hw_framebuffer.cpp
index 93bec4d..3c57e1e 100644
--- a/displayengine/libs/core/hw_framebuffer.cpp
+++ b/displayengine/libs/core/hw_framebuffer.cpp
@@ -639,10 +639,10 @@
 }
 
 void HWFrameBuffer::SetRect(const LayerRect &source, mdp_rect *target) {
-  target->x = INT(ceilf(source.left));
-  target->y = INT(ceilf(source.top));
-  target->w = INT(floorf(source.right)) - target->x;
-  target->h = INT(floorf(source.bottom)) - target->y;
+  target->x = UINT32(source.left);
+  target->y = UINT32(source.top);
+  target->w = UINT32(source.right) - target->x;
+  target->h = UINT32(source.bottom) - target->y;
 }
 
 void* HWFrameBuffer::DisplayEventThread(void *context) {
diff --git a/displayengine/libs/core/hw_interface.h b/displayengine/libs/core/hw_interface.h
index 7309c32..8af461e 100644
--- a/displayengine/libs/core/hw_interface.h
+++ b/displayengine/libs/core/hw_interface.h
@@ -93,7 +93,7 @@
 };
 
 struct HWRotateInfo {
-  uint32_t pipe_id;
+  int pipe_id;
   LayerRect src_roi;
   LayerRect dst_roi;
   HWBlockType writeback_id;
@@ -107,7 +107,7 @@
 };
 
 struct HWPipeInfo {
-  uint32_t pipe_id;
+  int pipe_id;
   LayerRect src_roi;
   LayerRect dst_roi;
   uint8_t decimation;
diff --git a/displayengine/libs/core/res_config.cpp b/displayengine/libs/core/res_config.cpp
index d093ab2..a915b7d 100644
--- a/displayengine/libs/core/res_config.cpp
+++ b/displayengine/libs/core/res_config.cpp
@@ -185,6 +185,8 @@
       return kErrorNotSupported;
 
     struct HWLayerConfig *layer_config = &hw_layers->config[i];
+    HWPipeInfo &left_pipe = layer_config->left_pipe;
+    HWPipeInfo &right_pipe = layer_config->right_pipe;
     // config rotator first
     for (uint32_t j = 0; j < kMaxRotatePerLayer; j++) {
       layer_config->rotates[j].Reset();
@@ -211,6 +213,20 @@
     if (error != kErrorNone)
       break;
 
+    // 1. Normalize Video layer source rectangle to multiple of 2, as MDP hardware require source
+    //    rectangle of video layer to be even.
+    // 2. Normalize source and destination rect of a layer to multiple of 1.
+    uint32_t factor = (1 << layer.input_buffer->flags.video);
+    if (left_pipe.pipe_id == kPipeIdNeedsAssignment) {
+      NormalizeRect(factor, &left_pipe.src_roi);
+      NormalizeRect(1, &left_pipe.dst_roi);
+    }
+
+    if (right_pipe.pipe_id == kPipeIdNeedsAssignment) {
+      NormalizeRect(factor, &right_pipe.src_roi);
+      NormalizeRect(1, &right_pipe.dst_roi);
+    }
+
     DLOGV_IF(kTagResources, "layer = %d, left pipe_id = %x",
              i, layer_config->left_pipe.pipe_id);
     LogRectVerbose("input layer src_rect", layer.src_rect);
@@ -248,6 +264,12 @@
     return kErrorNotSupported;
   }
 
+  if (((crop_width - dst_width) == 1) || ((crop_height - dst_height) == 1)) {
+    DLOGV_IF(kTagResources, "One pixel downscaling detected crop_w %d, dst_w %d, crop_h %d, " \
+             "dst_h %d", crop_width, dst_width, crop_height, dst_height);
+    return kErrorNotSupported;
+  }
+
   float scale_x = crop_width / dst_width;
   float scale_y = crop_height / dst_height;
 
@@ -476,4 +498,16 @@
            prefix, roi.left, roi.top, roi.right, roi.bottom);
 }
 
+void ResManager::NormalizeRect(const uint32_t &factor, LayerRect *rect) {
+  uint32_t left = UINT32(ceilf(rect->left));
+  uint32_t top = UINT32(ceilf(rect->top));
+  uint32_t right = UINT32(floorf(rect->right));
+  uint32_t bottom = UINT32(floorf(rect->bottom));
+
+  rect->left = FLOAT(CeilToMultipleOf(left, factor));
+  rect->top = FLOAT(CeilToMultipleOf(top, factor));
+  rect->right = FLOAT(FloorToMultipleOf(right, factor));
+  rect->bottom = FLOAT(FloorToMultipleOf(bottom, factor));
+}
+
 }  // namespace sde
diff --git a/displayengine/libs/core/res_manager.h b/displayengine/libs/core/res_manager.h
index 5b63299..28bae1c 100644
--- a/displayengine/libs/core/res_manager.h
+++ b/displayengine/libs/core/res_manager.h
@@ -183,6 +183,7 @@
                               const uint32_t roate_cnt);
   void AssignRotator(HWRotateInfo *rotate, uint32_t *rotate_cnt);
   void ClearRotator(DisplayResourceContext *display_resource_ctx);
+  void NormalizeRect(const uint32_t &factor, LayerRect *rect);
 
   template <class T>
   inline void Swap(T &a, T &b) {
@@ -191,6 +192,17 @@
     b = c;
   }
 
+  // factor value should be in powers of 2(eg: 1, 2, 4, 8)
+  template <class T1, class T2>
+  inline T1 FloorToMultipleOf(const T1 &value, const T2 &factor) {
+    return (T1)(value & (~(factor - 1)));
+  }
+
+  template <class T1, class T2>
+  inline T1 CeilToMultipleOf(const T1 &value, const T2 &factor) {
+    return (T1)((value + (factor - 1)) & (~(factor - 1)));
+  }
+
   Locker locker_;
   HWResourceInfo hw_res_info_;
   HWBlockContext hw_block_ctx_[kHWBlockMax];
diff --git a/displayengine/libs/hwc/hwc_display.cpp b/displayengine/libs/hwc/hwc_display.cpp
index 771c07f..bf54a8a 100644
--- a/displayengine/libs/hwc/hwc_display.cpp
+++ b/displayengine/libs/hwc/hwc_display.cpp
@@ -302,9 +302,11 @@
       layer_buffer->height = pvt_handle->height;
       if (pvt_handle->bufferType == BUFFER_TYPE_VIDEO) {
         layer_stack_.flags.video_present = true;
+        layer_buffer->flags.video = true;
       }
       if (pvt_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
         layer_stack_.flags.secure_present = true;
+        layer_buffer->flags.secure = true;
       }
     }
 
@@ -348,6 +350,10 @@
     Layer &layer = layer_stack_.layers[i];
     LayerComposition composition = layer.composition;
 
+    if (composition == kCompositionSDE) {
+      hwc_layer.hints |= HWC_HINT_CLEAR_FB;
+    }
+
     // If current layer does not need frame buffer redraw, then mark it as HWC_OVERLAY
     if (!needs_fb_refresh && (composition != kCompositionGPUTarget)) {
       composition = kCompositionSDE;