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 "plugin/common/surface_memory.h"
18fa7767c5Sopenharmony_ci#include <utility>
19fa7767c5Sopenharmony_ci#include "foundation/log.h"
20fa7767c5Sopenharmony_ci#include "plugin/common/surface_allocator.h"
21fa7767c5Sopenharmony_ci
22fa7767c5Sopenharmony_cinamespace OHOS {
23fa7767c5Sopenharmony_cinamespace Media {
24fa7767c5Sopenharmony_cinamespace Plugin {
25fa7767c5Sopenharmony_ciSurfaceMemory::SurfaceMemory(size_t capacity, std::shared_ptr<Allocator> allocator, size_t align)
26fa7767c5Sopenharmony_ci    : Memory(capacity, std::move(allocator), align, MemoryType::SURFACE_BUFFER, false),
27fa7767c5Sopenharmony_ci      fence_(-1),
28fa7767c5Sopenharmony_ci      stride_(0)
29fa7767c5Sopenharmony_ci{
30fa7767c5Sopenharmony_ci    MEDIA_LOG_DD("SurfaceMemory ctor.");
31fa7767c5Sopenharmony_ci    if (this->allocator != nullptr && this->allocator->GetMemoryType() == MemoryType::SURFACE_BUFFER) {
32fa7767c5Sopenharmony_ci        surfaceAllocator_ = ReinterpretPointerCast<SurfaceAllocator>(this->allocator);
33fa7767c5Sopenharmony_ci        AllocSurfaceBuffer();
34fa7767c5Sopenharmony_ci    }
35fa7767c5Sopenharmony_ci}
36fa7767c5Sopenharmony_ci
37fa7767c5Sopenharmony_ciSurfaceMemory::SurfaceMemory(sptr<SurfaceBuffer> surfaceBuffer, int32_t surfaceCapacity)
38fa7767c5Sopenharmony_ci    : Memory(surfaceCapacity, nullptr, 1, MemoryType::SURFACE_BUFFER, false), // align 1
39fa7767c5Sopenharmony_ci      surfaceBuffer_(surfaceBuffer), fence_(-1), stride_(0)
40fa7767c5Sopenharmony_ci{
41fa7767c5Sopenharmony_ci}
42fa7767c5Sopenharmony_ci
43fa7767c5Sopenharmony_ciSurfaceMemory::~SurfaceMemory()
44fa7767c5Sopenharmony_ci{
45fa7767c5Sopenharmony_ci    MEDIA_LOG_DD("SurfaceMemory dtor.");
46fa7767c5Sopenharmony_ci    ReleaseSurfaceBuffer();
47fa7767c5Sopenharmony_ci}
48fa7767c5Sopenharmony_ci
49fa7767c5Sopenharmony_civoid SurfaceMemory::AllocSurfaceBuffer()
50fa7767c5Sopenharmony_ci{
51fa7767c5Sopenharmony_ci    if (surfaceAllocator_ == nullptr || surfaceBuffer_ != nullptr) {
52fa7767c5Sopenharmony_ci        MEDIA_LOG_E("No need to allocate surface buffer.");
53fa7767c5Sopenharmony_ci        return;
54fa7767c5Sopenharmony_ci    }
55fa7767c5Sopenharmony_ci    surfaceBuffer_ = surfaceAllocator_->AllocSurfaceBuffer();
56fa7767c5Sopenharmony_ci    if (surfaceBuffer_ != nullptr) {
57fa7767c5Sopenharmony_ci        auto bufferHandle = surfaceBuffer_->GetBufferHandle();
58fa7767c5Sopenharmony_ci        if (bufferHandle != nullptr) {
59fa7767c5Sopenharmony_ci            stride_ = bufferHandle->stride;
60fa7767c5Sopenharmony_ci        }
61fa7767c5Sopenharmony_ci        fence_ = -1;
62fa7767c5Sopenharmony_ci    } else {
63fa7767c5Sopenharmony_ci        // Surface often obtain buffer failed, but doesn't cause any problem.
64fa7767c5Sopenharmony_ci        MEDIA_LOG_DD("AllocSurfaceBuffer failed.");
65fa7767c5Sopenharmony_ci    }
66fa7767c5Sopenharmony_ci}
67fa7767c5Sopenharmony_ci
68fa7767c5Sopenharmony_cisptr<SurfaceBuffer> SurfaceMemory::GetSurfaceBuffer()
69fa7767c5Sopenharmony_ci{
70fa7767c5Sopenharmony_ci    OSAL::ScopedLock l(memMutex_);
71fa7767c5Sopenharmony_ci    if (!surfaceBuffer_ || needRender_) {
72fa7767c5Sopenharmony_ci        // request surface buffer again when old buffer flush to nullptr
73fa7767c5Sopenharmony_ci        surfaceBuffer_ = nullptr;
74fa7767c5Sopenharmony_ci        AllocSurfaceBuffer();
75fa7767c5Sopenharmony_ci        needRender_ = false;
76fa7767c5Sopenharmony_ci    }
77fa7767c5Sopenharmony_ci    return surfaceBuffer_;
78fa7767c5Sopenharmony_ci}
79fa7767c5Sopenharmony_ci
80fa7767c5Sopenharmony_civoid SurfaceMemory::ReleaseSurfaceBuffer()
81fa7767c5Sopenharmony_ci{
82fa7767c5Sopenharmony_ci    OSAL::ScopedLock l(memMutex_);
83fa7767c5Sopenharmony_ci    if (surfaceBuffer_ != nullptr && surfaceAllocator_) {
84fa7767c5Sopenharmony_ci        surfaceAllocator_->ReleaseSurfaceBuffer(surfaceBuffer_, needRender_);
85fa7767c5Sopenharmony_ci    }
86fa7767c5Sopenharmony_ci}
87fa7767c5Sopenharmony_ci
88fa7767c5Sopenharmony_ciint32_t SurfaceMemory::GetFlushFence()
89fa7767c5Sopenharmony_ci{
90fa7767c5Sopenharmony_ci    OSAL::ScopedLock l(memMutex_);
91fa7767c5Sopenharmony_ci    return fence_;
92fa7767c5Sopenharmony_ci}
93fa7767c5Sopenharmony_ci
94fa7767c5Sopenharmony_ciBufferHandle *SurfaceMemory::GetBufferHandle()
95fa7767c5Sopenharmony_ci{
96fa7767c5Sopenharmony_ci    OSAL::ScopedLock l(memMutex_);
97fa7767c5Sopenharmony_ci    if (surfaceBuffer_) {
98fa7767c5Sopenharmony_ci        return surfaceBuffer_->GetBufferHandle();
99fa7767c5Sopenharmony_ci    }
100fa7767c5Sopenharmony_ci    return nullptr;
101fa7767c5Sopenharmony_ci}
102fa7767c5Sopenharmony_ci
103fa7767c5Sopenharmony_civoid SurfaceMemory::SetNeedRender(bool needRender)
104fa7767c5Sopenharmony_ci{
105fa7767c5Sopenharmony_ci    OSAL::ScopedLock l(memMutex_);
106fa7767c5Sopenharmony_ci    needRender_ = needRender;
107fa7767c5Sopenharmony_ci}
108fa7767c5Sopenharmony_ci
109fa7767c5Sopenharmony_ciuint32_t SurfaceMemory::GetSurfaceBufferStride()
110fa7767c5Sopenharmony_ci{
111fa7767c5Sopenharmony_ci    OSAL::ScopedLock l(memMutex_);
112fa7767c5Sopenharmony_ci    return stride_;
113fa7767c5Sopenharmony_ci}
114fa7767c5Sopenharmony_ci
115fa7767c5Sopenharmony_ciuint8_t* SurfaceMemory::GetRealAddr() const
116fa7767c5Sopenharmony_ci{
117fa7767c5Sopenharmony_ci    OSAL::ScopedLock l(memMutex_);
118fa7767c5Sopenharmony_ci    if (surfaceBuffer_) {
119fa7767c5Sopenharmony_ci        return static_cast<uint8_t *>(surfaceBuffer_->GetVirAddr());
120fa7767c5Sopenharmony_ci    }
121fa7767c5Sopenharmony_ci    return nullptr;
122fa7767c5Sopenharmony_ci}
123fa7767c5Sopenharmony_ci} // namespace Plugin
124fa7767c5Sopenharmony_ci} // namespace Media
125fa7767c5Sopenharmony_ci} // namespace OHOS
126fa7767c5Sopenharmony_ci#endif