132a6e48fSopenharmony_ci/*
232a6e48fSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
332a6e48fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
432a6e48fSopenharmony_ci * you may not use this file except in compliance with the License.
532a6e48fSopenharmony_ci * You may obtain a copy of the License at
632a6e48fSopenharmony_ci *
732a6e48fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
832a6e48fSopenharmony_ci *
932a6e48fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1032a6e48fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1132a6e48fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1232a6e48fSopenharmony_ci * See the License for the specific language governing permissions and
1332a6e48fSopenharmony_ci * limitations under the License.
1432a6e48fSopenharmony_ci */
1532a6e48fSopenharmony_ci
1632a6e48fSopenharmony_ci#include <surface_utils.h>
1732a6e48fSopenharmony_ci#include <cinttypes>
1832a6e48fSopenharmony_ci#include "securec.h"
1932a6e48fSopenharmony_ci#include "buffer_log.h"
2032a6e48fSopenharmony_ci
2132a6e48fSopenharmony_cinamespace OHOS {
2232a6e48fSopenharmony_ciusing namespace HiviewDFX;
2332a6e48fSopenharmony_cistatic SurfaceUtils* instance = nullptr;
2432a6e48fSopenharmony_cistatic std::once_flag createFlag_;
2532a6e48fSopenharmony_ciconstexpr uint32_t MATRIX_ARRAY_SIZE = 16;
2632a6e48fSopenharmony_ci
2732a6e48fSopenharmony_ciSurfaceUtils* SurfaceUtils::GetInstance()
2832a6e48fSopenharmony_ci{
2932a6e48fSopenharmony_ci    std::call_once(createFlag_, [&]() {
3032a6e48fSopenharmony_ci        instance = new SurfaceUtils();
3132a6e48fSopenharmony_ci    });
3232a6e48fSopenharmony_ci
3332a6e48fSopenharmony_ci    return instance;
3432a6e48fSopenharmony_ci}
3532a6e48fSopenharmony_ci
3632a6e48fSopenharmony_ciSurfaceUtils::~SurfaceUtils()
3732a6e48fSopenharmony_ci{
3832a6e48fSopenharmony_ci    instance = nullptr;
3932a6e48fSopenharmony_ci    surfaceCache_.clear();
4032a6e48fSopenharmony_ci    nativeWindowCache_.clear();
4132a6e48fSopenharmony_ci}
4232a6e48fSopenharmony_ci
4332a6e48fSopenharmony_cisptr<Surface> SurfaceUtils::GetSurface(uint64_t uniqueId)
4432a6e48fSopenharmony_ci{
4532a6e48fSopenharmony_ci    std::lock_guard<std::mutex> lockGuard(mutex_);
4632a6e48fSopenharmony_ci    auto iter = surfaceCache_.find(uniqueId);
4732a6e48fSopenharmony_ci    if (iter == surfaceCache_.end()) {
4832a6e48fSopenharmony_ci        BLOGE("Cannot find surface, uniqueId: %{public}" PRIu64 ".", uniqueId);
4932a6e48fSopenharmony_ci        return nullptr;
5032a6e48fSopenharmony_ci    }
5132a6e48fSopenharmony_ci    sptr<Surface> surface = iter->second.promote();
5232a6e48fSopenharmony_ci    if (surface == nullptr) {
5332a6e48fSopenharmony_ci        BLOGE("surface is nullptr, uniqueId: %{public}" PRIu64 ".", uniqueId);
5432a6e48fSopenharmony_ci        return nullptr;
5532a6e48fSopenharmony_ci    }
5632a6e48fSopenharmony_ci    return surface;
5732a6e48fSopenharmony_ci}
5832a6e48fSopenharmony_ci
5932a6e48fSopenharmony_ciSurfaceError SurfaceUtils::Add(uint64_t uniqueId, const wptr<Surface> &surface)
6032a6e48fSopenharmony_ci{
6132a6e48fSopenharmony_ci    if (surface == nullptr) {
6232a6e48fSopenharmony_ci        return GSERROR_INVALID_ARGUMENTS;
6332a6e48fSopenharmony_ci    }
6432a6e48fSopenharmony_ci    std::lock_guard<std::mutex> lockGuard(mutex_);
6532a6e48fSopenharmony_ci    if (surfaceCache_.count(uniqueId) == 0) {
6632a6e48fSopenharmony_ci        surfaceCache_[uniqueId] = surface;
6732a6e48fSopenharmony_ci        return GSERROR_OK;
6832a6e48fSopenharmony_ci    }
6932a6e48fSopenharmony_ci    BLOGD("the surface already existed, uniqueId: %{public}" PRIu64, uniqueId);
7032a6e48fSopenharmony_ci    return GSERROR_OK;
7132a6e48fSopenharmony_ci}
7232a6e48fSopenharmony_ci
7332a6e48fSopenharmony_ciSurfaceError SurfaceUtils::Remove(uint64_t uniqueId)
7432a6e48fSopenharmony_ci{
7532a6e48fSopenharmony_ci    std::lock_guard<std::mutex> lockGuard(mutex_);
7632a6e48fSopenharmony_ci    auto iter = surfaceCache_.find(uniqueId);
7732a6e48fSopenharmony_ci    if (iter == surfaceCache_.end()) {
7832a6e48fSopenharmony_ci        BLOGD("Cannot find surface, uniqueId: %{public}" PRIu64 ".", uniqueId);
7932a6e48fSopenharmony_ci        return GSERROR_INVALID_OPERATING;
8032a6e48fSopenharmony_ci    }
8132a6e48fSopenharmony_ci    surfaceCache_.erase(iter);
8232a6e48fSopenharmony_ci    return GSERROR_OK;
8332a6e48fSopenharmony_ci}
8432a6e48fSopenharmony_ci
8532a6e48fSopenharmony_cistd::array<float, MATRIX_ARRAY_SIZE> SurfaceUtils::MatrixProduct(const std::array<float, MATRIX_ARRAY_SIZE>& lMat,
8632a6e48fSopenharmony_ci    const std::array<float, MATRIX_ARRAY_SIZE>& rMat)
8732a6e48fSopenharmony_ci{
8832a6e48fSopenharmony_ci    // Product matrix 4 * 4 = 16
8932a6e48fSopenharmony_ci    return std::array<float, MATRIX_ARRAY_SIZE> {
9032a6e48fSopenharmony_ci        lMat[0] * rMat[0] + lMat[4] * rMat[1] + lMat[8] * rMat[2] + lMat[12] * rMat[3],
9132a6e48fSopenharmony_ci        lMat[1] * rMat[0] + lMat[5] * rMat[1] + lMat[9] * rMat[2] + lMat[13] * rMat[3],
9232a6e48fSopenharmony_ci        lMat[2] * rMat[0] + lMat[6] * rMat[1] + lMat[10] * rMat[2] + lMat[14] * rMat[3],
9332a6e48fSopenharmony_ci        lMat[3] * rMat[0] + lMat[7] * rMat[1] + lMat[11] * rMat[2] + lMat[15] * rMat[3],
9432a6e48fSopenharmony_ci
9532a6e48fSopenharmony_ci        lMat[0] * rMat[4] + lMat[4] * rMat[5] + lMat[8] * rMat[6] + lMat[12] * rMat[7],
9632a6e48fSopenharmony_ci        lMat[1] * rMat[4] + lMat[5] * rMat[5] + lMat[9] * rMat[6] + lMat[13] * rMat[7],
9732a6e48fSopenharmony_ci        lMat[2] * rMat[4] + lMat[6] * rMat[5] + lMat[10] * rMat[6] + lMat[14] * rMat[7],
9832a6e48fSopenharmony_ci        lMat[3] * rMat[4] + lMat[7] * rMat[5] + lMat[11] * rMat[6] + lMat[15] * rMat[7],
9932a6e48fSopenharmony_ci
10032a6e48fSopenharmony_ci        lMat[0] * rMat[8] + lMat[4] * rMat[9] + lMat[8] * rMat[10] + lMat[12] * rMat[11],
10132a6e48fSopenharmony_ci        lMat[1] * rMat[8] + lMat[5] * rMat[9] + lMat[9] * rMat[10] + lMat[13] * rMat[11],
10232a6e48fSopenharmony_ci        lMat[2] * rMat[8] + lMat[6] * rMat[9] + lMat[10] * rMat[10] + lMat[14] * rMat[11],
10332a6e48fSopenharmony_ci        lMat[3] * rMat[8] + lMat[7] * rMat[9] + lMat[11] * rMat[10] + lMat[15] * rMat[11],
10432a6e48fSopenharmony_ci
10532a6e48fSopenharmony_ci        lMat[0] * rMat[12] + lMat[4] * rMat[13] + lMat[8] * rMat[14] + lMat[12] * rMat[15],
10632a6e48fSopenharmony_ci        lMat[1] * rMat[12] + lMat[5] * rMat[13] + lMat[9] * rMat[14] + lMat[13] * rMat[15],
10732a6e48fSopenharmony_ci        lMat[2] * rMat[12] + lMat[6] * rMat[13] + lMat[10] * rMat[14] + lMat[14] * rMat[15],
10832a6e48fSopenharmony_ci        lMat[3] * rMat[12] + lMat[7] * rMat[13] + lMat[11] * rMat[14] + lMat[15] * rMat[15]
10932a6e48fSopenharmony_ci    };
11032a6e48fSopenharmony_ci}
11132a6e48fSopenharmony_ci
11232a6e48fSopenharmony_civoid SurfaceUtils::ComputeTransformByMatrix(GraphicTransformType& transform,
11332a6e48fSopenharmony_ci    std::array<float, TRANSFORM_MATRIX_ELE_COUNT> *transformMatrix)
11432a6e48fSopenharmony_ci{
11532a6e48fSopenharmony_ci    const std::array<float, TRANSFORM_MATRIX_ELE_COUNT> rotate90 = {0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
11632a6e48fSopenharmony_ci    const std::array<float, TRANSFORM_MATRIX_ELE_COUNT> rotate180 = {-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
11732a6e48fSopenharmony_ci    const std::array<float, TRANSFORM_MATRIX_ELE_COUNT> rotate270 = {0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
11832a6e48fSopenharmony_ci    const std::array<float, TRANSFORM_MATRIX_ELE_COUNT> flipH = {-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
11932a6e48fSopenharmony_ci    const std::array<float, TRANSFORM_MATRIX_ELE_COUNT> flipV = {1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
12032a6e48fSopenharmony_ci
12132a6e48fSopenharmony_ci    switch (transform) {
12232a6e48fSopenharmony_ci        case GraphicTransformType::GRAPHIC_ROTATE_NONE:
12332a6e48fSopenharmony_ci            break;
12432a6e48fSopenharmony_ci        case GraphicTransformType::GRAPHIC_ROTATE_90:
12532a6e48fSopenharmony_ci            *transformMatrix = MatrixProduct(*transformMatrix, rotate90);
12632a6e48fSopenharmony_ci            break;
12732a6e48fSopenharmony_ci        case GraphicTransformType::GRAPHIC_ROTATE_180:
12832a6e48fSopenharmony_ci            *transformMatrix = MatrixProduct(*transformMatrix, rotate180);
12932a6e48fSopenharmony_ci            break;
13032a6e48fSopenharmony_ci        case GraphicTransformType::GRAPHIC_ROTATE_270:
13132a6e48fSopenharmony_ci            *transformMatrix = MatrixProduct(*transformMatrix, rotate270);
13232a6e48fSopenharmony_ci            break;
13332a6e48fSopenharmony_ci        case GraphicTransformType::GRAPHIC_FLIP_H:
13432a6e48fSopenharmony_ci            *transformMatrix = MatrixProduct(*transformMatrix, flipH);
13532a6e48fSopenharmony_ci            break;
13632a6e48fSopenharmony_ci        case GraphicTransformType::GRAPHIC_FLIP_V:
13732a6e48fSopenharmony_ci            *transformMatrix = MatrixProduct(*transformMatrix, flipV);
13832a6e48fSopenharmony_ci            break;
13932a6e48fSopenharmony_ci        case GraphicTransformType::GRAPHIC_FLIP_H_ROT90:
14032a6e48fSopenharmony_ci            *transformMatrix = MatrixProduct(flipH, rotate90);
14132a6e48fSopenharmony_ci            break;
14232a6e48fSopenharmony_ci        case GraphicTransformType::GRAPHIC_FLIP_V_ROT90:
14332a6e48fSopenharmony_ci            *transformMatrix = MatrixProduct(flipV, rotate90);
14432a6e48fSopenharmony_ci            break;
14532a6e48fSopenharmony_ci        case GraphicTransformType::GRAPHIC_FLIP_H_ROT180:
14632a6e48fSopenharmony_ci            *transformMatrix = MatrixProduct(flipH, rotate180);
14732a6e48fSopenharmony_ci            break;
14832a6e48fSopenharmony_ci        case GraphicTransformType::GRAPHIC_FLIP_V_ROT180:
14932a6e48fSopenharmony_ci            *transformMatrix = MatrixProduct(flipV, rotate180);
15032a6e48fSopenharmony_ci            break;
15132a6e48fSopenharmony_ci        case GraphicTransformType::GRAPHIC_FLIP_H_ROT270:
15232a6e48fSopenharmony_ci            *transformMatrix = MatrixProduct(flipH, rotate270);
15332a6e48fSopenharmony_ci            break;
15432a6e48fSopenharmony_ci        case GraphicTransformType::GRAPHIC_FLIP_V_ROT270:
15532a6e48fSopenharmony_ci            *transformMatrix = MatrixProduct(flipV, rotate270);
15632a6e48fSopenharmony_ci            break;
15732a6e48fSopenharmony_ci        default:
15832a6e48fSopenharmony_ci            break;
15932a6e48fSopenharmony_ci    }
16032a6e48fSopenharmony_ci}
16132a6e48fSopenharmony_ci
16232a6e48fSopenharmony_civoid SurfaceUtils::ComputeTransformMatrix(float matrix[MATRIX_ARRAY_SIZE], uint32_t matrixSize,
16332a6e48fSopenharmony_ci    sptr<SurfaceBuffer>& buffer, GraphicTransformType& transform, Rect& crop)
16432a6e48fSopenharmony_ci{
16532a6e48fSopenharmony_ci    if (buffer == nullptr) {
16632a6e48fSopenharmony_ci        return;
16732a6e48fSopenharmony_ci    }
16832a6e48fSopenharmony_ci    float tx = 0.f;
16932a6e48fSopenharmony_ci    float ty = 0.f;
17032a6e48fSopenharmony_ci    float sx = 1.f;
17132a6e48fSopenharmony_ci    float sy = 1.f;
17232a6e48fSopenharmony_ci    std::array<float, TRANSFORM_MATRIX_ELE_COUNT> transformMatrix = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
17332a6e48fSopenharmony_ci    ComputeTransformByMatrix(transform, &transformMatrix);
17432a6e48fSopenharmony_ci
17532a6e48fSopenharmony_ci    float bufferWidth = buffer->GetWidth();
17632a6e48fSopenharmony_ci    float bufferHeight = buffer->GetHeight();
17732a6e48fSopenharmony_ci    bool changeFlag = false;
17832a6e48fSopenharmony_ci    if (crop.w < bufferWidth && bufferWidth != 0) {
17932a6e48fSopenharmony_ci        tx = (float(crop.x) / bufferWidth);
18032a6e48fSopenharmony_ci        sx = (float(crop.w) / bufferWidth);
18132a6e48fSopenharmony_ci        changeFlag = true;
18232a6e48fSopenharmony_ci    }
18332a6e48fSopenharmony_ci    if (crop.h < bufferHeight && bufferHeight != 0) {
18432a6e48fSopenharmony_ci        ty = (float(bufferHeight - crop.y) / bufferHeight);
18532a6e48fSopenharmony_ci        sy = (float(crop.h) / bufferHeight);
18632a6e48fSopenharmony_ci        changeFlag = true;
18732a6e48fSopenharmony_ci    }
18832a6e48fSopenharmony_ci    if (changeFlag) {
18932a6e48fSopenharmony_ci        std::array<float, MATRIX_ARRAY_SIZE> cropMatrix = {sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, 1, 0, tx, ty, 0, 1};
19032a6e48fSopenharmony_ci        transformMatrix = MatrixProduct(cropMatrix, transformMatrix);
19132a6e48fSopenharmony_ci    }
19232a6e48fSopenharmony_ci
19332a6e48fSopenharmony_ci    auto ret = memcpy_s(matrix, matrixSize * sizeof(float),
19432a6e48fSopenharmony_ci                        transformMatrix.data(), sizeof(transformMatrix));
19532a6e48fSopenharmony_ci    if (ret != EOK) {
19632a6e48fSopenharmony_ci        BLOGE("memcpy_s failed, ret: %{public}d", ret);
19732a6e48fSopenharmony_ci    }
19832a6e48fSopenharmony_ci}
19932a6e48fSopenharmony_ci
20032a6e48fSopenharmony_civoid SurfaceUtils::ComputeTransformByMatrixV2(GraphicTransformType& transform,
20132a6e48fSopenharmony_ci    std::array<float, TRANSFORM_MATRIX_ELE_COUNT> *transformMatrix)
20232a6e48fSopenharmony_ci{
20332a6e48fSopenharmony_ci    const std::array<float, TRANSFORM_MATRIX_ELE_COUNT> rotate90 = {0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1};
20432a6e48fSopenharmony_ci    const std::array<float, TRANSFORM_MATRIX_ELE_COUNT> rotate180 = {-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1};
20532a6e48fSopenharmony_ci    const std::array<float, TRANSFORM_MATRIX_ELE_COUNT> rotate270 = {0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1};
20632a6e48fSopenharmony_ci    const std::array<float, TRANSFORM_MATRIX_ELE_COUNT> flipH = {-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1};
20732a6e48fSopenharmony_ci    const std::array<float, TRANSFORM_MATRIX_ELE_COUNT> flipV = {1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1};
20832a6e48fSopenharmony_ci
20932a6e48fSopenharmony_ci    switch (transform) {
21032a6e48fSopenharmony_ci        case GraphicTransformType::GRAPHIC_ROTATE_NONE:
21132a6e48fSopenharmony_ci            break;
21232a6e48fSopenharmony_ci        case GraphicTransformType::GRAPHIC_ROTATE_90:
21332a6e48fSopenharmony_ci            *transformMatrix = rotate90;
21432a6e48fSopenharmony_ci            break;
21532a6e48fSopenharmony_ci        case GraphicTransformType::GRAPHIC_ROTATE_180:
21632a6e48fSopenharmony_ci            *transformMatrix = rotate180;
21732a6e48fSopenharmony_ci            break;
21832a6e48fSopenharmony_ci        case GraphicTransformType::GRAPHIC_ROTATE_270:
21932a6e48fSopenharmony_ci            *transformMatrix = rotate270;
22032a6e48fSopenharmony_ci            break;
22132a6e48fSopenharmony_ci        case GraphicTransformType::GRAPHIC_FLIP_H:
22232a6e48fSopenharmony_ci            *transformMatrix = flipH;
22332a6e48fSopenharmony_ci            break;
22432a6e48fSopenharmony_ci        case GraphicTransformType::GRAPHIC_FLIP_V:
22532a6e48fSopenharmony_ci            *transformMatrix = flipV;
22632a6e48fSopenharmony_ci            break;
22732a6e48fSopenharmony_ci        case GraphicTransformType::GRAPHIC_FLIP_H_ROT90:
22832a6e48fSopenharmony_ci            *transformMatrix = MatrixProduct(flipV, rotate90);
22932a6e48fSopenharmony_ci            break;
23032a6e48fSopenharmony_ci        case GraphicTransformType::GRAPHIC_FLIP_V_ROT90:
23132a6e48fSopenharmony_ci            *transformMatrix = MatrixProduct(flipH, rotate90);
23232a6e48fSopenharmony_ci            break;
23332a6e48fSopenharmony_ci        case GraphicTransformType::GRAPHIC_FLIP_H_ROT180:
23432a6e48fSopenharmony_ci            *transformMatrix = flipV;
23532a6e48fSopenharmony_ci            break;
23632a6e48fSopenharmony_ci        case GraphicTransformType::GRAPHIC_FLIP_V_ROT180:
23732a6e48fSopenharmony_ci            *transformMatrix = flipH;
23832a6e48fSopenharmony_ci            break;
23932a6e48fSopenharmony_ci        case GraphicTransformType::GRAPHIC_FLIP_H_ROT270:
24032a6e48fSopenharmony_ci            *transformMatrix = MatrixProduct(flipH, rotate90);
24132a6e48fSopenharmony_ci            break;
24232a6e48fSopenharmony_ci        case GraphicTransformType::GRAPHIC_FLIP_V_ROT270:
24332a6e48fSopenharmony_ci            *transformMatrix = MatrixProduct(flipV, rotate90);
24432a6e48fSopenharmony_ci            break;
24532a6e48fSopenharmony_ci        default:
24632a6e48fSopenharmony_ci            break;
24732a6e48fSopenharmony_ci    }
24832a6e48fSopenharmony_ci}
24932a6e48fSopenharmony_ci
25032a6e48fSopenharmony_civoid SurfaceUtils::ComputeTransformMatrixV2(float matrix[MATRIX_ARRAY_SIZE], uint32_t matrixSize,
25132a6e48fSopenharmony_ci    sptr<SurfaceBuffer>& buffer, GraphicTransformType& transform, Rect& crop)
25232a6e48fSopenharmony_ci{
25332a6e48fSopenharmony_ci    if (buffer == nullptr) {
25432a6e48fSopenharmony_ci        return;
25532a6e48fSopenharmony_ci    }
25632a6e48fSopenharmony_ci    float tx = 0.f;
25732a6e48fSopenharmony_ci    float ty = 0.f;
25832a6e48fSopenharmony_ci    float sx = 1.f;
25932a6e48fSopenharmony_ci    float sy = 1.f;
26032a6e48fSopenharmony_ci    switch (transform) {
26132a6e48fSopenharmony_ci        case GraphicTransformType::GRAPHIC_ROTATE_90:
26232a6e48fSopenharmony_ci            transform = GraphicTransformType::GRAPHIC_ROTATE_270;
26332a6e48fSopenharmony_ci            break;
26432a6e48fSopenharmony_ci        case GraphicTransformType::GRAPHIC_ROTATE_270:
26532a6e48fSopenharmony_ci            transform = GraphicTransformType::GRAPHIC_ROTATE_90;
26632a6e48fSopenharmony_ci            break;
26732a6e48fSopenharmony_ci        default:
26832a6e48fSopenharmony_ci            break;
26932a6e48fSopenharmony_ci    }
27032a6e48fSopenharmony_ci    std::array<float, TRANSFORM_MATRIX_ELE_COUNT> transformMatrix = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
27132a6e48fSopenharmony_ci    ComputeTransformByMatrixV2(transform, &transformMatrix);
27232a6e48fSopenharmony_ci
27332a6e48fSopenharmony_ci    float bufferWidth = buffer->GetWidth();
27432a6e48fSopenharmony_ci    float bufferHeight = buffer->GetHeight();
27532a6e48fSopenharmony_ci    bool changeFlag = false;
27632a6e48fSopenharmony_ci    if (crop.w < bufferWidth && bufferWidth != 0) {
27732a6e48fSopenharmony_ci        tx = (float(crop.x) / bufferWidth);
27832a6e48fSopenharmony_ci        sx = (float(crop.w) / bufferWidth);
27932a6e48fSopenharmony_ci        changeFlag = true;
28032a6e48fSopenharmony_ci    }
28132a6e48fSopenharmony_ci    if (crop.h < bufferHeight && bufferHeight != 0) {
28232a6e48fSopenharmony_ci        ty = (float(bufferHeight - crop.y) / bufferHeight);
28332a6e48fSopenharmony_ci        sy = (float(crop.h) / bufferHeight);
28432a6e48fSopenharmony_ci        changeFlag = true;
28532a6e48fSopenharmony_ci    }
28632a6e48fSopenharmony_ci    if (changeFlag) {
28732a6e48fSopenharmony_ci        std::array<float, MATRIX_ARRAY_SIZE> cropMatrix = {sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, 1, 0, tx, ty, 0, 1};
28832a6e48fSopenharmony_ci        transformMatrix = MatrixProduct(cropMatrix, transformMatrix);
28932a6e48fSopenharmony_ci    }
29032a6e48fSopenharmony_ci
29132a6e48fSopenharmony_ci    const std::array<float, TRANSFORM_MATRIX_ELE_COUNT> flipV = {1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1};
29232a6e48fSopenharmony_ci    transformMatrix = MatrixProduct(flipV, transformMatrix);
29332a6e48fSopenharmony_ci
29432a6e48fSopenharmony_ci    auto ret = memcpy_s(matrix, matrixSize * sizeof(float),
29532a6e48fSopenharmony_ci                        transformMatrix.data(), sizeof(transformMatrix));
29632a6e48fSopenharmony_ci    if (ret != EOK) {
29732a6e48fSopenharmony_ci        BLOGE("memcpy_s failed, ret: %{public}d", ret);
29832a6e48fSopenharmony_ci    }
29932a6e48fSopenharmony_ci}
30032a6e48fSopenharmony_ci
30132a6e48fSopenharmony_civoid* SurfaceUtils::GetNativeWindow(uint64_t uniqueId)
30232a6e48fSopenharmony_ci{
30332a6e48fSopenharmony_ci    std::lock_guard<std::mutex> lockGuard(mutex_);
30432a6e48fSopenharmony_ci    auto iter = nativeWindowCache_.find(uniqueId);
30532a6e48fSopenharmony_ci    if (iter == nativeWindowCache_.end()) {
30632a6e48fSopenharmony_ci        BLOGE("Cannot find nativeWindow, uniqueId %{public}" PRIu64 ".", uniqueId);
30732a6e48fSopenharmony_ci        return nullptr;
30832a6e48fSopenharmony_ci    }
30932a6e48fSopenharmony_ci    return iter->second;
31032a6e48fSopenharmony_ci}
31132a6e48fSopenharmony_ci
31232a6e48fSopenharmony_ciSurfaceError SurfaceUtils::AddNativeWindow(uint64_t uniqueId, void *nativeWidow)
31332a6e48fSopenharmony_ci{
31432a6e48fSopenharmony_ci    if (nativeWidow == nullptr) {
31532a6e48fSopenharmony_ci        return GSERROR_INVALID_ARGUMENTS;
31632a6e48fSopenharmony_ci    }
31732a6e48fSopenharmony_ci    std::lock_guard<std::mutex> lockGuard(mutex_);
31832a6e48fSopenharmony_ci    if (nativeWindowCache_.count(uniqueId) == 0) {
31932a6e48fSopenharmony_ci        nativeWindowCache_[uniqueId] = nativeWidow;
32032a6e48fSopenharmony_ci        return GSERROR_OK;
32132a6e48fSopenharmony_ci    }
32232a6e48fSopenharmony_ci    BLOGD("the nativeWidow already existed, uniqueId %" PRIu64, uniqueId);
32332a6e48fSopenharmony_ci    return GSERROR_OK;
32432a6e48fSopenharmony_ci}
32532a6e48fSopenharmony_ci
32632a6e48fSopenharmony_ciSurfaceError SurfaceUtils::RemoveNativeWindow(uint64_t uniqueId)
32732a6e48fSopenharmony_ci{
32832a6e48fSopenharmony_ci    std::lock_guard<std::mutex> lockGuard(mutex_);
32932a6e48fSopenharmony_ci    nativeWindowCache_.erase(uniqueId);
33032a6e48fSopenharmony_ci    return GSERROR_OK;
33132a6e48fSopenharmony_ci}
33232a6e48fSopenharmony_ci} // namespace OHOS
333