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