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:
parent
b05e85c9d0
commit
ecf38487b3
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue