Merge "hwc : Enable ABC only for non intersecting layers."
diff --git a/libcopybit/copybit.cpp b/libcopybit/copybit.cpp
index 645cd81..84d7620 100644
--- a/libcopybit/copybit.cpp
+++ b/libcopybit/copybit.cpp
@@ -705,7 +705,7 @@
{
int status = -EINVAL;
- if (!strcmp(name, COPYBIT_HARDWARE_COPYBIT0)) {
+ if (strcmp(name, COPYBIT_HARDWARE_COPYBIT0)) {
return COPYBIT_FAILURE;
}
copybit_context_t *ctx;
diff --git a/libcopybit/copybit_c2d.cpp b/libcopybit/copybit_c2d.cpp
index 7e2c500..d2b00dd 100644
--- a/libcopybit/copybit_c2d.cpp
+++ b/libcopybit/copybit_c2d.cpp
@@ -962,7 +962,7 @@
/* Function to get the required size for a particular format, inorder for C2D to perform
* the blit operation.
*/
-static size_t get_size(const bufferInfo& info)
+static int get_size(const bufferInfo& info)
{
int size = 0;
int w = info.width;
diff --git a/libexternal/external.cpp b/libexternal/external.cpp
index 98a22cd..982146e 100644
--- a/libexternal/external.cpp
+++ b/libexternal/external.cpp
@@ -191,7 +191,7 @@
return;
} else {
len = read(hdmiScanInfoFile, scanInfo, sizeof(scanInfo)-1);
- ALOGD("%s: Scan Info string: %s length = %zu",
+ ALOGD("%s: Scan Info string: %s length = %zd",
__FUNCTION__, scanInfo, len);
if (len <= 0) {
close(hdmiScanInfoFile);
@@ -313,7 +313,7 @@
return false;
} else {
len = read(hdmiEDIDFile, edidStr, sizeof(edidStr)-1);
- ALOGD_IF(DEBUG, "%s: EDID string: %s length = %zu",
+ ALOGD_IF(DEBUG, "%s: EDID string: %s length = %zd",
__FUNCTION__, edidStr, len);
if ( len <= 0) {
ALOGE("%s: edid_modes file empty '%s'",
@@ -620,6 +620,13 @@
mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].mDownScaleMode =true;
}
}
+ //Initialize the display viewFrame info
+ mHwcContext->mViewFrame[HWC_DISPLAY_EXTERNAL].left = 0;
+ mHwcContext->mViewFrame[HWC_DISPLAY_EXTERNAL].top = 0;
+ mHwcContext->mViewFrame[HWC_DISPLAY_EXTERNAL].right =
+ (int)mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].xres;
+ mHwcContext->mViewFrame[HWC_DISPLAY_EXTERNAL].bottom =
+ (int)mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].yres;
mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].vsync_period =
(int) 1000000000l / fps;
}
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index 78e875a..8739f34 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -152,6 +152,10 @@
flags |= private_handle_t::PRIV_FLAGS_TILE_RENDERED;
}
+ if(usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
+ flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
+ }
+
flags |= data.allocType;
uint64_t eBaseAddr = (uint64_t)(eData.base) + eData.offset;
private_handle_t *hnd = new private_handle_t(data.fd, size, flags,
@@ -233,7 +237,7 @@
// find a free slot
for (uint32_t i=0 ; i<numBuffers ; i++) {
if ((bufferMask & (1LU<<i)) == 0) {
- m->bufferMask |= (1LU<<i);
+ m->bufferMask |= (uint32_t)(1LU<<i);
break;
}
vaddr += bufferSize;
@@ -323,7 +327,7 @@
const unsigned int bufferSize = m->finfo.line_length * m->info.yres;
unsigned int index = (unsigned int) ((hnd->base - m->framebuffer->base)
/ bufferSize);
- m->bufferMask &= ~(1LU<<index);
+ m->bufferMask &= (uint32_t)~(1LU<<index);
} else {
terminateBuffer(&m->base, const_cast<private_handle_t*>(hnd));
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index 7a4fc15..f029b80 100644
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -202,7 +202,9 @@
PRIV_FLAGS_ITU_R_709 = 0x00800000,
PRIV_FLAGS_SECURE_DISPLAY = 0x01000000,
// Buffer is rendered in Tile Format
- PRIV_FLAGS_TILE_RENDERED = 0x02000000
+ PRIV_FLAGS_TILE_RENDERED = 0x02000000,
+ // Buffer rendered using CPU/SW renderer
+ PRIV_FLAGS_CPU_RENDERED = 0x04000000
};
// file-descriptors
@@ -259,7 +261,7 @@
hnd->magic != sMagic)
{
ALOGD("Invalid gralloc handle (at %p): "
- "ver(%d/%u) ints(%d/%d) fds(%d/%d)"
+ "ver(%d/%zu) ints(%d/%d) fds(%d/%d)"
"magic(%c%c%c%c/%c%c%c%c)",
h,
h ? h->version : -1, sizeof(native_handle),
diff --git a/libgralloc/ionalloc.cpp b/libgralloc/ionalloc.cpp
index 2097320..ccf6ed5 100644
--- a/libgralloc/ionalloc.cpp
+++ b/libgralloc/ionalloc.cpp
@@ -114,7 +114,7 @@
data.base = base;
data.fd = fd_data.fd;
ioctl(mIonFd, ION_IOC_FREE, &handle_data);
- ALOGD_IF(DEBUG, "ion: Allocated buffer base:%p size:%u fd:%d",
+ ALOGD_IF(DEBUG, "ion: Allocated buffer base:%p size:%zu fd:%d",
data.base, ionAllocData.len, data.fd);
return 0;
}
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index b2466d0..267815f 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -143,11 +143,11 @@
hwc_layer_1_t const* layer = &list->hwLayers[layerIndex];
private_handle_t *hnd = (private_handle_t *)layer->handle;
- /* If a video layer requires rotation, set the DMA state
+ /* If a layer requires rotation, set the DMA state
* to BLOCK_MODE */
- if (UNLIKELY(isYuvBuffer(hnd)) && canUseRotator(ctx, dpy) &&
- (layer->transform & HWC_TRANSFORM_ROT_90)) {
+ if (canUseRotator(ctx, dpy) &&
+ has90Transform(layer) && isRotationDoable(ctx, hnd)) {
if(not ctx->mOverlay->isDMAMultiplexingSupported()) {
if(ctx->mOverlay->isPipeTypeAttached(
overlay::utils::OV_MDP_PIPE_DMA))
@@ -335,9 +335,9 @@
//Will be unlocked at the end of set
ctx->mDrawLock.lock();
- setPaddingRound(ctx,numDisplays,displays);
- setDMAState(ctx,numDisplays,displays);
- setNumActiveDisplays(ctx,numDisplays,displays);
+ setPaddingRound(ctx, (int)numDisplays, displays);
+ setDMAState(ctx, (int)numDisplays, displays);
+ setNumActiveDisplays(ctx, (int)numDisplays, displays);
reset(ctx, (int)numDisplays, displays);
ctx->mOverlay->configBegin();
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index 78e71eb..a5ecb3a 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -208,8 +208,8 @@
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 @@
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;
+ // Allocate render buffers if they're not allocated
+ 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)) {
@@ -384,7 +405,7 @@
hwc_display_contents_1_t *list,
int dpy, int *copybitFd) {
int layerCount = 0;
- uint32_t last = list->numHwLayers - 1;
+ uint32_t last = (uint32_t)list->numHwLayers - 1;
hwc_layer_1_t *fbLayer = &list->hwLayers[last];
private_handle_t *fbhnd = (private_handle_t *)fbLayer->handle;
@@ -512,7 +533,6 @@
// 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];
if(!(layerProp[i].mFlags & HWC_COPYBIT)) {
ALOGD_IF(DEBUG_COPYBIT, "%s: Not Marked for copybit", __FUNCTION__);
continue;
@@ -553,9 +573,9 @@
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__);
@@ -570,30 +590,34 @@
}
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;
- 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) {
- ALOGE("%s: sync_wait error!! error no = %d err str = %s",
- __FUNCTION__, errno, strerror(errno));
+ // Draw overlapped content of layers on render buffer
+ for (int i = 0; i <= ovlapIndex; i++) {
+ hwc_layer_1_t *layer = &list->hwLayers[i];
+ if(!isValidRect(getIntersection(layer->displayFrame,
+ overlap))) {
+ continue;
}
- close(list->hwLayers[i].acquireFenceFd);
- list->hwLayers[i].acquireFenceFd = -1;
- }
+ if ((list->hwLayers[i].acquireFenceFd != -1)) {
+ // Wait for acquire fence on the App buffers.
+ 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;
+ }
- hwc_layer_1_t *layer = &list->hwLayers[i];
- int retVal = drawRectUsingCopybit(ctx, layer, renderBuffer, overlap);
- copybitLayerCount++;
-
- if(retVal < 0) {
- ALOGE("%s: drawRectUsingCopybit failed", __FUNCTION__);
- copybitLayerCount = 0;
+ int retVal = drawRectUsingCopybit(ctx, layer, renderBuffer, overlap,
+ ptorInfo->displayFrame[j]);
+ copybitLayerCount++;
+ if(retVal < 0) {
+ ALOGE("%s: drawRectUsingCopybit failed", __FUNCTION__);
+ copybitLayerCount = 0;
+ }
}
}
@@ -602,12 +626,14 @@
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) {
@@ -637,16 +663,20 @@
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;
@@ -658,20 +688,27 @@
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 = ®Rect;
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, ©bitRegion);
+ int err = copybit->stretch(copybit, &dst, &src, &dstRect, &srcRect,
+ ©bitRegion);
if (err < 0)
ALOGE("%s: copybit stretch failed",__FUNCTION__);
@@ -1065,8 +1102,8 @@
return mEngine;
}
-CopyBit::CopyBit(hwc_context_t *ctx, const int& dpy) : mIsModeOn(false),
- mCopyBitDraw(false), mCurRenderBufferIndex(0), mEngine(0) {
+CopyBit::CopyBit(hwc_context_t *ctx, const int& dpy) : mEngine(0),
+ mIsModeOn(false), mCopyBitDraw(false), mCurRenderBufferIndex(0) {
getBufferSizeAndDimensions(ctx->dpyAttr[dpy].xres,
ctx->dpyAttr[dpy].yres,
diff --git a/libhwcomposer/hwc_copybit.h b/libhwcomposer/hwc_copybit.h
index 3d3d302..99a39c8 100644
--- a/libhwcomposer/hwc_copybit.h
+++ b/libhwcomposer/hwc_copybit.h
@@ -51,11 +51,9 @@
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 @@
// 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);
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index 59f6245..de4cd05 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -109,8 +109,7 @@
mRot = NULL;
return false;
}
- info.format = (mRot)->getDstFormat();
- updateSource(orient, info, sourceCrop);
+ updateSource(orient, info, sourceCrop, mRot);
rotFlags |= ovutils::ROT_PREROTATED;
}
return true;
@@ -208,7 +207,7 @@
transform, orient);
//Store the displayFrame, will be used in getDisplayViewFrame
ctx->dpyAttr[mDpy].mDstRect = displayFrame;
- setMdpFlags(layer, mdpFlags, 0, transform);
+ setMdpFlags(ctx, layer, mdpFlags, 0, transform);
// For External use rotator if there is a rotation value set
ret = preRotateExtDisplay(ctx, layer, info,
sourceCrop, mdpFlags, rotFlags);
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index b0953da..3a60fa3 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -127,11 +127,6 @@
sEnableMixedMode = false;
}
- if(property_get("debug.mdpcomp.logs", property, NULL) > 0) {
- if(atoi(property) != 0)
- sDebugLogs = true;
- }
-
sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
int val = atoi(property);
@@ -320,7 +315,7 @@
bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
private_handle_t *hnd = (private_handle_t *)layer->handle;
- if((not isYuvBuffer(hnd) and has90Transform(layer)) or
+ if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
(not isValidDimension(ctx,layer))
//More conditions here, SKIP, sRGB+Blend etc
) {
@@ -347,7 +342,7 @@
hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
hwc_rect_t dst = layer->displayFrame;
- bool rotated90 = (bool)layer->transform & HAL_TRANSFORM_ROT_90;
+ bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
int dst_w = dst.right - dst.left;
@@ -616,8 +611,9 @@
for(int index = 0; index < numAppLayers; index++ ) {
hwc_layer_1_t* layer = &list->hwLayers[index];
+ private_handle_t *hnd = (private_handle_t *)layer->handle;
if ((mCachedFrame.hnd[index] != layer->handle) ||
- isYuvBuffer((private_handle_t *)layer->handle)) {
+ isYuvBuffer(hnd)) {
hwc_rect_t dst = layer->displayFrame;
hwc_rect_t updatingRect = dst;
@@ -714,7 +710,7 @@
hwc_layer_1_t* layer = &list->hwLayers[i];
private_handle_t *hnd = (private_handle_t *)layer->handle;
- if(isYuvBuffer(hnd) && has90Transform(layer)) {
+ if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
if(!canUseRotator(ctx, mDpy)) {
ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
__FUNCTION__, mDpy);
@@ -816,80 +812,117 @@
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;
+ if(not isSupportedForMDPComp(ctx, layer)) {
+ ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
+ return false;
}
}
- // No overlap
- if (!overlapIdx)
- 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);
+ }
- // Update layer attributes
- hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
- hwc_rect_t destRect = deductRect(layer->displayFrame, overlap);
- 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;
+ 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,
+ 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;
@@ -902,7 +935,7 @@
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;
@@ -912,12 +945,16 @@
}
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;
}
@@ -1100,6 +1137,8 @@
mDpy ) {
return false;
}
+ if(ctx->listStats[mDpy].secureUI)
+ return false;
return true;
}
@@ -1158,7 +1197,7 @@
return false;
}
- if(layer->transform & HWC_TRANSFORM_ROT_90 && !canUseRotator(ctx,mDpy)) {
+ if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
return false;
}
@@ -1421,7 +1460,7 @@
hwc_display_contents_1_t* list) {
//Capability checks
- if(!resourceCheck()) {
+ if(!resourceCheck(ctx, list)) {
ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
return false;
}
@@ -1495,12 +1534,31 @@
return true;
}
-bool MDPComp::resourceCheck() {
+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;
}
+ // Init rotCount to number of rotate sessions used by other displays
+ int rotCount = ctx->mRotMgr->getNumActiveSessions();
+ // Count the number of rotator sessions required for current display
+ for (int index = 0; index < mCurrentFrame.layerCount; index++) {
+ if(!mCurrentFrame.isFBComposed[index]) {
+ hwc_layer_1_t* layer = &list->hwLayers[index];
+ private_handle_t *hnd = (private_handle_t *)layer->handle;
+ if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
+ rotCount++;
+ }
+ }
+ }
+ // if number of layers to rotate exceeds max rotator sessions, bail out.
+ if(rotCount > RotMgr::MAX_ROT_SESS) {
+ ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
+ __FUNCTION__, mDpy);
+ return false;
+ }
return true;
}
@@ -1566,7 +1624,9 @@
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)) {
@@ -1665,11 +1725,10 @@
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;
@@ -1682,6 +1741,8 @@
//fbz is above 4k2k layer, increment fb zorder by 1
//as we split 4k2k layer and increment zorder for right half
//of the layer
+ if(!ctx)
+ return;
if(mCurrentFrame.fbZ >= 0) {
for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
index++) {
@@ -1861,17 +1922,20 @@
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))
@@ -2110,12 +2174,14 @@
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();
@@ -2256,14 +2322,14 @@
}
eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
- setMdpFlags(layer, mdpFlags, 0, transform);
+ setMdpFlags(ctx, layer, mdpFlags, 0, transform);
if(lDest != OV_INVALID && rDest != OV_INVALID) {
//Enable overfetch
setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
}
- if(isYuvBuffer(hnd) && (transform & HWC_TRANSFORM_ROT_90)) {
+ if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
(*rot) = ctx->mRotMgr->getNext();
if((*rot) == NULL) return -1;
ctx->mLayerRotMap[mDpy]->add(layer, *rot);
@@ -2276,8 +2342,7 @@
ALOGE("%s: configRotator failed!", __FUNCTION__);
return -1;
}
- whf.format = (*rot)->getDstFormat();
- updateSource(orient, whf, crop);
+ updateSource(orient, whf, crop, *rot);
rotFlags |= ROT_PREROTATED;
}
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index 850e242..1ebe0bd 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -48,7 +48,6 @@
/* 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 */
@@ -57,6 +56,7 @@
static bool init(hwc_context_t *ctx);
static void resetIdleFallBack() { sIdleFallBack = false; }
static bool isIdleFallback() { return sIdleFallBack; }
+ static void dynamicDebug(bool enable){ sDebugLogs = enable; }
protected:
enum { MAX_SEC_LAYERS = 1 }; //TODO add property support
@@ -228,7 +228,7 @@
hwc_display_contents_1_t* list);
void reset(hwc_context_t *ctx);
bool isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer);
- bool resourceCheck();
+ bool resourceCheck(hwc_context_t* ctx, hwc_display_contents_1_t* list);
hwc_rect_t getUpdatingFBRect(hwc_context_t *ctx,
hwc_display_contents_1_t* list);
/* checks for conditions to enable partial udpate */
@@ -249,8 +249,6 @@
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);
};
diff --git a/libhwcomposer/hwc_qclient.cpp b/libhwcomposer/hwc_qclient.cpp
index 77215ca..892e9c0 100644
--- a/libhwcomposer/hwc_qclient.cpp
+++ b/libhwcomposer/hwc_qclient.cpp
@@ -31,6 +31,7 @@
#include <IQService.h>
#include <hwc_utils.h>
#include <mdp_version.h>
+#include <hwc_mdpcomp.h>
#define QCLIENT_DEBUG 0
@@ -213,6 +214,26 @@
}
}
+static void toggleDynamicDebug(hwc_context_t* ctx, const Parcel* inParcel) {
+ int debug_type = inParcel->readInt32();
+ bool enable = !!inParcel->readInt32();
+ ALOGD("%s: debug_type: %d enable:%d",
+ __FUNCTION__, debug_type, enable);
+ Locker::Autolock _sl(ctx->mDrawLock);
+ switch (debug_type) {
+ //break is ignored for DEBUG_ALL to toggle all of them at once
+ case IQService::DEBUG_ALL:
+ case IQService::DEBUG_MDPCOMP:
+ qhwc::MDPComp::dynamicDebug(enable);
+ if (debug_type != IQService::DEBUG_ALL)
+ break;
+ case IQService::DEBUG_VSYNC:
+ ctx->vstate.debug = enable;
+ if (debug_type != IQService::DEBUG_ALL)
+ break;
+ }
+}
+
status_t QClient::notifyCallback(uint32_t command, const Parcel* inParcel,
Parcel* outParcel) {
status_t ret = NO_ERROR;
@@ -255,6 +276,9 @@
case IQService::SET_VIEW_FRAME:
setViewFrame(mHwcContext, inParcel);
break;
+ case IQService::DYNAMIC_DEBUG:
+ toggleDynamicDebug(mHwcContext, inParcel);
+ break;
default:
ret = NO_ERROR;
}
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 671388b..cc18686 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -232,6 +232,13 @@
ctx->mMDPComp[HWC_DISPLAY_PRIMARY] =
MDPComp::getObject(ctx, HWC_DISPLAY_PRIMARY);
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].connected = true;
+ //Initialize the primary display viewFrame info
+ ctx->mViewFrame[HWC_DISPLAY_PRIMARY].left = 0;
+ ctx->mViewFrame[HWC_DISPLAY_PRIMARY].top = 0;
+ ctx->mViewFrame[HWC_DISPLAY_PRIMARY].right =
+ (int)ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
+ ctx->mViewFrame[HWC_DISPLAY_PRIMARY].bottom =
+ (int)ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
ctx->mVDSEnabled = false;
if((property_get("persist.hwc.enable_vds", value, NULL) > 0)) {
@@ -295,6 +302,7 @@
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);
}
@@ -481,10 +489,10 @@
width = float(rect.right - rect.left);
height = float(rect.bottom - rect.top);
}
- xRatio = (float)(inPos.x/actualWidth);
- yRatio = (float)(inPos.y/actualHeight);
- wRatio = (float)(inPos.w/actualWidth);
- hRatio = (float)(inPos.h/actualHeight);
+ xRatio = (float)((float)inPos.x/actualWidth);
+ yRatio = (float)((float)inPos.y/actualHeight);
+ wRatio = (float)((float)inPos.w/actualWidth);
+ hRatio = (float)((float)inPos.h/actualHeight);
//Calculate the pos9ition...
outPos.x = uint32_t((xRatio * width) + (float)xPos);
@@ -955,6 +963,32 @@
return false;
}
+bool isRotatorSupportedFormat(private_handle_t *hnd) {
+ // Following rotator src formats are supported by mdp driver
+ // TODO: Add more formats in future, if mdp driver adds support
+ switch(hnd->format) {
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_RGB_565:
+ case HAL_PIXEL_FORMAT_RGB_888:
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ return true;
+ default:
+ return false;
+ }
+ return false;
+}
+
+bool isRotationDoable(hwc_context_t *ctx, private_handle_t *hnd) {
+ // Rotate layers, if it is YUV type or rendered by CPU and not
+ // for the MDP versions below MDP5
+ if((isCPURendered(hnd) && isRotatorSupportedFormat(hnd) &&
+ !ctx->mMDP.version < qdutils::MDSS_V5)
+ || isYuvBuffer(hnd)) {
+ return true;
+ }
+ return false;
+}
+
// returns true if Action safe dimensions are set and target supports Actionsafe
bool isActionSafePresent(hwc_context_t *ctx, int dpy) {
// if external supports underscan, do nothing
@@ -1288,6 +1322,7 @@
if(ret < 0) {
ALOGE("%s: ioctl MSMFB_BUFFER_SYNC failed for rot sync, err=%s",
__FUNCTION__, strerror(errno));
+ close(rotReleaseFd);
} else {
close(currLayer->acquireFenceFd);
//For MDP to wait on.
@@ -1337,7 +1372,7 @@
}
}
- 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;
}
@@ -1347,10 +1382,7 @@
//Waits for acquire fences, returns a release fence
if(LIKELY(!swapzero)) {
- uint64_t start = systemTime();
ret = ioctl(fbFd, MSMFB_BUFFER_SYNC, &data);
- ALOGD_IF(HWC_UTILS_DEBUG, "%s: time taken for MSMFB_BUFFER_SYNC IOCTL = %d",
- __FUNCTION__, (size_t) ns2ms(systemTime() - start));
}
if(ret < 0) {
@@ -1359,6 +1391,10 @@
ALOGE("%s: acq_fen_fd_cnt=%d flags=%d fd=%d dpy=%d numHwLayers=%zu",
__FUNCTION__, data.acq_fen_fd_cnt, data.flags, fbFd,
dpy, list->numHwLayers);
+ close(releaseFd);
+ releaseFd = -1;
+ close(retireFd);
+ retireFd = -1;
}
for(uint32_t i = 0; i < list->numHwLayers; i++) {
@@ -1403,7 +1439,7 @@
}
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);
@@ -1422,7 +1458,7 @@
return ret;
}
-void setMdpFlags(hwc_layer_1_t *layer,
+void setMdpFlags(hwc_context_t *ctx, hwc_layer_1_t *layer,
ovutils::eMdpFlags &mdpFlags,
int rotDownscale, int transform) {
private_handle_t *hnd = (private_handle_t *)layer->handle;
@@ -1443,11 +1479,6 @@
ovutils::setMdpFlags(mdpFlags,
ovutils::OV_MDP_DEINTERLACE);
}
- //Pre-rotation will be used using rotator.
- if(transform & HWC_TRANSFORM_ROT_90) {
- ovutils::setMdpFlags(mdpFlags,
- ovutils::OV_MDP_SOURCE_ROTATED_90);
- }
}
if(isSecureDisplayBuffer(hnd)) {
@@ -1457,6 +1488,12 @@
ovutils::setMdpFlags(mdpFlags,
ovutils::OV_MDP_SECURE_DISPLAY_OVERLAY_SESSION);
}
+
+ //Pre-rotation will be used using rotator.
+ if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
+ ovutils::setMdpFlags(mdpFlags,
+ ovutils::OV_MDP_SOURCE_ROTATED_90);
+ }
//No 90 component and no rot-downscale then flips done by MDP
//If we use rot then it might as well do flips
if(!(transform & HWC_TRANSFORM_ROT_90) && !rotDownscale) {
@@ -1491,18 +1528,8 @@
if (qdutils::MDPVersion::getInstance().getMDPVersion() >=
qdutils::MDSS_V5) {
- uint32_t crop_w = (crop.right - crop.left);
- uint32_t crop_h = (crop.bottom - crop.top);
- if (ovutils::isYuv(whf.format)) {
- ovutils::normalizeCrop((uint32_t&)crop.left, crop_w);
- ovutils::normalizeCrop((uint32_t&)crop.top, crop_h);
- // For interlaced, crop.h should be 4-aligned
- if ((mdpFlags & ovutils::OV_MDP_DEINTERLACE) && (crop_h % 4))
- crop_h = ovutils::aligndown(crop_h, 4);
- crop.right = crop.left + crop_w;
- crop.bottom = crop.top + crop_h;
- }
- Dim rotCrop(crop.left, crop.top, crop_w, crop_h);
+ Dim rotCrop(crop.left, crop.top, crop.right - crop.left,
+ crop.bottom - crop.top);
rot->setCrop(rotCrop);
}
@@ -1577,28 +1604,27 @@
}
void updateSource(eTransform& orient, Whf& whf,
- hwc_rect_t& crop) {
- Dim srcCrop(crop.left, crop.top,
+ hwc_rect_t& crop, Rotator *rot) {
+ Dim transformedCrop(crop.left, crop.top,
crop.right - crop.left,
crop.bottom - crop.top);
- orient = static_cast<eTransform>(ovutils::getMdpOrient(orient));
- preRotateSource(orient, whf, srcCrop);
if (qdutils::MDPVersion::getInstance().getMDPVersion() >=
qdutils::MDSS_V5) {
- // Source for overlay will be the cropped (and rotated)
- crop.left = 0;
- crop.top = 0;
- crop.right = srcCrop.w;
- crop.bottom = srcCrop.h;
- // Set width & height equal to sourceCrop w & h
- whf.w = srcCrop.w;
- whf.h = srcCrop.h;
+ //B-family rotator internally could modify destination dimensions if
+ //downscaling is supported
+ whf = rot->getDstWhf();
+ transformedCrop = rot->getDstDimensions();
} else {
- crop.left = srcCrop.x;
- crop.top = srcCrop.y;
- crop.right = srcCrop.x + srcCrop.w;
- crop.bottom = srcCrop.y + srcCrop.h;
+ //A-family rotator rotates entire buffer irrespective of crop, forcing
+ //us to recompute the crop based on transform
+ orient = static_cast<eTransform>(ovutils::getMdpOrient(orient));
+ preRotateSource(orient, whf, transformedCrop);
}
+
+ crop.left = transformedCrop.x;
+ crop.top = transformedCrop.y;
+ crop.right = transformedCrop.x + transformedCrop.w;
+ crop.bottom = transformedCrop.y + transformedCrop.h;
}
int configureNonSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
@@ -1649,22 +1675,22 @@
}
}
- setMdpFlags(layer, mdpFlags, downscale, transform);
+ setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
- if(isYuvBuffer(hnd) && //if 90 component or downscale, use rot
- ((transform & HWC_TRANSFORM_ROT_90) || downscale)) {
+ //if 90 component or downscale, use rot
+ if((has90Transform(layer) && isRotationDoable(ctx, hnd)) || downscale) {
*rot = ctx->mRotMgr->getNext();
if(*rot == NULL) return -1;
ctx->mLayerRotMap[dpy]->add(layer, *rot);
- if(!dpy)
+ // BWC is not tested for other formats So enable it only for YUV format
+ if(!dpy && isYuvBuffer(hnd))
BwcPM::setBwc(crop, dst, transform, mdpFlags);
//Configure rotator for pre-rotation
if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
ALOGE("%s: configRotator failed!", __FUNCTION__);
return -1;
}
- whf.format = (*rot)->getDstFormat();
- updateSource(orient, whf, crop);
+ updateSource(orient, whf, crop, *rot);
rotFlags |= ovutils::ROT_PREROTATED;
}
@@ -1746,7 +1772,7 @@
ActionSafe, and extorientation features. */
calcExtDisplayPosition(ctx, hnd, dpy, crop, dst, transform, orient);
- setMdpFlags(layer, mdpFlagsL, 0, transform);
+ setMdpFlags(ctx, layer, mdpFlagsL, 0, transform);
if(lDest != OV_INVALID && rDest != OV_INVALID) {
//Enable overfetch
@@ -1760,7 +1786,7 @@
whf.format = wb->getOutputFormat();
}
- if(isYuvBuffer(hnd) && (transform & HWC_TRANSFORM_ROT_90)) {
+ if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
(*rot) = ctx->mRotMgr->getNext();
if((*rot) == NULL) return -1;
ctx->mLayerRotMap[dpy]->add(layer, *rot);
@@ -1769,8 +1795,7 @@
ALOGE("%s: configRotator failed!", __FUNCTION__);
return -1;
}
- whf.format = (*rot)->getDstFormat();
- updateSource(orient, whf, crop);
+ updateSource(orient, whf, crop, *rot);
rotFlags |= ROT_PREROTATED;
}
@@ -1888,22 +1913,22 @@
ActionSafe, and extorientation features. */
calcExtDisplayPosition(ctx, hnd, dpy, crop, dst, transform, orient);
- setMdpFlags(layer, mdpFlagsL, 0, transform);
+ setMdpFlags(ctx, layer, mdpFlagsL, 0, transform);
trimLayer(ctx, dpy, transform, crop, dst);
- if(isYuvBuffer(hnd) && (transform & HWC_TRANSFORM_ROT_90)) {
+ if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
(*rot) = ctx->mRotMgr->getNext();
if((*rot) == NULL) return -1;
ctx->mLayerRotMap[dpy]->add(layer, *rot);
- if(!dpy)
+ // BWC is not tested for other formats So enable it only for YUV format
+ if(!dpy && isYuvBuffer(hnd))
BwcPM::setBwc(crop, dst, transform, mdpFlagsL);
//Configure rotator for pre-rotation
if(configRotator(*rot, whf, crop, mdpFlagsL, orient, downscale) < 0) {
ALOGE("%s: configRotator failed!", __FUNCTION__);
return -1;
}
- whf.format = (*rot)->getDstFormat();
- updateSource(orient, whf, crop);
+ updateSource(orient, whf, crop, *rot);
rotFlags |= ROT_PREROTATED;
}
@@ -2177,30 +2202,23 @@
if(!qdutils::MDPVersion::getInstance().supportsBWC()) {
return;
}
+ int src_w = crop.right - crop.left;
+ int src_h = crop.bottom - crop.top;
+ int dst_w = dst.right - dst.left;
+ int dst_h = dst.bottom - dst.top;
+ if(transform & HAL_TRANSFORM_ROT_90) {
+ swap(src_w, src_h);
+ }
//src width > MAX mixer supported dim
- if((crop.right - crop.left) > qdutils::MAX_DISPLAY_DIM) {
+ if(src_w > qdutils::MAX_DISPLAY_DIM) {
return;
}
//Decimation necessary, cannot use BWC. H/W requirement.
if(qdutils::MDPVersion::getInstance().supportsDecimation()) {
- int src_w = crop.right - crop.left;
- int src_h = crop.bottom - crop.top;
- int dst_w = dst.right - dst.left;
- int dst_h = dst.bottom - dst.top;
- if(transform & HAL_TRANSFORM_ROT_90) {
- swap(src_w, src_h);
- }
- float horDscale = 0.0f;
- float verDscale = 0.0f;
- int horzDeci = 0;
- int vertDeci = 0;
- ovutils::getDecimationFactor(src_w, src_h, dst_w, dst_h, horDscale,
- verDscale);
- //TODO Use log2f once math.h has it
- if((int)horDscale)
- horzDeci = (int)(log(horDscale) / log(2));
- if((int)verDscale)
- vertDeci = (int)(log(verDscale) / log(2));
+ uint8_t horzDeci = 0;
+ uint8_t vertDeci = 0;
+ ovutils::getDecimationFactor(src_w, src_h, dst_w, dst_h, horzDeci,
+ vertDeci);
if(horzDeci || vertDeci) return;
}
//Property
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 06f7f9f..49a01b2 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -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 @@
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){};
@@ -139,6 +158,7 @@
struct VsyncState {
bool enable;
bool fakevsync;
+ bool debug;
};
struct BwcPM {
@@ -235,6 +255,10 @@
hwc_rect_t& nwr);
bool isSecuring(hwc_context_t* ctx, hwc_layer_1_t const* layer);
bool isSecureModePolicy(int mdpVersion);
+// Returns true, if the input layer format is supported by rotator
+bool isRotatorSupportedFormat(private_handle_t *hnd);
+//Returns true, if the layer is YUV or the layer has been rendered by CPU
+bool isRotationDoable(hwc_context_t *ctx, private_handle_t *hnd);
bool isExternalActive(hwc_context_t* ctx);
bool isAlphaScaled(hwc_layer_1_t const* layer);
bool needsScaling(hwc_layer_1_t const* layer);
@@ -315,7 +339,7 @@
int fd);
//Sets appropriate mdp flags for a layer.
-void setMdpFlags(hwc_layer_1_t *layer,
+void setMdpFlags(hwc_context_t *ctx, hwc_layer_1_t *layer,
ovutils::eMdpFlags &mdpFlags,
int rotDownscale, int transform);
@@ -333,7 +357,7 @@
ovutils::eIsFg& isFg, const ovutils::eDest& dest);
void updateSource(ovutils::eTransform& orient, ovutils::Whf& whf,
- hwc_rect_t& crop);
+ hwc_rect_t& crop, overlay::Rotator *rot);
//Routine to configure low resolution panels (<= 2048 width)
int configureNonSplit(hwc_context_t *ctx, hwc_layer_1_t *layer, const int& dpy,
@@ -400,6 +424,10 @@
return (hnd && (private_handle_t::PRIV_FLAGS_TILE_RENDERED & hnd->flags));
}
+static inline bool isCPURendered(const private_handle_t* hnd) {
+ return (hnd && (private_handle_t::PRIV_FLAGS_CPU_RENDERED & hnd->flags));
+}
+
//Return true if buffer is marked locked
static inline bool isBufferLocked(const private_handle_t* hnd) {
return (hnd && (private_handle_t::PRIV_FLAGS_HWC_LOCK & hnd->flags));
@@ -566,6 +594,8 @@
struct gpu_hint_info mGPUHintInfo;
//App Buffer Composition
bool enableABC;
+ // PTOR Info
+ qhwc::PtorInfo mPtorInfo;
};
namespace qhwc {
@@ -577,7 +607,7 @@
return ctx->listStats[dpy].yuvCount;
}
-static inline bool has90Transform(hwc_layer_1_t *layer) {
+static inline bool has90Transform(hwc_layer_1_t const* layer) {
return ((layer->transform & HWC_TRANSFORM_ROT_90) &&
!(layer->flags & HWC_COLOR_FILL));
}
diff --git a/libhwcomposer/hwc_vsync.cpp b/libhwcomposer/hwc_vsync.cpp
index 7bde83b..47f2229 100644
--- a/libhwcomposer/hwc_vsync.cpp
+++ b/libhwcomposer/hwc_vsync.cpp
@@ -40,7 +40,6 @@
#define PANEL_ON_STR "panel_power_on ="
#define ARRAY_LENGTH(array) (sizeof((array))/sizeof((array)[0]))
const int MAX_DATA = 64;
-bool logvsync = false;
int hwc_vsync_control(hwc_context_t* ctx, int dpy, int enable)
{
@@ -63,7 +62,7 @@
timestamp = strtoull(data + strlen("VSYNC="), NULL, 0);
}
// send timestamp to SurfaceFlinger
- ALOGD_IF (logvsync, "%s: timestamp %"PRIu64" sent to SF for dpy=%d",
+ ALOGD_IF (ctx->vstate.debug, "%s: timestamp %"PRIu64" sent to SF for dpy=%d",
__FUNCTION__, timestamp, dpy);
ctx->proc->vsync(ctx->proc, dpy, timestamp);
}
@@ -71,8 +70,8 @@
static void handle_blank_event(hwc_context_t* ctx, int dpy, char *data)
{
if (!strncmp(data, PANEL_ON_STR, strlen(PANEL_ON_STR))) {
- uint32_t poweron = strtoul(data + strlen(PANEL_ON_STR), NULL, 0);
- ALOGI("%s: dpy:%d panel power state: %d", __FUNCTION__, dpy, poweron);
+ unsigned long int poweron = strtoul(data + strlen(PANEL_ON_STR), NULL, 0);
+ ALOGI("%s: dpy:%d panel power state: %ld", __FUNCTION__, dpy, poweron);
ctx->dpyAttr[dpy].isActive = poweron ? true: false;
}
}
@@ -110,11 +109,6 @@
ctx->vstate.fakevsync = true;
}
- if(property_get("debug.hwc.logvsync", property, 0) > 0) {
- if(atoi(property) == 1)
- logvsync = true;
- }
-
char node_path[MAX_SYSFS_FILE_PATH];
for (int dpy = HWC_DISPLAY_PRIMARY; dpy < num_displays; dpy++) {
@@ -151,7 +145,7 @@
if (LIKELY(!ctx->vstate.fakevsync)) {
do {
- int err = poll(*pfd, num_displays * num_events, -1);
+ int err = poll(*pfd, (int)(num_displays * num_events), -1);
if(err > 0) {
for (int dpy = HWC_DISPLAY_PRIMARY; dpy < num_displays; dpy++) {
for(size_t ev = 0; ev < num_events; ev++) {
diff --git a/liblight/lights.c b/liblight/lights.c
index 6fd1290..615ddd8 100644
--- a/liblight/lights.c
+++ b/liblight/lights.c
@@ -168,12 +168,18 @@
}
if (blink) {
- if (red)
- write_int(RED_BLINK_FILE, blink);
- if (green)
- write_int(GREEN_BLINK_FILE, blink);
- if (blue)
- write_int(BLUE_BLINK_FILE, blink);
+ if (red) {
+ if (write_int(RED_BLINK_FILE, blink))
+ write_int(RED_LED_FILE, 0);
+ }
+ if (green) {
+ if (write_int(GREEN_BLINK_FILE, blink))
+ write_int(GREEN_LED_FILE, 0);
+ }
+ if (blue) {
+ if (write_int(BLUE_BLINK_FILE, blink))
+ write_int(BLUE_LED_FILE, 0);
+ }
} else {
write_int(RED_LED_FILE, red);
write_int(GREEN_LED_FILE, green);
@@ -194,6 +200,17 @@
}
static int
+set_light_battery(struct light_device_t* dev,
+ struct light_state_t const* state)
+{
+ pthread_mutex_lock(&g_lock);
+ g_battery = *state;
+ handle_speaker_battery_locked(dev);
+ pthread_mutex_unlock(&g_lock);
+ return 0;
+}
+
+static int
set_light_notifications(struct light_device_t* dev,
struct light_state_t const* state)
{
@@ -259,6 +276,8 @@
if (0 == strcmp(LIGHT_ID_BACKLIGHT, name))
set_light = set_light_backlight;
+ else if (0 == strcmp(LIGHT_ID_BATTERY, name))
+ set_light = set_light_battery;
else if (0 == strcmp(LIGHT_ID_NOTIFICATIONS, name))
set_light = set_light_notifications;
else if (0 == strcmp(LIGHT_ID_BUTTONS, name))
diff --git a/libmemtrack/kgsl.c b/libmemtrack/kgsl.c
index 6194043..b644d73 100644
--- a/libmemtrack/kgsl.c
+++ b/libmemtrack/kgsl.c
@@ -87,7 +87,7 @@
* gpuaddr useraddr size id flags type usage sglen
* 545ba000 545ba000 4096 1 ----pY gpumem arraybuffer 1
*/
- ret = sscanf(line, "%*x %*lx %lu %*d %6s %6s %*s %*d\n",
+ ret = sscanf(line, "%*x %*x %lu %*d %6s %6s %*s %*d\n",
&size, flags, line_type);
if (ret != 3) {
continue;
diff --git a/liboverlay/mdpWrapper.h b/liboverlay/mdpWrapper.h
index 1bfa058..e24ad6a 100644
--- a/liboverlay/mdpWrapper.h
+++ b/liboverlay/mdpWrapper.h
@@ -30,6 +30,8 @@
#ifndef MDP_WRAPPER_H
#define MDP_WRAPPER_H
+#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
+
/*
* In order to make overlay::mdp_wrapper shorter, please do something like:
* namespace mdpwrap = overlay::mdp_wrapper;
@@ -39,6 +41,7 @@
#include <linux/msm_rotator.h>
#include <sys/ioctl.h>
#include <utils/Log.h>
+#include <utils/Trace.h>
#include <errno.h>
#include "overlayUtils.h"
@@ -80,9 +83,6 @@
/* MSMFB_OVERLAY_PLAY */
bool play(int fd, msmfb_overlay_data& od);
-/* MSMFB_OVERLAY_3D */
-bool set3D(int fd, msmfb_overlay_3d& ov);
-
/* MSMFB_DISPLAY_COMMIT */
bool displayCommit(int fd);
@@ -119,6 +119,7 @@
//---------------Inlines -------------------------------------
inline bool getFScreenInfo(int fd, fb_fix_screeninfo& finfo) {
+ ATRACE_CALL();
if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) < 0) {
ALOGE("Failed to call ioctl FBIOGET_FSCREENINFO err=%s",
strerror(errno));
@@ -128,6 +129,7 @@
}
inline bool getVScreenInfo(int fd, fb_var_screeninfo& vinfo) {
+ ATRACE_CALL();
if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) < 0) {
ALOGE("Failed to call ioctl FBIOGET_VSCREENINFO err=%s",
strerror(errno));
@@ -137,6 +139,7 @@
}
inline bool setVScreenInfo(int fd, fb_var_screeninfo& vinfo) {
+ ATRACE_CALL();
if (ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo) < 0) {
ALOGE("Failed to call ioctl FBIOPUT_VSCREENINFO err=%s",
strerror(errno));
@@ -146,6 +149,7 @@
}
inline bool startRotator(int fd, msm_rotator_img_info& rot) {
+ ATRACE_CALL();
if (ioctl(fd, MSM_ROTATOR_IOCTL_START, &rot) < 0){
ALOGE("Failed to call ioctl MSM_ROTATOR_IOCTL_START err=%s",
strerror(errno));
@@ -155,6 +159,7 @@
}
inline bool rotate(int fd, msm_rotator_data_info& rot) {
+ ATRACE_CALL();
if (ioctl(fd, MSM_ROTATOR_IOCTL_ROTATE, &rot) < 0) {
ALOGE("Failed to call ioctl MSM_ROTATOR_IOCTL_ROTATE err=%s",
strerror(errno));
@@ -164,6 +169,7 @@
}
inline bool setOverlay(int fd, mdp_overlay& ov) {
+ ATRACE_CALL();
if (ioctl(fd, MSMFB_OVERLAY_SET, &ov) < 0) {
ALOGE("Failed to call ioctl MSMFB_OVERLAY_SET err=%s",
strerror(errno));
@@ -173,6 +179,7 @@
}
inline bool validateAndSet(const int& fd, mdp_overlay_list& list) {
+ ATRACE_CALL();
if (ioctl(fd, MSMFB_OVERLAY_PREPARE, &list) < 0) {
ALOGD_IF(IOCTL_DEBUG, "Failed to call ioctl MSMFB_OVERLAY_PREPARE "
"err=%s", strerror(errno));
@@ -182,6 +189,7 @@
}
inline bool endRotator(int fd, uint32_t sessionId) {
+ ATRACE_CALL();
if (ioctl(fd, MSM_ROTATOR_IOCTL_FINISH, &sessionId) < 0) {
ALOGE("Failed to call ioctl MSM_ROTATOR_IOCTL_FINISH err=%s",
strerror(errno));
@@ -191,6 +199,7 @@
}
inline bool unsetOverlay(int fd, int ovId) {
+ ATRACE_CALL();
if (ioctl(fd, MSMFB_OVERLAY_UNSET, &ovId) < 0) {
ALOGE("Failed to call ioctl MSMFB_OVERLAY_UNSET err=%s",
strerror(errno));
@@ -200,6 +209,7 @@
}
inline bool getOverlay(int fd, mdp_overlay& ov) {
+ ATRACE_CALL();
if (ioctl(fd, MSMFB_OVERLAY_GET, &ov) < 0) {
ALOGE("Failed to call ioctl MSMFB_OVERLAY_GET err=%s",
strerror(errno));
@@ -209,6 +219,7 @@
}
inline bool play(int fd, msmfb_overlay_data& od) {
+ ATRACE_CALL();
if (ioctl(fd, MSMFB_OVERLAY_PLAY, &od) < 0) {
ALOGE("Failed to call ioctl MSMFB_OVERLAY_PLAY err=%s",
strerror(errno));
@@ -217,16 +228,8 @@
return true;
}
-inline bool set3D(int fd, msmfb_overlay_3d& ov) {
- if (ioctl(fd, MSMFB_OVERLAY_3D, &ov) < 0) {
- ALOGE("Failed to call ioctl MSMFB_OVERLAY_3D err=%s",
- strerror(errno));
- return false;
- }
- return true;
-}
-
inline bool displayCommit(int fd, mdp_display_commit& info) {
+ ATRACE_CALL();
if(ioctl(fd, MSMFB_DISPLAY_COMMIT, &info) == -1) {
ALOGE("Failed to call ioctl MSMFB_DISPLAY_COMMIT err=%s",
strerror(errno));
@@ -236,6 +239,7 @@
}
inline bool wbInitStart(int fbfd) {
+ ATRACE_CALL();
if(ioctl(fbfd, MSMFB_WRITEBACK_INIT, NULL) < 0) {
ALOGE("Failed to call ioctl MSMFB_WRITEBACK_INIT err=%s",
strerror(errno));
@@ -250,6 +254,7 @@
}
inline bool wbStopTerminate(int fbfd) {
+ ATRACE_CALL();
if(ioctl(fbfd, MSMFB_WRITEBACK_STOP, NULL) < 0) {
ALOGE("Failed to call ioctl MSMFB_WRITEBACK_STOP err=%s",
strerror(errno));
@@ -264,6 +269,7 @@
}
inline bool wbQueueBuffer(int fbfd, struct msmfb_data& fbData) {
+ ATRACE_CALL();
if(ioctl(fbfd, MSMFB_WRITEBACK_QUEUE_BUFFER, &fbData) < 0) {
ALOGE("Failed to call ioctl MSMFB_WRITEBACK_QUEUE_BUFFER err=%s",
strerror(errno));
@@ -273,6 +279,7 @@
}
inline bool wbDequeueBuffer(int fbfd, struct msmfb_data& fbData) {
+ ATRACE_CALL();
if(ioctl(fbfd, MSMFB_WRITEBACK_DEQUEUE_BUFFER, &fbData) < 0) {
ALOGE("Failed to call ioctl MSMFB_WRITEBACK_DEQUEUE_BUFFER err=%s",
strerror(errno));
diff --git a/liboverlay/overlayCtrlData.h b/liboverlay/overlayCtrlData.h
index 5cadebd..2eec98c 100644
--- a/liboverlay/overlayCtrlData.h
+++ b/liboverlay/overlayCtrlData.h
@@ -77,8 +77,6 @@
/* retrieve crop data */
utils::Dim getCrop() const;
utils::Dim getPosition() const;
- /* Set downscale */
- void setDownscale(int dscale_factor);
/* Update the src format based on rotator's dest */
void updateSrcFormat(const uint32_t& rotDstFormat);
/* return pipe priority */
@@ -213,10 +211,6 @@
return mMdp->getDstRectDim();
}
-inline void Ctrl::setDownscale(int dscale_factor) {
- mMdp->setDownscale(dscale_factor);
-}
-
inline uint8_t Ctrl::getPriority() const {
return mMdp->getPriority();
}
diff --git a/liboverlay/overlayMdp.cpp b/liboverlay/overlayMdp.cpp
index 4622d16..7f9f136 100644
--- a/liboverlay/overlayMdp.cpp
+++ b/liboverlay/overlayMdp.cpp
@@ -54,7 +54,6 @@
utils::memset0(mOVInfo);
mOVInfo.id = MSMFB_NEW_REQUEST;
mOrientation = utils::OVERLAY_TRANSFORM_0;
- mDownscale = 0;
mDpy = 0;
#ifdef USES_POST_PROCESSING
memset(&mParams, 0, sizeof(struct compute_params));
@@ -147,39 +146,10 @@
}
void MdpCtrl::doDownscale() {
- int mdpVersion = MDPVersion::getInstance().getMDPVersion();
- if(mdpVersion < MDSS_V5) {
- mOVInfo.src_rect.x >>= mDownscale;
- mOVInfo.src_rect.y >>= mDownscale;
- mOVInfo.src_rect.w >>= mDownscale;
- mOVInfo.src_rect.h >>= mDownscale;
- } else if(MDPVersion::getInstance().supportsDecimation()) {
- //Decimation + MDP Downscale
- mOVInfo.horz_deci = 0;
- mOVInfo.vert_deci = 0;
- int minHorDeci = 0;
- if(mOVInfo.src_rect.w > 2048) {
- //If the client sends us something > what a layer mixer supports
- //then it means it doesn't want to use split-pipe but wants us to
- //decimate. A minimum decimation of 2 will ensure that the width is
- //always within layer mixer limits.
- minHorDeci = 2;
- }
-
- float horDscale = 0.0f;
- float verDscale = 0.0f;
-
+ if(MDPVersion::getInstance().supportsDecimation()) {
utils::getDecimationFactor(mOVInfo.src_rect.w, mOVInfo.src_rect.h,
- mOVInfo.dst_rect.w, mOVInfo.dst_rect.h, horDscale, verDscale);
-
- if(horDscale < minHorDeci)
- horDscale = minHorDeci;
-
- if((int)horDscale)
- mOVInfo.horz_deci = (int)log2f(horDscale);
-
- if((int)verDscale)
- mOVInfo.vert_deci = (int)log2f(verDscale);
+ mOVInfo.dst_rect.w, mOVInfo.dst_rect.h, mOVInfo.horz_deci,
+ mOVInfo.vert_deci);
}
}
@@ -247,12 +217,6 @@
ovutils::getDump(buf, len, "Data", mOvData);
}
-void MdpCtrl3D::dump() const {
- ALOGE("== Dump MdpCtrl start ==");
- mFd.dump();
- ALOGE("== Dump MdpCtrl end ==");
-}
-
bool MdpCtrl::setVisualParams(const MetaData_t& data) {
ALOGD_IF(0, "In %s: data.operation = %d", __FUNCTION__, data.operation);
#ifdef USES_POST_PROCESSING
diff --git a/liboverlay/overlayMdp.h b/liboverlay/overlayMdp.h
index f7d64f0..cb8e057 100644
--- a/liboverlay/overlayMdp.h
+++ b/liboverlay/overlayMdp.h
@@ -64,8 +64,6 @@
void setPosition(const utils::Dim& dim);
/* using user_data, sets/unsets roationvalue in mdp flags */
void setRotationFlags();
- /* Performs downscale calculations */
- void setDownscale(int dscale_factor);
/* Update the src format with rotator's dest*/
void updateSrcFormat(const uint32_t& rotDstFormat);
/* dump state of the object */
@@ -125,7 +123,6 @@
mdp_overlay mOVInfo;
/* FD for the mdp fbnum */
OvFD mFd;
- int mDownscale;
int mDpy;
#ifdef USES_POST_PROCESSING
@@ -134,31 +131,6 @@
#endif
};
-
-/* MDP 3D related ctrl */
-class MdpCtrl3D {
-public:
- /* ctor reset data */
- MdpCtrl3D();
- /* calls MSMFB_OVERLAY_3D */
- bool close();
- /* set w/h. format is ignored*/
- void setWh(const utils::Whf& whf);
- /* set is_3d calls MSMFB_OVERLAY_3D */
- bool useVirtualFB();
- /* set fd to be used in ioctl */
- void setFd(int fd);
- /* dump */
- void dump() const;
-private:
- /* reset */
- void reset();
- /* actual MSM 3D info */
- msmfb_overlay_3d m3DOVInfo;
- /* FD for the mdp 3D */
- OvFD mFd;
-};
-
/* MDP data */
class MdpData {
public:
@@ -236,10 +208,6 @@
mOVInfo.is_fg = isFg;
}
-inline void MdpCtrl::setDownscale(int dscale) {
- mDownscale = dscale;
-}
-
inline void MdpCtrl::setPlaneAlpha(int planeAlpha) {
mOVInfo.alpha = planeAlpha;
}
@@ -312,46 +280,6 @@
return mOVInfo.priority;
}
-/////// MdpCtrl3D //////
-
-inline MdpCtrl3D::MdpCtrl3D() { reset(); }
-inline bool MdpCtrl3D::close() {
- if (m3DOVInfo.is_3d) {
- m3DOVInfo.is_3d = 0;
- if(!mdp_wrapper::set3D(mFd.getFD(), m3DOVInfo)) {
- ALOGE("MdpCtrl3D close failed set3D with 0");
- return false;
- }
- }
- reset();
- return true;
-}
-inline void MdpCtrl3D::reset() {
- utils::memset0(m3DOVInfo);
-}
-
-inline void MdpCtrl3D::setFd(int fd) {
- mFd.copy(fd);
- OVASSERT(mFd.valid(), "MdpCtrl3D setFd, FD should be valid");
-}
-
-inline void MdpCtrl3D::setWh(const utils::Whf& whf) {
- // ignore fmt. Needed for useVirtualFB callflow
- m3DOVInfo.width = whf.w;
- m3DOVInfo.height = whf.h;
-}
-
-inline bool MdpCtrl3D::useVirtualFB() {
- if(!m3DOVInfo.is_3d) {
- m3DOVInfo.is_3d = 1;
- if(!mdp_wrapper::set3D(mFd.getFD(), m3DOVInfo)) {
- ALOGE("MdpCtrl3D close failed set3D with 0");
- return false;
- }
- }
- return true;
-}
-
/////// MdpData //////
inline MdpData::MdpData(const int& dpy) {
diff --git a/liboverlay/overlayMdpRot.cpp b/liboverlay/overlayMdpRot.cpp
index 38b0a92..bb985d7 100755
--- a/liboverlay/overlayMdpRot.cpp
+++ b/liboverlay/overlayMdpRot.cpp
@@ -19,6 +19,7 @@
#include "overlayUtils.h"
#include "overlayRotator.h"
+#include "gr.h"
namespace ovutils = overlay::utils;
@@ -33,7 +34,7 @@
bool MdpRot::enabled() const { return mRotImgInfo.enable; }
-void MdpRot::setRotations(uint32_t r) { mRotImgInfo.rotations = r; }
+void MdpRot::setRotations(uint32_t r) { mRotImgInfo.rotations = (uint8_t)r; }
int MdpRot::getDstMemId() const {
return mRotDataInfo.dst.memory_id;
@@ -47,6 +48,24 @@
return mRotImgInfo.dst.format;
}
+//Added for completeness. Not expected to be called.
+utils::Whf MdpRot::getDstWhf() const {
+ int alW = 0, alH = 0;
+ int halFormat = ovutils::getHALFormat(mRotImgInfo.dst.format);
+ getBufferSizeAndDimensions(mRotImgInfo.dst.width, mRotImgInfo.dst.height,
+ halFormat, alW, alH);
+ return utils::Whf(alW, alH, mRotImgInfo.dst.format);
+}
+
+//Added for completeness. Not expected to be called.
+utils::Dim MdpRot::getDstDimensions() const {
+ int alW = 0, alH = 0;
+ int halFormat = ovutils::getHALFormat(mRotImgInfo.dst.format);
+ getBufferSizeAndDimensions(mRotImgInfo.dst.width, mRotImgInfo.dst.height,
+ halFormat, alW, alH);
+ return utils::Dim(0, 0, alW, alH);
+}
+
uint32_t MdpRot::getSessId() const { return mRotImgInfo.session_id; }
void MdpRot::setDownscale(int ds) {
diff --git a/liboverlay/overlayMdssRot.cpp b/liboverlay/overlayMdssRot.cpp
index f7bc87a..5783dcb 100644
--- a/liboverlay/overlayMdssRot.cpp
+++ b/liboverlay/overlayMdssRot.cpp
@@ -63,6 +63,21 @@
return mRotInfo.src.format;
}
+utils::Whf MdssRot::getDstWhf() const {
+ //For Mdss dst_rect itself represents buffer dimensions. We ignore actual
+ //aligned values during buffer allocation. Also the driver overwrites the
+ //src.format field if destination format is different.
+ //This implementation detail makes it possible to retrieve w,h even before
+ //buffer allocation, which happens in queueBuffer.
+ return utils::Whf(mRotInfo.dst_rect.w, mRotInfo.dst_rect.h,
+ mRotInfo.src.format);
+}
+
+utils::Dim MdssRot::getDstDimensions() const {
+ return utils::Dim(mRotInfo.dst_rect.x, mRotInfo.dst_rect.y,
+ mRotInfo.dst_rect.w, mRotInfo.dst_rect.h);
+}
+
uint32_t MdssRot::getSessId() const { return mRotInfo.id; }
bool MdssRot::init() {
@@ -82,16 +97,10 @@
}
void MdssRot::setCrop(const utils::Dim& crop) {
-
mRotInfo.src_rect.x = crop.x;
mRotInfo.src_rect.y = crop.y;
mRotInfo.src_rect.w = crop.w;
mRotInfo.src_rect.h = crop.h;
-
- mRotInfo.dst_rect.x = 0;
- mRotInfo.dst_rect.y = 0;
- mRotInfo.dst_rect.w = crop.w;
- mRotInfo.dst_rect.h = crop.h;
}
void MdssRot::setDownscale(int /*ds*/) {
@@ -119,7 +128,22 @@
}
bool MdssRot::commit() {
+ if (utils::isYuv(mRotInfo.src.format)) {
+ utils::normalizeCrop(mRotInfo.src_rect.x, mRotInfo.src_rect.w);
+ utils::normalizeCrop(mRotInfo.src_rect.y, mRotInfo.src_rect.h);
+ // For interlaced, crop.h should be 4-aligned
+ if ((mRotInfo.flags & utils::OV_MDP_DEINTERLACE) and
+ (mRotInfo.src_rect.h % 4))
+ mRotInfo.src_rect.h = utils::aligndown(mRotInfo.src_rect.h, 4);
+ }
+
+ mRotInfo.dst_rect.x = 0;
+ mRotInfo.dst_rect.y = 0;
+ mRotInfo.dst_rect.w = mRotInfo.src_rect.w;
+ mRotInfo.dst_rect.h = mRotInfo.src_rect.h;
+
doTransform();
+
mRotInfo.flags |= MDSS_MDP_ROT_ONLY;
mEnabled = true;
if(!overlay::mdp_wrapper::setOverlay(mFd.getFD(), mRotInfo)) {
diff --git a/liboverlay/overlayRotator.h b/liboverlay/overlayRotator.h
index f7b44bd..64387cd 100644
--- a/liboverlay/overlayRotator.h
+++ b/liboverlay/overlayRotator.h
@@ -74,9 +74,14 @@
virtual void setTransform(const utils::eTransform& rot) = 0;
virtual bool commit() = 0;
virtual void setDownscale(int ds) = 0;
+ //Mem id and offset should be retrieved only after rotator kickoff
virtual int getDstMemId() const = 0;
virtual uint32_t getDstOffset() const = 0;
+ //Destination width, height, format, position should be retrieved only after
+ //rotator configuration is committed via commit API
virtual uint32_t getDstFormat() const = 0;
+ virtual utils::Whf getDstWhf() const = 0;
+ virtual utils::Dim getDstDimensions() const = 0;
virtual uint32_t getSessId() const = 0;
virtual bool queueBuffer(int fd, uint32_t offset) = 0;
virtual void dump() const = 0;
@@ -112,6 +117,8 @@
virtual int getDstMemId() const;
virtual uint32_t getDstOffset() const;
virtual uint32_t getDstFormat() const;
+ virtual utils::Whf getDstWhf() const;
+ virtual utils::Dim getDstDimensions() const;
virtual uint32_t getSessId() const;
virtual bool queueBuffer(int fd, uint32_t offset);
virtual void dump() const;
@@ -169,6 +176,8 @@
virtual int getDstMemId() const;
virtual uint32_t getDstOffset() const;
virtual uint32_t getDstFormat() const;
+ virtual utils::Whf getDstWhf() const;
+ virtual utils::Dim getDstDimensions() const;
virtual uint32_t getSessId() const;
virtual bool queueBuffer(int fd, uint32_t offset);
virtual void dump() const;
@@ -210,6 +219,9 @@
// Holder of rotator objects. Manages lifetimes
class RotMgr {
public:
+ //Virtually we can support as many rotator sessions as possible, However
+ // more number of rotator sessions leads to performance issues, so
+ // restricting the max rotator session to 4
enum { MAX_ROT_SESS = 4 };
~RotMgr();
diff --git a/liboverlay/overlayUtils.cpp b/liboverlay/overlayUtils.cpp
index 0b78e4d..0e063ab 100644
--- a/liboverlay/overlayUtils.cpp
+++ b/liboverlay/overlayUtils.cpp
@@ -74,12 +74,6 @@
//----------From class Res ------------------------------
const char* const Res::fbPath = "/dev/graphics/fb%u";
const char* const Res::rotPath = "/dev/msm_rotator";
-const char* const Res::format3DFile =
- "/sys/class/graphics/fb1/format_3d";
-const char* const Res::edid3dInfoFile =
- "/sys/class/graphics/fb1/3d_present";
-const char* const Res::barrierFile =
- "/sys/devices/platform/mipi_novatek.0/enable_3d_barrier";
//--------------------------------------------------------
@@ -285,10 +279,12 @@
}
void getDecimationFactor(const int& src_w, const int& src_h,
- const int& dst_w, const int& dst_h, float& horDscale,
- float& verDscale) {
- horDscale = ceilf((float)src_w / (float)dst_w);
- verDscale = ceilf((float)src_h / (float)dst_h);
+ const int& dst_w, const int& dst_h, uint8_t& horzDeci,
+ uint8_t& vertDeci) {
+ horzDeci = 0;
+ vertDeci = 0;
+ float horDscale = ceilf((float)src_w / (float)dst_w);
+ float verDscale = ceilf((float)src_h / (float)dst_h);
//Next power of 2, if not already
horDscale = powf(2.0f, ceilf(log2f(horDscale)));
@@ -298,6 +294,21 @@
//between decimator and MDP downscale
horDscale /= 4.0f;
verDscale /= 4.0f;
+
+ if((int)horDscale)
+ horzDeci = (uint8_t)log2f(horDscale);
+
+ if((int)verDscale)
+ vertDeci = (uint8_t)log2f(verDscale);
+
+ if(src_w > 2048) {
+ //If the client sends us something > what a layer mixer supports
+ //then it means it doesn't want to use split-pipe but wants us to
+ //decimate. A minimum decimation of 2 will ensure that the width is
+ //always within layer mixer limits.
+ if(horzDeci < 2)
+ horzDeci = 2;
+ }
}
static inline int compute(const uint32_t& x, const uint32_t& y,
@@ -323,86 +334,6 @@
}
}
-bool is3DTV() {
- char is3DTV = '0';
- IOFile fp(Res::edid3dInfoFile, "r");
- (void)fp.read(is3DTV, 1);
- ALOGI("3DTV EDID flag: %d", is3DTV);
- return (is3DTV == '0') ? false : true;
-}
-
-bool isPanel3D() {
- OvFD fd;
- if(!overlay::open(fd, 0 /*fb*/, Res::fbPath)){
- ALOGE("isPanel3D Can't open framebuffer 0");
- return false;
- }
- fb_fix_screeninfo finfo;
- if(!mdp_wrapper::getFScreenInfo(fd.getFD(), finfo)) {
- ALOGE("isPanel3D read fb0 failed");
- }
- fd.close();
- return (FB_TYPE_3D_PANEL == finfo.type) ? true : false;
-}
-
-bool usePanel3D() {
- if(!isPanel3D())
- return false;
- char value[PROPERTY_VALUE_MAX];
- property_get("persist.user.panel3D", value, "0");
- int usePanel3D = atoi(value);
- return usePanel3D ? true : false;
-}
-
-bool send3DInfoPacket (uint32_t format3D) {
- IOFile fp(Res::format3DFile, "wb");
- (void)fp.write("%d", format3D);
- if(!fp.valid()) {
- ALOGE("send3DInfoPacket: no sysfs entry for setting 3d mode");
- return false;
- }
- return true;
-}
-
-bool enableBarrier (uint32_t orientation) {
- IOFile fp(Res::barrierFile, "wb");
- (void)fp.write("%d", orientation);
- if(!fp.valid()) {
- ALOGE("enableBarrier no sysfs entry for "
- "enabling barriers on 3D panel");
- return false;
- }
- return true;
-}
-
-uint32_t getS3DFormat(uint32_t fmt) {
- // The S3D is part of the HAL_PIXEL_FORMAT_YV12 value. Add
- // an explicit check for the format
- if (fmt == HAL_PIXEL_FORMAT_YV12) {
- return 0;
- }
- uint32_t fmt3D = format3D(fmt);
- uint32_t fIn3D = format3DInput(fmt3D); // MSB 2 bytes - inp
- uint32_t fOut3D = format3DOutput(fmt3D); // LSB 2 bytes - out
- fmt3D = fIn3D | fOut3D;
- if (!fIn3D) {
- fmt3D |= fOut3D << SHIFT_TOT_3D; //Set the input format
- }
- if (!fOut3D) {
- switch (fIn3D) {
- case HAL_3D_IN_SIDE_BY_SIDE_L_R:
- case HAL_3D_IN_SIDE_BY_SIDE_R_L:
- // For all side by side formats, set the output
- // format as Side-by-Side i.e 0x1
- fmt3D |= HAL_3D_IN_SIDE_BY_SIDE_L_R >> SHIFT_TOT_3D;
- break;
- default:
- fmt3D |= fIn3D >> SHIFT_TOT_3D; //Set the output format
- }
- }
- return fmt3D;
-}
-
void getDump(char *buf, size_t len, const char *prefix,
const mdp_overlay& ov) {
char str[256] = {'\0'};
diff --git a/liboverlay/overlayUtils.h b/liboverlay/overlayUtils.h
index c2649f3..530377b 100644
--- a/liboverlay/overlayUtils.h
+++ b/liboverlay/overlayUtils.h
@@ -120,40 +120,9 @@
const NoCopy& operator=(const NoCopy&);
};
-
-/* 3D related utils, defines etc...
- * The compound format passed to the overlay is
- * ABCCC where A is the input 3D format
- * B is the output 3D format
- * CCC is the color format e.g YCbCr420SP YCrCb420SP etc */
-enum { SHIFT_OUT_3D = 12,
- SHIFT_TOT_3D = 16 };
-enum { INPUT_3D_MASK = 0xFFFF0000,
- OUTPUT_3D_MASK = 0x0000FFFF };
-enum { BARRIER_LAND = 1,
- BARRIER_PORT = 2 };
-
-inline uint32_t format3D(uint32_t x) { return x & 0xFF000; }
-inline uint32_t format3DOutput(uint32_t x) {
- return (x & 0xF000) >> SHIFT_OUT_3D; }
-inline uint32_t format3DInput(uint32_t x) { return x & 0xF0000; }
-
-bool isHDMIConnected ();
-bool is3DTV();
-bool isPanel3D();
-bool usePanel3D();
-bool send3DInfoPacket (uint32_t fmt);
-bool enableBarrier (uint32_t orientation);
-uint32_t getS3DFormat(uint32_t fmt);
bool isMdssRotator();
void normalizeCrop(uint32_t& xy, uint32_t& wh);
-template <int CHAN>
-bool getPositionS3D(const Whf& whf, Dim& out);
-
-template <int CHAN>
-bool getCropS3D(const Dim& in, Dim& out, uint32_t fmt);
-
template <class Type>
void swapWidthHeight(Type& width, Type& height);
@@ -413,8 +382,8 @@
int getDownscaleFactor(const int& src_w, const int& src_h,
const int& dst_w, const int& dst_h);
void getDecimationFactor(const int& src_w, const int& src_h,
- const int& dst_w, const int& dst_h, float& horDscale,
- float& verDscale);
+ const int& dst_w, const int& dst_h, uint8_t& horzDeci,
+ uint8_t& vertDeci);
/* flip is upside down and such. V, H flip
* rotation is 90, 180 etc
@@ -446,39 +415,6 @@
return a ? ((value + (a-1)) & ~(a-1)) : value;
}
-enum eRotOutFmt {
- ROT_OUT_FMT_DEFAULT,
- ROT_OUT_FMT_Y_CRCB_H2V2
-};
-
-template <int ROT_OUT_FMT> struct RotOutFmt;
-
-// FIXME, taken from gralloc_priv.h. Need to
-// put it back as soon as overlay takes place of the old one
-/* possible formats for 3D content*/
-enum {
- HAL_NO_3D = 0x0000,
- HAL_3D_IN_SIDE_BY_SIDE_L_R = 0x10000,
- HAL_3D_IN_TOP_BOTTOM = 0x20000,
- HAL_3D_IN_INTERLEAVE = 0x40000,
- HAL_3D_IN_SIDE_BY_SIDE_R_L = 0x80000,
- HAL_3D_OUT_SIDE_BY_SIDE = 0x1000,
- HAL_3D_OUT_TOP_BOTTOM = 0x2000,
- HAL_3D_OUT_INTERLEAVE = 0x4000,
- HAL_3D_OUT_MONOSCOPIC = 0x8000
-};
-
-enum { HAL_3D_OUT_SBS_MASK =
- HAL_3D_OUT_SIDE_BY_SIDE >> overlay::utils::SHIFT_OUT_3D,
- HAL_3D_OUT_TOP_BOT_MASK =
- HAL_3D_OUT_TOP_BOTTOM >> overlay::utils::SHIFT_OUT_3D,
- HAL_3D_OUT_INTERL_MASK =
- HAL_3D_OUT_INTERLEAVE >> overlay::utils::SHIFT_OUT_3D,
- HAL_3D_OUT_MONOS_MASK =
- HAL_3D_OUT_MONOSCOPIC >> overlay::utils::SHIFT_OUT_3D
-};
-
-
inline bool isYuv(uint32_t format) {
switch(format){
case MDP_Y_CBCR_H2V1:
@@ -577,105 +513,6 @@
ALOGE("== Dump Dim x=%d y=%d w=%d h=%d start/end ==", x, y, w, h);
}
-// FB0
-template <int CHAN>
-inline Dim getPositionS3DImpl(const Whf& whf)
-{
- switch (whf.format & OUTPUT_3D_MASK)
- {
- case HAL_3D_OUT_SBS_MASK:
- // x, y, w, h
- return Dim(0, 0, whf.w/2, whf.h);
- case HAL_3D_OUT_TOP_BOT_MASK:
- return Dim(0, 0, whf.w, whf.h/2);
- case HAL_3D_OUT_MONOS_MASK:
- return Dim();
- case HAL_3D_OUT_INTERL_MASK:
- // FIXME error?
- ALOGE("%s HAL_3D_OUT_INTERLEAVE_MASK", __FUNCTION__);
- return Dim();
- default:
- ALOGE("%s Unsupported 3D output format %d", __FUNCTION__,
- whf.format);
- }
- return Dim();
-}
-
-template <>
-inline Dim getPositionS3DImpl<utils::OV_RIGHT_SPLIT>(const Whf& whf)
-{
- switch (whf.format & OUTPUT_3D_MASK)
- {
- case HAL_3D_OUT_SBS_MASK:
- return Dim(whf.w/2, 0, whf.w/2, whf.h);
- case HAL_3D_OUT_TOP_BOT_MASK:
- return Dim(0, whf.h/2, whf.w, whf.h/2);
- case HAL_3D_OUT_MONOS_MASK:
- return Dim(0, 0, whf.w, whf.h);
- case HAL_3D_OUT_INTERL_MASK:
- // FIXME error?
- ALOGE("%s HAL_3D_OUT_INTERLEAVE_MASK", __FUNCTION__);
- return Dim();
- default:
- ALOGE("%s Unsupported 3D output format %d", __FUNCTION__,
- whf.format);
- }
- return Dim();
-}
-
-template <int CHAN>
-inline bool getPositionS3D(const Whf& whf, Dim& out) {
- out = getPositionS3DImpl<CHAN>(whf);
- return (out != Dim());
-}
-
-template <int CHAN>
-inline Dim getCropS3DImpl(const Dim& in, uint32_t fmt) {
- switch (fmt & INPUT_3D_MASK)
- {
- case HAL_3D_IN_SIDE_BY_SIDE_L_R:
- return Dim(0, 0, in.w/2, in.h);
- case HAL_3D_IN_SIDE_BY_SIDE_R_L:
- return Dim(in.w/2, 0, in.w/2, in.h);
- case HAL_3D_IN_TOP_BOTTOM:
- return Dim(0, 0, in.w, in.h/2);
- case HAL_3D_IN_INTERLEAVE:
- ALOGE("%s HAL_3D_IN_INTERLEAVE", __FUNCTION__);
- break;
- default:
- ALOGE("%s Unsupported 3D format %d", __FUNCTION__, fmt);
- break;
- }
- return Dim();
-}
-
-template <>
-inline Dim getCropS3DImpl<utils::OV_RIGHT_SPLIT>(const Dim& in, uint32_t fmt) {
- switch (fmt & INPUT_3D_MASK)
- {
- case HAL_3D_IN_SIDE_BY_SIDE_L_R:
- return Dim(in.w/2, 0, in.w/2, in.h);
- case HAL_3D_IN_SIDE_BY_SIDE_R_L:
- return Dim(0, 0, in.w/2, in.h);
- case HAL_3D_IN_TOP_BOTTOM:
- return Dim(0, in.h/2, in.w, in.h/2);
- case HAL_3D_IN_INTERLEAVE:
- ALOGE("%s HAL_3D_IN_INTERLEAVE", __FUNCTION__);
- break;
- default:
- ALOGE("%s Unsupported 3D format %d", __FUNCTION__, fmt);
- break;
- }
- return Dim();
-}
-
-template <int CHAN>
-inline bool getCropS3D(const Dim& in, Dim& out, uint32_t fmt)
-{
- out = getCropS3DImpl<CHAN>(in, fmt);
- return (out != Dim());
-}
-
template <class Type>
void swapWidthHeight(Type& width, Type& height) {
Type tmp = width;
@@ -706,6 +543,14 @@
value--;
}
+/* Prerotation adjusts crop co-ordinates to the new transformed values within
+ * destination buffer. This is necessary only when the entire buffer is rotated
+ * irrespective of crop (A-family). If only the crop portion of the buffer is
+ * rotated into a destination buffer matching the size of crop, we don't need to
+ * use this helper (B-family).
+ * @Deprecated as of now, retained for the case where a full buffer needs
+ * transform and also as a reference.
+ */
void preRotateSource(const eTransform& tr, Whf& whf, Dim& srcCrop);
void getDump(char *buf, size_t len, const char *prefix, const mdp_overlay& ov);
void getDump(char *buf, size_t len, const char *prefix, const msmfb_img& ov);
@@ -728,12 +573,6 @@
static const char* const fbPath;
// /dev/msm_rotator
static const char* const rotPath;
- // /sys/class/graphics/fb1/format_3d
- static const char* const format3DFile;
- // /sys/class/graphics/fb1/3d_present
- static const char* const edid3dInfoFile;
- // /sys/devices/platform/mipi_novatek.0/enable_3d_barrier
- static const char* const barrierFile;
};
diff --git a/liboverlay/pipes/overlay3DPipe.h b/liboverlay/pipes/overlay3DPipe.h
deleted file mode 100644
index 4e5630e..0000000
--- a/liboverlay/pipes/overlay3DPipe.h
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
-* Copyright (c) 2011-2012, 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 copyright
-* 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 OVERLAY_M3D_EXT_PIPE_H
-#define OVERLAY_M3D_EXT_PIPE_H
-
-#include "overlayGenPipe.h"
-#include "overlayUtils.h"
-
-namespace overlay {
-
-///////////// M3DExt Pipe ////////////////////////////
-/**
-* A specific impl of GenericPipe for 3D.
-* Whenever needed to have a pass through - we do it.
-* If there is a special need for special/diff behavior
-* do it here
-* PANEL is always EXTERNAL for this pipe.
-* CHAN = 0,1 it's either Channel 1 or channel 2 needed for
-* 3D crop and position */
-template <int CHAN>
-class M3DExtPipe : utils::NoCopy {
-public:
- /* Please look at overlayGenPipe.h for info */
- explicit M3DExtPipe();
- ~M3DExtPipe();
- bool init(RotatorBase* rot);
- bool close();
- bool commit();
- bool queueBuffer(int fd, uint32_t offset);
- bool setCrop(const utils::Dim& d);
- bool setPosition(const utils::Dim& dim);
- bool setTransform(const utils::eTransform& param);
- bool setSource(const utils::PipeArgs& args);
- void dump() const;
-private:
- overlay::GenericPipe<utils::EXTERNAL> mM3d;
- // Cache the M3D format
- uint32_t mM3Dfmt;
-};
-
-///////////// M3DPrimary Pipe ////////////////////////////
-/**
-* A specific impl of GenericPipe for 3D.
-* Whenever needed to have a pass through - we do it.
-* If there is a special need for special/diff behavior
-* do it here
-* PANEL is always PRIMARY for this pipe.
-* CHAN = 0,1 it's either Channel 1 or channel 2 needed for
-* 3D crop and position */
-template <int CHAN>
-class M3DPrimaryPipe : utils::NoCopy {
-public:
- /* Please look at overlayGenPipe.h for info */
- explicit M3DPrimaryPipe();
- ~M3DPrimaryPipe();
- bool init(RotatorBase* rot);
- bool close();
- bool commit();
- bool queueBuffer(int fd, uint32_t offset);
- bool setCrop(const utils::Dim& d);
- bool setPosition(const utils::Dim& dim);
- bool setTransform(const utils::eTransform& param);
- bool setSource(const utils::PipeArgs& args);
- void dump() const;
-private:
- overlay::GenericPipe<utils::PRIMARY> mM3d;
- // Cache the M3D format
- uint32_t mM3Dfmt;
-};
-
-///////////// S3DExt Pipe ////////////////////////////////
-/**
-* A specific impl of GenericPipe for 3D.
-* Whenever needed to have a pass through - we do it.
-* If there is a special need for special/diff behavior
-* do it here.
-* PANEL is always EXTERNAL for this pipe.
-* CHAN = 0,1 it's either Channel 1 or channel 2 needed for
-* 3D crop and position */
-template <int CHAN>
-class S3DExtPipe : utils::NoCopy {
-public:
- /* Please look at overlayGenPipe.h for info */
- explicit S3DExtPipe();
- ~S3DExtPipe();
- bool init(RotatorBase* rot);
- bool close();
- bool commit();
- bool queueBuffer(int fd, uint32_t offset);
- bool setCrop(const utils::Dim& d);
- bool setPosition(const utils::Dim& dim);
- bool setTransform(const utils::eTransform& param);
- bool setSource(const utils::PipeArgs& args);
- void dump() const;
-private:
- overlay::GenericPipe<utils::EXTERNAL> mS3d;
- // Cache the 3D format
- uint32_t mS3Dfmt;
-};
-
-///////////// S3DPrimary Pipe ////////////////////////////
-/**
-* A specific impl of GenericPipe for 3D.
-* Whenever needed to have a pass through - we do it.
-* If there is a special need for special/diff behavior
-* do it here
-* PANEL is always PRIMARY for this pipe.
-* CHAN = 0,1 it's either Channel 1 or channel 2 needed for
-* 3D crop and position */
-template <int CHAN>
-class S3DPrimaryPipe : utils::NoCopy {
-public:
- /* Please look at overlayGenPipe.h for info */
- explicit S3DPrimaryPipe();
- ~S3DPrimaryPipe();
- bool init(RotatorBase* rot);
- bool close();
- bool commit();
- bool queueBuffer(int fd, uint32_t offset);
- bool setCrop(const utils::Dim& d);
- bool setPosition(const utils::Dim& dim);
- bool setTransform(const utils::eTransform& param);
- bool setSource(const utils::PipeArgs& args);
- void dump() const;
-private:
- /* needed for 3D related IOCTL */
- MdpCtrl3D mCtrl3D;
- overlay::GenericPipe<utils::PRIMARY> mS3d;
- // Cache the 3D format
- uint32_t mS3Dfmt;
-};
-
-
-
-
-//------------------------Inlines and Templates--------------------------
-
-
-///////////// M3DExt Pipe ////////////////////////////
-template <int CHAN>
-inline M3DExtPipe<CHAN>::M3DExtPipe() : mM3Dfmt(0) {}
-template <int CHAN>
-inline M3DExtPipe<CHAN>::~M3DExtPipe() { close(); }
-template <int CHAN>
-inline bool M3DExtPipe<CHAN>::init(RotatorBase* rot) {
- ALOGE_IF(DEBUG_OVERLAY, "M3DExtPipe init");
- if(!mM3d.init(rot)) {
- ALOGE("3Dpipe failed to init");
- return false;
- }
- return true;
-}
-template <int CHAN>
-inline bool M3DExtPipe<CHAN>::close() {
- return mM3d.close();
-}
-template <int CHAN>
-inline bool M3DExtPipe<CHAN>::commit() { return mM3d.commit(); }
-template <int CHAN>
-inline bool M3DExtPipe<CHAN>::queueBuffer(int fd, uint32_t offset) {
- return mM3d.queueBuffer(fd, offset);
-}
-template <int CHAN>
-inline bool M3DExtPipe<CHAN>::setCrop(const utils::Dim& d) {
- utils::Dim _dim;
- if(!utils::getCropS3D<CHAN>(d, _dim, mM3Dfmt)){
- ALOGE("M3DExtPipe setCrop failed to getCropS3D");
- _dim = d;
- }
- return mM3d.setCrop(_dim);
-}
-
-template <int CHAN>
-inline bool M3DExtPipe<CHAN>::setPosition(const utils::Dim& d) {
- utils::Dim _dim;
- // original setPositionHandleState has getPositionS3D(...,true)
- // which means format is HAL_3D_OUT_SBS_MASK
- // HAL_3D_OUT_SBS_MASK is 0x1000 >> 12 == 0x1 as the orig
- // code suggets
- utils::Whf _whf(mM3d.getScreenInfo().mFBWidth,
- mM3d.getScreenInfo().mFBHeight,
- mM3Dfmt);
- if(!utils::getPositionS3D<CHAN>(_whf, _dim)) {
- ALOGE("S3DPrimaryPipe setPosition err in getPositionS3D");
- _dim = d;
- }
- return mM3d.setPosition(_dim);
-}
-template <int CHAN>
-inline bool M3DExtPipe<CHAN>::setTransform(const utils::eTransform& param) {
- return mM3d.setTransform(param);
-}
-template <int CHAN>
-inline bool M3DExtPipe<CHAN>::setSource(const utils::PipeArgs& args)
-{
- // extract 3D fmt
- mM3Dfmt = utils::format3DInput(utils::getS3DFormat(args.whf.format)) |
- utils::HAL_3D_OUT_MONOS_MASK;
- return mM3d.setSource(args);
-}
-template <int CHAN>
-inline void M3DExtPipe<CHAN>::dump() const {
- ALOGE("M3DExtPipe Pipe fmt=%d", mM3Dfmt);
- mM3d.dump();
-}
-
-
-///////////// M3DPrimary Pipe ////////////////////////////
-template <int CHAN>
-inline M3DPrimaryPipe<CHAN>::M3DPrimaryPipe() : mM3Dfmt(0) {}
-template <int CHAN>
-inline M3DPrimaryPipe<CHAN>::~M3DPrimaryPipe() { close(); }
-template <int CHAN>
-inline bool M3DPrimaryPipe<CHAN>::init(RotatorBase* rot) {
- ALOGE_IF(DEBUG_OVERLAY, "M3DPrimaryPipe init");
- if(!mM3d.init(rot)) {
- ALOGE("3Dpipe failed to init");
- return false;
- }
- return true;
-}
-template <int CHAN>
-inline bool M3DPrimaryPipe<CHAN>::close() {
- return mM3d.close();
-}
-template <int CHAN>
-inline bool M3DPrimaryPipe<CHAN>::commit() { return mM3d.commit(); }
-template <int CHAN>
-inline bool M3DPrimaryPipe<CHAN>::queueBuffer(int fd, uint32_t offset) {
- return mM3d.queueBuffer(fd, offset);
-}
-template <int CHAN>
-inline bool M3DPrimaryPipe<CHAN>::setCrop(const utils::Dim& d) {
- utils::Dim _dim;
- if(!utils::getCropS3D<CHAN>(d, _dim, mM3Dfmt)){
- ALOGE("M3DPrimaryPipe setCrop failed to getCropS3D");
- _dim = d;
- }
- return mM3d.setCrop(_dim);
-}
-template <int CHAN>
-inline bool M3DPrimaryPipe<CHAN>::setPosition(const utils::Dim& d) {
- return mM3d.setPosition(d);
-}
-template <int CHAN>
-inline bool M3DPrimaryPipe<CHAN>::setTransform(const utils::eTransform& param) {
- return mM3d.setTransform(param);
-}
-template <int CHAN>
-inline bool M3DPrimaryPipe<CHAN>::setSource(const utils::PipeArgs& args)
-{
- // extract 3D fmt
- mM3Dfmt = utils::format3DInput(utils::getS3DFormat(args.whf.format)) |
- utils::HAL_3D_OUT_MONOS_MASK;
- return mM3d.setSource(args);
-}
-template <int CHAN>
-inline void M3DPrimaryPipe<CHAN>::dump() const {
- ALOGE("M3DPrimaryPipe Pipe fmt=%d", mM3Dfmt);
- mM3d.dump();
-}
-
-///////////// S3DExt Pipe ////////////////////////////////
-template <int CHAN>
-inline S3DExtPipe<CHAN>::S3DExtPipe() : mS3Dfmt(0) {}
-template <int CHAN>
-inline S3DExtPipe<CHAN>::~S3DExtPipe() { close(); }
-template <int CHAN>
-inline bool S3DExtPipe<CHAN>::init(RotatorBase* rot) {
- ALOGE_IF(DEBUG_OVERLAY, "S3DExtPipe init");
- if(!mS3d.init(rot)) {
- ALOGE("3Dpipe failed to init");
- return false;
- }
- return true;
-}
-template <int CHAN>
-inline bool S3DExtPipe<CHAN>::close() {
- if(!utils::send3DInfoPacket(0)) {
- ALOGE("S3DExtPipe close failed send3D info packet");
- }
- return mS3d.close();
-}
-template <int CHAN>
-inline bool S3DExtPipe<CHAN>::commit() { return mS3d.commit(); }
-template <int CHAN>
-inline bool S3DExtPipe<CHAN>::queueBuffer(int fd, uint32_t offset) {
- return mS3d.queueBuffer(fd, offset);
-}
-template <int CHAN>
-inline bool S3DExtPipe<CHAN>::setCrop(const utils::Dim& d) {
- utils::Dim _dim;
- if(!utils::getCropS3D<CHAN>(d, _dim, mS3Dfmt)){
- ALOGE("S3DExtPipe setCrop failed to getCropS3D");
- _dim = d;
- }
- return mS3d.setCrop(_dim);
-}
-template <int CHAN>
-inline bool S3DExtPipe<CHAN>::setPosition(const utils::Dim& d)
-{
- utils::Dim _dim;
- utils::Whf _whf(mS3d.getScreenInfo().mFBWidth,
- mS3d.getScreenInfo().mFBHeight,
- mS3Dfmt);
- if(!utils::getPositionS3D<CHAN>(_whf, _dim)) {
- ALOGE("S3DExtPipe setPosition err in getPositionS3D");
- _dim = d;
- }
- return mS3d.setPosition(_dim);
-}
-template <int CHAN>
-inline bool S3DExtPipe<CHAN>::setTransform(const utils::eTransform& param) {
- return mS3d.setTransform(param);
-}
-template <int CHAN>
-inline bool S3DExtPipe<CHAN>::setSource(const utils::PipeArgs& args) {
- mS3Dfmt = utils::getS3DFormat(args.whf.format);
- return mS3d.setSource(args);
-}
-template <int CHAN>
-inline void S3DExtPipe<CHAN>::dump() const {
- ALOGE("S3DExtPipe Pipe fmt=%d", mS3Dfmt);
- mS3d.dump();
-}
-
-///////////// S3DPrimary Pipe ////////////////////////////
-template <int CHAN>
-inline S3DPrimaryPipe<CHAN>::S3DPrimaryPipe() : mS3Dfmt(0) {}
-template <int CHAN>
-inline S3DPrimaryPipe<CHAN>::~S3DPrimaryPipe() { close(); }
-template <int CHAN>
-inline bool S3DPrimaryPipe<CHAN>::init(RotatorBase* rot) {
- ALOGE_IF(DEBUG_OVERLAY, "S3DPrimaryPipe init");
- if(!mS3d.init(rot)) {
- ALOGE("3Dpipe failed to init");
- return false;
- }
- // set the ctrl fd
- mCtrl3D.setFd(mS3d.getCtrlFd());
- return true;
-}
-template <int CHAN>
-inline bool S3DPrimaryPipe<CHAN>::close() {
- if(!utils::enableBarrier(0)) {
- ALOGE("S3DExtPipe close failed enable barrier");
- }
- mCtrl3D.close();
- return mS3d.close();
-}
-
-template <int CHAN>
-inline bool S3DPrimaryPipe<CHAN>::commit() {
- uint32_t fmt = mS3Dfmt & utils::OUTPUT_3D_MASK;
- if(!utils::send3DInfoPacket(fmt)){
- ALOGE("Error S3DExtPipe start error send3DInfoPacket %d", fmt);
- return false;
- }
- return mS3d.commit();
-}
-template <int CHAN>
-inline bool S3DPrimaryPipe<CHAN>::queueBuffer(int fd, uint32_t offset) {
- return mS3d.queueBuffer(fd, offset);
-}
-template <int CHAN>
-inline bool S3DPrimaryPipe<CHAN>::setCrop(const utils::Dim& d) {
- utils::Dim _dim;
- if(!utils::getCropS3D<CHAN>(d, _dim, mS3Dfmt)){
- ALOGE("S3DPrimaryPipe setCrop failed to getCropS3D");
- _dim = d;
- }
- return mS3d.setCrop(_dim);
-}
-template <int CHAN>
-inline bool S3DPrimaryPipe<CHAN>::setPosition(const utils::Dim& d)
-{
- utils::Whf fbwhf(mS3d.getScreenInfo().mFBWidth,
- mS3d.getScreenInfo().mFBHeight,
- 0 /* fmt dont care*/);
- mCtrl3D.setWh(fbwhf);
- if(!mCtrl3D.useVirtualFB()) {
- ALOGE("Failed to use VFB on %d (non fatal)", utils::FB0);
- return false;
- }
- utils::Dim _dim;
- // original setPositionHandleState has getPositionS3D(...,true)
- // which means format is HAL_3D_OUT_SBS_MASK
- // HAL_3D_OUT_SBS_MASK is 0x1000 >> 12 == 0x1 as the orig
- // code suggets
- utils::Whf _whf(d.w, d.h, utils::HAL_3D_OUT_SBS_MASK);
- if(!utils::getPositionS3D<CHAN>(_whf, _dim)) {
- ALOGE("S3DPrimaryPipe setPosition err in getPositionS3D");
- _dim = d;
- }
- return mS3d.setPosition(_dim);
-}
-
-/* for S3DPrimaryPipe, we need to have barriers once
-* So the easiest way to achieve it, is to make sure FB0 is having it before
-* setParam is running */
-template <>
-inline bool S3DPrimaryPipe<utils::OV_PIPE0>::setTransform(
- const utils::eTransform& param) {
- uint32_t barrier=0;
- switch(param) {
- case utils::OVERLAY_TRANSFORM_ROT_90:
- case utils::OVERLAY_TRANSFORM_ROT_270:
- barrier = utils::BARRIER_LAND;
- break;
- default:
- barrier = utils::BARRIER_PORT;
- break;
- }
- if(!utils::enableBarrier(barrier)) {
- ALOGE("S3DPrimaryPipe setTransform failed to enable barrier");
- }
- return mS3d.setTransform(param);
-}
-
-template <int CHAN>
-inline bool S3DPrimaryPipe<CHAN>::setTransform(const utils::eTransform& param) {
- return mS3d.setTransform(param);
-}
-template <int CHAN>
-inline bool S3DPrimaryPipe<CHAN>::setSource(const utils::PipeArgs& args)
-{
- mS3Dfmt = utils::getS3DFormat(args.whf.format);
- return mS3d.setSource(args);
-}
-template <int CHAN>
-inline void S3DPrimaryPipe<CHAN>::dump() const {
- ALOGE("S3DPrimaryPipe Pipe fmt=%d", mS3Dfmt);
- mS3d.dump();
-}
-
-} // overlay
-
-#endif // OVERLAY_M3D_EXT_PIPE_H
diff --git a/liboverlay/pipes/overlayGenPipe.cpp b/liboverlay/pipes/overlayGenPipe.cpp
index 41cb271..aebaebf 100644
--- a/liboverlay/pipes/overlayGenPipe.cpp
+++ b/liboverlay/pipes/overlayGenPipe.cpp
@@ -32,18 +32,16 @@
namespace overlay {
-GenericPipe::GenericPipe(const int& dpy) : mDpy(dpy), mRotDownscaleOpt(false),
- pipeState(CLOSED), mCtrl(new Ctrl(dpy)), mData(new Data(dpy)) {
+GenericPipe::GenericPipe(const int& dpy) : mDpy(dpy),
+ mCtrl(new Ctrl(dpy)), mData(new Data(dpy)) {
}
GenericPipe::~GenericPipe() {
delete mCtrl;
delete mData;
- setClosed();
}
void GenericPipe::setSource(const utils::PipeArgs& args) {
- mRotDownscaleOpt = args.rotFlags & utils::ROT_DOWNSCALE_ENABLED;
mCtrl->setSource(args);
}
@@ -73,26 +71,10 @@
}
bool GenericPipe::commit() {
- bool ret = false;
- int downscale_factor = utils::ROT_DS_NONE;
-
- if(mRotDownscaleOpt) {
- ovutils::Dim src(mCtrl->getCrop());
- ovutils::Dim dst(mCtrl->getPosition());
- downscale_factor = ovutils::getDownscaleFactor(
- src.w, src.h, dst.w, dst.h);
- }
-
- mCtrl->setDownscale(downscale_factor);
- ret = mCtrl->commit();
-
- pipeState = ret ? OPEN : CLOSED;
- return ret;
+ return mCtrl->commit();
}
bool GenericPipe::queueBuffer(int fd, uint32_t offset) {
- //TODO Move pipe-id transfer to CtrlData class. Make ctrl and data private.
- OVASSERT(isOpen(), "State is closed, cannot queueBuffer");
int pipeId = mCtrl->getPipeId();
OVASSERT(-1 != pipeId, "Ctrl ID should not be -1");
// set pipe id from ctrl to data
@@ -101,10 +83,6 @@
return mData->queueBuffer(fd, offset);
}
-int GenericPipe::getCtrlFd() const {
- return mCtrl->getFd();
-}
-
utils::Dim GenericPipe::getCrop() const
{
return mCtrl->getCrop();
@@ -117,7 +95,6 @@
void GenericPipe::dump() const
{
ALOGE("== Dump Generic pipe start ==");
- ALOGE("pipe state = %d", (int)pipeState);
mCtrl->dump();
mData->dump();
ALOGE("== Dump Generic pipe end ==");
@@ -128,19 +105,6 @@
mData->getDump(buf, len);
}
-bool GenericPipe::isClosed() const {
- return (pipeState == CLOSED);
-}
-
-bool GenericPipe::isOpen() const {
- return (pipeState == OPEN);
-}
-
-bool GenericPipe::setClosed() {
- pipeState = CLOSED;
- return true;
-}
-
int GenericPipe::getPipeId() {
return mCtrl->getPipeId();
}
diff --git a/liboverlay/pipes/overlayGenPipe.h b/liboverlay/pipes/overlayGenPipe.h
index c7e16f3..0a2639a 100644
--- a/liboverlay/pipes/overlayGenPipe.h
+++ b/liboverlay/pipes/overlayGenPipe.h
@@ -65,12 +65,6 @@
const utils::PipeArgs& getArgs() const;
/* retrieve cached crop data */
utils::Dim getCrop() const;
- /* is closed */
- bool isClosed() const;
- /* is open */
- bool isOpen() const;
- /* return Ctrl fd. Used for S3D */
- int getCtrlFd() const;
/* return pipe priority */
uint8_t getPriority() const;
/* dump the state of the object */
@@ -82,19 +76,7 @@
static bool validateAndSet(GenericPipe* pipeArray[], const int& count,
const int& fbFd);
private:
- /* set Closed pipe */
- bool setClosed();
-
int mDpy;
- //Whether we will do downscale opt. This is just a request. If the frame is
- //not a candidate, we might not do it.
- bool mRotDownscaleOpt;
- /* Pipe open or closed */
- enum ePipeState {
- CLOSED,
- OPEN
- };
- ePipeState pipeState;
Ctrl *mCtrl;
Data *mData;
};
diff --git a/libqdutils/idle_invalidator.cpp b/libqdutils/idle_invalidator.cpp
index d30375e..86191e9 100644
--- a/libqdutils/idle_invalidator.cpp
+++ b/libqdutils/idle_invalidator.cpp
@@ -103,7 +103,7 @@
char data[64];
// Consume the node by reading it
ssize_t len = pread(pFd.fd, data, 64, 0);
- ALOGD_IF(II_DEBUG, "IdleInvalidator::%s Idle Timeout fired len %zu",
+ ALOGD_IF(II_DEBUG, "IdleInvalidator::%s Idle Timeout fired len %zd",
__FUNCTION__, len);
mHandler((void*)mHwcContext);
}
diff --git a/libqdutils/mdp_version.cpp b/libqdutils/mdp_version.cpp
index bc63ddf..6b53522 100644
--- a/libqdutils/mdp_version.cpp
+++ b/libqdutils/mdp_version.cpp
@@ -53,7 +53,7 @@
#define MDSS_MDP_HW_REV_104 0x10040000 //Next version
#endif
#ifndef MDSS_MDP_HW_REV_105
-#define MDSS_MDP_HW_REV_105 0x10050000 //Next version
+#define MDSS_MDP_HW_REV_105 0x10050000 //8994
#endif
#ifndef MDSS_MDP_HW_REV_106
#define MDSS_MDP_HW_REV_106 0x10060000 //8x16
@@ -90,6 +90,7 @@
mSourceSplit = false;
mSourceSplitAlways = false;
mRGBHasNoScalar = false;
+ mRotDownscale = false;
updatePanelInfo();
@@ -137,7 +138,6 @@
FILE *panelInfoNodeFP = NULL;
const int MAX_FRAME_BUFFER_NAME_SIZE = 128;
char fbType[MAX_FRAME_BUFFER_NAME_SIZE];
- char panelInfo[MAX_FRAME_BUFFER_NAME_SIZE];
const char *strCmdPanel = "mipi dsi cmd panel";
const char *strVideoPanel = "mipi dsi video panel";
const char *strLVDSPanel = "lvds panel";
@@ -283,22 +283,22 @@
for(int i=1; i<index;i++) {
if(!strncmp(tokens[i], "bwc", strlen("bwc"))) {
mFeatures |= MDP_BWC_EN;
- }
- else if(!strncmp(tokens[i], "decimation",
+ } else if(!strncmp(tokens[i], "decimation",
strlen("decimation"))) {
mFeatures |= MDP_DECIMATION_EN;
- }
- else if(!strncmp(tokens[i], "tile_format",
+ } else if(!strncmp(tokens[i], "tile_format",
strlen("tile_format"))) {
if(enableMacroTile)
mMacroTileEnabled = true;
} else if(!strncmp(tokens[i], "src_split",
strlen("src_split"))) {
mSourceSplit = true;
- }
- else if(!strncmp(tokens[i], "non_scalar_rgb",
+ } else if(!strncmp(tokens[i], "non_scalar_rgb",
strlen("non_scalar_rgb"))) {
mRGBHasNoScalar = true;
+ } else if(!strncmp(tokens[i], "rotator_downscale",
+ strlen("rotator_downscale"))) {
+ mRotDownscale = true;
}
}
}
@@ -424,6 +424,11 @@
mMdpRev < MDSS_MDP_HW_REV_206);
}
+bool MDPVersion::is8994() {
+ return (mMdpRev >= MDSS_MDP_HW_REV_105 and
+ mMdpRev < MDSS_MDP_HW_REV_106);
+}
+
bool MDPVersion::is8x16() {
return (mMdpRev >= MDSS_MDP_HW_REV_106 and
mMdpRev < MDSS_MDP_HW_REV_107);
diff --git a/libqdutils/mdp_version.h b/libqdutils/mdp_version.h
index 8bb9c39..6c4a3f4 100644
--- a/libqdutils/mdp_version.h
+++ b/libqdutils/mdp_version.h
@@ -139,6 +139,7 @@
bool needsROIMerge() { return mPanelInfo.mNeedsROIMerge; }
unsigned long getLowBw() { return mLowBw; }
unsigned long getHighBw() { return mHighBw; }
+ bool isRotDownscaleEnabled() { return mRotDownscale; }
bool isSrcSplit() const;
bool isSrcSplitAlways() const;
bool isRGBScalarSupported() const;
@@ -146,6 +147,7 @@
bool is8x74v2();
bool is8084();
bool is8092();
+ bool is8994();
bool is8x16();
bool is8x39();
@@ -174,6 +176,7 @@
//Additional property on top of source split
bool mSourceSplitAlways;
bool mRGBHasNoScalar;
+ bool mRotDownscale;
};
}; //namespace qdutils
#endif //INCLUDE_LIBQCOMUTILS_MDPVER
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index 5c9acf7..c222eb9 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -52,6 +52,7 @@
PAUSE_WFD, // Pause/Resume WFD
SET_WFD_STATUS, // Set if wfd connection is on/off
SET_VIEW_FRAME, // Set view frame of display
+ DYNAMIC_DEBUG, // Enable more logging on the fly
COMMAND_LIST_END = 400,
};
@@ -60,6 +61,12 @@
START,
};
+ enum {
+ DEBUG_ALL,
+ DEBUG_MDPCOMP,
+ DEBUG_VSYNC,
+ };
+
// Register a client that can be notified
virtual void connect(const android::sp<qClient::IQClient>& client) = 0;
// Generic function to dispatch binder commands
diff --git a/libvirtual/virtual.cpp b/libvirtual/virtual.cpp
index 1f8e70c..264d045 100644
--- a/libvirtual/virtual.cpp
+++ b/libvirtual/virtual.cpp
@@ -194,6 +194,13 @@
setDownScaleMode(maxArea);
}
+ //Initialize the display viewFrame info
+ mHwcContext->mViewFrame[HWC_DISPLAY_VIRTUAL].left = 0;
+ mHwcContext->mViewFrame[HWC_DISPLAY_VIRTUAL].top = 0;
+ mHwcContext->mViewFrame[HWC_DISPLAY_VIRTUAL].right =
+ (int)mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].xres;
+ mHwcContext->mViewFrame[HWC_DISPLAY_VIRTUAL].bottom =
+ (int)mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].yres;
mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].vsync_period =
1000000000l /60;
ALOGD_IF(DEBUG,"%s: Setting Virtual Attr: res(%d x %d)",__FUNCTION__,