1 /*
2 * Copyright (c) 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 #include "hdi_framebuffer_surface.h"
17
18 #include "hdi_log.h"
19 #include "sync_fence.h"
20
21 using namespace OHOS;
22
23 namespace OHOS {
24 namespace Rosen {
25
26 class BufferConsumerListener : public IBufferConsumerListener {
27 public:
BufferConsumerListener(HdiFramebufferSurface & fbSurface)28 explicit BufferConsumerListener(HdiFramebufferSurface& fbSurface) : fbSurface_(fbSurface) {}
29
~BufferConsumerListener()30 ~BufferConsumerListener() {}
31
32 private:
OnBufferAvailable()33 void OnBufferAvailable() override
34 {
35 fbSurface_.OnBufferAvailable();
36 }
37
38 HdiFramebufferSurface& fbSurface_;
39 };
40
HdiFramebufferSurface()41 HdiFramebufferSurface::HdiFramebufferSurface()
42 {
43 }
44
~HdiFramebufferSurface()45 HdiFramebufferSurface::~HdiFramebufferSurface() noexcept
46 {
47 }
48
CreateFramebufferSurface()49 sptr<HdiFramebufferSurface> HdiFramebufferSurface::CreateFramebufferSurface()
50 {
51 sptr<HdiFramebufferSurface> fbSurface = new HdiFramebufferSurface();
52
53 SurfaceError ret = fbSurface->CreateSurface();
54 if (ret != SURFACE_ERROR_OK) {
55 HLOGE("FramebufferSurface CreateSurface failed, ret is %{public}d", ret);
56 return nullptr;
57 }
58
59 ret = fbSurface->SetBufferQueueSize(MAX_BUFFER_SIZE);
60 if (ret != SURFACE_ERROR_OK) {
61 HLOGE("FramebufferSurface SetBufferQueueSize failed, ret is %{public}d", ret);
62 return nullptr;
63 }
64
65 return fbSurface;
66 }
67
CreateSurface()68 SurfaceError HdiFramebufferSurface::CreateSurface()
69 {
70 consumerSurface_ = IConsumerSurface::Create("FrameBuffer");
71 if (consumerSurface_ == nullptr) {
72 return SURFACE_ERROR_NO_CONSUMER;
73 }
74
75 sptr<IBufferProducer> producer = consumerSurface_->GetProducer();
76 producerSurface_ = Surface::CreateSurfaceAsProducer(producer);
77
78 listener_ = new BufferConsumerListener(*this);
79 SurfaceError ret = consumerSurface_->RegisterConsumerListener(listener_);
80 if (ret != SURFACE_ERROR_OK) {
81 return SURFACE_ERROR_NO_CONSUMER;
82 }
83
84 return SURFACE_ERROR_OK;
85 }
86
SetBufferQueueSize(uint32_t bufferSize)87 SurfaceError HdiFramebufferSurface::SetBufferQueueSize(uint32_t bufferSize)
88 {
89 if (consumerSurface_ == nullptr) {
90 return SURFACE_ERROR_NO_CONSUMER;
91 }
92 SurfaceError ret = consumerSurface_->SetQueueSize(bufferSize);
93 if (ret != SURFACE_ERROR_OK) {
94 HLOGE("fb SetQueueSize failed, ret is %{public}d", ret);
95 return ret;
96 }
97
98 return SURFACE_ERROR_OK;
99 }
100
GetBufferQueueSize()101 uint32_t HdiFramebufferSurface::GetBufferQueueSize()
102 {
103 if (consumerSurface_ == nullptr) {
104 HLOGE("consumer surface is nullptr.");
105 return 0;
106 }
107 return consumerSurface_->GetQueueSize();
108 }
109
OnBufferAvailable()110 void HdiFramebufferSurface::OnBufferAvailable()
111 {
112 if (consumerSurface_ == nullptr) {
113 return;
114 }
115 sptr<SurfaceBuffer> buffer = nullptr;
116 int64_t timestamp = 0;
117 Rect damage = {0};
118 sptr<SyncFence> acquireFence = SyncFence::InvalidFence();
119 SurfaceError ret = consumerSurface_->AcquireBuffer(buffer, acquireFence,
120 timestamp, damage);
121 if (ret != SURFACE_ERROR_OK || buffer == nullptr) {
122 HLOGE("AcquireBuffer failed, ret is %{public}d", ret);
123 return;
124 }
125
126 std::lock_guard<std::mutex> lock(mutex_);
127 availableBuffers_.push(std::make_unique<FrameBufferEntry>(buffer, acquireFence, timestamp, damage));
128 bufferCond_.notify_one();
129 }
130
GetSurface()131 sptr<OHOS::Surface> HdiFramebufferSurface::GetSurface()
132 {
133 return producerSurface_;
134 }
135
GetFramebuffer()136 std::unique_ptr<FrameBufferEntry> HdiFramebufferSurface::GetFramebuffer()
137 {
138 using namespace std::chrono_literals;
139 std::unique_lock<std::mutex> lock(mutex_);
140 if (availableBuffers_.empty()) {
141 bufferCond_.wait_for(lock, 1000ms, [this]() { return !availableBuffers_.empty(); });
142 }
143 if (availableBuffers_.empty()) {
144 return nullptr;
145 }
146 auto fbEntry = std::move(availableBuffers_.front());
147 availableBuffers_.pop();
148 return fbEntry;
149 }
150
ReleaseFramebuffer(sptr<SurfaceBuffer> & buffer,const sptr<SyncFence> & releaseFence)151 int32_t HdiFramebufferSurface::ReleaseFramebuffer(
152 sptr<SurfaceBuffer> &buffer, const sptr<SyncFence>& releaseFence)
153 {
154 if (buffer == nullptr || consumerSurface_ == nullptr) {
155 HLOGI("HdiFramebufferSurface::ReleaseFramebuffer:"
156 " buffer or consumerSurface_ is null, no need to release.");
157 return 0;
158 }
159
160 SurfaceError ret = consumerSurface_->ReleaseBuffer(buffer, releaseFence);
161 if (ret != SURFACE_ERROR_OK) {
162 HLOGE("ReleaseBuffer failed ret is %{public}d", ret);
163 }
164
165 return ret;
166 }
167
ClearFrameBuffer()168 void HdiFramebufferSurface::ClearFrameBuffer()
169 {
170 std::unique_lock<std::mutex> lock(mutex_);
171 while (!availableBuffers_.empty()) {
172 availableBuffers_.pop();
173 }
174 }
175
Dump(std::string & result)176 void HdiFramebufferSurface::Dump(std::string &result)
177 {
178 if (consumerSurface_ != nullptr) {
179 consumerSurface_->Dump(result);
180 }
181 }
182 } // namespace Rosen
183 } // namespace OHOS
184