Merge "hwc: Add support for clearing with c2d"
diff --git a/libcopybit/copybit.h b/libcopybit/copybit.h
index d57b84d..07593f3 100644
--- a/libcopybit/copybit.h
+++ b/libcopybit/copybit.h
@@ -250,6 +250,11 @@
     * @return 0 if successful
     */
   int (*flush_get_fence)(struct copybit_device_t *dev, int* fd);
+
+  /* Clears the buffer
+   */
+  int (*clear)(struct copybit_device_t *dev, struct copybit_image_t const *buf,
+               struct copybit_rect_t *rect);
 };
 
 
diff --git a/libcopybit/copybit_c2d.cpp b/libcopybit/copybit_c2d.cpp
index c186242..dfbbf76 100644
--- a/libcopybit/copybit_c2d.cpp
+++ b/libcopybit/copybit_c2d.cpp
@@ -90,6 +90,10 @@
 /* create a fence fd for the timestamp */
 C2D_STATUS (*LINK_c2dCreateFenceFD) ( uint32 target_id, c2d_ts_handle timestamp,
                                                             int32 *fd);
+
+C2D_STATUS (*LINK_c2dFillSurface) ( uint32 surface_id, uint32 fill_color,
+                                    C2D_RECT * fill_rect);
+
 /******************************************************************************/
 
 #if defined(COPYBIT_Z180)
@@ -674,6 +678,28 @@
     return status;
 }
 
+static int clear_copybit(struct copybit_device_t *dev,
+                         struct copybit_image_t const *buf,
+                         struct copybit_rect_t *rect)
+{
+    int ret = 0;
+    int flags = FLAGS_PREMULTIPLIED_ALPHA;
+    int mapped_dst_idx = -1;
+    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+    C2D_RECT c2drect = {rect->l, rect->t, rect->r - rect->l, rect->b - rect->t};
+    ret = set_image(ctx, ctx->dst[RGB_SURFACE], buf,
+                       (eC2DFlags)flags, mapped_dst_idx);
+    if(ret) {
+        ALOGE("%s: set_image error", __FUNCTION__);
+        unmap_gpuaddr(ctx, mapped_dst_idx);
+        return COPYBIT_FAILURE;
+    }
+
+    ret = LINK_c2dFillSurface(ctx->dst[RGB_SURFACE], 0x0, &c2drect);
+    return ret;
+}
+
+
 /** setup rectangles */
 static void set_rects(struct copybit_context_t *ctx,
                       C2D_OBJECT *c2dObject,
@@ -1476,11 +1502,14 @@
                                            "c2dGetDriverCapabilities");
     *(void **)&LINK_c2dCreateFenceFD = ::dlsym(ctx->libc2d2,
                                            "c2dCreateFenceFD");
+    *(void **)&LINK_c2dFillSurface = ::dlsym(ctx->libc2d2,
+                                           "c2dFillSurface");
 
     if (!LINK_c2dCreateSurface || !LINK_c2dUpdateSurface || !LINK_c2dReadSurface
         || !LINK_c2dDraw || !LINK_c2dFlush || !LINK_c2dWaitTimestamp ||
         !LINK_c2dFinish  || !LINK_c2dDestroySurface ||
-        !LINK_c2dGetDriverCapabilities || !LINK_c2dCreateFenceFD) {
+        !LINK_c2dGetDriverCapabilities || !LINK_c2dCreateFenceFD ||
+        !LINK_c2dFillSurface) {
         ALOGE("%s: dlsym ERROR", __FUNCTION__);
         clean_up(ctx);
         status = COPYBIT_FAILURE;
@@ -1498,6 +1527,7 @@
     ctx->device.stretch = stretch_copybit;
     ctx->device.finish = finish_copybit;
     ctx->device.flush_get_fence = flush_get_fence_copybit;
+    ctx->device.clear = clear_copybit;
 
     /* Create RGB Surface */
     surfDefinition.buffer = (void*)0xdddddddd;
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index 4549dcf..aa05aa9 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -201,6 +201,25 @@
     return true;
 }
 
+int CopyBit::clear (private_handle_t* hnd, hwc_rect_t& rect)
+{
+    int ret = 0;
+    copybit_rect_t clear_rect = {rect.left, rect.top,
+        rect.right,
+        rect.bottom};
+
+    copybit_image_t buf;
+    buf.w = ALIGN(hnd->width,32);
+    buf.h = hnd->height;
+    buf.format = hnd->format;
+    buf.base = (void *)hnd->base;
+    buf.handle = (native_handle_t *)hnd;
+
+    copybit_device_t *copybit = mEngine;
+    ret = copybit->clear(copybit, &buf, &clear_rect);
+    return ret;
+}
+
 bool CopyBit::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list,
                                                         int dpy, int32_t *fd) {
     // draw layers marked for COPYBIT
@@ -224,6 +243,12 @@
         close(mRelFd[0]);
         mRelFd[0] = -1;
     }
+
+    //Clear the visible region on the render buffer
+    //XXX: Do this only when needed.
+    hwc_rect_t clearRegion;
+    getNonWormholeRegion(list, clearRegion);
+    clear(renderBuffer, clearRegion);
     // numAppLayers-1, as we iterate from 0th layer index with HWC_COPYBIT flag
     for (int i = 0; i <= (ctx->listStats[dpy].numAppLayers-1); i++) {
         hwc_layer_1_t *layer = &list->hwLayers[i];
diff --git a/libhwcomposer/hwc_copybit.h b/libhwcomposer/hwc_copybit.h
index 45d254a..bc3f263 100644
--- a/libhwcomposer/hwc_copybit.h
+++ b/libhwcomposer/hwc_copybit.h
@@ -70,6 +70,8 @@
 
     void freeRenderBuffers();
 
+    int clear (private_handle_t* hnd, hwc_rect_t& rect);
+
     private_handle_t* mRenderBuffer[NUM_RENDER_BUFFERS];
 
     // Index of the current intermediate render buffer