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 "subwindow_normal_impl.h"
17
18 #include <display_type.h>
19 #include <scoped_bytrace.h>
20
21 #include "static_call.h"
22 #include "tester.h"
23 #include "window_impl.h"
24 #include "window_manager_hilog.h"
25 #include "wl_buffer_cache.h"
26 #include "wl_display.h"
27 #include "wl_dma_buffer_factory.h"
28 #include "wl_subsurface_factory.h"
29 #include "wl_surface_factory.h"
30
31 namespace OHOS {
32 namespace {
33 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "WMSubwindowImpl"};
34 } // namespace
35
CreateWlSurface(const sptr<WlSurface> & parentWlSurface)36 GSError SubwindowNormalImpl::CreateWlSurface(const sptr<WlSurface> &parentWlSurface)
37 {
38 wlSurface = SingletonContainer::Get<WlSurfaceFactory>()->Create();
39 if (wlSurface == nullptr) {
40 WMLOGFE("WlSurfaceFactory::Create return nullptr");
41 return GSERROR_API_FAILED;
42 }
43
44 auto subsurfaceFactory = SingletonContainer::Get<WlSubsurfaceFactory>();
45 wlSubsurf = subsurfaceFactory->Create(wlSurface, parentWlSurface);
46 if (wlSubsurf == nullptr) {
47 WMLOGFE("WlSubsurf::Create return nullptr");
48 return GSERROR_API_FAILED;
49 }
50
51 wlSubsurf->SetPosition(attr.GetX(), attr.GetY());
52 wlSubsurf->PlaceBelow(parentWlSurface);
53 wlSubsurf->SetDesync();
54 return GSERROR_OK;
55 }
56
CreateConsumerSurface(const sptr<SubwindowOption> & option)57 GSError SubwindowNormalImpl::CreateConsumerSurface(const sptr<SubwindowOption> &option)
58 {
59 auto csurf2 = option->GetConsumerSurface();
60 if (csurf2 != nullptr) {
61 csurf = csurf2;
62 WMLOGFI("use Option Surface");
63 } else {
64 const auto &sc = SingletonContainer::Get<StaticCall>();
65 csurf = sc->SurfaceCreateSurfaceAsConsumer("Normal Subwindow");
66 WMLOGFI("use Create Surface");
67 }
68
69 if (csurf == nullptr) {
70 WMLOGFE("SurfaceCreateSurfaceAsConsumer return nullptr");
71 return GSERROR_API_FAILED;
72 }
73
74 auto producer = csurf->GetProducer();
75 psurf = SingletonContainer::Get<StaticCall>()->SurfaceCreateSurfaceAsProducer(producer);
76 if (psurf == nullptr) {
77 WMLOGFE("SurfaceCreateSurfaceAsProducer return nullptr");
78 return GSERROR_API_FAILED;
79 }
80
81 csurf->RegisterConsumerListener(this);
82 csurf->SetDefaultWidthAndHeight(attr.GetWidth(), attr.GetHeight());
83 csurf->SetDefaultUsage(HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA);
84 return GSERROR_OK;
85 }
86
Init(const sptr<Window> & window,const sptr<SubwindowOption> & option)87 GSError SubwindowNormalImpl::Init(const sptr<Window> &window, const sptr<SubwindowOption> &option)
88 {
89 WMLOGFI("Create Normal Subwindow");
90
91 auto windowImpl = static_cast<WindowImpl *>(window.GetRefPtr());
92 if (windowImpl == nullptr) {
93 WMLOGFE("WindowImpl is nullptr");
94 return GSERROR_INVALID_ARGUMENTS;
95 }
96
97 if (option == nullptr) {
98 WMLOGFE("option is nullptr");
99 return GSERROR_INVALID_ARGUMENTS;
100 }
101
102 attr.SetWidthHeight(option->GetWidth(), option->GetHeight());
103 attr.SetXY(option->GetX(), option->GetY());
104
105 auto wret = CreateWlSurface(windowImpl->GetWlSurface());
106 if (wret != GSERROR_OK) {
107 return wret;
108 }
109
110 wret = CreateConsumerSurface(option);
111 if (wret != GSERROR_OK) {
112 return wret;
113 }
114
115 WMLOGFI("Create Normal Subwindow Success");
116 return GSERROR_OK;
117 }
118
GetSurface() const119 sptr<Surface> SubwindowNormalImpl::GetSurface() const
120 {
121 return psurf;
122 }
123
Move(int32_t x,int32_t y)124 GSError SubwindowNormalImpl::Move(int32_t x, int32_t y)
125 {
126 WMLOGFI("(subwindow normal) x: %{public}d, y: %{public}d", x, y);
127 std::lock_guard<std::mutex> lock(publicMutex);
128 if (isDestroy == true) {
129 WMLOGFI("object destroyed");
130 return GSERROR_DESTROYED_OBJECT;
131 }
132
133 attr.SetXY(x, y);
134 wlSubsurf->SetPosition(attr.GetX(), attr.GetY());
135 return GSERROR_OK;
136 }
137
Resize(uint32_t width,uint32_t height)138 GSError SubwindowNormalImpl::Resize(uint32_t width, uint32_t height)
139 {
140 WMLOGFI("(subwindow normal)%{public}u x %{public}u", width, height);
141 std::lock_guard<std::mutex> lock(publicMutex);
142 if (isDestroy == true) {
143 WMLOGFI("object destroyed");
144 return GSERROR_DESTROYED_OBJECT;
145 }
146
147 attr.SetWidthHeight(width, height);
148 wlSurface->Commit();
149 return GSERROR_OK;
150 }
151
Destroy()152 GSError SubwindowNormalImpl::Destroy()
153 {
154 WMLOGFI("(subwindow normal) Destroy");
155 std::lock_guard<std::mutex> lock(publicMutex);
156 Tester::Get().ScheduleForConcurrent();
157 isDestroy = true;
158 csurf = nullptr;
159 psurf = nullptr;
160 wlSubsurf = nullptr;
161 wlSurface = nullptr;
162 SingletonContainer::Get<WlBufferCache>()->CleanCache();
163 return GSERROR_OK;
164 }
165
OnPositionChange(WindowPositionChangeFunc func)166 void SubwindowNormalImpl::OnPositionChange(WindowPositionChangeFunc func)
167 {
168 std::lock_guard<std::mutex> lock(publicMutex);
169 attr.OnPositionChange(func);
170 }
171
OnSizeChange(WindowSizeChangeFunc func)172 void SubwindowNormalImpl::OnSizeChange(WindowSizeChangeFunc func)
173 {
174 std::lock_guard<std::mutex> lock(publicMutex);
175 attr.OnSizeChange(func);
176 }
177
OnBeforeFrameSubmit(BeforeFrameSubmitFunc func)178 void SubwindowNormalImpl::OnBeforeFrameSubmit(BeforeFrameSubmitFunc func)
179 {
180 onBeforeFrameSubmitFunc = func;
181 }
182
~SubwindowNormalImpl()183 SubwindowNormalImpl::~SubwindowNormalImpl()
184 {
185 Destroy();
186 }
187
OnWlBufferRelease(struct wl_buffer * wbuffer,int32_t fence)188 void SubwindowNormalImpl::OnWlBufferRelease(struct wl_buffer *wbuffer, int32_t fence)
189 {
190 ScopedBytrace bytrace("OnWlBufferRelease");
191 WMLOGFI("(subwindow normal) BufferRelease");
192 std::lock_guard<std::mutex> lock(publicMutex);
193 if (isDestroy) {
194 WMLOGFI("object destroyed");
195 return;
196 }
197
198 sptr<Surface> surf = nullptr;
199 sptr<SurfaceBuffer> sbuffer = nullptr;
200 if (SingletonContainer::Get<WlBufferCache>()->GetSurfaceBuffer(wbuffer, surf, sbuffer)) {
201 if (surf != nullptr && sbuffer != nullptr) {
202 surf->ReleaseBuffer(sbuffer, fence);
203 }
204 }
205 }
206
OnBufferAvailable()207 void SubwindowNormalImpl::OnBufferAvailable()
208 {
209 WMLOGFI("(subwindow normal) OnBufferAvailable enter");
210 {
211 std::lock_guard<std::mutex> lock(publicMutex);
212 if (isDestroy == true) {
213 WMLOGFI("object destroyed");
214 return;
215 }
216
217 if (onBeforeFrameSubmitFunc != nullptr) {
218 onBeforeFrameSubmitFunc();
219 }
220
221 if (csurf == nullptr || wlSurface == nullptr) {
222 WMLOGFE("csurf or wlSurface is nullptr");
223 return;
224 }
225 }
226
227 sptr<SurfaceBuffer> sbuffer = nullptr;
228 int32_t flushFence = -1;
229 int64_t timestamp = 0;
230 Rect damage = {};
231 GSError ret = csurf->AcquireBuffer(sbuffer, flushFence, timestamp, damage);
232 if (ret != GSERROR_OK) {
233 WMLOGFE("AcquireBuffer failed");
234 return;
235 }
236
237 auto bc = SingletonContainer::Get<WlBufferCache>();
238 auto wbuffer = bc->GetWlBuffer(csurf, sbuffer);
239 if (wbuffer == nullptr) {
240 auto dmaBufferFactory = SingletonContainer::Get<WlDMABufferFactory>();
241 auto dmaWlBuffer = dmaBufferFactory->Create(sbuffer->GetBufferHandle());
242 if (dmaWlBuffer == nullptr) {
243 WMLOGFE("Create DMA Buffer Failed");
244 auto sret = csurf->ReleaseBuffer(sbuffer, -1);
245 if (sret != GSERROR_OK) {
246 WMLOGFW("ReleaseBuffer failed");
247 }
248 return;
249 }
250 dmaWlBuffer->OnRelease(this);
251
252 wbuffer = dmaWlBuffer;
253 bc->AddWlBuffer(wbuffer, csurf, sbuffer);
254 }
255
256 SendBufferToServer(wbuffer, sbuffer, flushFence, damage);
257 WMLOGFI("(subwindow normal) OnBufferAvailable exit");
258 }
259
SendBufferToServer(sptr<WlBuffer> & wbuffer,sptr<SurfaceBuffer> & sbuffer,int32_t fence,Rect & damage)260 void SubwindowNormalImpl::SendBufferToServer(sptr<WlBuffer> &wbuffer,
261 sptr<SurfaceBuffer> &sbuffer, int32_t fence, Rect &damage)
262 {
263 if (wbuffer) {
264 auto br = wlSurface->GetBufferRelease();
265 wbuffer->SetBufferRelease(br);
266 wlSurface->Attach(wbuffer, 0, 0);
267 wlSurface->SetAcquireFence(fence);
268 wlSurface->Damage(damage.x, damage.y, damage.w, damage.h);
269 wlSurface->SetSource(0, 0, sbuffer->GetWidth(), sbuffer->GetHeight());
270 wlSurface->SetDestination(attr.GetWidth(), attr.GetHeight());
271 WMLOGFI("(subwindow normal) Source[%{public}d x %{public}d] Dest[%{public}d x %{public}d]",
272 sbuffer->GetWidth(), sbuffer->GetHeight(), attr.GetWidth(), attr.GetHeight());
273 wlSurface->Commit();
274 SingletonContainer::Get<WlDisplay>()->Flush();
275 }
276 }
277 } // namespace OHOS
278