• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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