hwc/copybit: Add Color layer support in MDP Copybit composition.
1. Color layer has a destination rectangle, RGBA color and plane
alpha. There is no gralloc buffer. Layer flag HWC_COLOR_FILL
denotes color layer. MDP BLIT happens via MDP_SOLID_FILL mode.
2. There is no color member in HWC layer, so RGBA color value is
passed via "tranform" member from framework to HAL.
3. Update HWC query to enable framework to query for Color layer
support in HAL, at run-time.
Change-Id: I2c698007c1689779fe86d549093bb5285432dc5f
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 93d65c5..8a46e3f 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,
};