Merge "hwcomposer : Fix copybit render buffer fence usage."
diff --git a/libcopybit/copybit.cpp b/libcopybit/copybit.cpp
index ff7dc4e..5d8da05 100644
--- a/libcopybit/copybit.cpp
+++ b/libcopybit/copybit.cpp
@@ -555,6 +555,108 @@
// NOP for MDP copybit
return 0;
}
+static int clear_copybit(struct copybit_device_t *dev,
+ struct copybit_image_t const *buf,
+ struct copybit_rect_t *rect)
+{
+ struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+ uint32_t color = 0; // black color
+
+ if (!ctx) {
+ ALOGE ("%s: Invalid copybit context", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ struct blitReq list1;
+ memset((char *)&list1 , 0 ,sizeof (struct blitReq) );
+ list1.count = 1;
+ int rel_fen_fd = -1;
+ int my_tmp_get_fence = -1;
+
+ list1.sync.rel_fen_fd = &my_tmp_get_fence;
+ mdp_blit_req* req = &list1.req[0];
+
+ if(!req) {
+ ALOGE ("%s : Invalid request", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ set_image(&req->dst, buf);
+ set_image(&req->src, buf);
+
+ if (rect->l < 0 || (uint32_t)(rect->r - rect->l) > req->dst.width ||
+ rect->t < 0 || (uint32_t)(rect->b - rect->t) > req->dst.height) {
+ ALOGE ("%s : Invalid rect : src_rect l %d t %d r %d b %d",\
+ __FUNCTION__, rect->l, rect->t, rect->r, rect->b);
+ return -EINVAL;
+ }
+
+ 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.b = (uint32_t)((color >> 16) & 0xff);
+ req->const_color.g = (uint32_t)((color >> 8) & 0xff);
+ req->const_color.r = (uint32_t)((color >> 0) & 0xff);
+ req->const_color.alpha = MDP_ALPHA_NOP;
+
+ req->transp_mask = MDP_TRANSP_NOP;
+ req->flags = MDP_SOLID_FILL | MDP_MEMORY_ID_TYPE_FB | MDP_BLEND_FG_PREMULT;
+ int status = msm_copybit(ctx, &list1);
+
+ if (my_tmp_get_fence != -1)
+ close(my_tmp_get_fence);
+
+ 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)
+{
+ 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;
+}
/*****************************************************************************/
@@ -606,7 +708,9 @@
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->device.clear = clear_copybit;
ctx->mAlpha = MDP_ALPHA_NOP;
ctx->mFlags = 0;
ctx->sync.flags = 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 7fbe6d6..2104bff 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -2,8 +2,7 @@
* Copyright (C) 2010 The Android Open Source Project
* Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
*
- * Not a Contribution, Apache license notifications and license are retained
- * for attribution purposes only.
+ * Not a Contribution.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,7 +24,9 @@
#include "hwc_copybit.h"
#include "comptype.h"
#include "gr.h"
+#include "cb_utils.h"
+using namespace qdutils;
namespace qhwc {
struct range {
@@ -127,20 +128,6 @@
return renderArea;
}
-bool checkNonWormholeRegion(private_handle_t* hnd, hwc_rect_t& rect)
-{
- unsigned int height = rect.bottom - rect.top;
- unsigned int width = rect.right - rect.left;
- copybit_image_t buf;
- buf.w = ALIGN(hnd->width, 32);
- buf.h = hnd->height;
-
- if (buf.h != height || buf.w != width)
- return false;
-
- return true;
-}
-
bool CopyBit::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list,
int dpy) {
@@ -189,15 +176,6 @@
if (layer->planeAlpha != 0xFF)
return true;
}
- /*
- * Fallback to GPU in MDP3 when NonWormholeRegion is not of frame buffer
- * size as artifact is seen in WormholeRegion of previous frame.
- */
- hwc_rect_t nonWormHoleRegion;
- getNonWormholeRegion(list, nonWormHoleRegion);
- if(!checkNonWormholeRegion(fbHnd, nonWormHoleRegion))
- return true;
-
}
//Allocate render buffers if they're not allocated
@@ -275,18 +253,18 @@
close(mRelFd[mCurRenderBufferIndex]);
mRelFd[mCurRenderBufferIndex] = -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);
} else {
if(mRelFd[mCurRenderBufferIndex] >=0) {
copybit_device_t *copybit = getCopyBitDevice();
copybit->set_sync(copybit, mRelFd[mCurRenderBufferIndex]);
}
}
+
+ //Clear the transparent or left out region on the render buffer
+ hwc_rect_t clearRegion = {0,0,0,0};
+ if(CBUtils::getuiClearRegion(list, clearRegion, layerProp))
+ 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];
@@ -338,6 +316,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 +567,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 0d63812..8278ff3 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_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 8eece52..ab11bc4 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -402,6 +402,12 @@
return ret;
}
+/*
+ * 1) Identify layers that are not visible in the updating ROI and drop them
+ * from composition.
+ * 2) If we have a scaling layers which needs cropping against generated ROI.
+ * Reset ROI to full resolution.
+ */
bool MDPComp::validateAndApplyROI(hwc_context_t *ctx,
hwc_display_contents_1_t* list, hwc_rect_t roi) {
int numAppLayers = ctx->listStats[mDpy].numAppLayers;
@@ -409,7 +415,15 @@
if(!isValidRect(roi))
return false;
- for(int i = 0; i < numAppLayers; i++){
+ hwc_rect_t visibleRect = roi;
+
+ for(int i = numAppLayers - 1; i >= 0; i--){
+
+ if(!isValidRect(visibleRect)) {
+ mCurrentFrame.drop[i] = true;
+ mCurrentFrame.dropCount++;
+ }
+
const hwc_layer_1_t* layer = &list->hwLayers[i];
hwc_rect_t dstRect = layer->displayFrame;
@@ -417,7 +431,7 @@
int transform = layer->transform;
trimLayer(ctx, mDpy, transform, srcRect, dstRect);
- hwc_rect_t res = getIntersection(roi, dstRect);
+ hwc_rect_t res = getIntersection(visibleRect, dstRect);
int res_w = res.right - res.left;
int res_h = res.bottom - res.top;
@@ -432,12 +446,15 @@
* cropping */
if((res_w != dst_w || res_h != dst_h) &&
needsScaling (ctx, layer, mDpy)) {
- ALOGE("%s: Resetting ROI due to scaling", __FUNCTION__);
+ ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
mCurrentFrame.dropCount = 0;
return false;
}
}
+
+ if (layer->blending == HWC_BLENDING_NONE)
+ visibleRect = deductRect(visibleRect, res);
}
return true;
}
@@ -456,6 +473,9 @@
return;
}
+ if(isSkipPresent(ctx, mDpy))
+ return;
+
if(list->flags & HWC_GEOMETRY_CHANGED)
return;
@@ -744,6 +764,12 @@
return false;
}
+ /* Bail out if we are processing only secured video layers
+ * and we dont have any */
+ if(!isSecurePresent(ctx, mDpy) && secureOnly){
+ return false;
+ }
+
if(!mdpCount)
return false;
@@ -1142,7 +1168,7 @@
//do not cache the information for next draw cycle.
if(numLayers > MAX_NUM_APP_LAYERS) {
mCachedFrame.updateCounts(mCurrentFrame);
- ALOGE("%s: Number of App layers exceeded the limit ",
+ ALOGI("%s: Number of App layers exceeded the limit ",
__FUNCTION__);
ret = -1;
return ret;
@@ -1218,10 +1244,11 @@
}
} else {
reset(numLayers, list);
+ memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
+ mCurrentFrame.dropCount = 0;
ret = -1;
goto exit;
}
-
//UpdateLayerFlags
setMDPCompLayerFlags(ctx, list);
mCachedFrame.cacheAll(list);
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index 926f425..5cb87f8 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -92,7 +92,7 @@
while(((iter_str - strUdata) <= len) && (*iter_str)) {
char* pstr = strstr(iter_str, "PANEL_ALIVE=0");
if (pstr != NULL) {
- ALOGE("%s: got change event in fb0 with PANEL_ALIVE=0",
+ ALOGI("%s: got change event in fb0 with PANEL_ALIVE=0",
__FUNCTION__);
ctx->mPanelResetStatus = true;
return true;
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index aa40223..9d1e30c 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -988,36 +988,25 @@
return res;
}
-/* deducts given rect from layers display-frame and source crop.
- also it avoid hole creation.*/
-void deductRect(const hwc_layer_1_t* layer, hwc_rect_t& irect) {
- hwc_rect_t& disprect = (hwc_rect_t&)layer->displayFrame;
- hwc_rect_t srcrect = integerizeSourceCrop(layer->sourceCropf);
- int irect_w = irect.right - irect.left;
- int irect_h = irect.bottom - irect.top;
+/* Not a geometrical rect deduction. Deducts rect2 from rect1 only if it results
+ * a single rect */
+hwc_rect_t deductRect(const hwc_rect_t& rect1, const hwc_rect_t& rect2) {
- if((disprect.left == irect.left) && (disprect.right == irect.right)) {
- if((disprect.top == irect.top) && (irect.bottom <= disprect.bottom)) {
- disprect.top = irect.bottom;
- srcrect.top += irect_h;
- }
- else if((disprect.bottom == irect.bottom)
- && (irect.top >= disprect.top)) {
- disprect.bottom = irect.top;
- srcrect.bottom -= irect_h;
- }
- }
- else if((disprect.top == irect.top) && (disprect.bottom == irect.bottom)) {
- if((disprect.left == irect.left) && (irect.right <= disprect.right)) {
- disprect.left = irect.right;
- srcrect.left += irect_w;
- }
- else if((disprect.right == irect.right)
- && (irect.left >= disprect.left)) {
- disprect.right = irect.left;
- srcrect.right -= irect_w;
- }
- }
+ hwc_rect_t res = rect1;
+
+ if((rect1.left == rect2.left) && (rect1.right == rect2.right)) {
+ if((rect1.top == rect2.top) && (rect2.bottom <= rect1.bottom))
+ res.top = rect2.bottom;
+ else if((rect1.bottom == rect2.bottom)&& (rect2.top >= rect1.top))
+ res.bottom = rect2.top;
+ }
+ else if((rect1.top == rect2.top) && (rect1.bottom == rect2.bottom)) {
+ if((rect1.left == rect2.left) && (rect2.right <= rect1.right))
+ res.left = rect2.right;
+ else if((rect1.right == rect2.right)&& (rect2.left >= rect1.left))
+ res.right = rect2.left;
+ }
+ return res;
}
void optimizeLayerRects(hwc_context_t *ctx,
@@ -1033,17 +1022,22 @@
hwc_rect_t& topframe =
(hwc_rect_t&)list->hwLayers[i].displayFrame;
while(j >= 0) {
- if(!needsScaling(ctx, &list->hwLayers[j], dpy)) {
- hwc_rect_t& bottomframe =
- (hwc_rect_t&)list->hwLayers[j].displayFrame;
+ if(!needsScaling(ctx, &list->hwLayers[j], dpy)) {
+ hwc_layer_1_t* layer = (hwc_layer_1_t*)&list->hwLayers[j];
+ hwc_rect_t& bottomframe = layer->displayFrame;
+ hwc_rect_t& bottomCrop = layer->sourceCrop;
+ int transform =layer->transform;
- hwc_rect_t irect = getIntersection(bottomframe, topframe);
- if(isValidRect(irect)) {
- //if intersection is valid rect, deduct it
- deductRect(&list->hwLayers[j], irect);
- }
- }
- j--;
+ hwc_rect_t irect = getIntersection(bottomframe, topframe);
+ if(isValidRect(irect)) {
+ //if intersection is valid rect, deduct it
+ bottomframe = deductRect(bottomframe, irect);
+ qhwc::calculate_crop_rects(bottomCrop, bottomframe,
+ bottomframe, transform);
+
+ }
+ }
+ j--;
}
}
i--;
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 93d65c5..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,
};
@@ -213,7 +214,7 @@
int getExtOrientation(hwc_context_t* ctx);
bool isValidRect(const hwc_rect_t& rect);
-void deductRect(const hwc_layer_1_t* layer, hwc_rect_t& irect);
+hwc_rect_t deductRect(const hwc_rect_t& rect1, const hwc_rect_t& rect2);
hwc_rect_t getIntersection(const hwc_rect_t& rect1, const hwc_rect_t& rect2);
hwc_rect_t getUnion(const hwc_rect_t& rect1, const hwc_rect_t& rect2);
void optimizeLayerRects(hwc_context_t *ctx,
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,
diff --git a/libqdutils/Android.mk b/libqdutils/Android.mk
index b6bbc47..d514405 100644
--- a/libqdutils/Android.mk
+++ b/libqdutils/Android.mk
@@ -4,13 +4,14 @@
LOCAL_MODULE := libqdutils
LOCAL_MODULE_TAGS := optional
-LOCAL_SHARED_LIBRARIES := $(common_libs)
+LOCAL_SHARED_LIBRARIES := $(common_libs) libui
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdutils\"
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_SRC_FILES := profiler.cpp mdp_version.cpp \
idle_invalidator.cpp \
- comptype.cpp qd_utils.cpp
+ comptype.cpp qd_utils.cpp \
+ cb_utils.cpp
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
diff --git a/libqdutils/cb_utils.cpp b/libqdutils/cb_utils.cpp
new file mode 100644
index 0000000..bc7e5b1
--- /dev/null
+++ b/libqdutils/cb_utils.cpp
@@ -0,0 +1,79 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+* Redistribution and use in source and binary forms, with or without
+* * modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyrigh
+* notice, this list of conditions and the following disclaimer
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "cb_utils.h"
+
+/* get union of two rects into 3rd rect */
+void getUnion(hwc_rect_t& rect1,hwc_rect_t& rect2, hwc_rect_t& irect) {
+ irect.left = min(rect1.left, rect2.left);
+ irect.top = min(rect1.top, rect2.top);
+ irect.right = max(rect1.right, rect2.right);
+ irect.bottom = max(rect1.bottom, rect2.bottom);
+}
+
+using namespace android;
+using namespace qhwc;
+namespace qdutils {
+
+int CBUtils::getuiClearRegion(hwc_display_contents_1_t* list,
+ hwc_rect_t &clearWormholeRect, LayerProp *layerProp) {
+
+ uint32_t last = list->numHwLayers - 1;
+ hwc_rect_t fbFrame = list->hwLayers[last].displayFrame;
+
+ Rect fbFrameRect(fbFrame.left,fbFrame.top,fbFrame.right,fbFrame.bottom);
+ Region wormholeRegion(fbFrameRect);
+
+ for (uint32_t i = 0 ; i < last; i++) {
+ // need to take care only in per pixel blending.
+ // Restrict calculation only for copybit layers.
+ if((list->hwLayers[i].blending != HWC_BLENDING_NONE) ||
+ !(layerProp[i].mFlags & HWC_COPYBIT))
+ continue ;
+ hwc_rect_t displayFrame = list->hwLayers[i].displayFrame;
+ Rect tmpRect(displayFrame.left,displayFrame.top,displayFrame.right,
+ displayFrame.bottom);
+ Region tmpRegion(tmpRect);
+ wormholeRegion.subtractSelf(wormholeRegion.intersect(tmpRegion));
+ }
+ if (wormholeRegion.isEmpty()) {
+ return 0;
+ }
+ //TO DO :- 1. remove union and call clear for each rect.
+ // :- 2. support swap ract feature.
+ Region::const_iterator it = wormholeRegion.begin();
+ Region::const_iterator const end = wormholeRegion.end();
+ while (it != end) {
+ const Rect& r = *it++;
+ hwc_rect_t tmpWormRect = {r.left,r.top,r.right,r.bottom};
+ getUnion(clearWormholeRect, tmpWormRect, clearWormholeRect);
+
+ }
+ return 1;
+}
+
+}//namespace qdutils
diff --git a/libqdutils/cb_utils.h b/libqdutils/cb_utils.h
new file mode 100644
index 0000000..85dd78f
--- /dev/null
+++ b/libqdutils/cb_utils.h
@@ -0,0 +1,45 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+* Redistribution and use in source and binary forms, with or without
+* * modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyrigh
+* notice, this list of conditions and the following disclaimer
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#ifndef CB_UTIL_H
+#define CB_UTIL_H
+
+#include <ui/Region.h>
+#include "hwc_utils.h"
+
+using namespace qhwc;
+namespace qdutils {
+class CBUtils {
+public:
+static int getuiClearRegion(hwc_display_contents_1_t* list,
+ hwc_rect_t &clearWormholeRec,
+ LayerProp *layerProp);
+};
+}//namespace qdutils
+#endif /* end of include guard: CB_UTIL_H*/
+