Merge "hwc: Extend PTOR feature for two layers"
This commit is contained in:
committed by
Gerrit - the friendly Code Review server
commit
d11e467892
@@ -208,8 +208,8 @@ int CopyBit::checkDirtyRect(hwc_context_t *ctx,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CopyBit::prepareOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list,
|
bool CopyBit::prepareOverlap(hwc_context_t *ctx,
|
||||||
int overlapIndex) {
|
hwc_display_contents_1_t *list) {
|
||||||
|
|
||||||
if (ctx->mMDP.version < qdutils::MDP_V4_0) {
|
if (ctx->mMDP.version < qdutils::MDP_V4_0) {
|
||||||
ALOGE("%s: Invalid request", __FUNCTION__);
|
ALOGE("%s: Invalid request", __FUNCTION__);
|
||||||
@@ -220,14 +220,35 @@ bool CopyBit::prepareOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list,
|
|||||||
ALOGE("%s: Invalid Params", __FUNCTION__);
|
ALOGE("%s: Invalid Params", __FUNCTION__);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
PtorInfo* ptorInfo = &(ctx->mPtorInfo);
|
||||||
|
|
||||||
//Allocate render buffers if they're not allocated
|
// Allocate render buffers if they're not allocated
|
||||||
hwc_rect_t overlap = list->hwLayers[overlapIndex].displayFrame;
|
int alignW = 0, alignH = 0;
|
||||||
int width = overlap.right - overlap.left;
|
int finalW = 0, finalH = 0;
|
||||||
int height = overlap.bottom - overlap.top;
|
for (int i = 0; i < ptorInfo->count; i++) {
|
||||||
int alignW, alignH;
|
int ovlapIndex = ptorInfo->layerIndex[i];
|
||||||
|
hwc_rect_t overlap = list->hwLayers[ovlapIndex].displayFrame;
|
||||||
|
// render buffer width will be the max of two layers
|
||||||
|
// Align Widht and height to 32, Mdp would be configured
|
||||||
|
// with Aligned overlap w/h
|
||||||
|
finalW = max(finalW, ALIGN((overlap.right - overlap.left), 32));
|
||||||
|
finalH += ALIGN((overlap.bottom - overlap.top), 32);
|
||||||
|
if(finalH > ALIGN((overlap.bottom - overlap.top), 32)) {
|
||||||
|
// Calculate the offset for RGBA(4BPP)
|
||||||
|
ptorInfo->mRenderBuffOffset[i] = finalW *
|
||||||
|
(finalH - ALIGN((overlap.bottom - overlap.top), 32)) * 4;
|
||||||
|
// Calculate the dest top, left will always be zero
|
||||||
|
ptorInfo->displayFrame[i].top = (finalH -
|
||||||
|
(ALIGN((overlap.bottom - overlap.top), 32)));
|
||||||
|
}
|
||||||
|
// calculate the right and bottom values
|
||||||
|
ptorInfo->displayFrame[i].right = ptorInfo->displayFrame[i].left +
|
||||||
|
(overlap.right - overlap.left);
|
||||||
|
ptorInfo->displayFrame[i].bottom = ptorInfo->displayFrame[i].top +
|
||||||
|
(overlap.bottom - overlap.top);
|
||||||
|
}
|
||||||
|
|
||||||
getBufferSizeAndDimensions(width, height, HAL_PIXEL_FORMAT_RGBA_8888,
|
getBufferSizeAndDimensions(finalW, finalH, HAL_PIXEL_FORMAT_RGBA_8888,
|
||||||
alignW, alignH);
|
alignW, alignH);
|
||||||
|
|
||||||
if ((mAlignedWidth != alignW) || (mAlignedHeight != alignH)) {
|
if ((mAlignedWidth != alignW) || (mAlignedHeight != alignH)) {
|
||||||
@@ -541,9 +562,9 @@ bool CopyBit::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CopyBit::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list,
|
int CopyBit::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list) {
|
||||||
int overlapIndex) {
|
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
|
PtorInfo* ptorInfo = &(ctx->mPtorInfo);
|
||||||
|
|
||||||
if (ctx->mMDP.version < qdutils::MDP_V4_0) {
|
if (ctx->mMDP.version < qdutils::MDP_V4_0) {
|
||||||
ALOGE("%s: Invalid request", __FUNCTION__);
|
ALOGE("%s: Invalid request", __FUNCTION__);
|
||||||
@@ -558,30 +579,34 @@ int CopyBit::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int copybitLayerCount = 0;
|
int copybitLayerCount = 0;
|
||||||
hwc_rect_t overlap = list->hwLayers[overlapIndex].displayFrame;
|
for(int j = 0; j < ptorInfo->count; j++) {
|
||||||
|
int ovlapIndex = ptorInfo->layerIndex[j];
|
||||||
|
hwc_rect_t overlap = list->hwLayers[ovlapIndex].displayFrame;
|
||||||
|
|
||||||
// Draw overlapped content of layers on render buffer
|
// Draw overlapped content of layers on render buffer
|
||||||
for (int i = 0; i <= overlapIndex; i++) {
|
for (int i = 0; i <= ovlapIndex; i++) {
|
||||||
|
hwc_layer_1_t *layer = &list->hwLayers[i];
|
||||||
int ret = -1;
|
if(!isValidRect(getIntersection(layer->displayFrame,
|
||||||
if ((list->hwLayers[i].acquireFenceFd != -1)) {
|
overlap))) {
|
||||||
// Wait for acquire fence on the App buffers.
|
continue;
|
||||||
ret = sync_wait(list->hwLayers[i].acquireFenceFd, 1000);
|
}
|
||||||
if (ret < 0) {
|
if ((list->hwLayers[i].acquireFenceFd != -1)) {
|
||||||
ALOGE("%s: sync_wait error!! error no = %d err str = %s",
|
// Wait for acquire fence on the App buffers.
|
||||||
__FUNCTION__, errno, strerror(errno));
|
if(sync_wait(list->hwLayers[i].acquireFenceFd, 1000) < 0) {
|
||||||
|
ALOGE("%s: sync_wait error!! error no = %d err str = %s",
|
||||||
|
__FUNCTION__, errno, strerror(errno));
|
||||||
|
}
|
||||||
|
close(list->hwLayers[i].acquireFenceFd);
|
||||||
|
list->hwLayers[i].acquireFenceFd = -1;
|
||||||
}
|
}
|
||||||
close(list->hwLayers[i].acquireFenceFd);
|
|
||||||
list->hwLayers[i].acquireFenceFd = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
hwc_layer_1_t *layer = &list->hwLayers[i];
|
int retVal = drawRectUsingCopybit(ctx, layer, renderBuffer, overlap,
|
||||||
int retVal = drawRectUsingCopybit(ctx, layer, renderBuffer, overlap);
|
ptorInfo->displayFrame[j]);
|
||||||
copybitLayerCount++;
|
copybitLayerCount++;
|
||||||
|
if(retVal < 0) {
|
||||||
if(retVal < 0) {
|
ALOGE("%s: drawRectUsingCopybit failed", __FUNCTION__);
|
||||||
ALOGE("%s: drawRectUsingCopybit failed", __FUNCTION__);
|
copybitLayerCount = 0;
|
||||||
copybitLayerCount = 0;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -590,12 +615,14 @@ int CopyBit::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list,
|
|||||||
copybit->flush_get_fence(copybit, &fd);
|
copybit->flush_get_fence(copybit, &fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
ALOGD_IF(DEBUG_COPYBIT, "%s: done!", __FUNCTION__);
|
ALOGD_IF(DEBUG_COPYBIT, "%s: done! copybitLayerCount = %d", __FUNCTION__,
|
||||||
|
copybitLayerCount);
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CopyBit::drawRectUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
|
int CopyBit::drawRectUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
|
||||||
private_handle_t *renderBuffer, hwc_rect_t rect)
|
private_handle_t *renderBuffer, hwc_rect_t overlap,
|
||||||
|
hwc_rect_t destRect)
|
||||||
{
|
{
|
||||||
hwc_context_t* ctx = (hwc_context_t*)(dev);
|
hwc_context_t* ctx = (hwc_context_t*)(dev);
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
@@ -625,16 +652,20 @@ int CopyBit::drawRectUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
|
|||||||
src.horiz_padding = 0;
|
src.horiz_padding = 0;
|
||||||
src.vert_padding = 0;
|
src.vert_padding = 0;
|
||||||
|
|
||||||
|
|
||||||
hwc_rect_t dispFrame = layer->displayFrame;
|
hwc_rect_t dispFrame = layer->displayFrame;
|
||||||
hwc_rect_t iRect = getIntersection(dispFrame, rect);
|
hwc_rect_t iRect = getIntersection(dispFrame, overlap);
|
||||||
hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
|
hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
|
||||||
qhwc::calculate_crop_rects(crop, dispFrame, iRect, layer->transform);
|
qhwc::calculate_crop_rects(crop, dispFrame, iRect,
|
||||||
|
layer->transform);
|
||||||
|
|
||||||
// Copybit source rect
|
// Copybit source rect
|
||||||
copybit_rect_t srcRect = {crop.left, crop.top, crop.right, crop.bottom};
|
copybit_rect_t srcRect = {crop.left, crop.top, crop.right,
|
||||||
|
crop.bottom};
|
||||||
|
|
||||||
// Copybit destination rect
|
// Copybit destination rect
|
||||||
copybit_rect_t dstRect = {rect.left, rect.top, rect.right, rect.bottom};
|
copybit_rect_t dstRect = {destRect.left, destRect.top, destRect.right,
|
||||||
|
destRect.bottom};
|
||||||
|
|
||||||
// Copybit dst
|
// Copybit dst
|
||||||
copybit_image_t dst;
|
copybit_image_t dst;
|
||||||
@@ -646,20 +677,27 @@ int CopyBit::drawRectUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
|
|||||||
|
|
||||||
copybit_device_t *copybit = mEngine;
|
copybit_device_t *copybit = mEngine;
|
||||||
|
|
||||||
// Copybit region
|
// Copybit region is the destRect
|
||||||
hwc_region_t region = layer->visibleRegionScreen;
|
hwc_rect_t regRect = {dstRect.l,dstRect.t, dstRect.r, dstRect.b};
|
||||||
|
hwc_region_t region;
|
||||||
|
region.numRects = 1;
|
||||||
|
region.rects = ®Rect;
|
||||||
region_iterator copybitRegion(region);
|
region_iterator copybitRegion(region);
|
||||||
int acquireFd = layer->acquireFenceFd;
|
int acquireFd = layer->acquireFenceFd;
|
||||||
|
|
||||||
copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_WIDTH, renderBuffer->width);
|
copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_WIDTH,
|
||||||
copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_HEIGHT, renderBuffer->height);
|
renderBuffer->width);
|
||||||
|
copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_HEIGHT,
|
||||||
|
renderBuffer->height);
|
||||||
copybit->set_parameter(copybit, COPYBIT_TRANSFORM, layer->transform);
|
copybit->set_parameter(copybit, COPYBIT_TRANSFORM, layer->transform);
|
||||||
copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, layer->planeAlpha);
|
copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, layer->planeAlpha);
|
||||||
copybit->set_parameter(copybit, COPYBIT_BLEND_MODE, layer->blending);
|
copybit->set_parameter(copybit, COPYBIT_BLEND_MODE, layer->blending);
|
||||||
copybit->set_parameter(copybit, COPYBIT_DITHER,
|
copybit->set_parameter(copybit, COPYBIT_DITHER,
|
||||||
(dst.format == HAL_PIXEL_FORMAT_RGB_565) ? COPYBIT_ENABLE : COPYBIT_DISABLE);
|
(dst.format == HAL_PIXEL_FORMAT_RGB_565) ? COPYBIT_ENABLE :
|
||||||
|
COPYBIT_DISABLE);
|
||||||
copybit->set_sync(copybit, acquireFd);
|
copybit->set_sync(copybit, acquireFd);
|
||||||
int err = copybit->stretch(copybit, &dst, &src, &dstRect, &srcRect, ©bitRegion);
|
int err = copybit->stretch(copybit, &dst, &src, &dstRect, &srcRect,
|
||||||
|
©bitRegion);
|
||||||
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
ALOGE("%s: copybit stretch failed",__FUNCTION__);
|
ALOGE("%s: copybit stretch failed",__FUNCTION__);
|
||||||
|
|||||||
@@ -51,11 +51,9 @@ public:
|
|||||||
|
|
||||||
void setReleaseFdSync(int fd);
|
void setReleaseFdSync(int fd);
|
||||||
|
|
||||||
bool prepareOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list,
|
bool prepareOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list);
|
||||||
int overlapIndex);
|
|
||||||
|
|
||||||
int drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list,
|
int drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list);
|
||||||
int overlapIndex);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* cached data */
|
/* cached data */
|
||||||
@@ -87,8 +85,10 @@ private:
|
|||||||
// Helper functions for copybit composition
|
// Helper functions for copybit composition
|
||||||
int drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
|
int drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
|
||||||
private_handle_t *renderBuffer, bool isFG);
|
private_handle_t *renderBuffer, bool isFG);
|
||||||
|
// Helper function to draw copybit layer for PTOR comp
|
||||||
int drawRectUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
|
int drawRectUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
|
||||||
private_handle_t *renderBuffer, hwc_rect_t rect);
|
private_handle_t *renderBuffer, hwc_rect_t overlap,
|
||||||
|
hwc_rect_t destRect);
|
||||||
int fillColorUsingCopybit(hwc_layer_1_t *layer,
|
int fillColorUsingCopybit(hwc_layer_1_t *layer,
|
||||||
private_handle_t *renderBuffer);
|
private_handle_t *renderBuffer);
|
||||||
bool canUseCopybitForYUV (hwc_context_t *ctx);
|
bool canUseCopybitForYUV (hwc_context_t *ctx);
|
||||||
|
|||||||
@@ -817,80 +817,117 @@ bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
|
|||||||
ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
|
ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// MDP comp checks
|
||||||
// Find overlap index
|
for(int i = 0; i < numAppLayers; i++) {
|
||||||
int overlapIdx = numAppLayers - 1;
|
|
||||||
uint32_t layerPixelCount, minPixelCount = 0;
|
|
||||||
for (int i = numAppLayers - 1; i >= 0; i--) {
|
|
||||||
hwc_layer_1_t* layer = &list->hwLayers[i];
|
hwc_layer_1_t* layer = &list->hwLayers[i];
|
||||||
hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
|
if(not isSupportedForMDPComp(ctx, layer)) {
|
||||||
layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
|
ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
|
||||||
if (!minPixelCount || (layerPixelCount < minPixelCount)) {
|
return false;
|
||||||
minPixelCount = layerPixelCount;
|
|
||||||
overlapIdx = i;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// No overlap
|
|
||||||
if (!overlapIdx)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
/* We cannot use this composition mode, if:
|
/* We cannot use this composition mode, if:
|
||||||
1. A below layer needs scaling.
|
1. A below layer needs scaling.
|
||||||
2. Overlap is not peripheral to display.
|
2. Overlap is not peripheral to display.
|
||||||
3. Overlap or a below layer has 90 degree transform.
|
3. Overlap or a below layer has 90 degree transform.
|
||||||
4. Intersection of Overlap layer with a below layer is not valid.
|
4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
|
||||||
5. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
hwc_rect_t overlap = list->hwLayers[overlapIdx].displayFrame;
|
int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
|
||||||
if (!isPeripheral(overlap, ctx->mViewFrame[mDpy]))
|
hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
|
||||||
return false;
|
memset(overlapRect, 0, sizeof(overlapRect));
|
||||||
|
int layerPixelCount, minPixelCount = 0;
|
||||||
if ((3 * (overlap.right - overlap.left) * (overlap.bottom - overlap.top)) >
|
int numPTORLayersFound = 0;
|
||||||
((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres))
|
for (int i = numAppLayers-1; (i >= 0 &&
|
||||||
return false;
|
numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
|
||||||
|
|
||||||
for (int i = overlapIdx; i >= 0; i--) {
|
|
||||||
hwc_layer_1_t* layer = &list->hwLayers[i];
|
hwc_layer_1_t* layer = &list->hwLayers[i];
|
||||||
|
hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
|
||||||
hwc_rect_t dispFrame = layer->displayFrame;
|
hwc_rect_t dispFrame = layer->displayFrame;
|
||||||
|
layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
|
||||||
if (has90Transform(layer))
|
// PTOR layer should be peripheral and cannot have transform
|
||||||
return false;
|
if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
|
||||||
|
has90Transform(layer)) {
|
||||||
if (i < overlapIdx) {
|
continue;
|
||||||
if (needsScaling(layer) ||
|
}
|
||||||
!isValidRect(getIntersection(dispFrame, overlap)))
|
if((3 * (layerPixelCount + minPixelCount)) >
|
||||||
return false;
|
((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
|
||||||
|
// Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Found the PTOR layer
|
||||||
|
bool found = true;
|
||||||
|
for (int j = i-1; j >= 0; j--) {
|
||||||
|
// Check if the layers below this layer qualifies for PTOR comp
|
||||||
|
hwc_layer_1_t* layer = &list->hwLayers[j];
|
||||||
|
hwc_rect_t disFrame = layer->displayFrame;
|
||||||
|
//layer below PTOR is intersecting and has 90 degree transform or
|
||||||
|
// needs scaling cannot be supported.
|
||||||
|
if ((isValidRect(getIntersection(dispFrame, disFrame)))
|
||||||
|
&& (has90Transform(layer) || needsScaling(layer))) {
|
||||||
|
found = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Store the minLayer Index
|
||||||
|
if(found) {
|
||||||
|
minLayerIndex[numPTORLayersFound] = i;
|
||||||
|
overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
|
||||||
|
minPixelCount += layerPixelCount;
|
||||||
|
numPTORLayersFound++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mOverlapIndex = overlapIdx;
|
if(isValidRect(getIntersection(overlapRect[0], overlapRect[1]))) {
|
||||||
if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list, overlapIdx)) {
|
ALOGD_IF(isDebug(), "%s: Ignore Rect2 its intersects with Rect1",
|
||||||
ALOGD_IF(isDebug(), "%s: Overlap prepare failed!",__FUNCTION__);
|
__FUNCTION__);
|
||||||
mOverlapIndex = -1;
|
// reset second minLayerIndex[1];
|
||||||
return false;
|
minLayerIndex[1] = -1;
|
||||||
|
numPTORLayersFound--;
|
||||||
}
|
}
|
||||||
|
|
||||||
hwc_rect_t sourceCrop[overlapIdx];
|
// No overlap layers
|
||||||
hwc_rect_t displayFrame[overlapIdx];
|
if (!numPTORLayersFound)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Remove overlap from crop & displayFrame of below layers
|
ctx->mPtorInfo.count = numPTORLayersFound;
|
||||||
for (int i = 0; i < overlapIdx; i++) {
|
for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
|
||||||
|
ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
|
||||||
|
// reset PTOR
|
||||||
|
ctx->mPtorInfo.count = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Store the displayFrame and the sourceCrops of the layers
|
||||||
|
hwc_rect_t displayFrame[numAppLayers];
|
||||||
|
hwc_rect_t sourceCrop[numAppLayers];
|
||||||
|
for(int i = 0; i < numAppLayers; i++) {
|
||||||
hwc_layer_1_t* layer = &list->hwLayers[i];
|
hwc_layer_1_t* layer = &list->hwLayers[i];
|
||||||
displayFrame[i] = layer->displayFrame;
|
displayFrame[i] = layer->displayFrame;
|
||||||
sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
|
sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
|
||||||
|
}
|
||||||
|
|
||||||
// Update layer attributes
|
for(int j = 0; j < numPTORLayersFound; j++) {
|
||||||
hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
|
int index = ctx->mPtorInfo.layerIndex[j];
|
||||||
hwc_rect_t destRect = deductRect(layer->displayFrame, overlap);
|
// Remove overlap from crop & displayFrame of below layers
|
||||||
qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
|
for (int i = 0; i < index && index !=-1; i++) {
|
||||||
layer->transform);
|
hwc_layer_1_t* layer = &list->hwLayers[i];
|
||||||
|
if(!isValidRect(getIntersection(layer->displayFrame,
|
||||||
layer->sourceCropf.left = (float)srcCrop.left;
|
overlapRect[j]))) {
|
||||||
layer->sourceCropf.top = (float)srcCrop.top;
|
continue;
|
||||||
layer->sourceCropf.right = (float)srcCrop.right;
|
}
|
||||||
layer->sourceCropf.bottom = (float)srcCrop.bottom;
|
// Update layer attributes
|
||||||
|
hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
|
||||||
|
hwc_rect_t destRect = deductRect(layer->displayFrame,
|
||||||
|
overlapRect[j]);
|
||||||
|
qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
|
||||||
|
layer->transform);
|
||||||
|
layer->sourceCropf.left = (float)srcCrop.left;
|
||||||
|
layer->sourceCropf.top = (float)srcCrop.top;
|
||||||
|
layer->sourceCropf.right = (float)srcCrop.right;
|
||||||
|
layer->sourceCropf.bottom = (float)srcCrop.bottom;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mCurrentFrame.mdpCount = numAppLayers;
|
mCurrentFrame.mdpCount = numAppLayers;
|
||||||
@@ -903,7 +940,7 @@ bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
|
|||||||
bool result = postHeuristicsHandling(ctx, list);
|
bool result = postHeuristicsHandling(ctx, list);
|
||||||
|
|
||||||
// Restore layer attributes
|
// Restore layer attributes
|
||||||
for (int i = 0; i < overlapIdx; i++) {
|
for(int i = 0; i < numAppLayers; i++) {
|
||||||
hwc_layer_1_t* layer = &list->hwLayers[i];
|
hwc_layer_1_t* layer = &list->hwLayers[i];
|
||||||
layer->displayFrame = displayFrame[i];
|
layer->displayFrame = displayFrame[i];
|
||||||
layer->sourceCropf.left = (float)sourceCrop[i].left;
|
layer->sourceCropf.left = (float)sourceCrop[i].left;
|
||||||
@@ -913,12 +950,16 @@ bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
mOverlapIndex = -1;
|
// reset PTOR
|
||||||
|
ctx->mPtorInfo.count = 0;
|
||||||
reset(ctx);
|
reset(ctx);
|
||||||
|
} else {
|
||||||
|
ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
|
||||||
|
ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ALOGD_IF(isDebug(), "%s: Postheuristics %s!, Overlap index = %d",
|
ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
|
||||||
__FUNCTION__, (result ? "successful" : "failed"), mOverlapIndex);
|
(result ? "successful" : "failed"));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1586,7 +1627,9 @@ int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
|
|||||||
sSimulationFlags, sSimulationFlags);
|
sSimulationFlags, sSimulationFlags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mOverlapIndex = -1;
|
// reset PTOR
|
||||||
|
if(!mDpy)
|
||||||
|
memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
|
||||||
|
|
||||||
//Do not cache the information for next draw cycle.
|
//Do not cache the information for next draw cycle.
|
||||||
if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
|
if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
|
||||||
@@ -1685,11 +1728,10 @@ bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
|
|||||||
|
|
||||||
int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
|
int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
if (mOverlapIndex != -1) {
|
if (ctx->mPtorInfo.isActive()) {
|
||||||
fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list, mOverlapIndex);
|
fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
|
ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
|
||||||
mOverlapIndex = -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fd;
|
return fd;
|
||||||
@@ -1883,17 +1925,20 @@ bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mDpy && (i == mOverlapIndex)) {
|
int fd = hnd->fd;
|
||||||
|
uint32_t offset = (uint32_t)hnd->offset;
|
||||||
|
int index = ctx->mPtorInfo.getPTORArrayIndex(i);
|
||||||
|
if (!mDpy && (index != -1)) {
|
||||||
hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
|
hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
|
||||||
|
fd = hnd->fd;
|
||||||
|
// Use the offset of the RenderBuffer
|
||||||
|
offset = ctx->mPtorInfo.mRenderBuffOffset[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
|
ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
|
||||||
using pipe: %d", __FUNCTION__, layer,
|
using pipe: %d", __FUNCTION__, layer,
|
||||||
hnd, dest );
|
hnd, dest );
|
||||||
|
|
||||||
int fd = hnd->fd;
|
|
||||||
uint32_t offset = (uint32_t)hnd->offset;
|
|
||||||
|
|
||||||
Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
|
Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
|
||||||
if(rot) {
|
if(rot) {
|
||||||
if(!rot->queueBuffer(fd, offset))
|
if(!rot->queueBuffer(fd, offset))
|
||||||
@@ -2132,12 +2177,14 @@ bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
|
|||||||
ovutils::eDest indexL = pipe_info.lIndex;
|
ovutils::eDest indexL = pipe_info.lIndex;
|
||||||
ovutils::eDest indexR = pipe_info.rIndex;
|
ovutils::eDest indexR = pipe_info.rIndex;
|
||||||
|
|
||||||
if (!mDpy && (i == mOverlapIndex)) {
|
|
||||||
hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
int fd = hnd->fd;
|
int fd = hnd->fd;
|
||||||
int offset = (uint32_t)hnd->offset;
|
uint32_t offset = (uint32_t)hnd->offset;
|
||||||
|
int index = ctx->mPtorInfo.getPTORArrayIndex(i);
|
||||||
|
if (!mDpy && (index != -1)) {
|
||||||
|
hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
|
||||||
|
fd = hnd->fd;
|
||||||
|
offset = ctx->mPtorInfo.mRenderBuffOffset[index];
|
||||||
|
}
|
||||||
|
|
||||||
if(ctx->mAD->draw(ctx, fd, offset)) {
|
if(ctx->mAD->draw(ctx, fd, offset)) {
|
||||||
fd = ctx->mAD->getDstFd();
|
fd = ctx->mAD->getDstFd();
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ public:
|
|||||||
/* dumpsys */
|
/* dumpsys */
|
||||||
void dump(android::String8& buf, hwc_context_t *ctx);
|
void dump(android::String8& buf, hwc_context_t *ctx);
|
||||||
bool isGLESOnlyComp() { return (mCurrentFrame.mdpCount == 0); }
|
bool isGLESOnlyComp() { return (mCurrentFrame.mdpCount == 0); }
|
||||||
bool isPTORActive() { return (mOverlapIndex != -1); }
|
|
||||||
int drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list);
|
int drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list);
|
||||||
static MDPComp* getObject(hwc_context_t *ctx, const int& dpy);
|
static MDPComp* getObject(hwc_context_t *ctx, const int& dpy);
|
||||||
/* Handler to invoke frame redraw on Idle Timer expiry */
|
/* Handler to invoke frame redraw on Idle Timer expiry */
|
||||||
@@ -249,8 +248,6 @@ protected:
|
|||||||
struct LayerCache mCachedFrame;
|
struct LayerCache mCachedFrame;
|
||||||
//Enable 4kx2k yuv layer split
|
//Enable 4kx2k yuv layer split
|
||||||
static bool sEnable4k2kYUVSplit;
|
static bool sEnable4k2kYUVSplit;
|
||||||
/* Overlap layer index */
|
|
||||||
int mOverlapIndex;
|
|
||||||
bool mModeOn; // if prepare happened
|
bool mModeOn; // if prepare happened
|
||||||
bool allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index);
|
bool allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -295,6 +295,7 @@ void initContext(hwc_context_t *ctx)
|
|||||||
ctx->mGPUHintInfo.mCompositionState = COMPOSITION_STATE_MDP;
|
ctx->mGPUHintInfo.mCompositionState = COMPOSITION_STATE_MDP;
|
||||||
ctx->mGPUHintInfo.mCurrGPUPerfMode = EGL_GPU_LEVEL_0;
|
ctx->mGPUHintInfo.mCurrGPUPerfMode = EGL_GPU_LEVEL_0;
|
||||||
#endif
|
#endif
|
||||||
|
memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
|
||||||
ALOGI("Initializing Qualcomm Hardware Composer");
|
ALOGI("Initializing Qualcomm Hardware Composer");
|
||||||
ALOGI("MDP version: %d", ctx->mMDP.version);
|
ALOGI("MDP version: %d", ctx->mMDP.version);
|
||||||
}
|
}
|
||||||
@@ -1363,7 +1364,7 @@ int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((fd >= 0) && !dpy && ctx->mMDPComp[dpy]->isPTORActive()) {
|
if ((fd >= 0) && !dpy && ctx->mPtorInfo.isActive()) {
|
||||||
// Acquire c2d fence of Overlap render buffer
|
// Acquire c2d fence of Overlap render buffer
|
||||||
acquireFd[count++] = fd;
|
acquireFd[count++] = fd;
|
||||||
}
|
}
|
||||||
@@ -1426,7 +1427,7 @@ int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!dpy && ctx->mCopyBit[dpy]) {
|
if (!dpy && ctx->mCopyBit[dpy]) {
|
||||||
if (ctx->mMDPComp[dpy]->isPTORActive())
|
if (ctx->mPtorInfo.isActive())
|
||||||
ctx->mCopyBit[dpy]->setReleaseFdSync(releaseFd);
|
ctx->mCopyBit[dpy]->setReleaseFdSync(releaseFd);
|
||||||
else
|
else
|
||||||
ctx->mCopyBit[dpy]->setReleaseFd(releaseFd);
|
ctx->mCopyBit[dpy]->setReleaseFd(releaseFd);
|
||||||
|
|||||||
@@ -41,6 +41,8 @@
|
|||||||
#define MIN_DISPLAY_YRES 200
|
#define MIN_DISPLAY_YRES 200
|
||||||
#define HWC_WFDDISPSYNC_LOG 0
|
#define HWC_WFDDISPSYNC_LOG 0
|
||||||
#define STR(f) #f;
|
#define STR(f) #f;
|
||||||
|
// Max number of PTOR layers handled
|
||||||
|
#define MAX_PTOR_LAYERS 2
|
||||||
|
|
||||||
//Fwrd decls
|
//Fwrd decls
|
||||||
struct hwc_context_t;
|
struct hwc_context_t;
|
||||||
@@ -131,6 +133,23 @@ struct ListStats {
|
|||||||
int renderBufIndexforABC;
|
int renderBufIndexforABC;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//PTOR Comp info
|
||||||
|
struct PtorInfo {
|
||||||
|
int count;
|
||||||
|
int layerIndex[MAX_PTOR_LAYERS];
|
||||||
|
int mRenderBuffOffset[MAX_PTOR_LAYERS];
|
||||||
|
hwc_rect_t displayFrame[MAX_PTOR_LAYERS];
|
||||||
|
bool isActive() { return (count>0); }
|
||||||
|
int getPTORArrayIndex(int index) {
|
||||||
|
int idx = -1;
|
||||||
|
for(int i = 0; i < count; i++) {
|
||||||
|
if(index == layerIndex[i])
|
||||||
|
idx = i;
|
||||||
|
}
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct LayerProp {
|
struct LayerProp {
|
||||||
uint32_t mFlags; //qcom specific layer flags
|
uint32_t mFlags; //qcom specific layer flags
|
||||||
LayerProp():mFlags(0){};
|
LayerProp():mFlags(0){};
|
||||||
@@ -574,6 +593,8 @@ struct hwc_context_t {
|
|||||||
struct gpu_hint_info mGPUHintInfo;
|
struct gpu_hint_info mGPUHintInfo;
|
||||||
//App Buffer Composition
|
//App Buffer Composition
|
||||||
bool enableABC;
|
bool enableABC;
|
||||||
|
// PTOR Info
|
||||||
|
qhwc::PtorInfo mPtorInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace qhwc {
|
namespace qhwc {
|
||||||
|
|||||||
Reference in New Issue
Block a user