1/*
2 * Copyright (c) 2020-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 "window/window_impl.h"
17#include "core/render_manager.h"
18#include "gfx_utils/graphic_log.h"
19#include "iwindows_manager.h"
20
21namespace OHOS {
22WindowImpl::WindowImpl() : rootView_(nullptr), iWindow_(nullptr), isShow_(false), gfxAlloc_({}) {}
23
24WindowImpl::~WindowImpl() {}
25
26bool WindowImpl::Create(const WindowConfig& config)
27{
28    GRAPHIC_LOGI("Create");
29    if (iWindow_ == nullptr) {
30        config_ = config;
31        LiteWinConfig liteConfig;
32        liteConfig.rect = config.rect;
33        liteConfig.pixelFormat = IMAGE_PIXEL_FORMAT_ARGB8888;
34        liteConfig.opacity = config.opacity;
35        liteConfig.isModal = config.isModal;
36        liteConfig.compositeMode = static_cast<LiteWinConfig::CompositeMode>(config.compositeMode);
37        iWindow_ = IWindowsManager::GetInstance()->CreateWindow(liteConfig);
38        if (iWindow_ == nullptr) {
39            return false;
40        }
41    }
42    return true;
43}
44
45void WindowImpl::Destroy()
46{
47    Flush();
48    if (iWindow_ != nullptr) {
49        IWindowsManager::GetInstance()->RemoveWindow(iWindow_);
50        iWindow_ = nullptr;
51    }
52}
53
54void WindowImpl::AddToDisplay()
55{
56    GRAPHIC_LOGI("AddToDisplay");
57    RenderManager::GetInstance().AddToDisplay(this);
58}
59
60void WindowImpl::RemoveFromDisplay()
61{
62    GRAPHIC_LOGI("RemoveFromDisplay");
63    RenderManager::GetInstance().RemoveFromDisplay(this);
64}
65
66void WindowImpl::BindRootView(RootView* rootView)
67{
68    if (rootView == nullptr) {
69        return;
70    }
71    UnbindRootView();
72    GRAPHIC_LOGI("BindRootView");
73    rootView_ = rootView;
74    rootView_->boundWindow_ = this;
75}
76
77void WindowImpl::UnbindRootView()
78{
79    GRAPHIC_LOGI("UnbindRootView");
80    if (rootView_ != nullptr) {
81        rootView_->boundWindow_ = nullptr;
82        rootView_ = nullptr;
83    }
84}
85
86RootView* WindowImpl::GetRootView()
87{
88    return rootView_;
89}
90
91Rect WindowImpl::GetRect()
92{
93    return config_.rect;
94}
95
96void WindowImpl::Show()
97{
98    if (iWindow_ == nullptr) {
99        return;
100    }
101
102    if (!isShow_) {
103        isShow_ = true;
104        Render();
105        iWindow_->Show();
106    }
107}
108
109void WindowImpl::Hide()
110{
111    if (iWindow_ == nullptr) {
112        return;
113    }
114
115    if (isShow_) {
116        isShow_ = false;
117        iWindow_->Hide();
118    }
119}
120
121void WindowImpl::MoveTo(int16_t x, int16_t y)
122{
123    GRAPHIC_LOGI("MoveTo");
124    config_.rect.SetPosition(x, y);
125    if (iWindow_ != nullptr) {
126        iWindow_->MoveTo(x, y);
127    }
128}
129
130void WindowImpl::Resize(int16_t width, int16_t height)
131{
132    GRAPHIC_LOGI("Resize");
133    if ((width == config_.rect.GetWidth()) && (height == config_.rect.GetHeight())) {
134        return;
135    }
136
137    config_.rect.Resize(width, height);
138    Flush();
139    if (iWindow_ != nullptr) {
140        iWindow_->Resize(width, height);
141    }
142
143    if (rootView_ != nullptr) {
144        rootView_->Invalidate();
145    }
146}
147
148void WindowImpl::RaiseToTop()
149{
150    GRAPHIC_LOGI("RaiseToTop");
151    if (iWindow_ != nullptr) {
152        iWindow_->RaiseToTop();
153    }
154}
155
156void WindowImpl::LowerToBottom()
157{
158    GRAPHIC_LOGI("LowerToBottom");
159    if (iWindow_ != nullptr) {
160        iWindow_->LowerToBottom();
161    }
162}
163
164void WindowImpl::Render()
165{
166    UpdateHalDisplayBuffer();
167    if (gfxAlloc_.virAddr == nullptr) {
168        GRAPHIC_LOGE("window buffer is null, windId=%d", GetWindowId());
169        return;
170    }
171
172    if (rootView_ != nullptr) {
173        rootView_->Measure();
174        rootView_->Render();
175    }
176}
177
178void WindowImpl::Update()
179{
180    if (iWindow_ == nullptr) {
181        return;
182    }
183    iWindow_->Update();
184}
185
186int32_t WindowImpl::GetWindowId()
187{
188    if (iWindow_ != nullptr) {
189        return iWindow_->GetWindowId();
190    } else {
191        GRAPHIC_LOGE("iwindow is null!");
192        return INVALID_WINDOW_ID;
193    }
194}
195
196void WindowImpl::Flush()
197{
198    GRAPHIC_LOGI("Flush");
199    if (iWindow_ == nullptr) {
200        return;
201    }
202    ISurface* surface = iWindow_->GetSurface();
203    if (surface != nullptr) {
204        surface->Unlock();
205        gfxAlloc_ = {};
206    }
207}
208
209void WindowImpl::UpdateHalDisplayBuffer()
210{
211    if ((gfxAlloc_.virAddr == nullptr) && (iWindow_ != nullptr)) {
212        ISurface* surface = iWindow_->GetSurface();
213        if (surface == nullptr) {
214            return;
215        }
216        surface->Lock(reinterpret_cast<void**>(&gfxAlloc_.virAddr),
217            reinterpret_cast<void**>(&gfxAlloc_.phyAddr), &gfxAlloc_.stride);
218    }
219}
220
221BufferInfo* WindowImpl::GetBufferInfo()
222{
223    static BufferInfo bufferInfo;
224    bufferInfo.virAddr = gfxAlloc_.virAddr;
225    bufferInfo.phyAddr = gfxAlloc_.phyAddr;
226    bufferInfo.width = config_.rect.GetWidth();
227    bufferInfo.height = config_.rect.GetHeight();
228    bufferInfo.mode = ARGB8888;
229    bufferInfo.stride = gfxAlloc_.stride;
230
231    bufferInfo.rect = {
232        0,
233        0,
234        static_cast<int16_t>(bufferInfo.width - 1),
235        static_cast<int16_t>(bufferInfo.height - 1)
236    };
237    return &bufferInfo;
238}
239} // namespace OHOS
240