summaryrefslogtreecommitdiff
path: root/libhwc2.1/libresource/ExynosResourceManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libhwc2.1/libresource/ExynosResourceManager.cpp')
-rw-r--r--libhwc2.1/libresource/ExynosResourceManager.cpp243
1 files changed, 163 insertions, 80 deletions
diff --git a/libhwc2.1/libresource/ExynosResourceManager.cpp b/libhwc2.1/libresource/ExynosResourceManager.cpp
index 622bf05..f4c0861 100644
--- a/libhwc2.1/libresource/ExynosResourceManager.cpp
+++ b/libhwc2.1/libresource/ExynosResourceManager.cpp
@@ -19,17 +19,21 @@
*/
#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
+#include "ExynosResourceManager.h"
+
#include <cutils/properties.h>
+
+#include <numeric>
#include <unordered_set>
-#include "ExynosResourceManager.h"
-#include "ExynosMPPModule.h"
-#include "ExynosLayer.h"
+
+#include "ExynosDeviceInterface.h"
+#include "ExynosExternalDisplay.h"
#include "ExynosHWCDebug.h"
-#include "hardware/exynos/acryl.h"
+#include "ExynosLayer.h"
+#include "ExynosMPPModule.h"
#include "ExynosPrimaryDisplayModule.h"
#include "ExynosVirtualDisplay.h"
-#include "ExynosExternalDisplay.h"
-#include "ExynosDeviceInterface.h"
+#include "hardware/exynos/acryl.h"
#ifndef USE_MODULE_ATTR
/* Basic supported features */
@@ -1125,6 +1129,158 @@ int32_t ExynosResourceManager::validateLayer(uint32_t index, ExynosDisplay *disp
return NO_ERROR;
}
+exynos_image ExynosResourceManager::getAlignedImage(exynos_image image, const ExynosMPP *m2mMpp,
+ const ExynosMPP *otfMpp) const {
+ const auto srcCropWidthAlign = otfMpp->getSrcCropWidthAlign(image);
+ const auto srcCropHeightAlign = otfMpp->getSrcCropHeightAlign(image);
+ const auto dstwidthAlign = m2mMpp->getDstWidthAlign(image);
+ const auto dstHeightAlign = m2mMpp->getDstHeightAlign(image);
+
+ const auto widthAlign = std::lcm(srcCropWidthAlign, dstwidthAlign);
+ const auto heighAlign = std::lcm(srcCropHeightAlign, dstHeightAlign);
+
+ image.w = pixel_align(image.w, widthAlign);
+ image.h = pixel_align(image.h, heighAlign);
+
+ return image;
+}
+
+void ExynosResourceManager::getCandidateScalingM2mMPPOutImages(
+ const ExynosDisplay *display, exynos_image src_img, exynos_image dst_img,
+ std::vector<exynos_image> &image_lists) {
+ uint32_t dstW = dst_img.w;
+ uint32_t dstH = dst_img.h;
+ bool isPerpendicular = !!(src_img.transform & HAL_TRANSFORM_ROT_90);
+ if (isPerpendicular) {
+ dstW = dst_img.h;
+ dstH = dst_img.w;
+ }
+
+ const bool scaleUp = (dstW > src_img.w && dstH > src_img.h);
+ const bool scaleDown = (dstW < src_img.w && dstH < src_img.h);
+
+ if (!scaleUp && !scaleDown) {
+ return;
+ }
+
+ /* otfMPP doesn't rotate image, m2mMPP rotates image */
+ exynos_image dst_scale_img = dst_img;
+ dst_scale_img.transform = src_img.transform;
+ src_img.transform = 0;
+
+ if (hasHdrInfo(src_img)) {
+ if (isFormatYUV(src_img.format))
+ dst_scale_img.format = HAL_PIXEL_FORMAT_YCBCR_P010;
+ else
+ dst_scale_img.format = HAL_PIXEL_FORMAT_RGBA_1010102;
+ } else {
+ if (isFormatYUV(src_img.format)) {
+ dst_scale_img.format = DEFAULT_MPP_DST_YUV_FORMAT;
+ }
+ }
+
+ const uint32_t reqRatio = (scaleUp ? max((dstW - 1) / src_img.w, (dstH - 1) / src_img.h)
+ : max((src_img.w - 1) / dstW, (src_img.h - 1) / dstH)) +
+ 1;
+
+ ExynosMPP *otfMpp = nullptr;
+ ExynosMPP *m2mMpp = nullptr;
+ uint32_t otfMppRatio = 1;
+ uint32_t m2mMppRatio = 1;
+ if (scaleUp) {
+ std::find_if(mOtfMPPs.begin(), mOtfMPPs.end(),
+ [&dst_scale_img, &dst_img, &otfMpp, &otfMppRatio](auto m) {
+ auto ratio = m->getMaxUpscale(dst_scale_img, dst_img);
+ if (ratio > 1) {
+ otfMpp = m;
+ otfMppRatio = ratio;
+ return true;
+ }
+ return false;
+ });
+ std::find_if(mM2mMPPs.begin(), mM2mMPPs.end(),
+ [&src_img, &dst_scale_img, otfMppRatio, reqRatio, &m2mMpp,
+ &m2mMppRatio](auto m) {
+ auto ratio = m->getMaxUpscale(src_img, dst_scale_img);
+ if (ratio * otfMppRatio >= reqRatio) {
+ m2mMpp = m;
+ m2mMppRatio = ratio;
+ return true;
+ }
+ return false;
+ });
+ } else {
+ std::find_if(mM2mMPPs.begin(), mM2mMPPs.end(),
+ [&src_img, &dst_scale_img, display, &m2mMpp, &m2mMppRatio](auto m) {
+ auto ratio = m->getMaxDownscale(*display, src_img, dst_scale_img);
+ if (ratio > 1) {
+ m2mMpp = m;
+ m2mMppRatio = ratio;
+ return true;
+ }
+ return false;
+ });
+ std::find_if(mOtfMPPs.begin(), mOtfMPPs.end(),
+ [&dst_scale_img, &dst_img, display, m2mMppRatio, reqRatio, &otfMpp,
+ &otfMppRatio](auto m) {
+ auto ratio = m->getMaxDownscale(*display, dst_scale_img, dst_img);
+ if (ratio * m2mMppRatio >= reqRatio) {
+ otfMpp = m;
+ otfMppRatio = ratio;
+ return true;
+ }
+ return false;
+ });
+ }
+
+ if (!otfMpp || !m2mMpp) {
+ HDEBUGLOGD(eDebugResourceManager,
+ "Cannot find available MPP for scaling w: %d, h: %d, ratio %d", dst_scale_img.w,
+ dst_scale_img.h, reqRatio);
+ return;
+ }
+
+ dst_scale_img.x = 0;
+ dst_scale_img.y = 0;
+ dst_scale_img.w = scaleDown ? dst_img.w : isPerpendicular ? src_img.h : src_img.w;
+ dst_scale_img.h = scaleDown ? dst_img.h : isPerpendicular ? src_img.w : src_img.h;
+
+ HDEBUGLOGD(eDebugResourceManager,
+ "scaling w: %d, h: %d, ratio %d = (otfType %d - %d, m2mType %d - %d)",
+ dst_scale_img.w, dst_scale_img.h, reqRatio, otfMpp->mLogicalType, otfMppRatio,
+ m2mMpp->mLogicalType, m2mMppRatio);
+ if (scaleUp) {
+ if (dst_scale_img.w * otfMppRatio < dst_img.w) {
+ dst_scale_img.w = uint32_t(ceilf(float(dst_img.w) / float(otfMppRatio)));
+ }
+ if (dst_scale_img.h * otfMppRatio < dst_img.h) {
+ dst_scale_img.h = uint32_t(ceilf(float(dst_img.h) / float(otfMppRatio)));
+ }
+ } else {
+ if (dst_scale_img.w * m2mMppRatio < src_img.w) {
+ dst_scale_img.w = uint32_t(ceilf(float(src_img.w) / float(m2mMppRatio)));
+ }
+ if (dst_scale_img.h * m2mMppRatio < src_img.h) {
+ dst_scale_img.h = uint32_t(ceilf(float(src_img.h) / float(m2mMppRatio)));
+ }
+ }
+ HDEBUGLOGD(eDebugResourceManager,
+ "\tsrc[%d, %d, %d,%d], dst[%d, %d, %d,%d], mid[%d, %d, %d, %d]", src_img.x,
+ src_img.y, src_img.w, src_img.h, dst_img.x, dst_img.y, dst_img.w, dst_img.h,
+ dst_scale_img.x, dst_scale_img.y, dst_scale_img.w, dst_scale_img.h);
+
+ if (isFormatSBWC(dst_scale_img.format)) {
+ image_lists.emplace_back(getAlignedImage(dst_scale_img, m2mMpp, otfMpp));
+ /*
+ * SBWC format could not be supported in specific dst size
+ * Add uncompressed YUV format to cover this size
+ */
+ dst_scale_img.format = DEFAULT_MPP_DST_UNCOMP_YUV_FORMAT;
+ }
+
+ image_lists.emplace_back(getAlignedImage(dst_scale_img, m2mMpp, otfMpp));
+}
+
int32_t ExynosResourceManager::getCandidateM2mMPPOutImages(ExynosDisplay *display,
ExynosLayer *layer, std::vector<exynos_image> &image_lists)
{
@@ -1144,80 +1300,7 @@ int32_t ExynosResourceManager::getCandidateM2mMPPOutImages(ExynosDisplay *displa
/* Copy origin source HDR metadata */
dst_img.metaParcel = src_img.metaParcel;
- uint32_t dstW = dst_img.w;
- uint32_t dstH = dst_img.h;
- bool isPerpendicular = !!(src_img.transform & HAL_TRANSFORM_ROT_90);
- if (isPerpendicular) {
- dstW = dst_img.h;
- dstH = dst_img.w;
- }
-
- /* Scale up case */
- if ((dstW > src_img.w) && (dstH > src_img.h))
- {
- /* otfMPP doesn't rotate image, m2mMPP rotates image */
- src_img.transform = 0;
- exynos_image dst_scale_img = dst_img;
-
- ExynosMPP *otfMppForScale = nullptr;
- auto mpp_it = std::find_if(mOtfMPPs.begin(), mOtfMPPs.end(),
- [&src_img, &dst_scale_img](auto m) {
- return (m->getMaxUpscale(src_img, dst_scale_img) > 1);
- });
- otfMppForScale = mpp_it == mOtfMPPs.end() ? nullptr : *mpp_it;
-
- if (hasHdrInfo(src_img)) {
- if (isFormatYUV(src_img.format))
- dst_scale_img.format = HAL_PIXEL_FORMAT_YCBCR_P010;
- else
- dst_scale_img.format = HAL_PIXEL_FORMAT_RGBA_1010102;
- } else {
- if (isFormatYUV(src_img.format)) {
- dst_scale_img.format = DEFAULT_MPP_DST_YUV_FORMAT;
- }
- }
-
- if (otfMppForScale) {
- uint32_t upScaleRatio = otfMppForScale->getMaxUpscale(src_img, dst_scale_img);
- uint32_t downScaleRatio = otfMppForScale->getMaxDownscale(*display, src_img, dst_scale_img);
- uint32_t srcCropWidthAlign = otfMppForScale->getSrcCropWidthAlign(src_img);
- uint32_t srcCropHeightAlign = otfMppForScale->getSrcCropHeightAlign(src_img);
-
- dst_scale_img.x = 0;
- dst_scale_img.y = 0;
- if (isPerpendicular) {
- dst_scale_img.w = pixel_align(src_img.h, srcCropWidthAlign);
- dst_scale_img.h = pixel_align(src_img.w, srcCropHeightAlign);
- } else {
- dst_scale_img.w = pixel_align(src_img.w, srcCropWidthAlign);
- dst_scale_img.h = pixel_align(src_img.h, srcCropHeightAlign);
- }
-
- HDEBUGLOGD(eDebugResourceManager, "scale up w: %d, h: %d, ratio(type: %d, %d, %d)",
- dst_scale_img.w, dst_scale_img.h,
- otfMppForScale->mLogicalType, upScaleRatio, downScaleRatio);
- if (dst_scale_img.w * upScaleRatio < dst_img.w) {
- dst_scale_img.w = pixel_align((uint32_t)ceilf((float)dst_img.w/(float)upScaleRatio), srcCropWidthAlign);
- }
- if (dst_scale_img.h * upScaleRatio < dst_img.h) {
- dst_scale_img.h = pixel_align((uint32_t)ceilf((float)dst_img.h/(float)upScaleRatio), srcCropHeightAlign);
- }
- HDEBUGLOGD(eDebugResourceManager, "\tsrc[%d, %d, %d,%d], dst[%d, %d, %d,%d], mid[%d, %d, %d, %d]",
- src_img.x, src_img.y, src_img.w, src_img.h,
- dst_img.x, dst_img.y, dst_img.w, dst_img.h,
- dst_scale_img.x, dst_scale_img.y, dst_scale_img.w, dst_scale_img.h);
- image_lists.push_back(dst_scale_img);
-
- if (isFormatSBWC(dst_scale_img.format)) {
- /*
- * SBWC format could not be supported in specific dst size
- * Add uncompressed YUV format to cover this size
- */
- dst_scale_img.format = DEFAULT_MPP_DST_UNCOMP_YUV_FORMAT;
- image_lists.push_back(dst_scale_img);
- }
- }
- }
+ getCandidateScalingM2mMPPOutImages(display, src_img, dst_img, image_lists);
if (isFormatYUV(src_img.format) && !hasHdrInfo(src_img)) {
dst_img.format = DEFAULT_MPP_DST_YUV_FORMAT;