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
HdiFramebufferSurface()26 HdiFramebufferSurface::HdiFramebufferSurface()
27 {
28 }
29
~HdiFramebufferSurface()30 HdiFramebufferSurface::~HdiFramebufferSurface() noexcept
31 {
32 }
33
CreateFramebufferSurface()34 sptr<HdiFramebufferSurface> HdiFramebufferSurface::CreateFramebufferSurface()
35 {
36 sptr<HdiFramebufferSurface> fbSurface = new HdiFramebufferSurface();
37
38 SurfaceError ret = fbSurface->CreateSurface(fbSurface);
39 if (ret != SURFACE_ERROR_OK) {
40 HLOGE("FramebufferSurface CreateSurface failed, ret is %{public}d", ret);
41 return nullptr;
42 }
43
44 ret = fbSurface->SetBufferQueueSize(MAX_BUFFER_SIZE);
45 if (ret != SURFACE_ERROR_OK) {
46 HLOGE("FramebufferSurface SetBufferQueueSize failed, ret is %{public}d", ret);
47 return nullptr;
48 }
49
50 return fbSurface;
51 }
52
CreateSurface(sptr<HdiFramebufferSurface> & fbSurface)53 SurfaceError HdiFramebufferSurface::CreateSurface(sptr<HdiFramebufferSurface> &fbSurface)
54 {
55 consumerSurface_ = IConsumerSurface::Create("FrameBuffer");
56
57 sptr<IBufferProducer> producer = consumerSurface_->GetProducer();
58 producerSurface_ = Surface::CreateSurfaceAsProducer(producer);
59
60 sptr<IBufferConsumerListener> listener = fbSurface;
61 SurfaceError ret = consumerSurface_->RegisterConsumerListener(listener);
62 if (ret != SURFACE_ERROR_OK) {
63 return SURFACE_ERROR_NO_CONSUMER;
64 }
65
66 return SURFACE_ERROR_OK;
67 }
68
SetBufferQueueSize(uint32_t bufferSize)69 SurfaceError HdiFramebufferSurface::SetBufferQueueSize(uint32_t bufferSize)
70 {
71 SurfaceError ret = consumerSurface_->SetQueueSize(bufferSize);
72 if (ret != SURFACE_ERROR_OK) {
73 HLOGE("fb SetQueueSize failed, ret is %{public}d", ret);
74 return ret;
75 }
76
77 return SURFACE_ERROR_OK;
78 }
79
GetBufferQueueSize()80 uint32_t HdiFramebufferSurface::GetBufferQueueSize()
81 {
82 if (consumerSurface_ == nullptr) {
83 HLOGE("consumer surface is nullptr.");
84 return 0;
85 }
86 return consumerSurface_->GetQueueSize();
87 }
88
OnBufferAvailable()89 void HdiFramebufferSurface::OnBufferAvailable()
90 {
91 sptr<SurfaceBuffer> buffer;
92 int64_t timestamp = 0;
93 Rect damage = {0};
94 sptr<SyncFence> acquireFence = SyncFence::INVALID_FENCE;
95 SurfaceError ret = consumerSurface_->AcquireBuffer(buffer, acquireFence,
96 timestamp, damage);
97 if (ret != SURFACE_ERROR_OK || buffer == nullptr) {
98 HLOGE("AcquireBuffer failed, ret is %{public}d", ret);
99 return;
100 }
101
102 std::lock_guard<std::mutex> lock(mutex_);
103 availableBuffers_.push(std::make_unique<FrameBufferEntry>(buffer, acquireFence, timestamp, damage));
104 bufferCond_.notify_one();
105 }
106
GetSurface()107 sptr<OHOS::Surface> HdiFramebufferSurface::GetSurface()
108 {
109 return producerSurface_;
110 }
111
GetFramebuffer()112 std::unique_ptr<FrameBufferEntry> HdiFramebufferSurface::GetFramebuffer()
113 {
114 using namespace std::chrono_literals;
115 std::unique_lock<std::mutex> lock(mutex_);
116 if (availableBuffers_.empty()) {
117 bufferCond_.wait_for(lock, 1000ms, [this]() { return !availableBuffers_.empty(); });
118 }
119 if (availableBuffers_.empty()) {
120 return nullptr;
121 }
122 auto fbEntry = std::move(availableBuffers_.front());
123 availableBuffers_.pop();
124 return fbEntry;
125 }
126
ReleaseFramebuffer(sptr<SurfaceBuffer> & buffer,const sptr<SyncFence> & releaseFence)127 int32_t HdiFramebufferSurface::ReleaseFramebuffer(
128 sptr<SurfaceBuffer> &buffer, const sptr<SyncFence>& releaseFence)
129 {
130 if (buffer == nullptr) {
131 HLOGI("HdiFramebufferSurface::ReleaseFramebuffer: buffer is null, no need to release.");
132 return 0;
133 }
134
135 SurfaceError ret = consumerSurface_->ReleaseBuffer(buffer, releaseFence);
136 if (ret != SURFACE_ERROR_OK) {
137 HLOGE("ReleaseBuffer failed ret is %{public}d", ret);
138 }
139
140 return ret;
141 }
142
Dump(std::string & result)143 void HdiFramebufferSurface::Dump(std::string &result)
144 {
145 if (consumerSurface_ != nullptr) {
146 consumerSurface_->Dump(result);
147 }
148 }
149 } // namespace Rosen
150 } // namespace OHOS
151