hwc: use surfaceDamage to calculate the dirtyrect as per HWC 1.5

Update the HWC version to HWC 1.5

surfaceDamage is passed as part of the layer, use this information
to determine if the layer is changing and handle cache.

The total dirty rectangle for a given layer will be the sum of all
the damageRectangles, use that to calculate the ROI

Bug: 11239309
Change-Id: Iddff278e716099d252e059aae02764f4b8630a6f
This commit is contained in:
Arun Kumar K.R 2015-03-10 19:25:42 -07:00 committed by Pat Tjin
parent b05e85c9d0
commit ecf38487b3
5 changed files with 58 additions and 47 deletions

View File

@ -879,7 +879,7 @@ static int hwc_device_open(const struct hw_module_t* module, const char* name,
//Setup HWC methods
dev->device.common.tag = HARDWARE_DEVICE_TAG;
dev->device.common.version = HWC_DEVICE_API_VERSION_1_4;
dev->device.common.version = HWC_DEVICE_API_VERSION_1_5;
dev->device.common.module = const_cast<hw_module_t*>(module);
dev->device.common.close = hwc_device_close;
dev->device.prepare = hwc_prepare;

View File

@ -269,19 +269,11 @@ MDPComp::LayerCache::LayerCache() {
}
void MDPComp::LayerCache::reset() {
memset(&hnd, 0, sizeof(hnd));
memset(&isFBComposed, true, sizeof(isFBComposed));
memset(&drop, false, sizeof(drop));
layerCount = 0;
}
void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
const int numAppLayers = (int)list->numHwLayers - 1;
for(int i = 0; i < numAppLayers; i++) {
hnd[i] = list->hwLayers[i].handle;
}
}
void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
layerCount = curFrame.layerCount;
memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
@ -297,8 +289,8 @@ bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
(curFrame.drop[i] != drop[i])) {
return false;
}
if(curFrame.isFBComposed[i] &&
(hnd[i] != list->hwLayers[i].handle)){
hwc_layer_1_t const* layer = &list->hwLayers[i];
if(curFrame.isFBComposed[i] && layerUpdating(layer)){
return false;
}
}
@ -426,6 +418,32 @@ bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
return ret;
}
hwc_rect_t MDPComp::calculateDirtyRect(const hwc_layer_1_t* layer,
hwc_rect_t& scissor) {
hwc_region_t surfDamage = layer->surfaceDamage;
hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
hwc_rect_t dst = layer->displayFrame;
int x_off = dst.left - src.left;
int y_off = dst.top - src.top;
hwc_rect dirtyRect = (hwc_rect){0, 0, 0, 0};
hwc_rect_t updatingRect = dst;
if (surfDamage.numRects == 0) {
// full layer updating, dirty rect is full frame
dirtyRect = getIntersection(layer->displayFrame, scissor);
} else {
for(uint32_t i = 0; i < surfDamage.numRects; i++) {
updatingRect = moveRect(surfDamage.rects[i], x_off, y_off);
hwc_rect_t intersect = getIntersection(updatingRect, scissor);
if(isValidRect(intersect)) {
dirtyRect = getUnion(intersect, dirtyRect);
}
}
}
return dirtyRect;
}
void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
fbRect = getIntersection(fbRect, roi);
@ -487,22 +505,14 @@ void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
for(int index = 0; index < numAppLayers; index++ ) {
hwc_layer_1_t* layer = &list->hwLayers[index];
if ((mCachedFrame.hnd[index] != layer->handle) ||
if (layerUpdating(layer) ||
isYuvBuffer((private_handle_t *)layer->handle)) {
hwc_rect_t dst = layer->displayFrame;
hwc_rect_t updatingRect = dst;
#ifdef QCOM_BSP
if(!needsScaling(layer) && !layer->transform)
{
hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
int x_off = dst.left - src.left;
int y_off = dst.top - src.top;
updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
hwc_rect_t dirtyRect = (struct hwc_rect){0, 0, 0, 0};;
if(!needsScaling(layer) && !layer->transform) {
dirtyRect = calculateDirtyRect(layer, fullFrame);
}
#endif
roi = getUnion(roi, updatingRect);
roi = getUnion(roi, dirtyRect);
}
}
@ -601,28 +611,20 @@ void MDPCompSplit::generateROI(hwc_context_t *ctx,
for(int index = 0; index < numAppLayers; index++ ) {
hwc_layer_1_t* layer = &list->hwLayers[index];
if ((mCachedFrame.hnd[index] != layer->handle) ||
isYuvBuffer((private_handle_t *)layer->handle)) {
hwc_rect_t dst = layer->displayFrame;
hwc_rect_t updatingRect = dst;
private_handle_t *hnd = (private_handle_t *)layer->handle;
if (layerUpdating(layer) || isYuvBuffer(hnd)) {
hwc_rect_t l_dirtyRect = (struct hwc_rect){0, 0, 0, 0};
hwc_rect_t r_dirtyRect = (struct hwc_rect){0, 0, 0, 0};
#ifdef QCOM_BSP
if(!needsScaling(layer) && !layer->transform)
{
hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
int x_off = dst.left - src.left;
int y_off = dst.top - src.top;
updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
if(!needsScaling(layer) && !layer->transform) {
l_dirtyRect = calculateDirtyRect(layer, l_frame);
r_dirtyRect = calculateDirtyRect(layer, r_frame);
}
#endif
if(isValidRect(l_dirtyRect))
l_roi = getUnion(l_roi, l_dirtyRect);
hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
if(isValidRect(l_dst))
l_roi = getUnion(l_roi, l_dst);
hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
if(isValidRect(r_dst))
r_roi = getUnion(r_roi, r_dst);
if(isValidRect(r_dirtyRect))
r_roi = getUnion(r_roi, r_dirtyRect);
}
}
@ -1215,7 +1217,8 @@ void MDPComp::updateLayerCache(hwc_context_t* ctx,
int fbCount = 0;
for(int i = 0; i < numAppLayers; i++) {
if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
hwc_layer_1_t * layer = &list->hwLayers[i];
if (!layerUpdating(layer)) {
if(!mCurrentFrame.drop[i])
fbCount++;
mCurrentFrame.isFBComposed[i] = true;
@ -1477,7 +1480,6 @@ int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
ALOGD("%s",sDump.string());
}
mCachedFrame.cacheAll(list);
mCachedFrame.updateCounts(mCurrentFrame);
return ret;
}

View File

@ -123,7 +123,6 @@ protected:
/* cached data */
struct LayerCache {
int layerCount;
buffer_handle_t hnd[MAX_NUM_APP_LAYERS];
bool isFBComposed[MAX_NUM_APP_LAYERS];
bool drop[MAX_NUM_APP_LAYERS];
@ -131,7 +130,6 @@ protected:
LayerCache();
/* clear caching info*/
void reset();
void cacheAll(hwc_display_contents_1_t* list);
void updateCounts(const FrameInfo&);
bool isSameFrame(const FrameInfo& curFrame,
hwc_display_contents_1_t* list);
@ -153,6 +151,9 @@ protected:
/* generates ROI based on the modified area of the frame */
virtual void generateROI(hwc_context_t *ctx,
hwc_display_contents_1_t* list) = 0;
/* Calculates the dirtyRegion for the given layer */
hwc_rect_t calculateDirtyRect(const hwc_layer_1_t* layer,
hwc_rect_t& scissor);
/* validates the ROI generated for fallback conditions */
virtual bool validateAndApplyROI(hwc_context_t *ctx,
hwc_display_contents_1_t* list) = 0;

View File

@ -1111,6 +1111,12 @@ bool isValidRect(const hwc_rect& rect)
return ((rect.bottom > rect.top) && (rect.right > rect.left)) ;
}
bool layerUpdating(const hwc_layer_1_t* layer) {
hwc_region_t surfDamage = layer->surfaceDamage;
return ((surfDamage.numRects == 0) ||
isValidRect(layer->surfaceDamage.rects[0]));
}
hwc_rect_t moveRect(const hwc_rect_t& rect, const int& x_off, const int& y_off)
{
hwc_rect_t res;

View File

@ -269,6 +269,8 @@ hwc_rect_t getUnion(const hwc_rect_t& rect1, const hwc_rect_t& rect2);
void optimizeLayerRects(const hwc_display_contents_1_t *list);
bool areLayersIntersecting(const hwc_layer_1_t* layer1,
const hwc_layer_1_t* layer2);
bool layerUpdating(const hwc_layer_1_t* layer);
// returns true if Action safe dimensions are set and target supports Actionsafe
bool isActionSafePresent(hwc_context_t *ctx, int dpy);