You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1118 lines
41 KiB
1118 lines
41 KiB
/*
|
|
* Copyright (C) 2012 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include <utils/Errors.h>
|
|
#include <linux/videodev2.h>
|
|
#include <sys/mman.h>
|
|
#include <hardware/hwcomposer_defs.h>
|
|
#include <hardware/exynos/ion.h>
|
|
#include "ExynosLayer.h"
|
|
#include "ExynosResourceManager.h"
|
|
#include "ExynosHWCDebug.h"
|
|
#include "ExynosExternalDisplay.h"
|
|
|
|
#include "VendorVideoAPI.h"
|
|
|
|
/**
|
|
* ExynosLayer implementation
|
|
*/
|
|
|
|
ExynosLayer::ExynosLayer(ExynosDisplay* display)
|
|
: ExynosMPPSource(MPP_SOURCE_LAYER, this),
|
|
mDisplay(display),
|
|
mCompositionType(HWC2_COMPOSITION_INVALID),
|
|
mExynosCompositionType(HWC2_COMPOSITION_INVALID),
|
|
mValidateCompositionType(HWC2_COMPOSITION_INVALID),
|
|
mValidateExynosCompositionType(HWC2_COMPOSITION_INVALID),
|
|
mOverlayInfo(0x0),
|
|
mSupportedMPPFlag(0x0),
|
|
mFps(0),
|
|
mOverlayPriority(ePriorityLow),
|
|
mGeometryChanged(0x0),
|
|
mWindowIndex(0),
|
|
mCompressed(false),
|
|
mAcquireFence(-1),
|
|
mPrevAcquireFence(-1),
|
|
mReleaseFence(-1),
|
|
mFrameCount(0),
|
|
mLastFrameCount(0),
|
|
mLastFpsTime(0),
|
|
mLastLayerBuffer(NULL),
|
|
mLayerBuffer(NULL),
|
|
mDamageNum(0),
|
|
mBlending(HWC2_BLEND_MODE_NONE),
|
|
mPlaneAlpha(1.0),
|
|
mTransform(0),
|
|
mZOrder(0),
|
|
mDataSpace(HAL_DATASPACE_UNKNOWN),
|
|
mLayerFlag(0x0),
|
|
mIsHdrLayer(false),
|
|
mBufferHasMetaParcel(false),
|
|
mMetaParcelFd(-1) {
|
|
memset(&mDisplayFrame, 0, sizeof(mDisplayFrame));
|
|
memset(&mSourceCrop, 0, sizeof(mSourceCrop));
|
|
mVisibleRegionScreen.numRects = 0;
|
|
mVisibleRegionScreen.rects = NULL;
|
|
memset(&mColor, 0, sizeof(mColor));
|
|
memset(&mPreprocessedInfo, 0, sizeof(mPreprocessedInfo));
|
|
mCheckMPPFlag.clear();
|
|
mCheckMPPFlag.reserve(MPP_LOGICAL_TYPE_NUM);
|
|
mMetaParcel = NULL;
|
|
mDamageRects.clear();
|
|
}
|
|
|
|
ExynosLayer::~ExynosLayer() {
|
|
if (mMetaParcel != NULL) {
|
|
munmap(mMetaParcel, sizeof(ExynosVideoMeta));
|
|
mMetaParcel = NULL;
|
|
}
|
|
|
|
if (mMetaParcelFd >= 0) {
|
|
close(mMetaParcelFd);
|
|
mMetaParcelFd = -1;
|
|
}
|
|
|
|
if (mPrevAcquireFence != -1)
|
|
mPrevAcquireFence = fence_close(mPrevAcquireFence, mDisplay, FENCE_TYPE_SRC_ACQUIRE,
|
|
FENCE_IP_UNDEFINED);
|
|
}
|
|
|
|
/**
|
|
* @return uint32_t
|
|
*/
|
|
uint32_t ExynosLayer::checkFps() {
|
|
uint32_t frameDiff;
|
|
bool wasLowFps = (mFps < LOW_FPS_THRESHOLD) ? true:false;
|
|
if (mLastLayerBuffer != mLayerBuffer) {
|
|
mFrameCount++;
|
|
}
|
|
nsecs_t now = systemTime();
|
|
nsecs_t diff = now - mLastFpsTime;
|
|
if (mFrameCount >= mLastFrameCount)
|
|
frameDiff = (mFrameCount - mLastFrameCount);
|
|
else
|
|
frameDiff = (mFrameCount + (UINT_MAX - mLastFrameCount));
|
|
|
|
if (diff >= ms2ns(250)) {
|
|
mFps = (uint32_t)(frameDiff * float(s2ns(1))) / diff;
|
|
mLastFrameCount = mFrameCount;
|
|
mLastFpsTime = now;
|
|
}
|
|
bool nowLowFps = (mFps < LOW_FPS_THRESHOLD) ? true:false;
|
|
|
|
if ((mDisplay->mDisplayControl.handleLowFpsLayers) &&
|
|
(wasLowFps != nowLowFps))
|
|
setGeometryChanged(GEOMETRY_LAYER_FPS_CHANGED);
|
|
|
|
return mFps;
|
|
}
|
|
|
|
/**
|
|
* @return float
|
|
*/
|
|
uint32_t ExynosLayer::getFps() {
|
|
return mFps;
|
|
}
|
|
|
|
int32_t ExynosLayer::doPreProcess()
|
|
{
|
|
overlay_priority priority = ePriorityLow;
|
|
mIsHdrLayer = false;
|
|
mBufferHasMetaParcel = false;
|
|
mLayerFlag = 0x0;
|
|
|
|
mPreprocessedInfo.preProcessed = false;
|
|
mPreprocessedInfo.sourceCrop = mSourceCrop;
|
|
mPreprocessedInfo.displayFrame = mDisplayFrame;
|
|
mPreprocessedInfo.interlacedType = V4L2_FIELD_NONE;
|
|
|
|
if (mCompositionType == HWC2_COMPOSITION_SOLID_COLOR) {
|
|
mLayerFlag |= EXYNOS_HWC_DIM_LAYER;
|
|
} else {
|
|
mLayerFlag &= ~(EXYNOS_HWC_DIM_LAYER);
|
|
}
|
|
|
|
if (mLayerBuffer == NULL) {
|
|
if (mOverlayPriority != priority)
|
|
setGeometryChanged(GEOMETRY_LAYER_PRIORITY_CHANGED);
|
|
|
|
mOverlayPriority = priority;
|
|
return NO_ERROR;
|
|
}
|
|
|
|
VendorGraphicBufferMeta gmeta(mLayerBuffer);
|
|
|
|
mPreprocessedInfo.mUsePrivateFormat = false;
|
|
mPreprocessedInfo.mPrivateFormat = gmeta.format;
|
|
|
|
if (isFormatYUV(gmeta.format)) {
|
|
mPreprocessedInfo.sourceCrop.top = (int)mSourceCrop.top;
|
|
mPreprocessedInfo.sourceCrop.left = (int)mSourceCrop.left;
|
|
mPreprocessedInfo.sourceCrop.bottom = (int)(mSourceCrop.bottom + 0.9);
|
|
mPreprocessedInfo.sourceCrop.right = (int)(mSourceCrop.right + 0.9);
|
|
mPreprocessedInfo.preProcessed = true;
|
|
}
|
|
|
|
if (isFormatYUV(gmeta.format)) {
|
|
|
|
ExynosVideoMeta *metaData = NULL;
|
|
int priv_fd = -1;
|
|
|
|
if (gmeta.flags & VendorGraphicBufferMeta::PRIV_FLAGS_USES_2PRIVATE_DATA)
|
|
priv_fd = gmeta.fd1;
|
|
else if (gmeta.flags & VendorGraphicBufferMeta::PRIV_FLAGS_USES_3PRIVATE_DATA)
|
|
priv_fd = gmeta.fd2;
|
|
|
|
if (priv_fd >= 0) {
|
|
|
|
metaData = (ExynosVideoMeta*)mmap(0, sizeof(ExynosVideoMeta), PROT_READ|PROT_WRITE, MAP_SHARED, priv_fd, 0);
|
|
|
|
if (metaData == NULL) {
|
|
HWC_LOGE(mDisplay, "Layer's metadata is NULL!!");
|
|
} else if (metaData == MAP_FAILED) {
|
|
HWC_LOGE(mDisplay, "Layer's metadata map failed!!");
|
|
} else {
|
|
mBufferHasMetaParcel = true;
|
|
if ((metaData->eType & VIDEO_INFO_TYPE_HDR_STATIC) ||
|
|
(metaData->eType & VIDEO_INFO_TYPE_HDR_DYNAMIC)) {
|
|
if (allocMetaParcel() == NO_ERROR) {
|
|
mMetaParcel->eType = metaData->eType;
|
|
if (metaData->eType & VIDEO_INFO_TYPE_HDR_STATIC) {
|
|
mMetaParcel->sHdrStaticInfo = metaData->sHdrStaticInfo;
|
|
HDEBUGLOGD(eDebugLayer, "HWC2: Static metadata min(%d), max(%d)",
|
|
mMetaParcel->sHdrStaticInfo.sType1.mMinDisplayLuminance,
|
|
mMetaParcel->sHdrStaticInfo.sType1.mMaxDisplayLuminance);
|
|
}
|
|
if (metaData->eType & VIDEO_INFO_TYPE_HDR_DYNAMIC) {
|
|
/* Reserved field for dynamic meta data */
|
|
/* Currently It's not be used not only HWC but also OMX */
|
|
mMetaParcel->sHdrDynamicInfo = metaData->sHdrDynamicInfo;
|
|
HDEBUGLOGD(eDebugLayer, "HWC2: Layer has dynamic metadata");
|
|
}
|
|
}
|
|
}
|
|
if (metaData->eType & VIDEO_INFO_TYPE_INTERLACED) {
|
|
mPreprocessedInfo.interlacedType = metaData->data.dec.nInterlacedType;
|
|
if (mPreprocessedInfo.interlacedType == V4L2_FIELD_INTERLACED_BT) {
|
|
if ((int)mSourceCrop.left < (int)(gmeta.stride)) {
|
|
mPreprocessedInfo.sourceCrop.left = (int)mSourceCrop.left + gmeta.stride;
|
|
mPreprocessedInfo.sourceCrop.right = (int)mSourceCrop.right + gmeta.stride;
|
|
}
|
|
}
|
|
if (mPreprocessedInfo.interlacedType == V4L2_FIELD_INTERLACED_TB ||
|
|
mPreprocessedInfo.interlacedType == V4L2_FIELD_INTERLACED_BT) {
|
|
mPreprocessedInfo.sourceCrop.top = (int)(mSourceCrop.top)/2;
|
|
mPreprocessedInfo.sourceCrop.bottom = (int)(mSourceCrop.bottom)/2;
|
|
}
|
|
}
|
|
if (metaData->eType & VIDEO_INFO_TYPE_CHECK_PIXEL_FORMAT) {
|
|
mPreprocessedInfo.mUsePrivateFormat = true;
|
|
mPreprocessedInfo.mPrivateFormat = metaData->nPixelFormat;
|
|
}
|
|
munmap(metaData, sizeof(ExynosVideoMeta));
|
|
}
|
|
}
|
|
mPreprocessedInfo.preProcessed = true;
|
|
}
|
|
|
|
exynos_image src_img;
|
|
exynos_image dst_img;
|
|
setSrcExynosImage(&src_img);
|
|
setDstExynosImage(&dst_img);
|
|
ExynosMPP *exynosMPPVG = nullptr;
|
|
if (isFormatYUV(gmeta.format)) {
|
|
auto otfMPPs = ExynosResourceManager::getOtfMPPs();
|
|
auto mpp_it = std::find_if(otfMPPs.begin(), otfMPPs.end(),
|
|
[&src_img](auto m) { return m->isSrcFormatSupported(src_img); });
|
|
exynosMPPVG = mpp_it == otfMPPs.end() ? nullptr : *mpp_it;
|
|
}
|
|
|
|
/* Set HDR Flag */
|
|
if(hasHdrInfo(src_img)) mIsHdrLayer = true;
|
|
|
|
if (isFormatYUV(gmeta.format) && exynosMPPVG) {
|
|
/*
|
|
* layer's sourceCrop should be aligned
|
|
*/
|
|
uint32_t srcCropXAlign = exynosMPPVG->getSrcXOffsetAlign(src_img);
|
|
uint32_t srcCropYAlign = exynosMPPVG->getSrcYOffsetAlign(src_img);
|
|
uint32_t srcCropWidthAlign = exynosMPPVG->getSrcWidthAlign(src_img);
|
|
uint32_t srcCropHeightAlign = exynosMPPVG->getSrcHeightAlign(src_img);
|
|
mPreprocessedInfo.sourceCrop.left = pixel_align((int)mPreprocessedInfo.sourceCrop.left, srcCropXAlign);
|
|
mPreprocessedInfo.sourceCrop.top = pixel_align((int)mPreprocessedInfo.sourceCrop.top, srcCropYAlign);
|
|
mPreprocessedInfo.sourceCrop.right = mPreprocessedInfo.sourceCrop.left +
|
|
pixel_align_down(WIDTH(mPreprocessedInfo.sourceCrop), srcCropWidthAlign);
|
|
mPreprocessedInfo.sourceCrop.bottom = mPreprocessedInfo.sourceCrop.top +
|
|
pixel_align_down(HEIGHT(mPreprocessedInfo.sourceCrop), srcCropHeightAlign);
|
|
mPreprocessedInfo.preProcessed = true;
|
|
}
|
|
|
|
if (exynosMPPVG && ((getDrmMode(mLayerBuffer) != NO_DRM) ||
|
|
(mIsHdrLayer == true)))
|
|
{
|
|
if ((mDisplay->mDisplayControl.adjustDisplayFrame == true) &&
|
|
((mSupportedMPPFlag & (MPP_LOGICAL_DPP_G | MPP_LOGICAL_DPP_VG | MPP_LOGICAL_DPP_VGFS | MPP_LOGICAL_DPP_VGRFS)) == 0))
|
|
{
|
|
/*
|
|
* M2mMPP should be used for DRM, HDR video
|
|
* layer's displayFrame is the source of DPP
|
|
*/
|
|
uint32_t cropWidthAlign = exynosMPPVG->getSrcCropWidthAlign(src_img);
|
|
uint32_t cropHeightAlign = exynosMPPVG->getSrcCropHeightAlign(src_img);
|
|
|
|
mPreprocessedInfo.displayFrame.right = mDisplayFrame.left +
|
|
pixel_align(WIDTH(mDisplayFrame), cropWidthAlign);
|
|
mPreprocessedInfo.displayFrame.bottom = mDisplayFrame.top +
|
|
pixel_align(HEIGHT(mDisplayFrame), cropHeightAlign);
|
|
|
|
if (mPreprocessedInfo.displayFrame.right > (int)(mDisplay->mXres)) {
|
|
mPreprocessedInfo.displayFrame.left = mDisplay->mXres -
|
|
pixel_align(WIDTH(mPreprocessedInfo.displayFrame), cropWidthAlign);
|
|
mPreprocessedInfo.displayFrame.right = mDisplay->mXres;
|
|
}
|
|
|
|
if (mPreprocessedInfo.displayFrame.bottom > (int)(mDisplay->mYres)) {
|
|
mPreprocessedInfo.displayFrame.top = mDisplay->mYres -
|
|
pixel_align_down(HEIGHT(mPreprocessedInfo.displayFrame), cropHeightAlign);
|
|
mPreprocessedInfo.displayFrame.bottom = mDisplay->mYres;
|
|
}
|
|
}
|
|
|
|
uint32_t minDstWidth = exynosMPPVG->getDstMinWidth(dst_img);
|
|
uint32_t minDstHeight = exynosMPPVG->getDstMinHeight(dst_img);
|
|
if ((uint32_t)WIDTH(mDisplayFrame) < minDstWidth) {
|
|
ALOGI("%s DRM layer displayFrame width %d is smaller than otf minWidth %d",
|
|
mDisplay->mDisplayName.string(),
|
|
WIDTH(mDisplayFrame), minDstWidth);
|
|
mPreprocessedInfo.displayFrame.right = mDisplayFrame.left +
|
|
pixel_align(WIDTH(mDisplayFrame), minDstWidth);
|
|
|
|
if (mPreprocessedInfo.displayFrame.right > (int)(mDisplay->mXres)) {
|
|
mPreprocessedInfo.displayFrame.left = mDisplay->mXres -
|
|
pixel_align(WIDTH(mPreprocessedInfo.displayFrame), minDstWidth);
|
|
mPreprocessedInfo.displayFrame.right = mDisplay->mXres;
|
|
}
|
|
}
|
|
if ((uint32_t)HEIGHT(mDisplayFrame) < minDstHeight) {
|
|
ALOGI("%s DRM layer displayFrame height %d is smaller than vpp minHeight %d",
|
|
mDisplay->mDisplayName.string(),
|
|
HEIGHT(mDisplayFrame), minDstHeight);
|
|
mPreprocessedInfo.displayFrame.bottom = mDisplayFrame.top +
|
|
pixel_align(HEIGHT(mDisplayFrame), minDstHeight);
|
|
|
|
if (mPreprocessedInfo.displayFrame.bottom > (int)(mDisplay->mYres)) {
|
|
mPreprocessedInfo.displayFrame.top = mDisplay->mYres -
|
|
pixel_align(HEIGHT(mPreprocessedInfo.displayFrame), minDstHeight);
|
|
mPreprocessedInfo.displayFrame.bottom = mDisplay->mYres;
|
|
}
|
|
}
|
|
mPreprocessedInfo.preProcessed = true;
|
|
}
|
|
|
|
if (getDrmMode(mLayerBuffer) != NO_DRM) {
|
|
priority = ePriorityMax;
|
|
} else if (mIsHdrLayer) {
|
|
if (isFormatRgb(gmeta.format))
|
|
priority = ePriorityMax;
|
|
else
|
|
priority = ePriorityHigh;
|
|
} else if (isFormatYUV(gmeta.format)) {
|
|
priority = ePriorityHigh;
|
|
} else if ((mDisplay->mDisplayControl.cursorSupport == true) &&
|
|
(mCompositionType == HWC2_COMPOSITION_CURSOR)) {
|
|
priority = ePriorityMid;
|
|
} else {
|
|
priority = ePriorityLow;
|
|
}
|
|
|
|
if (mOverlayPriority != priority)
|
|
setGeometryChanged(GEOMETRY_LAYER_PRIORITY_CHANGED);
|
|
|
|
mOverlayPriority = priority;
|
|
return NO_ERROR;
|
|
}
|
|
|
|
int32_t ExynosLayer::setCursorPosition(int32_t x, int32_t y) {
|
|
return mDisplay->setCursorPositionAsync(x, y);
|
|
}
|
|
|
|
|
|
int32_t ExynosLayer::setLayerBuffer(buffer_handle_t buffer, int32_t acquireFence) {
|
|
|
|
/* TODO : Exception here ? */
|
|
//TODO mGeometryChanged here
|
|
|
|
uint64_t internal_format = 0;
|
|
|
|
if (mDisplay->mPlugState == false)
|
|
buffer = NULL;
|
|
|
|
if (buffer != NULL) {
|
|
if (VendorGraphicBufferMeta::get_fd(buffer,0) < 0)
|
|
return HWC2_ERROR_BAD_LAYER;
|
|
}
|
|
|
|
VendorGraphicBufferMeta gmeta(mLayerBuffer);
|
|
internal_format = gmeta.format;
|
|
|
|
if ((mLayerBuffer == NULL) || (buffer == NULL))
|
|
setGeometryChanged(GEOMETRY_LAYER_UNKNOWN_CHANGED);
|
|
else {
|
|
if (getDrmMode(VendorGraphicBufferMeta::get_producer_usage(mLayerBuffer)) != getDrmMode(gmeta.producer_usage))
|
|
setGeometryChanged(GEOMETRY_LAYER_DRM_CHANGED);
|
|
if (VendorGraphicBufferMeta::get_format(mLayerBuffer) != gmeta.format)
|
|
setGeometryChanged(GEOMETRY_LAYER_FORMAT_CHANGED);
|
|
}
|
|
|
|
mLayerBuffer = buffer;
|
|
mPrevAcquireFence =
|
|
fence_close(mPrevAcquireFence, mDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_UNDEFINED);
|
|
mAcquireFence = fence_close(mAcquireFence, mDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_UNDEFINED);
|
|
|
|
mAcquireFence = hwcCheckFenceDebug(mDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_LAYER, acquireFence);
|
|
mPrevAcquireFence = hwcCheckFenceDebug(mDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_LAYER,
|
|
hwc_dup(mAcquireFence, mDisplay, FENCE_TYPE_SRC_ACQUIRE,
|
|
FENCE_IP_LAYER, true));
|
|
if (mReleaseFence >= 0)
|
|
HWC_LOGE(NULL, "Layer's release fence is not initialized");
|
|
mReleaseFence = -1;
|
|
#ifdef DISABLE_FENCE
|
|
if (mAcquireFence >= 0)
|
|
fence_close(mAcquireFence);
|
|
mAcquireFence = -1;
|
|
#endif
|
|
bool compressed = isAFBCCompressed(mLayerBuffer);
|
|
if (mCompressed != compressed)
|
|
setGeometryChanged(GEOMETRY_LAYER_COMPRESSED_CHANGED);
|
|
mCompressed = compressed;
|
|
|
|
if (buffer != NULL) {
|
|
/*
|
|
* HAL_DATASPACE_V0_JFIF = HAL_DATASPACE_STANDARD_BT601_625 |
|
|
* HAL_DATASPACE_TRANSFER_SMPTE_170M | HAL_DATASPACE_RANGE_FULL,
|
|
*/
|
|
if (gmeta.format == HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL)
|
|
setLayerDataspace(HAL_DATASPACE_V0_JFIF);
|
|
} else {
|
|
setLayerDataspace(HAL_DATASPACE_UNKNOWN);
|
|
}
|
|
|
|
HDEBUGLOGD(eDebugFence,
|
|
"layers bufferHandle: %p, mDataSpace: 0x%8x, acquireFence: %d, afbc: %d, "
|
|
"internal_format: 0x%" PRIx64 "",
|
|
mLayerBuffer, mDataSpace, mAcquireFence, mCompressed, internal_format);
|
|
|
|
/* Update fps */
|
|
checkFps();
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int32_t ExynosLayer::setLayerSurfaceDamage(hwc_region_t damage) {
|
|
|
|
mDamageNum = damage.numRects;
|
|
mDamageRects.clear();
|
|
|
|
if (mDamageNum == 0) return 0;
|
|
|
|
for (size_t i = 0; i<mDamageNum; i++){
|
|
mDamageRects.push_back(damage.rects[i]);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t ExynosLayer::setLayerBlendMode(int32_t /*hwc2_blend_mode_t*/ mode) {
|
|
|
|
//TODO mGeometryChanged here
|
|
if (mode < 0)
|
|
return HWC2_ERROR_BAD_PARAMETER;
|
|
if (mBlending != mode)
|
|
setGeometryChanged(GEOMETRY_LAYER_BLEND_CHANGED);
|
|
mBlending = mode;
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
|
|
int32_t ExynosLayer::setLayerColor(hwc_color_t color) {
|
|
/* TODO : Implementation here */
|
|
mColor = color;
|
|
return 0;
|
|
}
|
|
|
|
int32_t ExynosLayer::setLayerCompositionType(int32_t /*hwc2_composition_t*/ type) {
|
|
|
|
if (type < 0)
|
|
return HWC2_ERROR_BAD_PARAMETER;
|
|
|
|
// FIXME: HWC2_COMPOSITION_SCREENSHOT is not defined in AOSP
|
|
// HWC guys should fix this.
|
|
#if 0
|
|
if (mDisplay->mType == HWC_DISPLAY_PRIMARY)
|
|
if (type == HWC2_COMPOSITION_SCREENSHOT)
|
|
type = HWC2_COMPOSITION_DEVICE;
|
|
#endif
|
|
|
|
if (type != mCompositionType) {
|
|
setGeometryChanged(GEOMETRY_LAYER_TYPE_CHANGED);
|
|
}
|
|
|
|
mCompositionType = type;
|
|
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t ExynosLayer::setLayerDataspace(int32_t /*android_dataspace_t*/ dataspace) {
|
|
android_dataspace currentDataSpace = (android_dataspace_t)dataspace;
|
|
if ((mLayerBuffer != NULL) && (VendorGraphicBufferMeta::get_format(mLayerBuffer) == HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL))
|
|
currentDataSpace = HAL_DATASPACE_V0_JFIF;
|
|
else {
|
|
/* Change legacy dataspace */
|
|
switch (dataspace) {
|
|
case HAL_DATASPACE_SRGB_LINEAR:
|
|
currentDataSpace = HAL_DATASPACE_V0_SRGB_LINEAR;
|
|
break;
|
|
case HAL_DATASPACE_SRGB:
|
|
currentDataSpace = HAL_DATASPACE_V0_SRGB;
|
|
break;
|
|
case HAL_DATASPACE_JFIF:
|
|
currentDataSpace = HAL_DATASPACE_V0_JFIF;
|
|
break;
|
|
case HAL_DATASPACE_BT601_625:
|
|
currentDataSpace = HAL_DATASPACE_V0_BT601_625;
|
|
break;
|
|
case HAL_DATASPACE_BT601_525:
|
|
currentDataSpace = HAL_DATASPACE_V0_BT601_525;
|
|
break;
|
|
case HAL_DATASPACE_BT709:
|
|
currentDataSpace = HAL_DATASPACE_V0_BT709;
|
|
break;
|
|
default:
|
|
currentDataSpace = (android_dataspace)dataspace;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (currentDataSpace != mDataSpace) {
|
|
setGeometryChanged(GEOMETRY_LAYER_DATASPACE_CHANGED);
|
|
}
|
|
mDataSpace = currentDataSpace;
|
|
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t ExynosLayer::setLayerDisplayFrame(hwc_rect_t frame) {
|
|
|
|
if ((frame.left != mDisplayFrame.left) ||
|
|
(frame.top != mDisplayFrame.top) ||
|
|
(frame.right != mDisplayFrame.right) ||
|
|
(frame.bottom != mDisplayFrame.bottom))
|
|
setGeometryChanged(GEOMETRY_LAYER_DISPLAYFRAME_CHANGED);
|
|
mDisplayFrame = frame;
|
|
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t ExynosLayer::setLayerPlaneAlpha(float alpha) {
|
|
|
|
if (alpha < 0.0)
|
|
return HWC2_ERROR_BAD_LAYER;
|
|
|
|
if ((mPlaneAlpha != alpha) && ((mPlaneAlpha == 0.0) || (alpha == 0.0)))
|
|
setGeometryChanged(GEOMETRY_LAYER_IGNORE_CHANGED);
|
|
|
|
mPlaneAlpha = alpha;
|
|
|
|
if (mPlaneAlpha > 0.0)
|
|
mLayerFlag &= ~(EXYNOS_HWC_IGNORE_LAYER);
|
|
else
|
|
mLayerFlag |= EXYNOS_HWC_IGNORE_LAYER;
|
|
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t ExynosLayer::setLayerSidebandStream(const native_handle_t* __unused stream) {
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t ExynosLayer::setLayerSourceCrop(hwc_frect_t crop) {
|
|
|
|
if ((crop.left != mSourceCrop.left) ||
|
|
(crop.top != mSourceCrop.top) ||
|
|
(crop.right != mSourceCrop.right) ||
|
|
(crop.bottom != mSourceCrop.bottom)) {
|
|
setGeometryChanged(GEOMETRY_LAYER_SOURCECROP_CHANGED);
|
|
mSourceCrop = crop;
|
|
}
|
|
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t ExynosLayer::setLayerTransform(int32_t /*hwc_transform_t*/ transform) {
|
|
|
|
if (mTransform != transform) {
|
|
setGeometryChanged(GEOMETRY_LAYER_TRANSFORM_CHANGED);
|
|
mTransform = transform;
|
|
}
|
|
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t ExynosLayer::setLayerVisibleRegion(hwc_region_t visible) {
|
|
|
|
mVisibleRegionScreen = visible;
|
|
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t ExynosLayer::setLayerZOrder(uint32_t z) {
|
|
if (mZOrder != z) {
|
|
setGeometryChanged(GEOMETRY_LAYER_ZORDER_CHANGED);
|
|
mZOrder = z;
|
|
}
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t ExynosLayer::setLayerPerFrameMetadata(uint32_t numElements,
|
|
const int32_t* /*hw2_per_frame_metadata_key_t*/ keys, const float* metadata)
|
|
{
|
|
if (allocMetaParcel() != NO_ERROR)
|
|
return -1;
|
|
unsigned int multipliedVal = 50000;
|
|
mMetaParcel->eType =
|
|
static_cast<ExynosVideoInfoType>(mMetaParcel->eType | VIDEO_INFO_TYPE_HDR_STATIC);
|
|
for (uint32_t i = 0; i < numElements; i++) {
|
|
HDEBUGLOGD(eDebugLayer, "HWC2: setLayerPerFrameMetadata key(%d), value(%7.5f)",
|
|
keys[i], metadata[i]);
|
|
switch (keys[i]) {
|
|
case HWC2_DISPLAY_RED_PRIMARY_X:
|
|
mMetaParcel->sHdrStaticInfo.sType1.mR.x =
|
|
(unsigned int)(metadata[i] * multipliedVal);
|
|
break;
|
|
case HWC2_DISPLAY_RED_PRIMARY_Y:
|
|
mMetaParcel->sHdrStaticInfo.sType1.mR.y =
|
|
(unsigned int)(metadata[i] * multipliedVal);
|
|
break;
|
|
case HWC2_DISPLAY_GREEN_PRIMARY_X:
|
|
mMetaParcel->sHdrStaticInfo.sType1.mG.x =
|
|
(unsigned int)(metadata[i] * multipliedVal);
|
|
break;
|
|
case HWC2_DISPLAY_GREEN_PRIMARY_Y:
|
|
mMetaParcel->sHdrStaticInfo.sType1.mG.y =
|
|
(unsigned int)(metadata[i] * multipliedVal);
|
|
break;
|
|
case HWC2_DISPLAY_BLUE_PRIMARY_X:
|
|
mMetaParcel->sHdrStaticInfo.sType1.mB.x =
|
|
(unsigned int)(metadata[i] * multipliedVal);
|
|
break;
|
|
case HWC2_DISPLAY_BLUE_PRIMARY_Y:
|
|
mMetaParcel->sHdrStaticInfo.sType1.mB.y =
|
|
(unsigned int)(metadata[i] * multipliedVal);
|
|
break;
|
|
case HWC2_WHITE_POINT_X:
|
|
mMetaParcel->sHdrStaticInfo.sType1.mW.x =
|
|
(unsigned int)(metadata[i] * multipliedVal);
|
|
break;
|
|
case HWC2_WHITE_POINT_Y:
|
|
mMetaParcel->sHdrStaticInfo.sType1.mW.y =
|
|
(unsigned int)(metadata[i] * multipliedVal);
|
|
break;
|
|
case HWC2_MAX_LUMINANCE:
|
|
mMetaParcel->sHdrStaticInfo.sType1.mMaxDisplayLuminance =
|
|
(unsigned int)(metadata[i] * 10000);
|
|
break;
|
|
case HWC2_MIN_LUMINANCE:
|
|
mMetaParcel->sHdrStaticInfo.sType1.mMinDisplayLuminance =
|
|
(unsigned int)(metadata[i] * 10000);
|
|
break;
|
|
case HWC2_MAX_CONTENT_LIGHT_LEVEL:
|
|
/* Should be checked */
|
|
mMetaParcel->sHdrStaticInfo.sType1.mMaxContentLightLevel =
|
|
(unsigned int)(metadata[i]);
|
|
break;
|
|
case HWC2_MAX_FRAME_AVERAGE_LIGHT_LEVEL:
|
|
/* Should be checked */
|
|
mMetaParcel->sHdrStaticInfo.sType1.mMaxFrameAverageLightLevel =
|
|
(unsigned int)(metadata[i]);
|
|
break;
|
|
default:
|
|
return HWC2_ERROR_UNSUPPORTED;
|
|
}
|
|
}
|
|
return NO_ERROR;
|
|
}
|
|
|
|
int32_t ExynosLayer::setLayerPerFrameMetadataBlobs(uint32_t numElements, const int32_t* keys, const uint32_t* sizes,
|
|
const uint8_t* metadata)
|
|
{
|
|
const uint8_t *metadata_start = metadata;
|
|
for (uint32_t i = 0; i < numElements; i++) {
|
|
HDEBUGLOGD(eDebugLayer, "HWC2: setLayerPerFrameMetadataBlobs key(%d)", keys[i]);
|
|
switch (keys[i]) {
|
|
case HWC2_HDR10_PLUS_SEI:
|
|
if (allocMetaParcel() == NO_ERROR) {
|
|
mMetaParcel->eType =
|
|
static_cast<ExynosVideoInfoType>(mMetaParcel->eType | VIDEO_INFO_TYPE_HDR_DYNAMIC);
|
|
ExynosHdrDynamicInfo *info = &(mMetaParcel->sHdrDynamicInfo);
|
|
Exynos_parsing_user_data_registered_itu_t_t35(info, (void *)metadata_start);
|
|
} else {
|
|
ALOGE("Layer has no metaParcel!");
|
|
return HWC2_ERROR_UNSUPPORTED;
|
|
}
|
|
break;
|
|
default:
|
|
return HWC2_ERROR_BAD_PARAMETER;
|
|
}
|
|
metadata_start += sizes[i];
|
|
}
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t ExynosLayer::setLayerColorTransform(const float* matrix)
|
|
{
|
|
mLayerColorTransform.enable = true;
|
|
for (uint32_t i = 0; i < TRANSFORM_MAT_SIZE; i++)
|
|
{
|
|
mLayerColorTransform.mat[i] = matrix[i];
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t ExynosLayer::setLayerGenericMetadata(hwc2_layer_t __unused layer,
|
|
uint32_t __unused keyLength, const char* __unused key,
|
|
bool __unused mandatory, uint32_t __unused valueLength, const uint8_t* __unused value)
|
|
{
|
|
return HWC2_ERROR_UNSUPPORTED;
|
|
}
|
|
|
|
void ExynosLayer::resetValidateData()
|
|
{
|
|
mValidateCompositionType = HWC2_COMPOSITION_INVALID;
|
|
mOtfMPP = NULL;
|
|
mM2mMPP = NULL;
|
|
mOverlayInfo = 0x0;
|
|
mWindowIndex = 0;
|
|
}
|
|
|
|
int32_t ExynosLayer::setSrcExynosImage(exynos_image *src_img)
|
|
{
|
|
buffer_handle_t handle = mLayerBuffer;
|
|
if (isDimLayer()) {
|
|
src_img->format = HAL_PIXEL_FORMAT_RGBA_8888;
|
|
src_img->usageFlags = 0xb00;
|
|
src_img->bufferHandle = 0;
|
|
|
|
src_img->x = 0;
|
|
src_img->y = 0;
|
|
|
|
if (mDisplay != NULL) {
|
|
src_img->fullWidth = src_img->w = mDisplay->mXres;
|
|
src_img->fullHeight = src_img->h = mDisplay->mYres;
|
|
} else {
|
|
src_img->fullWidth = src_img->w = 1440;
|
|
src_img->fullHeight = src_img->h = 2560;
|
|
}
|
|
|
|
src_img->layerFlags = mLayerFlag;
|
|
src_img->acquireFenceFd = mAcquireFence;
|
|
src_img->releaseFenceFd = -1;
|
|
src_img->dataSpace = HAL_DATASPACE_V0_SRGB;
|
|
src_img->blending = mBlending;
|
|
src_img->transform = mTransform;
|
|
src_img->compressed = mCompressed;
|
|
src_img->planeAlpha = mPlaneAlpha;
|
|
src_img->zOrder = mZOrder;
|
|
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
if (handle == NULL) {
|
|
src_img->fullWidth = 0;
|
|
src_img->fullHeight = 0;
|
|
src_img->format = 0;
|
|
src_img->usageFlags = 0x0;
|
|
src_img->bufferHandle = handle;
|
|
} else {
|
|
VendorGraphicBufferMeta gmeta(handle);
|
|
|
|
if ((mPreprocessedInfo.interlacedType == V4L2_FIELD_INTERLACED_TB) ||
|
|
(mPreprocessedInfo.interlacedType == V4L2_FIELD_INTERLACED_BT))
|
|
{
|
|
src_img->fullWidth = (gmeta.stride * 2);
|
|
src_img->fullHeight = pixel_align_down((gmeta.vstride / 2), 2);
|
|
} else {
|
|
src_img->fullWidth = gmeta.stride;
|
|
src_img->fullHeight = gmeta.vstride;
|
|
}
|
|
if (!mPreprocessedInfo.mUsePrivateFormat)
|
|
src_img->format = gmeta.format;
|
|
else
|
|
src_img->format = mPreprocessedInfo.mPrivateFormat;
|
|
src_img->usageFlags = gmeta.producer_usage;
|
|
src_img->bufferHandle = handle;
|
|
}
|
|
src_img->x = (int)mPreprocessedInfo.sourceCrop.left;
|
|
src_img->y = (int)mPreprocessedInfo.sourceCrop.top;
|
|
src_img->w = (int)mPreprocessedInfo.sourceCrop.right - (int)mPreprocessedInfo.sourceCrop.left;
|
|
src_img->h = (int)mPreprocessedInfo.sourceCrop.bottom - (int)mPreprocessedInfo.sourceCrop.top;
|
|
if ((mPreprocessedInfo.interlacedType == V4L2_FIELD_INTERLACED_TB) ||
|
|
(mPreprocessedInfo.interlacedType == V4L2_FIELD_INTERLACED_BT))
|
|
{
|
|
while ((src_img->h % 2 != 0) ||
|
|
(src_img->h > src_img->fullHeight)) {
|
|
src_img->h -= 1;
|
|
}
|
|
}
|
|
src_img->layerFlags = mLayerFlag;
|
|
src_img->acquireFenceFd = mAcquireFence;
|
|
src_img->releaseFenceFd = -1;
|
|
|
|
src_img->dataSpace = mDataSpace;
|
|
if(src_img->dataSpace == HAL_DATASPACE_UNKNOWN)
|
|
src_img->dataSpace = HAL_DATASPACE_V0_SRGB;
|
|
|
|
src_img->blending = mBlending;
|
|
src_img->transform = mTransform;
|
|
src_img->compressed = mCompressed;
|
|
src_img->planeAlpha = mPlaneAlpha;
|
|
src_img->zOrder = mZOrder;
|
|
/* Copy HDR metadata */
|
|
memset(&(src_img->metaParcel), 0, sizeof(src_img->metaParcel));
|
|
src_img->metaType = VIDEO_INFO_TYPE_INVALID;
|
|
if (mMetaParcel != NULL) {
|
|
memcpy(&(src_img->metaParcel), mMetaParcel, sizeof(src_img->metaParcel));
|
|
src_img->metaType = mMetaParcel->eType;
|
|
src_img->hasMetaParcel = true;
|
|
} else {
|
|
src_img->hasMetaParcel = false;
|
|
}
|
|
|
|
src_img->needColorTransform = mLayerColorTransform.enable;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
int32_t ExynosLayer::setDstExynosImage(exynos_image *dst_img)
|
|
{
|
|
buffer_handle_t handle = mLayerBuffer;
|
|
|
|
if (handle == NULL) {
|
|
dst_img->usageFlags = 0x0;
|
|
} else {
|
|
dst_img->usageFlags = VendorGraphicBufferMeta::get_producer_usage(handle);
|
|
}
|
|
|
|
if (isDimLayer()) {
|
|
dst_img->usageFlags = 0xb00;
|
|
}
|
|
|
|
dst_img->format = DEFAULT_MPP_DST_FORMAT;
|
|
dst_img->x = mPreprocessedInfo.displayFrame.left;
|
|
dst_img->y = mPreprocessedInfo.displayFrame.top;
|
|
dst_img->w = (mPreprocessedInfo.displayFrame.right - mPreprocessedInfo.displayFrame.left);
|
|
dst_img->h = (mPreprocessedInfo.displayFrame.bottom - mPreprocessedInfo.displayFrame.top);
|
|
dst_img->layerFlags = mLayerFlag;
|
|
dst_img->acquireFenceFd = -1;
|
|
dst_img->releaseFenceFd = -1;
|
|
dst_img->bufferHandle = NULL;
|
|
dst_img->dataSpace = HAL_DATASPACE_UNKNOWN;
|
|
if (mDisplay != NULL) {
|
|
dst_img->fullWidth = mDisplay->mXres;
|
|
dst_img->fullHeight = mDisplay->mYres;
|
|
if (mDisplay->mColorMode != HAL_COLOR_MODE_NATIVE) {
|
|
dst_img->dataSpace = colorModeToDataspace(mDisplay->mColorMode);
|
|
} else {
|
|
if (hasHdrInfo(mDataSpace)) {
|
|
android_dataspace hdrDataSpace =
|
|
(android_dataspace)(HAL_DATASPACE_STANDARD_DCI_P3 | HAL_DATASPACE_TRANSFER_GAMMA2_2 | HAL_DATASPACE_RANGE_LIMITED);
|
|
if (mDisplay->mType == HWC_DISPLAY_EXTERNAL) {
|
|
ExynosExternalDisplay *externalDisplay = (ExynosExternalDisplay*)mDisplay;
|
|
if (externalDisplay->mExternalHdrSupported == true)
|
|
dst_img->dataSpace = HAL_DATASPACE_UNKNOWN;
|
|
else
|
|
dst_img->dataSpace = hdrDataSpace;
|
|
} else {
|
|
dst_img->dataSpace = hdrDataSpace;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
HWC_LOGE(NULL, "mDisplay is NULL");
|
|
}
|
|
dst_img->blending = mBlending;
|
|
dst_img->transform = 0;
|
|
dst_img->compressed = 0;
|
|
dst_img->planeAlpha = mPlaneAlpha;
|
|
dst_img->zOrder = mZOrder;
|
|
|
|
/* Copy HDR metadata */
|
|
memset(&(dst_img->metaParcel), 0, sizeof(dst_img->metaParcel));
|
|
dst_img->metaType = VIDEO_INFO_TYPE_INVALID;
|
|
if (mMetaParcel != NULL) {
|
|
memcpy(&(dst_img->metaParcel), mMetaParcel, sizeof(dst_img->metaParcel));
|
|
dst_img->metaType = mMetaParcel->eType;
|
|
dst_img->hasMetaParcel = true;
|
|
} else {
|
|
dst_img->hasMetaParcel = false;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
int32_t ExynosLayer::resetAssignedResource()
|
|
{
|
|
int32_t ret = NO_ERROR;
|
|
if (mM2mMPP != NULL) {
|
|
HDEBUGLOGD(eDebugResourceManager, "\t\t %s mpp is reset", mM2mMPP->mName.string());
|
|
mM2mMPP->resetAssignedState(this);
|
|
mM2mMPP = NULL;
|
|
}
|
|
if (mOtfMPP != NULL) {
|
|
HDEBUGLOGD(eDebugResourceManager, "\t\t %s mpp is reset", mOtfMPP->mName.string());
|
|
mOtfMPP->resetAssignedState();
|
|
mOtfMPP = NULL;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
bool ExynosLayer::checkDownscaleCap(uint32_t bts_refresh_rate)
|
|
{
|
|
if (mOtfMPP == nullptr) return true;
|
|
|
|
exynos_image src_img;
|
|
exynos_image dst_img;
|
|
|
|
setSrcExynosImage(&src_img);
|
|
setDstExynosImage(&dst_img);
|
|
|
|
const bool isPerpendicular = !!(src_img.transform & HAL_TRANSFORM_ROT_90);
|
|
const uint32_t srcWidth = isPerpendicular ? src_img.h : src_img.w;
|
|
const uint32_t srcHeight = isPerpendicular ? src_img.w : src_img.h;
|
|
const bool scaleDown = (srcWidth > dst_img.w || srcHeight > dst_img.h);
|
|
|
|
if (!scaleDown) return true;
|
|
|
|
const float resolution = float(src_img.w) * float(src_img.h) * bts_refresh_rate / 1000;
|
|
|
|
return mOtfMPP->checkDownscaleCap(resolution, float(dst_img.h) / float(mDisplay->mYres));
|
|
}
|
|
|
|
void ExynosLayer::setSrcAcquireFence() {
|
|
if (mAcquireFence == -1 && mPrevAcquireFence != -1) {
|
|
mAcquireFence = hwcCheckFenceDebug(mDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_LAYER,
|
|
hwc_dup(mPrevAcquireFence, mDisplay,
|
|
FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_LAYER));
|
|
} else if (mAcquireFence != -1) {
|
|
setFenceInfo(mAcquireFence, mDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_LAYER, FENCE_FROM);
|
|
}
|
|
}
|
|
|
|
void ExynosLayer::dump(String8& result)
|
|
{
|
|
int format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
|
|
int32_t fd, fd1, fd2;
|
|
if (mLayerBuffer != NULL)
|
|
{
|
|
VendorGraphicBufferMeta gmeta(mLayerBuffer);
|
|
format = gmeta.format;
|
|
fd = gmeta.fd;
|
|
fd1 = gmeta.fd1;
|
|
fd2 = gmeta.fd2;
|
|
} else {
|
|
format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
|
|
fd = -1;
|
|
fd1 = -1;
|
|
fd2 = -1;
|
|
}
|
|
|
|
{
|
|
TableBuilder tb;
|
|
tb.add("zOrder", mZOrder)
|
|
.add("priority", mOverlayPriority);
|
|
if (mCompositionType == HWC2_COMPOSITION_SOLID_COLOR) {
|
|
tb.add("color", std::vector<uint64_t>({mColor.r, mColor.g, mColor.b, mColor.a}), true);
|
|
} else {
|
|
tb.add("handle", mLayerBuffer)
|
|
.add("fd", std::vector<int>({fd, fd1, fd2}))
|
|
.add("AFBC", static_cast<bool>(mCompressed));
|
|
}
|
|
tb.add("format", getFormatStr(format, mCompressed ? AFBC : 0).string())
|
|
.add("dataSpace", mDataSpace, true)
|
|
.add("colorTr", mLayerColorTransform.enable)
|
|
.add("blend", mBlending, true)
|
|
.add("planeAlpha", mPlaneAlpha)
|
|
.add("fps", mFps);
|
|
result.append(tb.build().c_str());
|
|
}
|
|
|
|
result.append(TableBuilder()
|
|
.add("sourceCrop",
|
|
std::vector<double>({mPreprocessedInfo.sourceCrop.left,
|
|
mPreprocessedInfo.sourceCrop.top,
|
|
mPreprocessedInfo.sourceCrop.right,
|
|
mPreprocessedInfo.sourceCrop.bottom}))
|
|
.add("dispFrame",
|
|
std::vector<int>({mPreprocessedInfo.displayFrame.left,
|
|
mPreprocessedInfo.displayFrame.top,
|
|
mPreprocessedInfo.displayFrame.right,
|
|
mPreprocessedInfo.displayFrame.bottom}))
|
|
.add("tr", mTransform, true)
|
|
.add("windowIndex", mWindowIndex)
|
|
.add("type", mCompositionType)
|
|
.add("exynosType", mExynosCompositionType)
|
|
.add("validateType", mValidateCompositionType)
|
|
.add("overlayInfo", mOverlayInfo, true)
|
|
.add("supportedMPPFlag", mSupportedMPPFlag, true)
|
|
.build()
|
|
.c_str());
|
|
|
|
if ((mDisplay != NULL) && (mDisplay->mResourceManager != NULL)) {
|
|
result.appendFormat("MPPFlags for otfMPP\n");
|
|
for (uint32_t i = 0; i < mDisplay->mResourceManager->getOtfMPPSize(); i++) {
|
|
result.appendFormat("[%s: 0x%" PRIx64 "] ", mDisplay->mResourceManager->getOtfMPP(i)->mName.string(),
|
|
mCheckMPPFlag[mDisplay->mResourceManager->getOtfMPP(i)->mLogicalType]);
|
|
}
|
|
result.appendFormat("\n");
|
|
result.appendFormat("MPPFlags for m2mMPP\n");
|
|
for (uint32_t i = 0; i < mDisplay->mResourceManager->getM2mMPPSize(); i++) {
|
|
result.appendFormat("[%s: 0x%" PRIx64 "] ", mDisplay->mResourceManager->getM2mMPP(i)->mName.string(),
|
|
mCheckMPPFlag[mDisplay->mResourceManager->getM2mMPP(i)->mLogicalType]);
|
|
if ((i!=0) && (i%4==0)) result.appendFormat("\n");
|
|
}
|
|
result.appendFormat("\n");
|
|
}
|
|
result.appendFormat("acquireFence: %d\n", mAcquireFence);
|
|
if ((mOtfMPP == NULL) && (mM2mMPP == NULL))
|
|
result.appendFormat("\tresource is not assigned.\n");
|
|
if (mOtfMPP != NULL)
|
|
result.appendFormat("\tassignedMPP: %s\n", mOtfMPP->mName.string());
|
|
if (mM2mMPP != NULL)
|
|
result.appendFormat("\tassignedM2mMPP: %s\n", mM2mMPP->mName.string());
|
|
result.appendFormat("\tdump midImg\n");
|
|
dumpExynosImage(result, mMidImg);
|
|
|
|
}
|
|
|
|
void ExynosLayer::printLayer()
|
|
{
|
|
int format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
|
|
int32_t fd, fd1, fd2;
|
|
String8 result;
|
|
if (mLayerBuffer != NULL)
|
|
{
|
|
VendorGraphicBufferMeta gmeta(mLayerBuffer);
|
|
format = gmeta.format;
|
|
fd = gmeta.fd;
|
|
fd1 = gmeta.fd1;
|
|
fd2 = gmeta.fd2;
|
|
} else {
|
|
format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
|
|
fd = -1;
|
|
fd1 = -1;
|
|
fd2 = -1;
|
|
}
|
|
result.appendFormat("handle: %p [fd: %d, %d, %d], acquireFence: %d, tr: 0x%2x, AFBC: %1d, dataSpace: 0x%8x, format: %s\n",
|
|
mLayerBuffer, fd, fd1, fd2, mAcquireFence, mTransform, mCompressed, mDataSpace, getFormatStr(format, mCompressed? AFBC : 0).string());
|
|
result.appendFormat("\tblend: 0x%4x, planeAlpha: %3.1f, zOrder: %d, color[0x%2x, 0x%2x, 0x%2x, 0x%2x]\n",
|
|
mBlending, mPlaneAlpha, mZOrder, mColor.r, mColor.g, mColor.b, mColor.a);
|
|
result.appendFormat("\tfps: %2d, priority: %d, windowIndex: %d\n", mFps, mOverlayPriority, mWindowIndex);
|
|
result.appendFormat("\tsourceCrop[%7.1f,%7.1f,%7.1f,%7.1f], dispFrame[%5d,%5d,%5d,%5d]\n",
|
|
mSourceCrop.left, mSourceCrop.top, mSourceCrop.right, mSourceCrop.bottom,
|
|
mDisplayFrame.left, mDisplayFrame.top, mDisplayFrame.right, mDisplayFrame.bottom);
|
|
result.appendFormat("\ttype: %2d, exynosType: %2d, validateType: %2d\n",
|
|
mCompositionType, mExynosCompositionType, mValidateCompositionType);
|
|
result.appendFormat("\toverlayInfo: 0x%8x, supportedMPPFlag: 0x%8x, geometryChanged: 0x%" PRIx64 "\n",
|
|
mOverlayInfo, mSupportedMPPFlag, mGeometryChanged);
|
|
|
|
if ((mDisplay != NULL) && (mDisplay->mResourceManager != NULL)) {
|
|
result.appendFormat("MPPFlags for otfMPP\n");
|
|
for (uint32_t i = 0; i < mDisplay->mResourceManager->getOtfMPPSize(); i++) {
|
|
result.appendFormat("[%s: 0x%" PRIx64 "] ", mDisplay->mResourceManager->getOtfMPP(i)->mName.string(),
|
|
mCheckMPPFlag[mDisplay->mResourceManager->getOtfMPP(i)->mLogicalType]);
|
|
}
|
|
result.appendFormat("\n");
|
|
result.appendFormat("MPPFlags for m2mMPP\n");
|
|
for (uint32_t i = 0; i < mDisplay->mResourceManager->getM2mMPPSize(); i++) {
|
|
result.appendFormat("[%s: 0x%" PRIx64 "] ", mDisplay->mResourceManager->getM2mMPP(i)->mName.string(),
|
|
mCheckMPPFlag[mDisplay->mResourceManager->getM2mMPP(i)->mLogicalType]);
|
|
if ((i!=0) && (i%4==0)) result.appendFormat("\n");
|
|
}
|
|
result.appendFormat("\n");
|
|
}
|
|
|
|
ALOGD("%s", result.string());
|
|
result.clear();
|
|
|
|
if ((mOtfMPP == NULL) && (mM2mMPP == NULL))
|
|
ALOGD("\tresource is not assigned.");
|
|
if (mOtfMPP != NULL)
|
|
ALOGD("\tassignedMPP: %s", mOtfMPP->mName.string());
|
|
if (mM2mMPP != NULL)
|
|
ALOGD("\tassignedM2mMPP: %s", mM2mMPP->mName.string());
|
|
ALOGD("\t++ dump midImg ++");
|
|
dumpExynosImage(result, mMidImg);
|
|
ALOGD("%s", result.string());
|
|
|
|
}
|
|
|
|
void ExynosLayer::setGeometryChanged(uint64_t changedBit)
|
|
{
|
|
mGeometryChanged |= changedBit;
|
|
mDisplay->setGeometryChanged(changedBit);
|
|
}
|
|
|
|
int ExynosLayer::allocMetaParcel()
|
|
{
|
|
/* Already allocated */
|
|
if ((mMetaParcelFd >= 0) &&
|
|
(mMetaParcel != NULL))
|
|
return NO_ERROR;
|
|
|
|
if (mMetaParcelFd < 0) {
|
|
int ionFd = exynos_ion_open();
|
|
if (ionFd >= 0) {
|
|
mMetaParcelFd = exynos_ion_alloc(ionFd, sizeof(ExynosVideoMeta), EXYNOS_ION_HEAP_SYSTEM_MASK, 0);
|
|
if (mMetaParcelFd < 0) {
|
|
ALOGE("Failed to ion alloc for metadata parcel");
|
|
return -1;
|
|
}
|
|
exynos_ion_close(ionFd);
|
|
} else {
|
|
ALOGE("Failed to open ion fd");
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
mMetaParcel =
|
|
(ExynosVideoMeta*)mmap(0, sizeof(ExynosVideoMeta), PROT_READ|PROT_WRITE, MAP_SHARED, mMetaParcelFd, 0);
|
|
if (mMetaParcel == NULL) {
|
|
ALOGE("Failed to map metadata parcel");
|
|
return -1;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
bool ExynosLayer::isDimLayer()
|
|
{
|
|
if (mLayerFlag & EXYNOS_HWC_DIM_LAYER)
|
|
return true;
|
|
return false;
|
|
}
|