1fa7767c5Sopenharmony_ci/*
2fa7767c5Sopenharmony_ci * Copyright (c) 2021-2021 Huawei Device Co., Ltd.
3fa7767c5Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fa7767c5Sopenharmony_ci * you may not use this file except in compliance with the License.
5fa7767c5Sopenharmony_ci * You may obtain a copy of the License at
6fa7767c5Sopenharmony_ci *
7fa7767c5Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8fa7767c5Sopenharmony_ci *
9fa7767c5Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fa7767c5Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fa7767c5Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fa7767c5Sopenharmony_ci * See the License for the specific language governing permissions and
13fa7767c5Sopenharmony_ci * limitations under the License.
14fa7767c5Sopenharmony_ci */
15fa7767c5Sopenharmony_ci
16fa7767c5Sopenharmony_ci#if !defined(OHOS_LITE) && defined(VIDEO_SUPPORT)
17fa7767c5Sopenharmony_ci#include "common/surface_memory.h"
18fa7767c5Sopenharmony_ci#include "plugin/plugin_memory.h"
19fa7767c5Sopenharmony_ci#include <utility>
20fa7767c5Sopenharmony_ci#include "inner_api/common/log.h"
21fa7767c5Sopenharmony_ci#include "surface_allocator.h"
22fa7767c5Sopenharmony_ci#include "cpp_ext/type_cast_ext.h"
23fa7767c5Sopenharmony_ci#include "osal/task/autolock.h"
24fa7767c5Sopenharmony_ci
25fa7767c5Sopenharmony_cinamespace {
26fa7767c5Sopenharmony_ciconstexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_FOUNDATION, "SurfaceMemory" };
27fa7767c5Sopenharmony_ci}
28fa7767c5Sopenharmony_ci
29fa7767c5Sopenharmony_cinamespace OHOS {
30fa7767c5Sopenharmony_cinamespace Media {
31fa7767c5Sopenharmony_cinamespace Plugins {
32fa7767c5Sopenharmony_ciSurfaceMemory::SurfaceMemory(size_t capacity, std::shared_ptr<Allocator> allocator, size_t align)
33fa7767c5Sopenharmony_ci    : Memory(capacity, std::move(allocator), align, MemoryType::SURFACE_MEMORY, false),
34fa7767c5Sopenharmony_ci      fence_(-1),
35fa7767c5Sopenharmony_ci      stride_(0)
36fa7767c5Sopenharmony_ci{
37fa7767c5Sopenharmony_ci    MEDIA_LOG_DD("SurfaceMemory ctor.");
38fa7767c5Sopenharmony_ci    if (this->allocator != nullptr && this->allocator->GetMemoryType() == MemoryType::SURFACE_MEMORY) {
39fa7767c5Sopenharmony_ci        surfaceAllocator_ = ReinterpretPointerCast<SurfaceAllocator>(this->allocator);
40fa7767c5Sopenharmony_ci        AllocSurfaceBuffer();
41fa7767c5Sopenharmony_ci    }
42fa7767c5Sopenharmony_ci}
43fa7767c5Sopenharmony_ci
44fa7767c5Sopenharmony_ciSurfaceMemory::SurfaceMemory(sptr<SurfaceBuffer> surfaceBuffer, int32_t surfaceCapacity)
45fa7767c5Sopenharmony_ci    : Memory(surfaceCapacity, nullptr, 1, MemoryType::SURFACE_MEMORY, false), // align 1
46fa7767c5Sopenharmony_ci      surfaceBuffer_(surfaceBuffer), fence_(-1), stride_(0)
47fa7767c5Sopenharmony_ci{
48fa7767c5Sopenharmony_ci}
49fa7767c5Sopenharmony_ci
50fa7767c5Sopenharmony_ciSurfaceMemory::~SurfaceMemory()
51fa7767c5Sopenharmony_ci{
52fa7767c5Sopenharmony_ci    MEDIA_LOG_DD("SurfaceMemory dtor.");
53fa7767c5Sopenharmony_ci    ReleaseSurfaceBuffer();
54fa7767c5Sopenharmony_ci}
55fa7767c5Sopenharmony_ci
56fa7767c5Sopenharmony_civoid SurfaceMemory::AllocSurfaceBuffer()
57fa7767c5Sopenharmony_ci{
58fa7767c5Sopenharmony_ci    if (surfaceAllocator_ == nullptr || surfaceBuffer_ != nullptr) {
59fa7767c5Sopenharmony_ci        MEDIA_LOG_E("No need to allocate surface buffer.");
60fa7767c5Sopenharmony_ci        return;
61fa7767c5Sopenharmony_ci    }
62fa7767c5Sopenharmony_ci    surfaceBuffer_ = surfaceAllocator_->AllocSurfaceBuffer();
63fa7767c5Sopenharmony_ci    if (surfaceBuffer_ != nullptr) {
64fa7767c5Sopenharmony_ci        auto bufferHandle = surfaceBuffer_->GetBufferHandle();
65fa7767c5Sopenharmony_ci        if (bufferHandle != nullptr) {
66fa7767c5Sopenharmony_ci            stride_ = bufferHandle->stride;
67fa7767c5Sopenharmony_ci        }
68fa7767c5Sopenharmony_ci        fence_ = -1;
69fa7767c5Sopenharmony_ci    } else {
70fa7767c5Sopenharmony_ci        // Surface often obtain buffer failed, but doesn't cause any problem.
71fa7767c5Sopenharmony_ci        MEDIA_LOG_DD("AllocSurfaceBuffer failed.");
72fa7767c5Sopenharmony_ci    }
73fa7767c5Sopenharmony_ci}
74fa7767c5Sopenharmony_ci
75fa7767c5Sopenharmony_cisptr<SurfaceBuffer> SurfaceMemory::GetSurfaceBuffer()
76fa7767c5Sopenharmony_ci{
77fa7767c5Sopenharmony_ci    OHOS::Media::AutoLock l(memMutex_);
78fa7767c5Sopenharmony_ci    if (!surfaceBuffer_ || needRender_) {
79fa7767c5Sopenharmony_ci        // request surface buffer again when old buffer flush to nullptr
80fa7767c5Sopenharmony_ci        surfaceBuffer_ = nullptr;
81fa7767c5Sopenharmony_ci        AllocSurfaceBuffer();
82fa7767c5Sopenharmony_ci        needRender_ = false;
83fa7767c5Sopenharmony_ci    }
84fa7767c5Sopenharmony_ci    return surfaceBuffer_;
85fa7767c5Sopenharmony_ci}
86fa7767c5Sopenharmony_ci
87fa7767c5Sopenharmony_civoid SurfaceMemory::ReleaseSurfaceBuffer()
88fa7767c5Sopenharmony_ci{
89fa7767c5Sopenharmony_ci    OHOS::Media::AutoLock l(memMutex_);
90fa7767c5Sopenharmony_ci    if (surfaceBuffer_ != nullptr && surfaceAllocator_) {
91fa7767c5Sopenharmony_ci        surfaceAllocator_->ReleaseSurfaceBuffer(surfaceBuffer_, needRender_);
92fa7767c5Sopenharmony_ci    }
93fa7767c5Sopenharmony_ci}
94fa7767c5Sopenharmony_ci
95fa7767c5Sopenharmony_ciint32_t SurfaceMemory::GetFlushFence()
96fa7767c5Sopenharmony_ci{
97fa7767c5Sopenharmony_ci    OHOS::Media::AutoLock l(memMutex_);
98fa7767c5Sopenharmony_ci    return fence_;
99fa7767c5Sopenharmony_ci}
100fa7767c5Sopenharmony_ci
101fa7767c5Sopenharmony_ciBufferHandle *SurfaceMemory::GetBufferHandle()
102fa7767c5Sopenharmony_ci{
103fa7767c5Sopenharmony_ci    OHOS::Media::AutoLock l(memMutex_);
104fa7767c5Sopenharmony_ci    if (surfaceBuffer_) {
105fa7767c5Sopenharmony_ci        return surfaceBuffer_->GetBufferHandle();
106fa7767c5Sopenharmony_ci    }
107fa7767c5Sopenharmony_ci    return nullptr;
108fa7767c5Sopenharmony_ci}
109fa7767c5Sopenharmony_ci
110fa7767c5Sopenharmony_civoid SurfaceMemory::SetNeedRender(bool needRender)
111fa7767c5Sopenharmony_ci{
112fa7767c5Sopenharmony_ci    OHOS::Media::AutoLock l(memMutex_);
113fa7767c5Sopenharmony_ci    needRender_ = needRender;
114fa7767c5Sopenharmony_ci}
115fa7767c5Sopenharmony_ci
116fa7767c5Sopenharmony_ciuint32_t SurfaceMemory::GetSurfaceBufferStride()
117fa7767c5Sopenharmony_ci{
118fa7767c5Sopenharmony_ci    OHOS::Media::AutoLock l(memMutex_);
119fa7767c5Sopenharmony_ci    return stride_;
120fa7767c5Sopenharmony_ci}
121fa7767c5Sopenharmony_ci
122fa7767c5Sopenharmony_ciuint8_t* SurfaceMemory::GetRealAddr() const
123fa7767c5Sopenharmony_ci{
124fa7767c5Sopenharmony_ci    OHOS::Media::AutoLock l(memMutex_);
125fa7767c5Sopenharmony_ci    if (surfaceBuffer_) {
126fa7767c5Sopenharmony_ci        return static_cast<uint8_t *>(surfaceBuffer_->GetVirAddr());
127fa7767c5Sopenharmony_ci    }
128fa7767c5Sopenharmony_ci    return nullptr;
129fa7767c5Sopenharmony_ci}
130fa7767c5Sopenharmony_ci} // namespace Plugins
131fa7767c5Sopenharmony_ci} // namespace Media
132fa7767c5Sopenharmony_ci} // namespace OHOS
133fa7767c5Sopenharmony_ci#endif