107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/*
207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * Copyright (C) 2008 The Android Open Source Project
307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * Not a Contribution, Apache license notifications and license are retained
507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * for attribution purposes only.
607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani *
707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * Licensed under the Apache License, Version 2.0 (the "License");
807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * you may not use this file except in compliance with the License.
907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * You may obtain a copy of the License at
1007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani *
1107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani *      http://www.apache.org/licenses/LICENSE-2.0
1207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani *
1307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * Unless required by applicable law or agreed to in writing, software
1407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * distributed under the License is distributed on an "AS IS" BASIS,
1507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * See the License for the specific language governing permissions and
1707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * limitations under the License.
1807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani*/
1907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
2007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <math.h>
2107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include "overlayUtils.h"
2207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include "overlayRotator.h"
2307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
2407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#define DEBUG_MDSS_ROT 0
2507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
2607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#ifdef VENUS_COLOR_FORMAT
2707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <media/msm_media_info.h>
2807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#else
2907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#define VENUS_BUFFER_SIZE(args...) 0
3007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#endif
3107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
3207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#ifndef MDSS_MDP_ROT_ONLY
3307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#define MDSS_MDP_ROT_ONLY 0x80
3407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#endif
3507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
3607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#define MDSS_ROT_MASK (MDP_ROT_90 | MDP_FLIP_UD | MDP_FLIP_LR)
3707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
3807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malaninamespace ovutils = overlay::utils;
3907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
4007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malaninamespace overlay {
4107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malaniusing namespace utils;
4207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
4307bbf1e89c031a5d41a7561433e832d396c311a5Prashant MalaniMdssRot::MdssRot() {
4407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    reset();
4507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    init();
4607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
4707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
4807bbf1e89c031a5d41a7561433e832d396c311a5Prashant MalaniMdssRot::~MdssRot() { close(); }
4907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
5007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanibool MdssRot::enabled() const { return mEnabled; }
5107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
5207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanivoid MdssRot::setRotations(uint32_t flags) { mRotInfo.flags |= flags; }
5307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
5407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malaniint MdssRot::getSrcMemId() const {
5507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return mRotData.data.memory_id;
5607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
5707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
5807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malaniint MdssRot::getDstMemId() const {
5907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return mRotData.dst_data.memory_id;
6007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
6107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
6207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malaniuint32_t MdssRot::getSrcOffset() const {
6307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return mRotData.data.offset;
6407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
6507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
6607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malaniuint32_t MdssRot::getDstOffset() const {
6707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return mRotData.dst_data.offset;
6807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
6907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
7007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malaniuint32_t MdssRot::getDstFormat() const {
7107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    //For mdss src and dst formats are same
7207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return mRotInfo.src.format;
7307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
7407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
7507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malaniutils::Whf MdssRot::getDstWhf() const {
7607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    //For Mdss dst_rect itself represents buffer dimensions. We ignore actual
7707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    //aligned values during buffer allocation. Also the driver overwrites the
7807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    //src.format field if destination format is different.
7907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    //This implementation detail makes it possible to retrieve w,h even before
8007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    //buffer allocation, which happens in queueBuffer.
8107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return utils::Whf(mRotInfo.dst_rect.w, mRotInfo.dst_rect.h,
8207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            mRotInfo.src.format);
8307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
8407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
8507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malaniutils::Dim MdssRot::getDstDimensions() const {
8607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return utils::Dim(mRotInfo.dst_rect.x, mRotInfo.dst_rect.y,
8707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            mRotInfo.dst_rect.w, mRotInfo.dst_rect.h);
8807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
8907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
9007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malaniuint32_t MdssRot::getSessId() const { return mRotInfo.id; }
9107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
9207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanivoid MdssRot::save() {
9307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mLSRotInfo = mRotInfo;
9407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
9507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
9607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanibool MdssRot::rotConfChanged() const {
9707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // 0 means same
9807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(0 == ::memcmp(&mRotInfo, &mLSRotInfo,
9907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                     sizeof (mdp_overlay))) {
10007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return false;
10107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
10207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return true;
10307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
10407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
10507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanibool MdssRot::init() {
10607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(!utils::openDev(mFd, 0, Res::fbPath, O_RDWR)) {
10707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("MdssRot failed to init fb0");
10807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return false;
10907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
11007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return true;
11107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
11207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
11307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanivoid MdssRot::setSource(const overlay::utils::Whf& awhf) {
11407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    utils::Whf whf(awhf);
11507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
11607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mRotInfo.src.format = whf.format;
11707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mRotInfo.src.width = whf.w;
11807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mRotInfo.src.height = whf.h;
11907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
12007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
12107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanivoid MdssRot::setCrop(const utils::Dim& crop) {
12207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mRotInfo.src_rect.x = crop.x;
12307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mRotInfo.src_rect.y = crop.y;
12407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mRotInfo.src_rect.w = crop.w;
12507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mRotInfo.src_rect.h = crop.h;
12607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
12707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
12807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanivoid MdssRot::setDownscale(int downscale) {
12907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mDownscale = downscale;
13007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
13107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
13207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanivoid MdssRot::setFlags(const utils::eMdpFlags& flags) {
13307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mRotInfo.flags = flags;
13407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
13507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
13607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanivoid MdssRot::setTransform(const utils::eTransform& rot)
13707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
13807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // reset rotation flags to avoid stale orientation values
13907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mRotInfo.flags &= ~MDSS_ROT_MASK;
14007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int flags = utils::getMdpOrient(rot);
14107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (flags != -1)
14207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        setRotations(flags);
14307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mOrientation = static_cast<utils::eTransform>(flags);
14407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ALOGE_IF(DEBUG_OVERLAY, "%s: rot=%d", __FUNCTION__, flags);
14507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
14607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
14707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanivoid MdssRot::doTransform() {
14807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mRotInfo.flags |= mOrientation;
14907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(mOrientation & utils::OVERLAY_TRANSFORM_ROT_90)
15007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        utils::swap(mRotInfo.dst_rect.w, mRotInfo.dst_rect.h);
15107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
15207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
15307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanibool MdssRot::commit() {
15407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    Dim adjCrop(mRotInfo.src_rect.x,mRotInfo.src_rect.y,
15507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            mRotInfo.src_rect.w,mRotInfo.src_rect.h);
15607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    adjCrop = getFormatAdjustedCrop(adjCrop, mRotInfo.src.format,
15707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            mRotInfo.flags & utils::OV_MDP_DEINTERLACE);
15807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    adjCrop = getDownscaleAdjustedCrop(adjCrop, mDownscale);
15907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
16007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mRotInfo.src_rect.x = adjCrop.x;
16107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mRotInfo.src_rect.y = adjCrop.y;
16207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mRotInfo.src_rect.w = adjCrop.w;
16307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mRotInfo.src_rect.h = adjCrop.h;
16407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
16507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mRotInfo.dst_rect.x = 0;
16607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mRotInfo.dst_rect.y = 0;
16707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mRotInfo.dst_rect.w = mDownscale ?
16807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            mRotInfo.src_rect.w / mDownscale : mRotInfo.src_rect.w;
16907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mRotInfo.dst_rect.h = mDownscale ?
17007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            mRotInfo.src_rect.h / mDownscale : mRotInfo.src_rect.h;
17107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    //Clear for next round
17207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mDownscale = 0;
17307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
17407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    doTransform();
17507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
17607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mRotInfo.flags |= MDSS_MDP_ROT_ONLY;
17707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mEnabled = true;
17807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(!overlay::mdp_wrapper::setOverlay(mFd.getFD(), mRotInfo)) {
17907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("MdssRot commit failed!");
18007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        dump();
18107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return (mEnabled = false);
18207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
18307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mRotData.id = mRotInfo.id;
18407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return true;
18507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
18607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
18707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanibool MdssRot::queueBuffer(int fd, uint32_t offset) {
18807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(enabled() and (not isRotCached(fd,offset))) {
18907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        int prev_fd = getSrcMemId();
19007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        uint32_t prev_offset = getSrcOffset();
19107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
19207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        mRotData.data.memory_id = fd;
19307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        mRotData.data.offset = offset;
19407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
19507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if(false == remap(RotMem::ROT_NUM_BUFS)) {
19607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ALOGE("%s Remap failed, not queuing", __FUNCTION__);
19707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            return false;
19807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
19907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
20007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        mRotData.dst_data.offset =
20107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                mMem.mRotOffset[mMem.mCurrIndex];
20207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
20307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if(!overlay::mdp_wrapper::play(mFd.getFD(), mRotData)) {
20407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ALOGE("MdssRot play failed!");
20507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            dump();
20607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            mRotData.data.memory_id = prev_fd;
20707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            mRotData.data.offset = prev_offset;
20807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            return false;
20907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
21007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        save();
21107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        mMem.mCurrIndex =
21207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                (mMem.mCurrIndex + 1) % mMem.mem.numBufs();
21307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
21407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return true;
21507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
21607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
21707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanibool MdssRot::open_i(uint32_t numbufs, uint32_t bufsz)
21807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
21907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    OvMem mem;
22007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    OVASSERT(MAP_FAILED == mem.addr(), "MAP failed in open_i");
22107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    bool isSecure = mRotInfo.flags & utils::OV_MDP_SECURE_OVERLAY_SESSION;
22207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
22307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(!mem.open(numbufs, bufsz, isSecure)){
22407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: Failed to open", __func__);
22507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        mem.close();
22607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return false;
22707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
22807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
22907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    OVASSERT(MAP_FAILED != mem.addr(), "MAP failed");
23007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    OVASSERT(mem.getFD() != -1, "getFd is -1");
23107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
23207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mRotData.dst_data.memory_id = mem.getFD();
23307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mRotData.dst_data.offset = 0;
23407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mMem.mem = mem;
23507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return true;
23607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
23707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
23807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanibool MdssRot::remap(uint32_t numbufs) {
23907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // Calculate the size based on rotator's dst format, w and h.
24007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    uint32_t opBufSize = calcOutputBufSize();
24107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // If current size changed, remap
24207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(opBufSize == mMem.size()) {
24307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE_IF(DEBUG_OVERLAY, "%s: same size %d", __FUNCTION__, opBufSize);
24407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return true;
24507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
24607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
24707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ALOGE_IF(DEBUG_OVERLAY, "%s: size changed - remapping", __FUNCTION__);
24807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
24907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(!mMem.close()) {
25007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s error in closing prev rot mem", __FUNCTION__);
25107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return false;
25207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
25307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
25407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(!open_i(numbufs, opBufSize)) {
25507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s Error could not open", __FUNCTION__);
25607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return false;
25707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
25807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
25907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    for (uint32_t i = 0; i < numbufs; ++i) {
26007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        mMem.mRotOffset[i] = i * opBufSize;
26107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
26207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
26307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return true;
26407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
26507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
26607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanibool MdssRot::close() {
26707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    bool success = true;
26807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(mFd.valid() && (getSessId() != (uint32_t) MSMFB_NEW_REQUEST)) {
26907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if(!mdp_wrapper::unsetOverlay(mFd.getFD(), getSessId())) {
27007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ALOGE("MdssRot::close unsetOverlay failed, fd=%d sessId=%d",
27107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                  mFd.getFD(), getSessId());
27207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            success = false;
27307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
27407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
27507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
27607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (!mFd.close()) {
27707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("Mdss Rot error closing fd");
27807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        success = false;
27907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
28007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (!mMem.close()) {
28107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("Mdss Rot error closing mem");
28207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        success = false;
28307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
28407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    reset();
28507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return success;
28607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
28707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
28807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanivoid MdssRot::reset() {
28907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ovutils::memset0(mRotInfo);
29007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ovutils::memset0(mLSRotInfo);
29107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ovutils::memset0(mRotData);
29207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mRotData.data.memory_id = -1;
29307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mRotInfo.id = MSMFB_NEW_REQUEST;
29407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ovutils::memset0(mMem.mRotOffset);
29507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mMem.mCurrIndex = 0;
29607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mOrientation = utils::OVERLAY_TRANSFORM_0;
29707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mDownscale = 0;
29807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
29907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
30007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanivoid MdssRot::dump() const {
30107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ALOGE("== Dump MdssRot start ==");
30207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mFd.dump();
30307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mMem.mem.dump();
30407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mdp_wrapper::dump("mRotInfo", mRotInfo);
30507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mdp_wrapper::dump("mRotData", mRotData);
30607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ALOGE("== Dump MdssRot end ==");
30707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
30807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
30907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malaniuint32_t MdssRot::calcOutputBufSize() {
31007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    uint32_t opBufSize = 0;
31107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ovutils::Whf destWhf(mRotInfo.dst_rect.w, mRotInfo.dst_rect.h,
31207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            mRotInfo.src.format); //mdss src and dst formats are same.
31307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
31407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (mRotInfo.flags & ovutils::OV_MDSS_MDP_BWC_EN) {
31507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        opBufSize = calcCompressedBufSize(destWhf);
31607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    } else {
31707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        opBufSize = Rotator::calcOutputBufSize(destWhf);
31807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
31907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
32007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return opBufSize;
32107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
32207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
32307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanivoid MdssRot::getDump(char *buf, size_t len) const {
32407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ovutils::getDump(buf, len, "MdssRotCtrl", mRotInfo);
32507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ovutils::getDump(buf, len, "MdssRotData", mRotData);
32607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
32707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
32807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani// Calculate the compressed o/p buffer size for BWC
32907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malaniuint32_t MdssRot::calcCompressedBufSize(const ovutils::Whf& destWhf) {
33007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    uint32_t bufSize = 0;
33107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    //Worst case alignments
33207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int aWidth = ovutils::align(destWhf.w, 64);
33307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int aHeight = ovutils::align(destWhf.h, 4);
33407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    /*
33507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani       Format           |   RAU size (width x height)
33607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani       ----------------------------------------------
33707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani       ARGB             |       32 pixel x 4 line
33807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani       RGB888           |       32 pixel x 4 line
33907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani       Y (Luma)         |       64 pixel x 4 line
34007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani       CRCB 420         |       32 pixel x 2 line
34107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani       CRCB 422 H2V1    |       32 pixel x 4 line
34207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani       CRCB 422 H1V2    |       64 pixel x 2 line
34307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
34407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani       Metadata requirements:-
34507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani       1 byte meta data for every 8 RAUs
34607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani       2 byte meta data per RAU
34707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani     */
34807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
34907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    //These blocks attempt to allocate for the worst case in each of the
35007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    //respective format classes, yuv/rgb. The table above is for reference
35107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(utils::isYuv(destWhf.format)) {
35207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        int yRauCount = aWidth / 64; //Y
35307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        int cRauCount = aWidth / 32; //C
35407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        int yStride = (64 * 4 * yRauCount) + alignup(yRauCount, 8) / 8;
35507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        int cStride = ((32 * 2 * cRauCount) + alignup(cRauCount, 8) / 8) * 2;
35607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        int yStrideOffset = (aHeight / 4);
35707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        int cStrideOffset = (aHeight / 2);
35807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        bufSize = (yStride * yStrideOffset + cStride * cStrideOffset) +
35907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                (yRauCount * yStrideOffset * 2) +
36007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                (cRauCount * cStrideOffset * 2) * 2;
36107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGD_IF(DEBUG_MDSS_ROT, "%s:YUV Y RAU Count = %d C RAU Count = %d",
36207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                __FUNCTION__, yRauCount, cRauCount);
36307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    } else {
36407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        int rauCount = aWidth / 32;
36507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        //Single plane
36607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        int stride = (32 * 4 * rauCount) + alignup(rauCount, 8) / 8;
36707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        int strideOffset = (aHeight / 4);
36807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        bufSize = (stride * strideOffset * 4 /*bpp*/) +
36907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            (rauCount * strideOffset * 2);
37007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGD_IF(DEBUG_MDSS_ROT, "%s:RGB RAU count = %d", __FUNCTION__,
37107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                rauCount);
37207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
37307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
37407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ALOGD_IF(DEBUG_MDSS_ROT, "%s: aligned width = %d, aligned height = %d "
37507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            "Buf Size = %d", __FUNCTION__, aWidth, aHeight, bufSize);
37607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
37707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return bufSize;
37807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
37907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
38007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malaniint MdssRot::getDownscaleFactor(const int& srcW, const int& srcH,
38107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        const int& dstW, const int& dstH, const uint32_t& mdpFormat,
38207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        const bool& isInterlaced) {
38307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(not srcW or not srcH or not dstW or not dstH or isInterlaced) return 0;
38407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
38507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    Dim crop(0, 0, srcW, srcH);
38607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    Dim adjCrop = getFormatAdjustedCrop(crop, mdpFormat,
38707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            false /*isInterlaced */);
38807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
38907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    uint32_t downscale = min((adjCrop.w / dstW), (adjCrop.h / dstH));
39007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    //Reduced to a power of 2
39107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    downscale = (uint32_t) powf(2.0f, floorf(log2f((float)downscale)));
39207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
39307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(downscale < 2 or downscale > 32) return 0;
39407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
39507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    //Allow only 1 line or pixel to be chopped off since the source needs to
39607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    //be aligned to downscale. Progressively try with smaller downscale to see
39707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    //if we can satisfy the threshold
39807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    //For YUV the loop shouldnt be needed, unless in exceptional cases
39907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    Dim dsAdjCrop = getDownscaleAdjustedCrop(adjCrop, downscale);
40007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    while(downscale > 2 and (adjCrop.w > dsAdjCrop.w or
40107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            adjCrop.h > dsAdjCrop.h)) {
40207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        downscale /= 2;
40307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        dsAdjCrop = getDownscaleAdjustedCrop(adjCrop, downscale);
40407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
40507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
40607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(not dsAdjCrop.w or not dsAdjCrop.h) return 0;
40707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return downscale;
40807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
40907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
41007bbf1e89c031a5d41a7561433e832d396c311a5Prashant MalaniDim MdssRot::getFormatAdjustedCrop(const Dim& crop,
41107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            const uint32_t& mdpFormat, const bool& isInterlaced) {
41207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    Dim adjCrop = crop;
41307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (isYuv(mdpFormat)) {
41407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        normalizeCrop(adjCrop.x, adjCrop.w);
41507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        normalizeCrop(adjCrop.y, adjCrop.h);
41607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        // For interlaced, crop.h should be 4-aligned
41707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if (isInterlaced and (adjCrop.h % 4))
41807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            adjCrop.h = aligndown(adjCrop.h, 4);
41907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
42007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return adjCrop;
42107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
42207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
42307bbf1e89c031a5d41a7561433e832d396c311a5Prashant MalaniDim MdssRot::getDownscaleAdjustedCrop(const Dim& crop,
42407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        const uint32_t& downscale) {
42507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    uint32_t alignedSrcW = aligndown(crop.w, downscale * 2);
42607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    uint32_t alignedSrcH = aligndown(crop.h, downscale * 2);
42707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return Dim(crop.x, crop.y, alignedSrcW, alignedSrcH);
42807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
42907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
43007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani} // namespace overlay
431