Merge "hwc: Add error check for secure layer handling"
diff --git a/libcopybit/copybit.cpp b/libcopybit/copybit.cpp
index ff7dc4e..b37eee0 100644
--- a/libcopybit/copybit.cpp
+++ b/libcopybit/copybit.cpp
@@ -556,6 +556,51 @@
     return 0;
 }
 
+/** Fill the rect on dst with RGBA color **/
+static int fill_color(struct copybit_device_t *dev,
+                      struct copybit_image_t const *dst,
+                      struct copybit_rect_t const *rect,
+                      uint32_t color)
+{
+    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+    if (!ctx) {
+        ALOGE("%s: Invalid copybit context", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) {
+        ALOGE("%s: Invalid DST w=%d h=%d", __FUNCTION__, dst->w, dst->h);
+        return -EINVAL;
+    }
+
+    if (rect->l < 0 || (uint32_t)(rect->r - rect->l) > dst->w ||
+        rect->t < 0 || (uint32_t)(rect->b - rect->t) > dst->h) {
+        ALOGE("%s: Invalid destination rect: l=%d t=%d r=%d b=%d",
+                __FUNCTION__, rect->l, rect->t, rect->r, rect->b);
+        return -EINVAL;
+    }
+
+    struct blitReq* list = &ctx->list;
+    mdp_blit_req* req = &list->req[list->count++];
+    set_infos(ctx, req, MDP_SOLID_FILL);
+    set_image(&req->src, dst);
+    set_image(&req->dst, dst);
+
+    req->dst_rect.x = rect->l;
+    req->dst_rect.y = rect->t;
+    req->dst_rect.w = rect->r - rect->l;
+    req->dst_rect.h = rect->b - rect->t;
+    req->src_rect = req->dst_rect;
+
+    req->const_color.r = (uint32_t)((color >> 0) & 0xff);
+    req->const_color.g = (uint32_t)((color >> 8) & 0xff);
+    req->const_color.b = (uint32_t)((color >> 16) & 0xff);
+    req->const_color.alpha = (uint32_t)((color >> 24) & 0xff);
+
+    int status = msm_copybit(ctx, list);
+    return status;
+}
+
 /*****************************************************************************/
 
 /** Close the copybit device */
@@ -606,6 +651,7 @@
     ctx->device.set_sync = set_sync_copybit;
     ctx->device.stretch = stretch_copybit;
     ctx->device.finish = finish_copybit;
+    ctx->device.fill_color = fill_color;
     ctx->device.flush_get_fence = flush_get_fence;
     ctx->mAlpha = MDP_ALPHA_NOP;
     ctx->mFlags = 0;
diff --git a/libcopybit/copybit.h b/libcopybit/copybit.h
index 13d78b5..dbb89f0 100644
--- a/libcopybit/copybit.h
+++ b/libcopybit/copybit.h
@@ -242,6 +242,21 @@
                    struct copybit_rect_t const *src_rect,
                    struct copybit_region_t const *region);
 
+    /**
+     * Fill the rect on dst with RGBA color
+     *
+     * @param dev from open
+     * @param dst is destination image
+     * @param rect is destination rectangle
+     * @param color is RGBA color to fill
+     *
+     * @return 0 if successful
+     */
+    int (*fill_color)(struct copybit_device_t *dev,
+                      struct copybit_image_t const *dst,
+                      struct copybit_rect_t const *rect,
+                      uint32_t color);
+
   /**
     * Execute the completion of the copybit draw operation.
     *
diff --git a/libcopybit/copybit_c2d.cpp b/libcopybit/copybit_c2d.cpp
index 914bed7..231bb2d 100644
--- a/libcopybit/copybit_c2d.cpp
+++ b/libcopybit/copybit_c2d.cpp
@@ -1428,6 +1428,16 @@
     return status;
 }
 
+/** Fill the rect on dst with RGBA color **/
+static int fill_color(struct copybit_device_t *dev,
+                      struct copybit_image_t const *dst,
+                      struct copybit_rect_t const *rect,
+                      uint32_t color)
+{
+    // TODO: Implement once c2d driver supports color fill
+    return -EINVAL;
+}
+
 /*****************************************************************************/
 
 static void clean_up(copybit_context_t* ctx)
@@ -1561,6 +1571,7 @@
     ctx->device.finish = finish_copybit;
     ctx->device.flush_get_fence = flush_get_fence_copybit;
     ctx->device.clear = clear_copybit;
+    ctx->device.fill_color = fill_color;
 
     /* Create RGB Surface */
     surfDefinition.buffer = (void*)0xdddddddd;
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index b6952d3..d86be3e 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -484,6 +484,9 @@
     case HWC_FORMAT_RB_SWAP:
         value[0] = 1;
         break;
+    case HWC_COLOR_FILL:
+        value[0] = 1;
+        break;
     default:
         return -EINVAL;
     }
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index 2068732..999fdb2 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -338,6 +338,9 @@
 
     private_handle_t *hnd = (private_handle_t *)layer->handle;
     if(!hnd) {
+        if (layer->flags & HWC_COLOR_FILL) { // Color layer
+            return fillColorUsingCopybit(layer, renderBuffer);
+        }
         ALOGE("%s: invalid handle", __FUNCTION__);
         return -1;
     }
@@ -586,6 +589,44 @@
     return err;
 }
 
+int CopyBit::fillColorUsingCopybit(hwc_layer_1_t *layer,
+                          private_handle_t *renderBuffer)
+{
+    if (!renderBuffer) {
+        ALOGE("%s: Render Buffer is NULL", __FUNCTION__);
+        return -1;
+    }
+
+    // Copybit dst
+    copybit_image_t dst;
+    dst.w = ALIGN(renderBuffer->width, 32);
+    dst.h = renderBuffer->height;
+    dst.format = renderBuffer->format;
+    dst.base = (void *)renderBuffer->base;
+    dst.handle = (native_handle_t *)renderBuffer;
+
+    // Copybit dst rect
+    hwc_rect_t displayFrame = layer->displayFrame;
+    copybit_rect_t dstRect = {displayFrame.left, displayFrame.top,
+                              displayFrame.right, displayFrame.bottom};
+
+    uint32_t color = layer->transform;
+    copybit_device_t *copybit = mEngine;
+    copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_WIDTH,
+                           renderBuffer->width);
+    copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_HEIGHT,
+                           renderBuffer->height);
+    copybit->set_parameter(copybit, COPYBIT_DITHER,
+                           (dst.format == HAL_PIXEL_FORMAT_RGB_565) ?
+                           COPYBIT_ENABLE : COPYBIT_DISABLE);
+    copybit->set_parameter(copybit, COPYBIT_BLEND_MODE, layer->blending);
+    copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, layer->planeAlpha);
+    copybit->set_parameter(copybit, COPYBIT_BLIT_TO_FRAMEBUFFER,COPYBIT_ENABLE);
+    int res = copybit->fill_color(copybit, &dst, &dstRect, color);
+    copybit->set_parameter(copybit,COPYBIT_BLIT_TO_FRAMEBUFFER,COPYBIT_DISABLE);
+    return res;
+}
+
 void CopyBit::getLayerResolution(const hwc_layer_1_t* layer,
                                  unsigned int& width, unsigned int& height)
 {
diff --git a/libhwcomposer/hwc_copybit.h b/libhwcomposer/hwc_copybit.h
index 03fe950..10863f3 100644
--- a/libhwcomposer/hwc_copybit.h
+++ b/libhwcomposer/hwc_copybit.h
@@ -50,6 +50,8 @@
     // Helper functions for copybit composition
     int  drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
                           private_handle_t *renderBuffer, int dpy, bool isFG);
+    int fillColorUsingCopybit(hwc_layer_1_t *layer,
+                          private_handle_t *renderBuffer);
     bool canUseCopybitForYUV (hwc_context_t *ctx);
     bool canUseCopybitForRGB (hwc_context_t *ctx,
                                      hwc_display_contents_1_t *list, int dpy);
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 77017bf..3dc327f 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -131,6 +131,7 @@
 
 // HAL specific features
 enum {
+    HWC_COLOR_FILL = 0x00000008,
     HWC_FORMAT_RB_SWAP = 0x00000040,
 };
 
diff --git a/libmemtrack/memtrack_msm.h b/libmemtrack/memtrack_msm.h
index ff2db3c..74aa576 100644
--- a/libmemtrack/memtrack_msm.h
+++ b/libmemtrack/memtrack_msm.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef _MEMTRACK_QCOM_H_
-#define _MEMTRACK_QCOM_H_
+#ifndef _MEMTRACK_MSM_H_
+#define _MEMTRACK_MSM_H_
 
 int kgsl_memtrack_get_memory(pid_t pid, enum memtrack_type type,
                              struct memtrack_record *records,