Merge "hwc: Extend PTOR feature for two layers"

This commit is contained in:
Linux Build Service Account
2014-06-20 23:00:53 -07:00
committed by Gerrit - the friendly Code Review server
6 changed files with 226 additions and 122 deletions

View File

@@ -208,8 +208,8 @@ int CopyBit::checkDirtyRect(hwc_context_t *ctx,
return -1;
}
bool CopyBit::prepareOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list,
int overlapIndex) {
bool CopyBit::prepareOverlap(hwc_context_t *ctx,
hwc_display_contents_1_t *list) {
if (ctx->mMDP.version < qdutils::MDP_V4_0) {
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__);
return false;
}
PtorInfo* ptorInfo = &(ctx->mPtorInfo);
// Allocate render buffers if they're not allocated
hwc_rect_t overlap = list->hwLayers[overlapIndex].displayFrame;
int width = overlap.right - overlap.left;
int height = overlap.bottom - overlap.top;
int alignW, alignH;
int alignW = 0, alignH = 0;
int finalW = 0, finalH = 0;
for (int i = 0; i < ptorInfo->count; i++) {
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);
if ((mAlignedWidth != alignW) || (mAlignedHeight != alignH)) {
@@ -541,9 +562,9 @@ bool CopyBit::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list,
return true;
}
int CopyBit::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list,
int overlapIndex) {
int CopyBit::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list) {
int fd = -1;
PtorInfo* ptorInfo = &(ctx->mPtorInfo);
if (ctx->mMDP.version < qdutils::MDP_V4_0) {
ALOGE("%s: Invalid request", __FUNCTION__);
@@ -558,16 +579,20 @@ int CopyBit::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list,
}
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
for (int i = 0; i <= overlapIndex; i++) {
int ret = -1;
for (int i = 0; i <= ovlapIndex; i++) {
hwc_layer_1_t *layer = &list->hwLayers[i];
if(!isValidRect(getIntersection(layer->displayFrame,
overlap))) {
continue;
}
if ((list->hwLayers[i].acquireFenceFd != -1)) {
// Wait for acquire fence on the App buffers.
ret = sync_wait(list->hwLayers[i].acquireFenceFd, 1000);
if (ret < 0) {
if(sync_wait(list->hwLayers[i].acquireFenceFd, 1000) < 0) {
ALOGE("%s: sync_wait error!! error no = %d err str = %s",
__FUNCTION__, errno, strerror(errno));
}
@@ -575,27 +600,29 @@ int CopyBit::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list,
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++;
if(retVal < 0) {
ALOGE("%s: drawRectUsingCopybit failed", __FUNCTION__);
copybitLayerCount = 0;
}
}
}
if (copybitLayerCount) {
copybit_device_t *copybit = getCopyBitDevice();
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;
}
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);
if (!ctx) {
@@ -625,16 +652,20 @@ int CopyBit::drawRectUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
src.horiz_padding = 0;
src.vert_padding = 0;
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);
qhwc::calculate_crop_rects(crop, dispFrame, iRect, layer->transform);
qhwc::calculate_crop_rects(crop, dispFrame, iRect,
layer->transform);
// 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_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_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 region
hwc_region_t region = layer->visibleRegionScreen;
// Copybit region is the destRect
hwc_rect_t regRect = {dstRect.l,dstRect.t, dstRect.r, dstRect.b};
hwc_region_t region;
region.numRects = 1;
region.rects = &regRect;
region_iterator copybitRegion(region);
int acquireFd = layer->acquireFenceFd;
copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_WIDTH, renderBuffer->width);
copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_HEIGHT, renderBuffer->height);
copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_WIDTH,
renderBuffer->width);
copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_HEIGHT,
renderBuffer->height);
copybit->set_parameter(copybit, COPYBIT_TRANSFORM, layer->transform);
copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, layer->planeAlpha);
copybit->set_parameter(copybit, COPYBIT_BLEND_MODE, layer->blending);
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);
int err = copybit->stretch(copybit, &dst, &src, &dstRect, &srcRect, &copybitRegion);
int err = copybit->stretch(copybit, &dst, &src, &dstRect, &srcRect,
&copybitRegion);
if (err < 0)
ALOGE("%s: copybit stretch failed",__FUNCTION__);

View File

@@ -51,11 +51,9 @@ public:
void setReleaseFdSync(int fd);
bool prepareOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list,
int overlapIndex);
bool prepareOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list);
int drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list,
int overlapIndex);
int drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list);
private:
/* cached data */
@@ -87,8 +85,10 @@ private:
// Helper functions for copybit composition
int drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
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,
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,
private_handle_t *renderBuffer);
bool canUseCopybitForYUV (hwc_context_t *ctx);

View File

@@ -817,81 +817,118 @@ bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
return false;
}
// Find overlap index
int overlapIdx = numAppLayers - 1;
uint32_t layerPixelCount, minPixelCount = 0;
for (int i = numAppLayers - 1; i >= 0; i--) {
// MDP comp checks
for(int i = 0; i < numAppLayers; i++) {
hwc_layer_1_t* layer = &list->hwLayers[i];
hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
if (!minPixelCount || (layerPixelCount < minPixelCount)) {
minPixelCount = layerPixelCount;
overlapIdx = i;
}
}
// No overlap
if (!overlapIdx)
if(not isSupportedForMDPComp(ctx, layer)) {
ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
return false;
}
}
/* We cannot use this composition mode, if:
1. A below layer needs scaling.
2. Overlap is not peripheral to display.
3. Overlap or a below layer has 90 degree transform.
4. Intersection of Overlap layer with a below layer is not valid.
5. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
*/
hwc_rect_t overlap = list->hwLayers[overlapIdx].displayFrame;
if (!isPeripheral(overlap, ctx->mViewFrame[mDpy]))
return false;
if ((3 * (overlap.right - overlap.left) * (overlap.bottom - overlap.top)) >
((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres))
return false;
for (int i = overlapIdx; i >= 0; i--) {
int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
memset(overlapRect, 0, sizeof(overlapRect));
int layerPixelCount, minPixelCount = 0;
int numPTORLayersFound = 0;
for (int i = numAppLayers-1; (i >= 0 &&
numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
hwc_layer_1_t* layer = &list->hwLayers[i];
hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
hwc_rect_t dispFrame = layer->displayFrame;
if (has90Transform(layer))
return false;
if (i < overlapIdx) {
if (needsScaling(layer) ||
!isValidRect(getIntersection(dispFrame, overlap)))
return false;
layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
// PTOR layer should be peripheral and cannot have transform
if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
has90Transform(layer)) {
continue;
}
if((3 * (layerPixelCount + minPixelCount)) >
((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 (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list, overlapIdx)) {
ALOGD_IF(isDebug(), "%s: Overlap prepare failed!",__FUNCTION__);
mOverlapIndex = -1;
return false;
if(isValidRect(getIntersection(overlapRect[0], overlapRect[1]))) {
ALOGD_IF(isDebug(), "%s: Ignore Rect2 its intersects with Rect1",
__FUNCTION__);
// reset second minLayerIndex[1];
minLayerIndex[1] = -1;
numPTORLayersFound--;
}
hwc_rect_t sourceCrop[overlapIdx];
hwc_rect_t displayFrame[overlapIdx];
// No overlap layers
if (!numPTORLayersFound)
return false;
// Remove overlap from crop & displayFrame of below layers
for (int i = 0; i < overlapIdx; i++) {
ctx->mPtorInfo.count = numPTORLayersFound;
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];
displayFrame[i] = layer->displayFrame;
sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
}
for(int j = 0; j < numPTORLayersFound; j++) {
int index = ctx->mPtorInfo.layerIndex[j];
// Remove overlap from crop & displayFrame of below layers
for (int i = 0; i < index && index !=-1; i++) {
hwc_layer_1_t* layer = &list->hwLayers[i];
if(!isValidRect(getIntersection(layer->displayFrame,
overlapRect[j]))) {
continue;
}
// Update layer attributes
hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
hwc_rect_t destRect = deductRect(layer->displayFrame, overlap);
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.fbCount = 0;
@@ -903,7 +940,7 @@ bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
bool result = postHeuristicsHandling(ctx, list);
// 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];
layer->displayFrame = displayFrame[i];
layer->sourceCropf.left = (float)sourceCrop[i].left;
@@ -913,12 +950,16 @@ bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
}
if (!result) {
mOverlapIndex = -1;
// reset PTOR
ctx->mPtorInfo.count = 0;
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",
__FUNCTION__, (result ? "successful" : "failed"), mOverlapIndex);
ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
(result ? "successful" : "failed"));
return result;
}
@@ -1586,7 +1627,9 @@ int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
sSimulationFlags, sSimulationFlags);
}
}
mOverlapIndex = -1;
// reset PTOR
if(!mDpy)
memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
//Do not cache the information for next draw cycle.
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 fd = -1;
if (mOverlapIndex != -1) {
fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list, mOverlapIndex);
if (ctx->mPtorInfo.isActive()) {
fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
if (fd < 0) {
ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
mOverlapIndex = -1;
}
}
return fd;
@@ -1883,17 +1925,20 @@ bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
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();
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 \
using pipe: %d", __FUNCTION__, layer,
hnd, dest );
int fd = hnd->fd;
uint32_t offset = (uint32_t)hnd->offset;
Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
if(rot) {
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 indexR = pipe_info.rIndex;
if (!mDpy && (i == mOverlapIndex)) {
hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
}
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)) {
fd = ctx->mAD->getDstFd();

View File

@@ -48,7 +48,6 @@ public:
/* dumpsys */
void dump(android::String8& buf, hwc_context_t *ctx);
bool isGLESOnlyComp() { return (mCurrentFrame.mdpCount == 0); }
bool isPTORActive() { return (mOverlapIndex != -1); }
int drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list);
static MDPComp* getObject(hwc_context_t *ctx, const int& dpy);
/* Handler to invoke frame redraw on Idle Timer expiry */
@@ -249,8 +248,6 @@ protected:
struct LayerCache mCachedFrame;
//Enable 4kx2k yuv layer split
static bool sEnable4k2kYUVSplit;
/* Overlap layer index */
int mOverlapIndex;
bool mModeOn; // if prepare happened
bool allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index);
};

View File

@@ -295,6 +295,7 @@ void initContext(hwc_context_t *ctx)
ctx->mGPUHintInfo.mCompositionState = COMPOSITION_STATE_MDP;
ctx->mGPUHintInfo.mCurrGPUPerfMode = EGL_GPU_LEVEL_0;
#endif
memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
ALOGI("Initializing Qualcomm Hardware Composer");
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
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 (ctx->mMDPComp[dpy]->isPTORActive())
if (ctx->mPtorInfo.isActive())
ctx->mCopyBit[dpy]->setReleaseFdSync(releaseFd);
else
ctx->mCopyBit[dpy]->setReleaseFd(releaseFd);

View File

@@ -41,6 +41,8 @@
#define MIN_DISPLAY_YRES 200
#define HWC_WFDDISPSYNC_LOG 0
#define STR(f) #f;
// Max number of PTOR layers handled
#define MAX_PTOR_LAYERS 2
//Fwrd decls
struct hwc_context_t;
@@ -131,6 +133,23 @@ struct ListStats {
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 {
uint32_t mFlags; //qcom specific layer flags
LayerProp():mFlags(0){};
@@ -574,6 +593,8 @@ struct hwc_context_t {
struct gpu_hint_info mGPUHintInfo;
//App Buffer Composition
bool enableABC;
// PTOR Info
qhwc::PtorInfo mPtorInfo;
};
namespace qhwc {