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