Merge "hwc: Fallback to gpu comp when copybit cannot handle scaling"
diff --git a/libcopybit/copybit.cpp b/libcopybit/copybit.cpp
index b37eee0..5d8da05 100644
--- a/libcopybit/copybit.cpp
+++ b/libcopybit/copybit.cpp
@@ -555,6 +555,63 @@
// 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,
@@ -653,6 +710,7 @@
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/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 06ce156..33c4f32 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -86,8 +86,13 @@
//-------------- AdrenoMemInfo-----------------------//
AdrenoMemInfo::AdrenoMemInfo()
{
+ LINK_adreno_compute_aligned_width_and_height = NULL;
+ LINK_adreno_compute_padding = NULL;
+
libadreno_utils = ::dlopen("libadreno_utils.so", RTLD_NOW);
if (libadreno_utils) {
+ *(void **)&LINK_adreno_compute_aligned_width_and_height =
+ ::dlsym(libadreno_utils, "compute_aligned_width_and_height");
*(void **)&LINK_adreno_compute_padding = ::dlsym(libadreno_utils,
"compute_surface_padding");
}
@@ -100,9 +105,11 @@
}
}
-int AdrenoMemInfo::getStride(int width, int format)
+void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format,
+ int& aligned_w, int& aligned_h)
{
- int stride = ALIGN(width, 32);
+ aligned_w = ALIGN(width, 32);
+ aligned_h = ALIGN(height, 32);
// Currently surface padding is only computed for RGB* surfaces.
if (format <= HAL_PIXEL_FORMAT_sRGB_X_8888) {
// Don't add any additional padding if debug.gralloc.map_fb_memory
@@ -111,7 +118,7 @@
if((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
(!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
(!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
- return stride;
+ return;
}
int bpp = 4;
@@ -125,25 +132,39 @@
break;
default: break;
}
- if ((libadreno_utils) && (LINK_adreno_compute_padding)) {
- int surface_tile_height = 1; // Linear surface
+ if (libadreno_utils) {
int raster_mode = 0; // Adreno unknown raster mode.
int padding_threshold = 512; // Threshold for padding surfaces.
- // the function below expects the width to be a multiple of
- // 32 pixels, hence we pass stride instead of width.
- stride = LINK_adreno_compute_padding(stride, bpp,
- surface_tile_height, raster_mode,
- padding_threshold);
+ // the function below computes aligned width and aligned height
+ // based on linear or macro tile mode selected.
+ if(LINK_adreno_compute_aligned_width_and_height) {
+ int tile_mode = 0; // Linear surface
+ LINK_adreno_compute_aligned_width_and_height(width,
+ height, bpp, tile_mode,
+ raster_mode, padding_threshold,
+ &aligned_w, &aligned_h);
+
+ } else if(LINK_adreno_compute_padding) {
+ int surface_tile_height = 1; // Linear surface
+ aligned_w = LINK_adreno_compute_padding(width, bpp,
+ surface_tile_height, raster_mode,
+ padding_threshold);
+ ALOGW("%s: Warning!! Old GFX API is used to calculate stride",
+ __FUNCTION__);
+ } else {
+ ALOGW("%s: Warning!! Symbols compute_surface_padding and " \
+ "compute_aligned_width_and_height not found", __FUNCTION__);
+ }
}
} else {
switch (format)
{
case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
case HAL_PIXEL_FORMAT_RAW_SENSOR:
- stride = ALIGN(width, 32);
+ aligned_w = ALIGN(width, 32);
break;
case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
- stride = ALIGN(width, 128);
+ aligned_w = ALIGN(width, 128);
break;
case HAL_PIXEL_FORMAT_YCbCr_420_SP:
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
@@ -152,22 +173,21 @@
case HAL_PIXEL_FORMAT_YCrCb_422_SP:
case HAL_PIXEL_FORMAT_YCbCr_422_I:
case HAL_PIXEL_FORMAT_YCrCb_422_I:
- stride = ALIGN(width, 16);
+ aligned_w = ALIGN(width, 16);
break;
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
- stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
+ aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
break;
case HAL_PIXEL_FORMAT_BLOB:
- stride = width;
+ aligned_w = width;
break;
case HAL_PIXEL_FORMAT_NV21_ZSL:
- stride = ALIGN(width, 64);
+ aligned_w = ALIGN(width, 64);
break;
default: break;
}
}
- return stride;
}
//-------------- IAllocController-----------------------//
@@ -274,8 +294,11 @@
{
size_t size;
- alignedw = AdrenoMemInfo::getInstance().getStride(width, format);
- alignedh = ALIGN(height, 32);
+ AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
+ height,
+ format,
+ alignedw,
+ alignedh);
switch (format) {
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
diff --git a/libgralloc/gr.h b/libgralloc/gr.h
index 5343c35..1949f45 100644
--- a/libgralloc/gr.h
+++ b/libgralloc/gr.h
@@ -89,12 +89,13 @@
~AdrenoMemInfo();
/*
- * Function to compute the adreno stride based on the width and format.
+ * Function to compute the adreno aligned width and aligned height
+ * based on the width and format.
*
- * @return stride.
+ * @return aligned width, aligned height
*/
- int getStride(int width, int format);
-
+ void getAlignedWidthAndHeight(int width, int height, int format,
+ int& alignedw, int &alignedh);
private:
// Pointer to the padding library.
void *libadreno_utils;
@@ -104,5 +105,15 @@
int surface_tile_height,
int screen_tile_height,
int padding_threshold);
+ // link to the surface padding library.
+ void (*LINK_adreno_compute_aligned_width_and_height) (int width,
+ int height,
+ int bpp,
+ int tile_mode,
+ int raster_mode,
+ int padding_threshold,
+ int *aligned_w,
+ int *aligned_h);
+
};
#endif /* GR_H_ */
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index ca0db00..a07bdc3 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -329,7 +329,10 @@
int width = va_arg(args, int);
int format = va_arg(args, int);
int *stride = va_arg(args, int *);
- *stride = AdrenoMemInfo::getInstance().getStride(width, format);
+ int alignedw = 0, alignedh = 0;
+ AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
+ 0, format, alignedw, alignedh);
+ *stride = alignedw;
res = 0;
} break;
case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE:
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index 155c1f5..bb1b032 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) {
@@ -210,15 +197,6 @@
if (dy > MAX_SCALE_FACTOR || dy < MIN_SCALE_FACTOR)
return false;
}
- /*
- * 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
@@ -291,23 +269,23 @@
if (ctx->mMDP.version >= qdutils::MDP_V4_0) {
//Wait for the previous frame to complete before rendering onto it
- if(mRelFd[0] >=0) {
- sync_wait(mRelFd[0], 1000);
- close(mRelFd[0]);
- mRelFd[0] = -1;
+ if(mRelFd[mCurRenderBufferIndex] >=0) {
+ sync_wait(mRelFd[mCurRenderBufferIndex], 1000);
+ 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[0] >=0) {
+ if(mRelFd[mCurRenderBufferIndex] >=0) {
copybit_device_t *copybit = getCopyBitDevice();
- copybit->set_sync(copybit, mRelFd[0]);
+ 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];
@@ -692,6 +670,11 @@
{
for (int i = 0; i < NUM_RENDER_BUFFERS; i++) {
if(mRenderBuffer[i]) {
+ //Since we are freeing buffer close the fence if it has a valid one.
+ if(mRelFd[i] >= 0) {
+ close(mRelFd[i]);
+ mRelFd[i] = -1;
+ }
free_buffer(mRenderBuffer[i]);
mRenderBuffer[i] = NULL;
}
@@ -703,10 +686,9 @@
}
void CopyBit::setReleaseFd(int fd) {
- if(mRelFd[0] >=0)
- close(mRelFd[0]);
- mRelFd[0] = mRelFd[1];
- mRelFd[1] = dup(fd);
+ if(mRelFd[mCurRenderBufferIndex] >=0)
+ close(mRelFd[mCurRenderBufferIndex]);
+ mRelFd[mCurRenderBufferIndex] = dup(fd);
}
struct copybit_device_t* CopyBit::getCopyBitDevice() {
@@ -716,10 +698,10 @@
CopyBit::CopyBit():mIsModeOn(false), mCopyBitDraw(false),
mCurRenderBufferIndex(0){
hw_module_t const *module;
- for (int i = 0; i < NUM_RENDER_BUFFERS; i++)
+ for (int i = 0; i < NUM_RENDER_BUFFERS; i++) {
mRenderBuffer[i] = NULL;
- mRelFd[0] = -1;
- mRelFd[1] = -1;
+ mRelFd[i] = -1;
+ }
char value[PROPERTY_VALUE_MAX];
property_get("debug.hwc.dynThreshold", value, "2");
@@ -737,10 +719,6 @@
CopyBit::~CopyBit()
{
freeRenderBuffers();
- if(mRelFd[0] >=0)
- close(mRelFd[0]);
- if(mRelFd[1] >=0)
- close(mRelFd[1]);
if(mEngine)
{
copybit_close(mEngine);
diff --git a/libhwcomposer/hwc_copybit.h b/libhwcomposer/hwc_copybit.h
index 2962a71..fd5c939 100644
--- a/libhwcomposer/hwc_copybit.h
+++ b/libhwcomposer/hwc_copybit.h
@@ -84,9 +84,8 @@
// Index of the current intermediate render buffer
int mCurRenderBufferIndex;
- //These are the the release FDs of the T-2 and T-1 round
- //We wait on the T-2 fence
- int mRelFd[2];
+ // Release FDs of the intermediate render buffer
+ int mRelFd[NUM_RENDER_BUFFERS];
//Dynamic composition threshold for deciding copybit usage.
double mDynThreshold;
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 8eece52..bdc2dbd 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -260,7 +260,8 @@
memcpy(&drop, &curFrame.drop, sizeof(drop));
}
-bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame) {
+bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
+ hwc_display_contents_1_t* list) {
if(layerCount != curFrame.layerCount)
return false;
for(int i = 0; i < curFrame.layerCount; i++) {
@@ -268,6 +269,10 @@
(curFrame.drop[i] != drop[i])) {
return false;
}
+ if(curFrame.isFBComposed[i] &&
+ (hnd[i] != list->hwLayers[i].handle)){
+ return false;
+ }
}
return true;
}
@@ -301,12 +306,6 @@
hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
hwc_rect_t dst = layer->displayFrame;
-
- if(dst.left < 0 || dst.top < 0 || dst.right > hw_w || dst.bottom > hw_h) {
- hwc_rect_t scissor = {0, 0, hw_w, hw_h };
- qhwc::calculate_crop_rects(crop, dst, scissor, layer->transform);
- }
-
int crop_w = crop.right - crop.left;
int crop_h = crop.bottom - crop.top;
int dst_w = dst.right - dst.left;
@@ -402,6 +401,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,15 +414,22 @@
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;
hwc_rect_t srcRect = integerizeSourceCrop(layer->sourceCropf);
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 +444,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 +471,9 @@
return;
}
+ if(isSkipPresent(ctx, mDpy))
+ return;
+
if(list->flags & HWC_GEOMETRY_CHANGED)
return;
@@ -469,7 +487,6 @@
int transform = list->hwLayers[index].transform;
/* Intersect against display boundaries */
- trimLayer(ctx, mDpy, transform, srcRect, dstRect);
roi = getUnion(roi, dstRect);
}
}
@@ -571,18 +588,8 @@
mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
mCurrentFrame.dropCount;
- if(mCurrentFrame.mdpCount > sMaxPipesPerMixer) {
- ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
- return false;
- }
-
- if(!arePipesAvailable(ctx, list)) {
- return false;
- }
-
- uint32_t size = calcMDPBytesRead(ctx, list);
- if(!bandwidthCheck(ctx, size)) {
- ALOGD_IF(isDebug(), "%s: Exceeds bandwidth",__FUNCTION__);
+ if(!resourceCheck(ctx, list)) {
+ ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
return false;
}
@@ -642,18 +649,8 @@
return false;
}
- if(mdpCount > (sMaxPipesPerMixer - 1)) { // -1 since FB is used
- ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
- return false;
- }
-
- if(!arePipesAvailable(ctx, list)) {
- return false;
- }
-
- uint32_t size = calcMDPBytesRead(ctx, list);
- if(!bandwidthCheck(ctx, size)) {
- ALOGD_IF(isDebug(), "%s: Exceeds bandwidth",__FUNCTION__);
+ if(!resourceCheck(ctx, list)) {
+ ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
return false;
}
@@ -713,7 +710,8 @@
mCurrentFrame.fbCount = batchSize;
mCurrentFrame.mdpCount = mCurrentFrame.layerCount - batchSize;
- if(!arePipesAvailable(ctx, list)) {
+ if(!resourceCheck(ctx, list)) {
+ ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
return false;
}
@@ -744,21 +742,17 @@
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;
- if(mdpCount > (sMaxPipesPerMixer - fbNeeded)) {
- ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
- return false;
- }
-
- if(!arePipesAvailable(ctx, list)) {
- return false;
- }
-
- uint32_t size = calcMDPBytesRead(ctx, list);
- if(!bandwidthCheck(ctx, size)) {
- ALOGD_IF(isDebug(), "%s: Exceeds bandwidth",__FUNCTION__);
+ if(!resourceCheck(ctx, list)) {
+ ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
return false;
}
@@ -974,7 +968,6 @@
mCurrentFrame.isFBComposed[i] = true;
} else {
mCurrentFrame.isFBComposed[i] = false;
- mCachedFrame.hnd[i] = list->hwLayers[i].handle;
}
}
@@ -1082,6 +1075,27 @@
return true;
}
+bool MDPComp::resourceCheck(hwc_context_t *ctx,
+ hwc_display_contents_1_t *list) {
+ const bool fbUsed = mCurrentFrame.fbCount;
+ if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
+ ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
+ return false;
+ }
+
+ if(!arePipesAvailable(ctx, list)) {
+ return false;
+ }
+
+ uint32_t size = calcMDPBytesRead(ctx, list);
+ if(!bandwidthCheck(ctx, size)) {
+ ALOGD_IF(isDebug(), "%s: Exceeds bandwidth",__FUNCTION__);
+ return false;
+ }
+
+ return true;
+}
+
uint32_t MDPComp::calcMDPBytesRead(hwc_context_t *ctx,
hwc_display_contents_1_t* list) {
uint32_t size = 0;
@@ -1096,7 +1110,6 @@
if (hnd) {
hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
hwc_rect_t dst = layer->displayFrame;
- trimLayer(ctx, mDpy, layer->transform, crop, dst);
float bpp = ((float)hnd->size) / (hnd->width * hnd->height);
size += bpp * (crop.right - crop.left) *
(crop.bottom - crop.top) *
@@ -1142,7 +1155,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;
@@ -1182,7 +1195,7 @@
} else { //Success
//Any change in composition types needs an FB refresh
mCurrentFrame.needsRedraw = false;
- if(!mCachedFrame.isSameFrame(mCurrentFrame) ||
+ if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
(list->flags & HWC_GEOMETRY_CHANGED) ||
isSkipPresent(ctx, mDpy)) {
mCurrentFrame.needsRedraw = true;
@@ -1218,10 +1231,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_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index 1d5d715..7063d32 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -118,7 +118,8 @@
void reset();
void cacheAll(hwc_display_contents_1_t* list);
void updateCounts(const FrameInfo&);
- bool isSameFrame(const FrameInfo& curFrame);
+ bool isSameFrame(const FrameInfo& curFrame,
+ hwc_display_contents_1_t* list);
};
/* allocates pipe from pipe book */
@@ -192,6 +193,7 @@
bool programYUV(hwc_context_t *ctx, hwc_display_contents_1_t* list);
void reset(const int& numAppLayers, hwc_display_contents_1_t* list);
bool isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer);
+ bool resourceCheck(hwc_context_t *ctx, hwc_display_contents_1_t *list);
int mDpy;
static bool sEnabled;
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..f32ad34 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -612,7 +612,6 @@
hwc_rect_t displayFrame = layer->displayFrame;
hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
- trimLayer(ctx, dpy, layer->transform, sourceCrop, displayFrame);
dst_w = displayFrame.right - displayFrame.left;
dst_h = displayFrame.bottom - displayFrame.top;
@@ -640,7 +639,6 @@
hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
hwc_rect_t displayFrame = layer->displayFrame;
private_handle_t *hnd = (private_handle_t *)layer->handle;
- trimLayer(ctx, dpy, layer->transform, sourceCrop, displayFrame);
cropL = sourceCrop;
dstL = displayFrame;
@@ -701,8 +699,35 @@
return false;
}
+static void trimLayer(hwc_context_t *ctx, const int& dpy, const int& transform,
+ hwc_rect_t& crop, hwc_rect_t& dst) {
+ int hw_w = ctx->dpyAttr[dpy].xres;
+ int hw_h = ctx->dpyAttr[dpy].yres;
+ if(dst.left < 0 || dst.top < 0 ||
+ dst.right > hw_w || dst.bottom > hw_h) {
+ hwc_rect_t scissor = {0, 0, hw_w, hw_h };
+ qhwc::calculate_crop_rects(crop, dst, scissor, transform);
+ }
+}
+
+static void trimList(hwc_context_t *ctx, hwc_display_contents_1_t *list,
+ const int& dpy) {
+ for(uint32_t i = 0; i < list->numHwLayers - 1; i++) {
+ hwc_layer_1_t *layer = &list->hwLayers[i];
+ hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
+ trimLayer(ctx, dpy,
+ list->hwLayers[i].transform,
+ (hwc_rect_t&)crop,
+ (hwc_rect_t&)list->hwLayers[i].displayFrame);
+ layer->sourceCropf.left = crop.left;
+ layer->sourceCropf.right = crop.right;
+ layer->sourceCropf.top = crop.top;
+ layer->sourceCropf.bottom = crop.bottom;
+ }
+}
+
void setListStats(hwc_context_t *ctx,
- const hwc_display_contents_1_t *list, int dpy) {
+ hwc_display_contents_1_t *list, int dpy) {
const int prevYuvCount = ctx->listStats[dpy].yuvCount;
memset(&ctx->listStats[dpy], 0, sizeof(ListStats));
ctx->listStats[dpy].numAppLayers = list->numHwLayers - 1;
@@ -719,6 +744,7 @@
(int)ctx->dpyAttr[dpy].xres, (int)ctx->dpyAttr[dpy].yres);
ctx->listStats[dpy].secureUI = false;
+ trimList(ctx, list, dpy);
optimizeLayerRects(ctx, list, dpy);
for (size_t i = 0; i < (size_t)ctx->listStats[dpy].numAppLayers; i++) {
@@ -988,36 +1014,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 +1048,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--;
@@ -1229,17 +1249,6 @@
return ret;
}
-void trimLayer(hwc_context_t *ctx, const int& dpy, const int& transform,
- hwc_rect_t& crop, hwc_rect_t& dst) {
- int hw_w = ctx->dpyAttr[dpy].xres;
- int hw_h = ctx->dpyAttr[dpy].yres;
- if(dst.left < 0 || dst.top < 0 ||
- dst.right > hw_w || dst.bottom > hw_h) {
- hwc_rect_t scissor = {0, 0, hw_w, hw_h };
- qhwc::calculate_crop_rects(crop, dst, scissor, transform);
- }
-}
-
void setMdpFlags(hwc_layer_1_t *layer,
ovutils::eMdpFlags &mdpFlags,
int rotDownscale, int transform) {
@@ -1448,7 +1457,6 @@
}
setMdpFlags(layer, mdpFlags, downscale, transform);
- trimLayer(ctx, dpy, transform, crop, dst);
if(isYuvBuffer(hnd) && //if 90 component or downscale, use rot
((transform & HWC_TRANSFORM_ROT_90) || downscale)) {
@@ -1565,7 +1573,6 @@
}
}
-
setMdpFlags(layer, mdpFlagsL, 0, transform);
if(lDest != OV_INVALID && rDest != OV_INVALID) {
@@ -1573,8 +1580,6 @@
setMdpFlags(mdpFlagsL, OV_MDSS_MDP_DUAL_PIPE);
}
- trimLayer(ctx, dpy, transform, crop, dst);
-
//Will do something only if feature enabled and conditions suitable
//hollow call otherwise
if(ctx->mAD->prepare(ctx, crop, whf, hnd)) {
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 8a46e3f..66a02d6 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -187,7 +187,7 @@
// -----------------------------------------------------------------------------
// Utility functions - implemented in hwc_utils.cpp
void dumpLayer(hwc_layer_1_t const* l);
-void setListStats(hwc_context_t *ctx, const hwc_display_contents_1_t *list,
+void setListStats(hwc_context_t *ctx, hwc_display_contents_1_t *list,
int dpy);
void initContext(hwc_context_t *ctx);
void closeContext(hwc_context_t *ctx);
@@ -214,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,
@@ -254,10 +254,6 @@
int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy,
int fd);
-//Trims a layer's source crop which is outside of screen boundary.
-void trimLayer(hwc_context_t *ctx, const int& dpy, const int& transform,
- hwc_rect_t& crop, hwc_rect_t& dst);
-
//Sets appropriate mdp flags for a layer.
void setMdpFlags(hwc_layer_1_t *layer,
ovutils::eMdpFlags &mdpFlags,
diff --git a/liboverlay/Android.mk b/liboverlay/Android.mk
index 560b57f..d8c2ab5 100644
--- a/liboverlay/Android.mk
+++ b/liboverlay/Android.mk
@@ -6,8 +6,12 @@
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
-LOCAL_SHARED_LIBRARIES := $(common_libs) libqdutils libmemalloc libsync
+LOCAL_SHARED_LIBRARIES := $(common_libs) libqdutils libmemalloc \
+ libsync libdl
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdoverlay\"
+ifeq ($(TARGET_USES_QSEED_SCALAR),true)
+ LOCAL_CFLAGS += -DUSES_QSEED_SCALAR
+endif
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_SRC_FILES := \
overlay.cpp \
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index b095e9e..9222af5 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -27,16 +27,23 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <dlfcn.h>
#include "overlay.h"
#include "pipes/overlayGenPipe.h"
#include "mdp_version.h"
#include "qdMetaData.h"
+#ifdef USES_QSEED_SCALAR
+#include <scale/scale.h>
+using namespace scale;
+#endif
+
#define PIPE_DEBUG 0
namespace overlay {
using namespace utils;
+
Overlay::Overlay() {
PipeBook::NUM_PIPES = qdutils::MDPVersion::getInstance().getTotalPipes();
for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
@@ -44,12 +51,14 @@
}
mDumpStr[0] = '\0';
+ initScalar();
}
Overlay::~Overlay() {
for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
mPipeBook[i].destroy();
}
+ destroyScalar();
}
void Overlay::configBegin() {
@@ -60,6 +69,13 @@
}
sForceSetBitmap = 0;
mDumpStr[0] = '\0';
+
+#ifdef USES_QSEED_SCALAR
+ Scale *scalar = getScalar();
+ if(scalar) {
+ scalar->configBegin();
+ }
+#endif
}
void Overlay::configDone() {
@@ -81,6 +97,13 @@
}
dump();
PipeBook::save();
+
+#ifdef USES_QSEED_SCALAR
+ Scale *scalar = getScalar();
+ if(scalar) {
+ scalar->configDone();
+ }
+#endif
}
eDest Overlay::nextPipe(eMdpPipeType type, int dpy, int mixer) {
@@ -381,6 +404,42 @@
}
}
+void Overlay::initScalar() {
+#ifdef USES_QSEED_SCALAR
+ if(sLibScaleHandle == NULL) {
+ sLibScaleHandle = dlopen("libscale.so", RTLD_NOW);
+ }
+
+ if(sLibScaleHandle) {
+ if(sScale == NULL) {
+ Scale* (*getInstance)();
+ *(void **) &getInstance = dlsym(sLibScaleHandle, "getInstance");
+ if(getInstance) {
+ sScale = getInstance();
+ }
+ }
+ }
+#endif
+}
+
+void Overlay::destroyScalar() {
+#ifdef USES_QSEED_SCALAR
+ if(sLibScaleHandle) {
+ if(sScale) {
+ void (*destroyInstance)(Scale*);
+ *(void **) &destroyInstance = dlsym(sLibScaleHandle,
+ "destroyInstance");
+ if(destroyInstance) {
+ destroyInstance(sScale);
+ sScale = NULL;
+ }
+ }
+ dlclose(sLibScaleHandle);
+ sLibScaleHandle = NULL;
+ }
+#endif
+}
+
void Overlay::PipeBook::init() {
mPipe = NULL;
mDisplay = DPY_UNUSED;
@@ -406,5 +465,7 @@
int Overlay::PipeBook::sAllocatedBitmap = 0;
utils::eMdpPipeType Overlay::PipeBook::pipeTypeLUT[utils::OV_MAX] =
{utils::OV_MDP_PIPE_ANY};
+void *Overlay::sLibScaleHandle = NULL;
+scale::Scale *Overlay::sScale = NULL;
}; // namespace overlay
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
index c16f6e6..854fa30 100644
--- a/liboverlay/overlay.h
+++ b/liboverlay/overlay.h
@@ -34,6 +34,9 @@
#include "utils/threads.h"
struct MetaData_t;
+namespace scale {
+class Scale;
+};
namespace overlay {
class GenericPipe;
@@ -111,6 +114,8 @@
static int getFbForDpy(const int& dpy);
static bool displayCommit(const int& fd, const utils::Dim& roi);
static bool displayCommit(const int& fd);
+ /* Returns the scalar object */
+ static scale::Scale *getScalar();
private:
/* Ctor setup */
@@ -118,6 +123,10 @@
/*Validate index range, abort if invalid */
void validate(int index);
void dump() const;
+ /* Creates a scalar object using libscale.so */
+ static void initScalar();
+ /* Destroys the scalar object using libscale.so */
+ static void destroyScalar();
/* Just like a Facebook for pipes, but much less profile info */
struct PipeBook {
@@ -177,6 +186,8 @@
static int sDpyFbMap[DPY_MAX];
static int sDMAMode;
static int sForceSetBitmap;
+ static void *sLibScaleHandle;
+ static scale::Scale *sScale;
};
inline void Overlay::validate(int index) {
@@ -249,6 +260,10 @@
sForceSetBitmap |= (1 << dpy);
}
+inline scale::Scale *Overlay::getScalar() {
+ return sScale;
+}
+
inline bool Overlay::PipeBook::valid() {
return (mPipe != NULL);
}
diff --git a/liboverlay/overlayCtrlData.h b/liboverlay/overlayCtrlData.h
index c3a7aa3..6746792 100644
--- a/liboverlay/overlayCtrlData.h
+++ b/liboverlay/overlayCtrlData.h
@@ -53,7 +53,7 @@
/* dtor close */
~Ctrl();
/* init fd etc*/
- bool init(uint32_t fbnum);
+ bool init(uint32_t dpy);
/* close underlying mdp */
bool close();
@@ -100,7 +100,7 @@
/* calls close */
~Data();
/* init fd etc */
- bool init(uint32_t fbnum);
+ bool init(uint32_t dpy);
/* calls underlying mdp close */
bool close();
/* set overlay pipe id in the mdp struct */
@@ -145,10 +145,10 @@
return true;
}
-inline bool Ctrl::init(uint32_t fbnum) {
+inline bool Ctrl::init(uint32_t dpy) {
// MDP/FD init
- if(!mMdp.init(fbnum)) {
- ALOGE("Ctrl failed to init fbnum=%d", fbnum);
+ if(!mMdp.init(dpy)) {
+ ALOGE("Ctrl failed to init dpy=%d", dpy);
return false;
}
return true;
@@ -239,8 +239,8 @@
inline int Data::getPipeId() const { return mMdp.getPipeId(); }
-inline bool Data::init(uint32_t fbnum) {
- if(!mMdp.init(fbnum)) {
+inline bool Data::init(uint32_t dpy) {
+ if(!mMdp.init(dpy)) {
ALOGE("Data cannot init mdp");
return false;
}
diff --git a/liboverlay/overlayMdp.cpp b/liboverlay/overlayMdp.cpp
index 674e62d..b4058bd 100644
--- a/liboverlay/overlayMdp.cpp
+++ b/liboverlay/overlayMdp.cpp
@@ -20,6 +20,12 @@
#include "overlayUtils.h"
#include "overlayMdp.h"
#include "mdp_version.h"
+#include <overlay.h>
+
+#ifdef USES_QSEED_SCALAR
+#include <scale/scale.h>
+using namespace scale;
+#endif
#define HSIC_SETTINGS_DEBUG 0
@@ -39,13 +45,20 @@
namespace ovutils = overlay::utils;
namespace overlay {
-bool MdpCtrl::init(uint32_t fbnum) {
+bool MdpCtrl::init(uint32_t dpy) {
+ int fbnum = Overlay::getFbForDpy(dpy);
+ if( fbnum < 0 ) {
+ ALOGE("%s: Invalid FB for the display: %d",__FUNCTION__, dpy);
+ return false;
+ }
+
// FD init
if(!utils::openDev(mFd, fbnum,
Res::fbPath, O_RDWR)){
ALOGE("Ctrl failed to init fbnum=%d", fbnum);
return false;
}
+ mDpy = dpy;
return true;
}
@@ -57,6 +70,7 @@
mOrientation = utils::OVERLAY_TRANSFORM_0;
mDownscale = 0;
mForceSet = false;
+ mDpy = 0;
#ifdef USES_POST_PROCESSING
mPPChanged = false;
memset(&mParams, 0, sizeof(struct compute_params));
@@ -201,11 +215,22 @@
mdp_wrapper::dump("== Bad OVInfo is: ", mOVInfo);
mdp_wrapper::dump("== Last good known OVInfo is: ", mLkgo);
this->restore();
+#ifdef USES_QSEED_SCALAR
+ if(Overlay::getScalar()) {
+ Overlay::getScalar()->configAbort(mDpy);
+ }
+#endif
return false;
}
this->save();
}
+#ifdef USES_QSEED_SCALAR
+ if(Overlay::getScalar()) {
+ Overlay::getScalar()->configSet(mOVInfo, mDpy, mFd.getFD());
+ }
+#endif
+
return true;
}
@@ -371,4 +396,21 @@
return true;
}
+
+//// MdpData ////////////
+bool MdpData::init(uint32_t dpy) {
+ int fbnum = Overlay::getFbForDpy(dpy);
+ if( fbnum < 0 ) {
+ ALOGE("%s: Invalid FB for the display: %d",__FUNCTION__, dpy);
+ return false;
+ }
+
+ // FD init
+ if(!utils::openDev(mFd, fbnum, Res::fbPath, O_RDWR)){
+ ALOGE("Ctrl failed to init fbnum=%d", fbnum);
+ return false;
+ }
+ return true;
+}
+
} // overlay
diff --git a/liboverlay/overlayMdp.h b/liboverlay/overlayMdp.h
index 5bfec6b..fe4ad69 100644
--- a/liboverlay/overlayMdp.h
+++ b/liboverlay/overlayMdp.h
@@ -39,8 +39,8 @@
explicit MdpCtrl();
/* dtor close */
~MdpCtrl();
- /* init underlying device using fbnum */
- bool init(uint32_t fbnum);
+ /* init underlying device using fbnum for dpy */
+ bool init(uint32_t dpy);
/* unset overlay, reset and close fd */
bool close();
/* reset and set ov id to -1 / MSMFB_NEW_REQUEST */
@@ -132,6 +132,7 @@
OvFD mFd;
int mDownscale;
bool mForceSet;
+ int mDpy;
#ifdef USES_POST_PROCESSING
/* PP Compute Params */
@@ -174,7 +175,7 @@
/* dtor close*/
~MdpData();
/* init FD */
- bool init(uint32_t fbnum);
+ bool init(uint32_t dpy);
/* memset0 the underlying mdp object */
void reset();
/* close fd, and reset */
@@ -395,15 +396,6 @@
inline MdpData::~MdpData() { close(); }
-inline bool MdpData::init(uint32_t fbnum) {
- // FD init
- if(!utils::openDev(mFd, fbnum, Res::fbPath, O_RDWR)){
- ALOGE("Ctrl failed to init fbnum=%d", fbnum);
- return false;
- }
- return true;
-}
-
inline void MdpData::reset() {
overlay::utils::memset0(mOvData);
mOvData.data.memory_id = -1;
diff --git a/liboverlay/pipes/overlayGenPipe.cpp b/liboverlay/pipes/overlayGenPipe.cpp
index 35f686c..06e8257 100644
--- a/liboverlay/pipes/overlayGenPipe.cpp
+++ b/liboverlay/pipes/overlayGenPipe.cpp
@@ -28,7 +28,6 @@
*/
#include "overlayGenPipe.h"
-#include "overlay.h"
#include "mdp_version.h"
namespace overlay {
@@ -47,20 +46,12 @@
ALOGE_IF(DEBUG_OVERLAY, "GenericPipe init");
mRotDownscaleOpt = false;
- int fbNum = Overlay::getFbForDpy(mDpy);
- if( fbNum < 0 ) {
- ALOGE("%s: Invalid FB for the display: %d",__FUNCTION__, mDpy);
- return false;
- }
-
- ALOGD_IF(DEBUG_OVERLAY,"%s: mFbNum:%d",__FUNCTION__, fbNum);
-
- if(!mCtrlData.ctrl.init(fbNum)) {
+ if(!mCtrlData.ctrl.init(mDpy)) {
ALOGE("GenericPipe failed to init ctrl");
return false;
}
- if(!mCtrlData.data.init(fbNum)) {
+ if(!mCtrlData.data.init(mDpy)) {
ALOGE("GenericPipe failed to init data");
return false;
}
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*/
+
diff --git a/libqdutils/mdp_version.cpp b/libqdutils/mdp_version.cpp
index 259d078..1850801 100644
--- a/libqdutils/mdp_version.cpp
+++ b/libqdutils/mdp_version.cpp
@@ -241,11 +241,17 @@
}
bool MDPVersion::is8x74v2() {
- if( mMdpRev >= MDSS_MDP_HW_REV_102 && mMdpRev < MDSS_MDP_HW_REV_103) {
+ if( mMdpRev >= MDSS_MDP_HW_REV_102 && mMdpRev < MDSS_MDP_HW_REV_200) {
return true;
}
return false;
}
+bool MDPVersion::is8x92() {
+ if( mMdpRev >= MDSS_MDP_HW_REV_200 && mMdpRev < MDSS_MDP_HW_REV_206) {
+ return true;
+ }
+ return false;
+}
}; //namespace qdutils
diff --git a/libqdutils/mdp_version.h b/libqdutils/mdp_version.h
index a14592b..b995582 100644
--- a/libqdutils/mdp_version.h
+++ b/libqdutils/mdp_version.h
@@ -57,7 +57,8 @@
MDSS_MDP_HW_REV_100 = 0x10000000, //8974 v1
MDSS_MDP_HW_REV_101 = 0x10010000, //8x26
MDSS_MDP_HW_REV_102 = 0x10020000, //8974 v2
- MDSS_MDP_HW_REV_103 = 0x10030000, //Future
+ MDSS_MDP_HW_REV_200 = 0x20000000, //8092
+ MDSS_MDP_HW_REV_206 = 0x20060000, //Future
};
enum {
@@ -103,6 +104,7 @@
bool supportsBWC();
bool is8x26();
bool is8x74v2();
+ bool is8x92();
int getLeftSplit() { return mSplit.left(); }
int getRightSplit() { return mSplit.right(); }
private: