* Copyright (c) 2024 Huawei Device Co., Ltd.
* 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 <surface_utils.h>
#include <cinttypes>
#include <array>
#include "securec.h"
#include "buffer_log.h"
#include "mock_surface.h"
#include "plugins/interfaces/native/inner_api/plugin_utils_inner.h"
namespace OHOS {
using namespace HiviewDFX;
constexpr int64_t TRANSFORM_MATRIX_ELE_COUNT = 16;
SurfaceUtils* SurfaceUtils::GetInstance()
{
static SurfaceUtils instance;
return &instance;
}
SurfaceUtils::~SurfaceUtils()
{
surfaceCache_.clear();
}
sptr<Surface> SurfaceUtils::GetSurface(uint64_t uniqueId)
{
auto surface = sptr(new MockSurface());
surface->SetUniqueId(uniqueId);
surface->SetInstanceId(Plugin::PluginUtilsInner::GetInstanceId());
return surface;
}
SurfaceError SurfaceUtils::Add(uint64_t uniqueId, const wptr<Surface> &surface)
{
std::lock_guard<std::mutex> lockGuard(mutex_);
if (surface == nullptr) {
BLOGE(" surface is nullptr.");
return GSERROR_INVALID_ARGUMENTS;
}
if (surfaceCache_.count(uniqueId) == 0) {
surfaceCache_[uniqueId] = surface;
return GSERROR_OK;
}
BLOGW("the surface by uniqueId %" PRIu64 " already existed", uniqueId);
return GSERROR_OK;
}
SurfaceError SurfaceUtils::Remove(uint64_t uniqueId)
{
std::lock_guard<std::mutex> lockGuard(mutex_);
if (surfaceCache_.count(uniqueId) == 0) {
BLOGE("Delete failed without surface by uniqueId %" PRIu64, uniqueId);
return GSERROR_INVALID_OPERATING;
}
surfaceCache_.erase(uniqueId);
return GSERROR_OK;
}
std::array<float, 16> SurfaceUtils::MatrixProduct(const std::array<float, 16>& lMat, const std::array<float, 16>& rMat)
{
return std::array<float, 16> {lMat[0] * rMat[0] + lMat[4] * rMat[1] + lMat[8] * rMat[2] + lMat[12] * rMat[3],
lMat[1] * rMat[0] + lMat[5] * rMat[1] + lMat[9] * rMat[2] + lMat[13] * rMat[3],
lMat[2] * rMat[0] + lMat[6] * rMat[1] + lMat[10] * rMat[2] + lMat[14] * rMat[3],
lMat[3] * rMat[0] + lMat[7] * rMat[1] + lMat[11] * rMat[2] + lMat[15] * rMat[3],
lMat[0] * rMat[4] + lMat[4] * rMat[5] + lMat[8] * rMat[6] + lMat[12] * rMat[7],
lMat[1] * rMat[4] + lMat[5] * rMat[5] + lMat[9] * rMat[6] + lMat[13] * rMat[7],
lMat[2] * rMat[4] + lMat[6] * rMat[5] + lMat[10] * rMat[6] + lMat[14] * rMat[7],
lMat[3] * rMat[4] + lMat[7] * rMat[5] + lMat[11] * rMat[6] + lMat[15] * rMat[7],
lMat[0] * rMat[8] + lMat[4] * rMat[9] + lMat[8] * rMat[10] + lMat[12] * rMat[11],
lMat[1] * rMat[8] + lMat[5] * rMat[9] + lMat[9] * rMat[10] + lMat[13] * rMat[11],
lMat[2] * rMat[8] + lMat[6] * rMat[9] + lMat[10] * rMat[10] + lMat[14] * rMat[11],
lMat[3] * rMat[8] + lMat[7] * rMat[9] + lMat[11] * rMat[10] + lMat[15] * rMat[11],
lMat[0] * rMat[12] + lMat[4] * rMat[13] + lMat[8] * rMat[14] + lMat[12] * rMat[15],
lMat[1] * rMat[12] + lMat[5] * rMat[13] + lMat[9] * rMat[14] + lMat[13] * rMat[15],
lMat[2] * rMat[12] + lMat[6] * rMat[13] + lMat[10] * rMat[14] + lMat[14] * rMat[15],
lMat[3] * rMat[12] + lMat[7] * rMat[13] + lMat[11] * rMat[14] + lMat[15] * rMat[15]};
}
void SurfaceUtils::ComputeTransformMatrix(float matrix[16], uint32_t matrixSize,
sptr<SurfaceBuffer>& buffer, GraphicTransformType& transform, const Rect& crop)
{
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};
std::array<float, TRANSFORM_MATRIX_ELE_COUNT> transformMatrix = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
float tx = 0.f;
float ty = 0.f;
float sx = 1.f;
float sy = 1.f;
if (transform == GraphicTransformType::GRAPHIC_ROTATE_90) {
transformMatrix = MatrixProduct(transformMatrix, rotate90);
}
float bufferWidth = buffer->GetWidth();
float bufferHeight = buffer->GetHeight();
if (crop.w < bufferWidth && bufferWidth != 0) {
tx = (float(crop.x) / bufferWidth);
sx = (float(crop.w) / bufferWidth);
}
if (crop.h < bufferHeight && bufferHeight != 0) {
ty = (float(bufferHeight - crop.y) / bufferHeight);
sy = (float(crop.h) / bufferHeight);
}
static const std::array<float, 16> cropMatrix = {sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, 1, 0, tx, ty, 0, 1};
transformMatrix = MatrixProduct(cropMatrix, transformMatrix);
auto ret = memcpy_s(matrix, sizeof(transformMatrix),
transformMatrix.data(), sizeof(transformMatrix));
if (ret != EOK) {
BLOGE("ComputeTransformMatrix: transformMatrix memcpy_s failed");
}
}
}