1a3e0fd82Sopenharmony_ci/* 2a3e0fd82Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 3a3e0fd82Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4a3e0fd82Sopenharmony_ci * you may not use this file except in compliance with the License. 5a3e0fd82Sopenharmony_ci * You may obtain a copy of the License at 6a3e0fd82Sopenharmony_ci * 7a3e0fd82Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8a3e0fd82Sopenharmony_ci * 9a3e0fd82Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10a3e0fd82Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11a3e0fd82Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12a3e0fd82Sopenharmony_ci * See the License for the specific language governing permissions and 13a3e0fd82Sopenharmony_ci * limitations under the License. 14a3e0fd82Sopenharmony_ci */ 15a3e0fd82Sopenharmony_ci 16a3e0fd82Sopenharmony_ci#include "components/root_view.h" 17a3e0fd82Sopenharmony_ci 18a3e0fd82Sopenharmony_ci#include "common/screen.h" 19a3e0fd82Sopenharmony_ci#include "core/render_manager.h" 20a3e0fd82Sopenharmony_ci#include "draw/draw_utils.h" 21a3e0fd82Sopenharmony_ci#include "gfx_utils/graphic_log.h" 22a3e0fd82Sopenharmony_ci#if defined(ENABLE_WINDOW) && ENABLE_WINDOW 23a3e0fd82Sopenharmony_ci#include "window/window_impl.h" 24a3e0fd82Sopenharmony_ci#endif 25a3e0fd82Sopenharmony_ci#include "securec.h" 26a3e0fd82Sopenharmony_cinamespace OHOS { 27a3e0fd82Sopenharmony_cinamespace { 28a3e0fd82Sopenharmony_ci#if defined(LOCAL_RENDER) && LOCAL_RENDER 29a3e0fd82Sopenharmony_ciconst constexpr uint8_t MAX_SPLIT_NUM = 32; // split at most 32 parts 30a3e0fd82Sopenharmony_ci// view along with its parents and siblings are at most 128 31a3e0fd82Sopenharmony_ciconst constexpr uint8_t VIEW_STACK_DEPTH = COMPONENT_NESTING_DEPTH * 2; 32a3e0fd82Sopenharmony_ci#else 33a3e0fd82Sopenharmony_ciconst constexpr uint8_t VIEW_STACK_DEPTH = COMPONENT_NESTING_DEPTH; 34a3e0fd82Sopenharmony_ciconst constexpr uint8_t MAX_INVALIDATE_SIZE = 24; 35a3e0fd82Sopenharmony_ci#endif 36a3e0fd82Sopenharmony_cistatic Rect g_maskStack[COMPONENT_NESTING_DEPTH]; 37a3e0fd82Sopenharmony_cistatic UIView* g_viewStack[VIEW_STACK_DEPTH]; 38a3e0fd82Sopenharmony_ci} // namespace 39a3e0fd82Sopenharmony_ciRootView::RootView() 40a3e0fd82Sopenharmony_ci{ 41a3e0fd82Sopenharmony_ci#if defined __linux__ || defined __LITEOS__ || defined __APPLE__ 42a3e0fd82Sopenharmony_ci pthread_mutex_init(&lock_, nullptr); 43a3e0fd82Sopenharmony_ci#endif 44a3e0fd82Sopenharmony_ci InitDrawContext(); 45a3e0fd82Sopenharmony_ci} 46a3e0fd82Sopenharmony_ci 47a3e0fd82Sopenharmony_ciRootView* RootView::GetInstance() 48a3e0fd82Sopenharmony_ci{ 49a3e0fd82Sopenharmony_ci static RootView instance; 50a3e0fd82Sopenharmony_ci return &instance; 51a3e0fd82Sopenharmony_ci} 52a3e0fd82Sopenharmony_ci 53a3e0fd82Sopenharmony_ciRootView::~RootView() 54a3e0fd82Sopenharmony_ci{ 55a3e0fd82Sopenharmony_ci DestroyDrawContext(); 56a3e0fd82Sopenharmony_ci#if defined __linux__ || defined __LITEOS__ || defined __APPLE__ 57a3e0fd82Sopenharmony_ci pthread_mutex_destroy(&lock_); 58a3e0fd82Sopenharmony_ci#endif 59a3e0fd82Sopenharmony_ci} 60a3e0fd82Sopenharmony_ci#if defined(ENABLE_WINDOW) && ENABLE_WINDOW 61a3e0fd82Sopenharmony_ciWindow* RootView::GetBoundWindow() const 62a3e0fd82Sopenharmony_ci{ 63a3e0fd82Sopenharmony_ci return boundWindow_; 64a3e0fd82Sopenharmony_ci} 65a3e0fd82Sopenharmony_ci#endif 66a3e0fd82Sopenharmony_ci 67a3e0fd82Sopenharmony_ciRect RootView::GetScreenRect() 68a3e0fd82Sopenharmony_ci{ 69a3e0fd82Sopenharmony_ci#if defined(ENABLE_WINDOW) && ENABLE_WINDOW 70a3e0fd82Sopenharmony_ci Rect screenRect = GetRect(); 71a3e0fd82Sopenharmony_ci#else 72a3e0fd82Sopenharmony_ci Rect screenRect(0, 0, Screen::GetInstance().GetWidth() - 1, Screen::GetInstance().GetHeight() - 1); 73a3e0fd82Sopenharmony_ci#endif 74a3e0fd82Sopenharmony_ci return screenRect; 75a3e0fd82Sopenharmony_ci} 76a3e0fd82Sopenharmony_ci 77a3e0fd82Sopenharmony_ci#if defined(LOCAL_RENDER) && LOCAL_RENDER 78a3e0fd82Sopenharmony_ciusing namespace Graphic; 79a3e0fd82Sopenharmony_cistatic void DivideInvalidateRect(const Rect& originRect, Rect& leftoverRect, Vector<Rect>& splitRects) 80a3e0fd82Sopenharmony_ci{ 81a3e0fd82Sopenharmony_ci Rect mask; 82a3e0fd82Sopenharmony_ci if (!mask.Intersect(originRect, leftoverRect)) { 83a3e0fd82Sopenharmony_ci splitRects.PushBack(leftoverRect); 84a3e0fd82Sopenharmony_ci return; 85a3e0fd82Sopenharmony_ci } 86a3e0fd82Sopenharmony_ci 87a3e0fd82Sopenharmony_ci /* 88a3e0fd82Sopenharmony_ci * +---+---+---+ 89a3e0fd82Sopenharmony_ci * | | A | | originRect :A+B 90a3e0fd82Sopenharmony_ci * | +---+ | leftoverRect :A->0 91a3e0fd82Sopenharmony_ci * | B | mask :A 92a3e0fd82Sopenharmony_ci * +-----------+ 93a3e0fd82Sopenharmony_ci */ 94a3e0fd82Sopenharmony_ci if (originRect.IsContains(leftoverRect)) { 95a3e0fd82Sopenharmony_ci return; 96a3e0fd82Sopenharmony_ci } 97a3e0fd82Sopenharmony_ci 98a3e0fd82Sopenharmony_ci int16_t reserveCnt = MAX_SPLIT_NUM - splitRects.Size(); 99a3e0fd82Sopenharmony_ci if (reserveCnt <= 0) { 100a3e0fd82Sopenharmony_ci splitRects.PushBack(leftoverRect); 101a3e0fd82Sopenharmony_ci return; 102a3e0fd82Sopenharmony_ci } 103a3e0fd82Sopenharmony_ci 104a3e0fd82Sopenharmony_ci if (mask.GetWidth() == leftoverRect.GetWidth()) { 105a3e0fd82Sopenharmony_ci /* 106a3e0fd82Sopenharmony_ci * +---+ 107a3e0fd82Sopenharmony_ci * | A | originRect :B+C 108a3e0fd82Sopenharmony_ci * +-----------+ leftoverRect :A+B->A 109a3e0fd82Sopenharmony_ci * | | B | | mask :B 110a3e0fd82Sopenharmony_ci * | +---+ | 111a3e0fd82Sopenharmony_ci * | C | 112a3e0fd82Sopenharmony_ci * +-----------+ 113a3e0fd82Sopenharmony_ci */ 114a3e0fd82Sopenharmony_ci if (mask.GetBottom() == leftoverRect.GetBottom()) { 115a3e0fd82Sopenharmony_ci leftoverRect.SetBottom(mask.GetTop() - 1); 116a3e0fd82Sopenharmony_ci } else if (mask.GetTop() == leftoverRect.GetTop()) { 117a3e0fd82Sopenharmony_ci leftoverRect.SetTop(mask.GetBottom() + 1); 118a3e0fd82Sopenharmony_ci } else { 119a3e0fd82Sopenharmony_ci splitRects.PushBack(leftoverRect); 120a3e0fd82Sopenharmony_ci splitRects.Back().SetBottom(mask.GetTop() - 1); 121a3e0fd82Sopenharmony_ci leftoverRect.SetTop(mask.GetBottom() + 1); 122a3e0fd82Sopenharmony_ci } 123a3e0fd82Sopenharmony_ci splitRects.PushBack(leftoverRect); 124a3e0fd82Sopenharmony_ci return; 125a3e0fd82Sopenharmony_ci } 126a3e0fd82Sopenharmony_ci if (mask.GetHeight() == leftoverRect.GetHeight()) { 127a3e0fd82Sopenharmony_ci /* 128a3e0fd82Sopenharmony_ci * +---------+ originRect :B+C 129a3e0fd82Sopenharmony_ci * +-------+ | leftoverRect :A+B->A 130a3e0fd82Sopenharmony_ci * | A | B | C | mask :B 131a3e0fd82Sopenharmony_ci * +-------+ | 132a3e0fd82Sopenharmony_ci * +---------+ 133a3e0fd82Sopenharmony_ci */ 134a3e0fd82Sopenharmony_ci if (mask.GetLeft() == leftoverRect.GetLeft()) { 135a3e0fd82Sopenharmony_ci leftoverRect.SetLeft(mask.GetRight() + 1); 136a3e0fd82Sopenharmony_ci } else if (mask.GetRight() == leftoverRect.GetRight()) { 137a3e0fd82Sopenharmony_ci leftoverRect.SetRight(mask.GetLeft() - 1); 138a3e0fd82Sopenharmony_ci } else { 139a3e0fd82Sopenharmony_ci splitRects.PushBack(leftoverRect); 140a3e0fd82Sopenharmony_ci splitRects.Back().SetRight(mask.GetLeft() - 1); 141a3e0fd82Sopenharmony_ci leftoverRect.SetLeft(mask.GetRight() + 1); 142a3e0fd82Sopenharmony_ci } 143a3e0fd82Sopenharmony_ci splitRects.PushBack(leftoverRect); 144a3e0fd82Sopenharmony_ci return; 145a3e0fd82Sopenharmony_ci } 146a3e0fd82Sopenharmony_ci 147a3e0fd82Sopenharmony_ci Vector<Rect> copyRect(splitRects); 148a3e0fd82Sopenharmony_ci if (mask.GetLeft() != leftoverRect.GetLeft()) { 149a3e0fd82Sopenharmony_ci /* 150a3e0fd82Sopenharmony_ci * | 151a3e0fd82Sopenharmony_ci * +-------+ 152a3e0fd82Sopenharmony_ci * | +---+ mask :A 153a3e0fd82Sopenharmony_ci * | B | A | leftoverRect :A+B 154a3e0fd82Sopenharmony_ci * | +---+ 155a3e0fd82Sopenharmony_ci * +-------+ 156a3e0fd82Sopenharmony_ci * | 157a3e0fd82Sopenharmony_ci */ 158a3e0fd82Sopenharmony_ci if (reserveCnt-- <= 0) { 159a3e0fd82Sopenharmony_ci splitRects.Swap(copyRect); 160a3e0fd82Sopenharmony_ci splitRects.PushBack(leftoverRect); 161a3e0fd82Sopenharmony_ci return; 162a3e0fd82Sopenharmony_ci } 163a3e0fd82Sopenharmony_ci splitRects.PushBack(leftoverRect); 164a3e0fd82Sopenharmony_ci splitRects.Back().SetRight(mask.GetLeft() - 1); 165a3e0fd82Sopenharmony_ci leftoverRect.SetLeft(mask.GetLeft()); 166a3e0fd82Sopenharmony_ci } 167a3e0fd82Sopenharmony_ci 168a3e0fd82Sopenharmony_ci if (mask.GetTop() != leftoverRect.GetTop()) { 169a3e0fd82Sopenharmony_ci /* 170a3e0fd82Sopenharmony_ci * +-------+ 171a3e0fd82Sopenharmony_ci * | B | mask :A 172a3e0fd82Sopenharmony_ci * ---+---+--- leftoverRect :A+B 173a3e0fd82Sopenharmony_ci * | | A | | 174a3e0fd82Sopenharmony_ci * +-+---+-+ 175a3e0fd82Sopenharmony_ci */ 176a3e0fd82Sopenharmony_ci if (reserveCnt-- <= 0) { 177a3e0fd82Sopenharmony_ci splitRects.Swap(copyRect); 178a3e0fd82Sopenharmony_ci splitRects.PushBack(leftoverRect); 179a3e0fd82Sopenharmony_ci return; 180a3e0fd82Sopenharmony_ci } 181a3e0fd82Sopenharmony_ci splitRects.PushBack(leftoverRect); 182a3e0fd82Sopenharmony_ci splitRects.Back().SetBottom(mask.GetTop() - 1); 183a3e0fd82Sopenharmony_ci leftoverRect.SetTop(mask.GetTop()); 184a3e0fd82Sopenharmony_ci } 185a3e0fd82Sopenharmony_ci 186a3e0fd82Sopenharmony_ci if (mask.GetRight() != leftoverRect.GetRight()) { 187a3e0fd82Sopenharmony_ci /* 188a3e0fd82Sopenharmony_ci * | 189a3e0fd82Sopenharmony_ci * +-------+ 190a3e0fd82Sopenharmony_ci * +---+ | mask :A 191a3e0fd82Sopenharmony_ci * | A | B | leftoverRect :A+B 192a3e0fd82Sopenharmony_ci * +---+ | 193a3e0fd82Sopenharmony_ci * +-------+ 194a3e0fd82Sopenharmony_ci * | 195a3e0fd82Sopenharmony_ci */ 196a3e0fd82Sopenharmony_ci if (reserveCnt-- <= 0) { 197a3e0fd82Sopenharmony_ci splitRects.Swap(copyRect); 198a3e0fd82Sopenharmony_ci splitRects.PushBack(leftoverRect); 199a3e0fd82Sopenharmony_ci return; 200a3e0fd82Sopenharmony_ci } 201a3e0fd82Sopenharmony_ci splitRects.PushBack(leftoverRect); 202a3e0fd82Sopenharmony_ci splitRects.Back().SetLeft(mask.GetRight() + 1); 203a3e0fd82Sopenharmony_ci leftoverRect.SetRight(mask.GetRight()); 204a3e0fd82Sopenharmony_ci } 205a3e0fd82Sopenharmony_ci 206a3e0fd82Sopenharmony_ci if (mask.GetBottom() != leftoverRect.GetBottom()) { 207a3e0fd82Sopenharmony_ci /* 208a3e0fd82Sopenharmony_ci * +-+---+-+ 209a3e0fd82Sopenharmony_ci * | | A | | mask :A 210a3e0fd82Sopenharmony_ci * ---+---+--- leftoverRect :A+B 211a3e0fd82Sopenharmony_ci * | B | 212a3e0fd82Sopenharmony_ci * +-------+ 213a3e0fd82Sopenharmony_ci */ 214a3e0fd82Sopenharmony_ci if (reserveCnt-- <= 0) { 215a3e0fd82Sopenharmony_ci splitRects.Swap(copyRect); 216a3e0fd82Sopenharmony_ci splitRects.PushBack(leftoverRect); 217a3e0fd82Sopenharmony_ci return; 218a3e0fd82Sopenharmony_ci } 219a3e0fd82Sopenharmony_ci splitRects.PushBack(leftoverRect); 220a3e0fd82Sopenharmony_ci splitRects.Back().SetTop(mask.GetBottom() + 1); 221a3e0fd82Sopenharmony_ci leftoverRect.SetBottom(mask.GetBottom()); 222a3e0fd82Sopenharmony_ci } 223a3e0fd82Sopenharmony_ci return; 224a3e0fd82Sopenharmony_ci} 225a3e0fd82Sopenharmony_ci 226a3e0fd82Sopenharmony_cistatic void AddRenderedRects(Rect& rect, List<Rect>& renderedRects, ListNode<Rect>* iter) 227a3e0fd82Sopenharmony_ci{ 228a3e0fd82Sopenharmony_ci /* Elements at front have larger area and more relevance */ 229a3e0fd82Sopenharmony_ci for (; iter != renderedRects.End(); iter = iter->next_) { 230a3e0fd82Sopenharmony_ci Rect& curRect = iter->data_; 231a3e0fd82Sopenharmony_ci if (!curRect.IsIntersect(rect)) { 232a3e0fd82Sopenharmony_ci continue; 233a3e0fd82Sopenharmony_ci } 234a3e0fd82Sopenharmony_ci 235a3e0fd82Sopenharmony_ci if (curRect.IsContains(rect)) { 236a3e0fd82Sopenharmony_ci return; 237a3e0fd82Sopenharmony_ci } 238a3e0fd82Sopenharmony_ci 239a3e0fd82Sopenharmony_ci /* Merge two rects */ 240a3e0fd82Sopenharmony_ci if (rect.IsContains(curRect)) { 241a3e0fd82Sopenharmony_ci } else if (((curRect.GetLeft() == rect.GetLeft()) && (curRect.GetRight() == rect.GetRight())) || 242a3e0fd82Sopenharmony_ci ((curRect.GetTop() == rect.GetTop()) && (curRect.GetBottom() == rect.GetBottom()))) { 243a3e0fd82Sopenharmony_ci rect.Join(curRect, rect); 244a3e0fd82Sopenharmony_ci } else { 245a3e0fd82Sopenharmony_ci continue; 246a3e0fd82Sopenharmony_ci } 247a3e0fd82Sopenharmony_ci iter = renderedRects.Remove(iter)->prev_; 248a3e0fd82Sopenharmony_ci break; 249a3e0fd82Sopenharmony_ci } 250a3e0fd82Sopenharmony_ci if (iter == renderedRects.End()) { // No merge rises 251a3e0fd82Sopenharmony_ci if (renderedRects.Size() == 128) { // record 128 rendered rects at most 252a3e0fd82Sopenharmony_ci renderedRects.PopBack(); 253a3e0fd82Sopenharmony_ci } 254a3e0fd82Sopenharmony_ci renderedRects.PushFront(rect); 255a3e0fd82Sopenharmony_ci } else { // merge rises, go over the rest nodes 256a3e0fd82Sopenharmony_ci AddRenderedRects(rect, renderedRects, iter); 257a3e0fd82Sopenharmony_ci } 258a3e0fd82Sopenharmony_ci} 259a3e0fd82Sopenharmony_ci 260a3e0fd82Sopenharmony_civoid RootView::RemoveViewFromInvalidMap(UIView* view) 261a3e0fd82Sopenharmony_ci{ 262a3e0fd82Sopenharmony_ci#if defined __linux__ || defined __LITEOS__ || defined __APPLE__ 263a3e0fd82Sopenharmony_ci pthread_mutex_lock(&lock_); 264a3e0fd82Sopenharmony_ci#endif 265a3e0fd82Sopenharmony_ci 266a3e0fd82Sopenharmony_ci int16_t stackCount = 0; 267a3e0fd82Sopenharmony_ci do { 268a3e0fd82Sopenharmony_ci while (view != nullptr) { 269a3e0fd82Sopenharmony_ci /* delete node itself */ 270a3e0fd82Sopenharmony_ci auto entry = invalidateMap_.find(view); 271a3e0fd82Sopenharmony_ci if (entry != invalidateMap_.end()) { 272a3e0fd82Sopenharmony_ci invalidateMap_.erase(entry); 273a3e0fd82Sopenharmony_ci } 274a3e0fd82Sopenharmony_ci /* delete node's children */ 275a3e0fd82Sopenharmony_ci if (view->IsViewGroup() && stackCount < COMPONENT_NESTING_DEPTH) { 276a3e0fd82Sopenharmony_ci g_viewStack[stackCount++] = view; 277a3e0fd82Sopenharmony_ci view = static_cast<UIViewGroup*>(view)->GetChildrenRenderHead(); 278a3e0fd82Sopenharmony_ci continue; 279a3e0fd82Sopenharmony_ci } 280a3e0fd82Sopenharmony_ci /* only go to child's render sibling */ 281a3e0fd82Sopenharmony_ci view = view->GetNextRenderSibling(); 282a3e0fd82Sopenharmony_ci } 283a3e0fd82Sopenharmony_ci if (--stackCount >= 0) { 284a3e0fd82Sopenharmony_ci view = g_viewStack[stackCount]->GetNextRenderSibling(); 285a3e0fd82Sopenharmony_ci } 286a3e0fd82Sopenharmony_ci } while (stackCount >= 0); 287a3e0fd82Sopenharmony_ci 288a3e0fd82Sopenharmony_ci#if defined __linux__ || defined __LITEOS__ || defined __APPLE__ 289a3e0fd82Sopenharmony_ci pthread_mutex_unlock(&lock_); 290a3e0fd82Sopenharmony_ci#endif 291a3e0fd82Sopenharmony_ci} 292a3e0fd82Sopenharmony_ci 293a3e0fd82Sopenharmony_civoid RootView::OptimizeInvalidView(UIView* curview, UIView* background, List<Rect>& renderedRects) 294a3e0fd82Sopenharmony_ci{ 295a3e0fd82Sopenharmony_ci if (curview == nullptr) { 296a3e0fd82Sopenharmony_ci return; 297a3e0fd82Sopenharmony_ci } 298a3e0fd82Sopenharmony_ci auto mapEntry = invalidateMap_.find(curview); 299a3e0fd82Sopenharmony_ci if (mapEntry == invalidateMap_.end()) { 300a3e0fd82Sopenharmony_ci return; 301a3e0fd82Sopenharmony_ci } 302a3e0fd82Sopenharmony_ci 303a3e0fd82Sopenharmony_ci Rect& invalidRect = mapEntry->second.Front(); 304a3e0fd82Sopenharmony_ci /* Transparent views should draw from background */ 305a3e0fd82Sopenharmony_ci if (((curview->GetStyleConst().bgOpa_ != OPA_OPAQUE) || (curview->GetOpaScale() != OPA_OPAQUE) || 306a3e0fd82Sopenharmony_ci (!curview->IsTransInvalid())) && 307a3e0fd82Sopenharmony_ci (curview != this)) { 308a3e0fd82Sopenharmony_ci AddInvalidateRect(invalidRect, background); 309a3e0fd82Sopenharmony_ci invalidateMap_.erase(mapEntry); 310a3e0fd82Sopenharmony_ci return; 311a3e0fd82Sopenharmony_ci } 312a3e0fd82Sopenharmony_ci 313a3e0fd82Sopenharmony_ci /* Remove the rendered parts and split the origin rect into splitInvalidRects 314a3e0fd82Sopenharmony_ci * For performance reason, split numbers are strictly restrained. 315a3e0fd82Sopenharmony_ci */ 316a3e0fd82Sopenharmony_ci Vector<Rect> splitInvalidRects(MAX_SPLIT_NUM << 1); 317a3e0fd82Sopenharmony_ci Rect invalidRectCopy(invalidRect); 318a3e0fd82Sopenharmony_ci /* Using forward order because entries at the front are closer to the current view and have larger Size */ 319a3e0fd82Sopenharmony_ci for (auto iter = renderedRects.Begin(); iter != renderedRects.End(); iter = iter->next_) { 320a3e0fd82Sopenharmony_ci for (int8_t i = 0; i < mapEntry->second.Size(); i++) { 321a3e0fd82Sopenharmony_ci DivideInvalidateRect(iter->data_, mapEntry->second[i], splitInvalidRects); 322a3e0fd82Sopenharmony_ci } 323a3e0fd82Sopenharmony_ci mapEntry->second.Swap(splitInvalidRects); 324a3e0fd82Sopenharmony_ci splitInvalidRects.Clear(); 325a3e0fd82Sopenharmony_ci } 326a3e0fd82Sopenharmony_ci 327a3e0fd82Sopenharmony_ci /* Add new opaque rects */ 328a3e0fd82Sopenharmony_ci Rect preDrawRect(invalidRectCopy); 329a3e0fd82Sopenharmony_ci if (!curview->OnPreDraw(preDrawRect)) { 330a3e0fd82Sopenharmony_ci AddInvalidateRect(invalidRectCopy, background); 331a3e0fd82Sopenharmony_ci } 332a3e0fd82Sopenharmony_ci AddRenderedRects(preDrawRect, renderedRects, renderedRects.Begin()); 333a3e0fd82Sopenharmony_ci} 334a3e0fd82Sopenharmony_ci 335a3e0fd82Sopenharmony_civoid RootView::OptimizeInvalidMap() 336a3e0fd82Sopenharmony_ci{ 337a3e0fd82Sopenharmony_ci UIView* curview = this; 338a3e0fd82Sopenharmony_ci int16_t stackCount = 0; 339a3e0fd82Sopenharmony_ci int16_t opaStackCount = 0; 340a3e0fd82Sopenharmony_ci UIView* background[VIEW_STACK_DEPTH]; 341a3e0fd82Sopenharmony_ci bool flags[VIEW_STACK_DEPTH]; // indicate whether stack go back from child 342a3e0fd82Sopenharmony_ci List<Rect> renderedRects; // Record rendered areas to avoid rerendering 343a3e0fd82Sopenharmony_ci 344a3e0fd82Sopenharmony_ci do { 345a3e0fd82Sopenharmony_ci /* push stack */ 346a3e0fd82Sopenharmony_ci if (curview != nullptr) { 347a3e0fd82Sopenharmony_ci if (stackCount >= VIEW_STACK_DEPTH) { 348a3e0fd82Sopenharmony_ci return; 349a3e0fd82Sopenharmony_ci } 350a3e0fd82Sopenharmony_ci g_viewStack[stackCount] = curview; 351a3e0fd82Sopenharmony_ci flags[stackCount++] = false; 352a3e0fd82Sopenharmony_ci curview = curview->GetNextRenderSibling(); 353a3e0fd82Sopenharmony_ci continue; 354a3e0fd82Sopenharmony_ci } 355a3e0fd82Sopenharmony_ci 356a3e0fd82Sopenharmony_ci curview = g_viewStack[--stackCount]; 357a3e0fd82Sopenharmony_ci Rect rect; 358a3e0fd82Sopenharmony_ci if (!curview->IsVisible() || !rect.Intersect(curview->GetRect(), GetScreenRect())) { 359a3e0fd82Sopenharmony_ci curview = nullptr; 360a3e0fd82Sopenharmony_ci continue; 361a3e0fd82Sopenharmony_ci } 362a3e0fd82Sopenharmony_ci if (!flags[stackCount]) { // Back from sibling 363a3e0fd82Sopenharmony_ci if (curview->IsViewGroup()) { 364a3e0fd82Sopenharmony_ci /* Set background/topview */ 365a3e0fd82Sopenharmony_ci if (((curview->GetStyleConst().bgOpa_ == OPA_OPAQUE) && (curview->GetOpaScale() == OPA_OPAQUE) && 366a3e0fd82Sopenharmony_ci curview->IsTransInvalid()) || 367a3e0fd82Sopenharmony_ci (curview == this)) { 368a3e0fd82Sopenharmony_ci background[opaStackCount] = curview; 369a3e0fd82Sopenharmony_ci } else { 370a3e0fd82Sopenharmony_ci background[opaStackCount] = background[opaStackCount - 1]; 371a3e0fd82Sopenharmony_ci } 372a3e0fd82Sopenharmony_ci ++opaStackCount; 373a3e0fd82Sopenharmony_ci if (opaStackCount >= VIEW_STACK_DEPTH) { 374a3e0fd82Sopenharmony_ci return; 375a3e0fd82Sopenharmony_ci } 376a3e0fd82Sopenharmony_ci flags[stackCount++] = true; 377a3e0fd82Sopenharmony_ci curview = static_cast<UIViewGroup*>(curview)->GetChildrenRenderHead(); 378a3e0fd82Sopenharmony_ci continue; 379a3e0fd82Sopenharmony_ci } 380a3e0fd82Sopenharmony_ci } else { // Back from child 381a3e0fd82Sopenharmony_ci opaStackCount--; 382a3e0fd82Sopenharmony_ci } 383a3e0fd82Sopenharmony_ci OptimizeInvalidView(curview, background[opaStackCount - 1], renderedRects); 384a3e0fd82Sopenharmony_ci curview = nullptr; 385a3e0fd82Sopenharmony_ci } while (stackCount > 0); 386a3e0fd82Sopenharmony_ci renderedRects.Clear(); 387a3e0fd82Sopenharmony_ci} 388a3e0fd82Sopenharmony_ci 389a3e0fd82Sopenharmony_civoid RootView::DrawInvalidMap(const Rect& buffRect) 390a3e0fd82Sopenharmony_ci{ 391a3e0fd82Sopenharmony_ci OptimizeInvalidMap(); 392a3e0fd82Sopenharmony_ci Rect rect; 393a3e0fd82Sopenharmony_ci for (auto& viewEntry : invalidateMap_) { 394a3e0fd82Sopenharmony_ci Vector<Rect>& viewRenderRect = viewEntry.second; 395a3e0fd82Sopenharmony_ci for (uint16_t i = 0; i < viewRenderRect.Size(); i++) { 396a3e0fd82Sopenharmony_ci rect.Intersect(viewRenderRect[i], buffRect); 397a3e0fd82Sopenharmony_ci DrawTop(viewEntry.first, rect); 398a3e0fd82Sopenharmony_ci } 399a3e0fd82Sopenharmony_ci } 400a3e0fd82Sopenharmony_ci} 401a3e0fd82Sopenharmony_ci#else 402a3e0fd82Sopenharmony_civoid RootView::OptimizeAddRect(Rect& rect) 403a3e0fd82Sopenharmony_ci{ 404a3e0fd82Sopenharmony_ci Rect joinRect; 405a3e0fd82Sopenharmony_ci for (ListNode<Rect>* iter = invalidateRects_.Begin(); iter != invalidateRects_.End(); iter = iter->next_) { 406a3e0fd82Sopenharmony_ci if (iter->data_.IsContains(rect)) { 407a3e0fd82Sopenharmony_ci return; 408a3e0fd82Sopenharmony_ci } 409a3e0fd82Sopenharmony_ci 410a3e0fd82Sopenharmony_ci if (iter->data_.IsIntersect(rect)) { 411a3e0fd82Sopenharmony_ci joinRect.Join(iter->data_, rect); 412a3e0fd82Sopenharmony_ci if (joinRect.GetSize() < iter->data_.GetSize() + rect.GetSize()) { 413a3e0fd82Sopenharmony_ci iter->data_ = joinRect; 414a3e0fd82Sopenharmony_ci return; 415a3e0fd82Sopenharmony_ci } 416a3e0fd82Sopenharmony_ci } 417a3e0fd82Sopenharmony_ci } 418a3e0fd82Sopenharmony_ci 419a3e0fd82Sopenharmony_ci if (invalidateRects_.Size() < MAX_INVALIDATE_SIZE) { 420a3e0fd82Sopenharmony_ci invalidateRects_.PushBack(rect); 421a3e0fd82Sopenharmony_ci } else { 422a3e0fd82Sopenharmony_ci invalidateRects_.Clear(); 423a3e0fd82Sopenharmony_ci invalidateRects_.PushBack(GetScreenRect()); 424a3e0fd82Sopenharmony_ci } 425a3e0fd82Sopenharmony_ci} 426a3e0fd82Sopenharmony_ci 427a3e0fd82Sopenharmony_civoid RootView::OptimizeInvalidateRects() 428a3e0fd82Sopenharmony_ci{ 429a3e0fd82Sopenharmony_ci Rect joinRect; 430a3e0fd82Sopenharmony_ci for (ListNode<Rect>* iter1 = invalidateRects_.Begin(); iter1 != invalidateRects_.End(); iter1 = iter1->next_) { 431a3e0fd82Sopenharmony_ci for (ListNode<Rect>* iter2 = invalidateRects_.Begin(); iter2 != invalidateRects_.End(); iter2 = iter2->next_) { 432a3e0fd82Sopenharmony_ci if (iter1 == iter2) { 433a3e0fd82Sopenharmony_ci continue; 434a3e0fd82Sopenharmony_ci } 435a3e0fd82Sopenharmony_ci 436a3e0fd82Sopenharmony_ci if (iter2->data_.IsIntersect(iter1->data_)) { 437a3e0fd82Sopenharmony_ci joinRect.Join(iter1->data_, iter2->data_); 438a3e0fd82Sopenharmony_ci if (joinRect.GetSize() < (iter1->data_.GetSize() + iter2->data_.GetSize())) { 439a3e0fd82Sopenharmony_ci iter2->data_ = joinRect; 440a3e0fd82Sopenharmony_ci iter1 = invalidateRects_.Remove(iter1)->prev_; 441a3e0fd82Sopenharmony_ci break; 442a3e0fd82Sopenharmony_ci } 443a3e0fd82Sopenharmony_ci } 444a3e0fd82Sopenharmony_ci } 445a3e0fd82Sopenharmony_ci } 446a3e0fd82Sopenharmony_ci} 447a3e0fd82Sopenharmony_ci#endif 448a3e0fd82Sopenharmony_ci 449a3e0fd82Sopenharmony_civoid RootView::AddInvalidateRect(Rect& rect, UIView* view) 450a3e0fd82Sopenharmony_ci{ 451a3e0fd82Sopenharmony_ci Rect commonRect; 452a3e0fd82Sopenharmony_ci if (commonRect.Intersect(rect, GetScreenRect())) { 453a3e0fd82Sopenharmony_ci#if defined(LOCAL_RENDER) && LOCAL_RENDER 454a3e0fd82Sopenharmony_ci Vector<Rect>& invalidRects = invalidateMap_[view]; 455a3e0fd82Sopenharmony_ci if (invalidRects.IsEmpty()) { 456a3e0fd82Sopenharmony_ci invalidRects.PushBack(commonRect); 457a3e0fd82Sopenharmony_ci } else { 458a3e0fd82Sopenharmony_ci invalidRects[0].Join(invalidRects[0], commonRect); 459a3e0fd82Sopenharmony_ci } 460a3e0fd82Sopenharmony_ci#else 461a3e0fd82Sopenharmony_ci OptimizeAddRect(commonRect); 462a3e0fd82Sopenharmony_ci#endif 463a3e0fd82Sopenharmony_ci } 464a3e0fd82Sopenharmony_ci} 465a3e0fd82Sopenharmony_ci 466a3e0fd82Sopenharmony_civoid RootView::AddInvalidateRectWithLock(Rect& rect, UIView* view) 467a3e0fd82Sopenharmony_ci{ 468a3e0fd82Sopenharmony_ci#if defined __linux__ || defined __LITEOS__ || defined __APPLE__ 469a3e0fd82Sopenharmony_ci pthread_mutex_lock(&lock_); 470a3e0fd82Sopenharmony_ci#endif 471a3e0fd82Sopenharmony_ci 472a3e0fd82Sopenharmony_ci AddInvalidateRect(rect, view); 473a3e0fd82Sopenharmony_ci 474a3e0fd82Sopenharmony_ci#if defined __linux__ || defined __LITEOS__ || defined __APPLE__ 475a3e0fd82Sopenharmony_ci pthread_mutex_unlock(&lock_); 476a3e0fd82Sopenharmony_ci#endif 477a3e0fd82Sopenharmony_ci} 478a3e0fd82Sopenharmony_ci 479a3e0fd82Sopenharmony_civoid RootView::Measure() 480a3e0fd82Sopenharmony_ci{ 481a3e0fd82Sopenharmony_ci#if defined(LOCAL_RENDER) && LOCAL_RENDER 482a3e0fd82Sopenharmony_ci if (!invalidateMap_.empty()) { 483a3e0fd82Sopenharmony_ci MeasureView(GetChildrenRenderHead()); 484a3e0fd82Sopenharmony_ci } 485a3e0fd82Sopenharmony_ci#else 486a3e0fd82Sopenharmony_ci if (invalidateRects_.Size() > 0) { 487a3e0fd82Sopenharmony_ci MeasureView(GetChildrenRenderHead()); 488a3e0fd82Sopenharmony_ci } 489a3e0fd82Sopenharmony_ci#endif 490a3e0fd82Sopenharmony_ci} 491a3e0fd82Sopenharmony_ci 492a3e0fd82Sopenharmony_civoid RootView::MeasureView(UIView* view) 493a3e0fd82Sopenharmony_ci{ 494a3e0fd82Sopenharmony_ci int16_t stackCount = 0; 495a3e0fd82Sopenharmony_ci UIView* curView = view; 496a3e0fd82Sopenharmony_ci while (stackCount >= 0) { 497a3e0fd82Sopenharmony_ci while (curView != nullptr) { 498a3e0fd82Sopenharmony_ci if (curView->IsVisible()) { 499a3e0fd82Sopenharmony_ci curView->ReMeasure(); 500a3e0fd82Sopenharmony_ci if (curView->IsViewGroup() && stackCount < COMPONENT_NESTING_DEPTH) { 501a3e0fd82Sopenharmony_ci g_viewStack[stackCount++] = curView; 502a3e0fd82Sopenharmony_ci curView = static_cast<UIViewGroup*>(curView)->GetChildrenRenderHead(); 503a3e0fd82Sopenharmony_ci continue; 504a3e0fd82Sopenharmony_ci } 505a3e0fd82Sopenharmony_ci } 506a3e0fd82Sopenharmony_ci curView = curView->GetNextRenderSibling(); 507a3e0fd82Sopenharmony_ci } 508a3e0fd82Sopenharmony_ci if (--stackCount >= 0) { 509a3e0fd82Sopenharmony_ci curView = (g_viewStack[stackCount])->GetNextRenderSibling(); 510a3e0fd82Sopenharmony_ci } 511a3e0fd82Sopenharmony_ci } 512a3e0fd82Sopenharmony_ci} 513a3e0fd82Sopenharmony_ci 514a3e0fd82Sopenharmony_civoid RootView::Render() 515a3e0fd82Sopenharmony_ci{ 516a3e0fd82Sopenharmony_ci#if defined __linux__ || defined __LITEOS__ || defined __APPLE__ 517a3e0fd82Sopenharmony_ci pthread_mutex_lock(&lock_); 518a3e0fd82Sopenharmony_ci#endif 519a3e0fd82Sopenharmony_ci#if defined(LOCAL_RENDER) && (!LOCAL_RENDER) 520a3e0fd82Sopenharmony_ci OptimizeInvalidateRects(); 521a3e0fd82Sopenharmony_ci#endif 522a3e0fd82Sopenharmony_ci 523a3e0fd82Sopenharmony_ci Rect flushRect(GetScreenRect()); 524a3e0fd82Sopenharmony_ci#if defined(LOCAL_RENDER) && LOCAL_RENDER 525a3e0fd82Sopenharmony_ci if (!invalidateMap_.empty()) { 526a3e0fd82Sopenharmony_ci RenderManager::RenderRect(flushRect, this); 527a3e0fd82Sopenharmony_ci invalidateMap_.clear(); 528a3e0fd82Sopenharmony_ci#else 529a3e0fd82Sopenharmony_ci if (invalidateRects_.Size() > 0) { 530a3e0fd82Sopenharmony_ci /* Fully draw whole reacts. If there are two buffers or more to display, buffers could be 531a3e0fd82Sopenharmony_ci independent between each other, so buffers need to be FULLY_RENDER. */ 532a3e0fd82Sopenharmony_ci#if defined(FULLY_RENDER) && (FULLY_RENDER != 1) 533a3e0fd82Sopenharmony_ci flushRect = invalidateRects_.Begin()->data_; 534a3e0fd82Sopenharmony_ci // only draw invalid rects. in this case, buffers (if there are two buffers or more to display) should keep 535a3e0fd82Sopenharmony_ci // same with each others, because only delta changes write to the buffer between each frames, so it fits one 536a3e0fd82Sopenharmony_ci // buffer to display. 537a3e0fd82Sopenharmony_ci for (ListNode<Rect>* iter = invalidateRects_.Begin(); iter != invalidateRects_.End(); iter = iter->next_) { 538a3e0fd82Sopenharmony_ci RenderManager::RenderRect(iter->data_, this); 539a3e0fd82Sopenharmony_ci flushRect.Join(flushRect, iter->data_); 540a3e0fd82Sopenharmony_ci } 541a3e0fd82Sopenharmony_ci#else 542a3e0fd82Sopenharmony_ci RenderManager::RenderRect(flushRect, this); 543a3e0fd82Sopenharmony_ci#endif 544a3e0fd82Sopenharmony_ci invalidateRects_.Clear(); 545a3e0fd82Sopenharmony_ci#endif 546a3e0fd82Sopenharmony_ci 547a3e0fd82Sopenharmony_ci#if defined __linux__ || defined __LITEOS__ || defined __APPLE__ 548a3e0fd82Sopenharmony_ci pthread_mutex_unlock(&lock_); 549a3e0fd82Sopenharmony_ci#endif 550a3e0fd82Sopenharmony_ci 551a3e0fd82Sopenharmony_ci#if defined(ENABLE_WINDOW) && ENABLE_WINDOW 552a3e0fd82Sopenharmony_ci if (boundWindow_) { 553a3e0fd82Sopenharmony_ci boundWindow_->Flush(); 554a3e0fd82Sopenharmony_ci boundWindow_->Update(); 555a3e0fd82Sopenharmony_ci } 556a3e0fd82Sopenharmony_ci#endif 557a3e0fd82Sopenharmony_ci BaseGfxEngine::GetInstance()->Flush(flushRect); 558a3e0fd82Sopenharmony_ci } else { 559a3e0fd82Sopenharmony_ci#if defined __linux__ || defined __LITEOS__ || defined __APPLE__ 560a3e0fd82Sopenharmony_ci pthread_mutex_unlock(&lock_); 561a3e0fd82Sopenharmony_ci#endif 562a3e0fd82Sopenharmony_ci } 563a3e0fd82Sopenharmony_ci} 564a3e0fd82Sopenharmony_ci 565a3e0fd82Sopenharmony_civoid RootView::BlitMapBuffer(Rect& curViewRect, TransformMap& transMap, const Rect& invalidatedArea) 566a3e0fd82Sopenharmony_ci{ 567a3e0fd82Sopenharmony_ci Rect invalidRect = curViewRect; 568a3e0fd82Sopenharmony_ci transMap.SetTransMapRect(curViewRect); 569a3e0fd82Sopenharmony_ci invalidRect.Join(invalidRect, transMap.GetBoxRect()); 570a3e0fd82Sopenharmony_ci if (invalidRect.Intersect(invalidRect, invalidatedArea)) { 571a3e0fd82Sopenharmony_ci uint8_t pxSize = DrawUtils::GetPxSizeByColorMode(dc_.mapBufferInfo->mode); 572a3e0fd82Sopenharmony_ci ImageInfo imageInfo; 573a3e0fd82Sopenharmony_ci imageInfo.header.colorMode = dc_.mapBufferInfo->mode; 574a3e0fd82Sopenharmony_ci imageInfo.dataSize = dc_.mapBufferInfo->width * dc_.mapBufferInfo->height * (pxSize >> 3); 575a3e0fd82Sopenharmony_ci imageInfo.header.width = dc_.mapBufferInfo->width; 576a3e0fd82Sopenharmony_ci imageInfo.header.height = dc_.mapBufferInfo->height; 577a3e0fd82Sopenharmony_ci imageInfo.header.reserved = 0; 578a3e0fd82Sopenharmony_ci imageInfo.data = reinterpret_cast<uint8_t*>(dc_.mapBufferInfo->virAddr); 579a3e0fd82Sopenharmony_ci TransformDataInfo imageTranDataInfo = {imageInfo.header, imageInfo.data, pxSize, LEVEL0, BILINEAR}; 580a3e0fd82Sopenharmony_ci BaseGfxEngine::GetInstance()->DrawTransform(*dc_.bufferInfo, invalidRect, {0, 0}, Color::Black(), OPA_OPAQUE, 581a3e0fd82Sopenharmony_ci transMap, imageTranDataInfo); 582a3e0fd82Sopenharmony_ci } 583a3e0fd82Sopenharmony_ci} 584a3e0fd82Sopenharmony_ci 585a3e0fd82Sopenharmony_civoid RootView::ClearMapBuffer() 586a3e0fd82Sopenharmony_ci{ 587a3e0fd82Sopenharmony_ci uint8_t pxSize = DrawUtils::GetPxSizeByColorMode(dc_.mapBufferInfo->mode); 588a3e0fd82Sopenharmony_ci uint32_t dataSize = dc_.mapBufferInfo->width * dc_.mapBufferInfo->height * (pxSize >> 3); 589a3e0fd82Sopenharmony_ci if (memset_s(dc_.mapBufferInfo->virAddr, dataSize, 0, dataSize) != EOK) { 590a3e0fd82Sopenharmony_ci GRAPHIC_LOGE("animator buffer memset failed."); 591a3e0fd82Sopenharmony_ci } 592a3e0fd82Sopenharmony_ci} 593a3e0fd82Sopenharmony_ci 594a3e0fd82Sopenharmony_civoid RootView::UpdateMapBufferInfo(Rect& invalidatedArea) 595a3e0fd82Sopenharmony_ci{ 596a3e0fd82Sopenharmony_ci int16_t width = invalidatedArea.GetWidth(); 597a3e0fd82Sopenharmony_ci int16_t height = invalidatedArea.GetHeight(); 598a3e0fd82Sopenharmony_ci invalidatedArea.SetWidth(height); 599a3e0fd82Sopenharmony_ci invalidatedArea.SetHeight(width); 600a3e0fd82Sopenharmony_ci dc_.mapBufferInfo->width = height; 601a3e0fd82Sopenharmony_ci dc_.mapBufferInfo->height = width; 602a3e0fd82Sopenharmony_ci dc_.mapBufferInfo->stride = 603a3e0fd82Sopenharmony_ci dc_.mapBufferInfo->width * (DrawUtils::GetPxSizeByColorMode(dc_.mapBufferInfo->mode) >> 3); // 3: Shift 3 bits 604a3e0fd82Sopenharmony_ci} 605a3e0fd82Sopenharmony_ci 606a3e0fd82Sopenharmony_civoid RootView::RestoreMapBufferInfo() 607a3e0fd82Sopenharmony_ci{ 608a3e0fd82Sopenharmony_ci dc_.mapBufferInfo->width = dc_.bufferInfo->width; 609a3e0fd82Sopenharmony_ci dc_.mapBufferInfo->height = dc_.bufferInfo->height; 610a3e0fd82Sopenharmony_ci dc_.mapBufferInfo->stride = 611a3e0fd82Sopenharmony_ci dc_.mapBufferInfo->width * (DrawUtils::GetPxSizeByColorMode(dc_.mapBufferInfo->mode) >> 3); // 3: Shift 3 bits 612a3e0fd82Sopenharmony_ci} 613a3e0fd82Sopenharmony_ci 614a3e0fd82Sopenharmony_cibool RootView::CheckNeedRootViewTransView(UIView *curView) { 615a3e0fd82Sopenharmony_ci if ((curView->GetViewType() == UI_IMAGE_VIEW) && (curView->GetStyle(STYLE_BORDER_WIDTH) == 0)) { 616a3e0fd82Sopenharmony_ci return false; 617a3e0fd82Sopenharmony_ci } 618a3e0fd82Sopenharmony_ci if (curView->GetViewType() == UI_TEXTURE_MAPPER) { 619a3e0fd82Sopenharmony_ci return false; 620a3e0fd82Sopenharmony_ci } 621a3e0fd82Sopenharmony_ci if (curView->IsTransInvalid()) { 622a3e0fd82Sopenharmony_ci return false; 623a3e0fd82Sopenharmony_ci } 624a3e0fd82Sopenharmony_ci return true; 625a3e0fd82Sopenharmony_ci} 626a3e0fd82Sopenharmony_ci 627a3e0fd82Sopenharmony_civoid RootView::DrawTop(UIView* view, const Rect& rect) 628a3e0fd82Sopenharmony_ci{ 629a3e0fd82Sopenharmony_ci if (view == nullptr) { 630a3e0fd82Sopenharmony_ci return; 631a3e0fd82Sopenharmony_ci } 632a3e0fd82Sopenharmony_ci 633a3e0fd82Sopenharmony_ci int16_t stackCount = 0; 634a3e0fd82Sopenharmony_ci UIView* par = view->GetParent(); 635a3e0fd82Sopenharmony_ci if (par == nullptr) { 636a3e0fd82Sopenharmony_ci par = view; 637a3e0fd82Sopenharmony_ci } 638a3e0fd82Sopenharmony_ci UIView* curView = view; 639a3e0fd82Sopenharmony_ci UIView* transViewGroup = nullptr; 640a3e0fd82Sopenharmony_ci Rect curViewRect; 641a3e0fd82Sopenharmony_ci Rect mask = rect; 642a3e0fd82Sopenharmony_ci Rect origRect; 643a3e0fd82Sopenharmony_ci Rect relativeRect; 644a3e0fd82Sopenharmony_ci bool enableAnimator = false; 645a3e0fd82Sopenharmony_ci TransformMap curTransMap; 646a3e0fd82Sopenharmony_ci bool updateMapBufferInfo = false; 647a3e0fd82Sopenharmony_ci 648a3e0fd82Sopenharmony_ci#if defined(ENABLE_WINDOW) && ENABLE_WINDOW 649a3e0fd82Sopenharmony_ci WindowImpl* boundWin = static_cast<WindowImpl*>(GetBoundWindow()); 650a3e0fd82Sopenharmony_ci BufferInfo* gfxDstBuffer = boundWin->GetBufferInfo(); 651a3e0fd82Sopenharmony_ci UpdateBufferInfo(gfxDstBuffer); 652a3e0fd82Sopenharmony_ci#endif 653a3e0fd82Sopenharmony_ci 654a3e0fd82Sopenharmony_ci while (par != nullptr) { 655a3e0fd82Sopenharmony_ci if (curView != nullptr) { 656a3e0fd82Sopenharmony_ci if (curView->IsVisible()) { 657a3e0fd82Sopenharmony_ci if (curViewRect.Intersect(curView->GetMaskedRect(), mask) || enableAnimator) { 658a3e0fd82Sopenharmony_ci if (CheckNeedRootViewTransView(curView) && !enableAnimator) { 659a3e0fd82Sopenharmony_ci origRect = curView->GetOrigRect(); 660a3e0fd82Sopenharmony_ci relativeRect = curView->GetRelativeRect(); 661a3e0fd82Sopenharmony_ci curView->GetTransformMap().SetInvalid(true); 662a3e0fd82Sopenharmony_ci curView->SetPosition( 663a3e0fd82Sopenharmony_ci relativeRect.GetX() - origRect.GetX() - curView->GetStyle(STYLE_MARGIN_LEFT), 664a3e0fd82Sopenharmony_ci relativeRect.GetY() - origRect.GetY() - curView->GetStyle(STYLE_MARGIN_TOP)); 665a3e0fd82Sopenharmony_ci 666a3e0fd82Sopenharmony_ci ClearMapBuffer(); 667a3e0fd82Sopenharmony_ci curTransMap = curView->GetTransformMap(); 668a3e0fd82Sopenharmony_ci enableAnimator = true; 669a3e0fd82Sopenharmony_ci } 670a3e0fd82Sopenharmony_ci 671a3e0fd82Sopenharmony_ci if (enableAnimator) { 672a3e0fd82Sopenharmony_ci Rect invalidatedArea; 673a3e0fd82Sopenharmony_ci invalidatedArea.SetWidth(dc_.mapBufferInfo->width); 674a3e0fd82Sopenharmony_ci invalidatedArea.SetHeight(dc_.mapBufferInfo->height); 675a3e0fd82Sopenharmony_ci if (invalidatedArea.GetWidth() < curView->GetWidth()) { 676a3e0fd82Sopenharmony_ci UpdateMapBufferInfo(invalidatedArea); 677a3e0fd82Sopenharmony_ci updateMapBufferInfo = true; 678a3e0fd82Sopenharmony_ci } 679a3e0fd82Sopenharmony_ci curView->OnDraw(*dc_.mapBufferInfo, invalidatedArea); 680a3e0fd82Sopenharmony_ci curViewRect = invalidatedArea; 681a3e0fd82Sopenharmony_ci } else { 682a3e0fd82Sopenharmony_ci curView->OnDraw(*dc_.bufferInfo, curViewRect); 683a3e0fd82Sopenharmony_ci } 684a3e0fd82Sopenharmony_ci 685a3e0fd82Sopenharmony_ci if ((curView->IsViewGroup()) && (stackCount < COMPONENT_NESTING_DEPTH)) { 686a3e0fd82Sopenharmony_ci if (enableAnimator && (transViewGroup == nullptr)) { 687a3e0fd82Sopenharmony_ci transViewGroup = curView; 688a3e0fd82Sopenharmony_ci } 689a3e0fd82Sopenharmony_ci par = curView; 690a3e0fd82Sopenharmony_ci g_viewStack[stackCount] = curView; 691a3e0fd82Sopenharmony_ci g_maskStack[stackCount] = mask; 692a3e0fd82Sopenharmony_ci stackCount++; 693a3e0fd82Sopenharmony_ci curView = static_cast<UIViewGroup*>(curView)->GetChildrenRenderHead(); 694a3e0fd82Sopenharmony_ci mask = par->GetContentRect(); 695a3e0fd82Sopenharmony_ci mask.Intersect(mask, curViewRect); 696a3e0fd82Sopenharmony_ci continue; 697a3e0fd82Sopenharmony_ci } 698a3e0fd82Sopenharmony_ci 699a3e0fd82Sopenharmony_ci if (enableAnimator) { 700a3e0fd82Sopenharmony_ci curView->OnPostDraw(*dc_.mapBufferInfo, curViewRect); 701a3e0fd82Sopenharmony_ci } else { 702a3e0fd82Sopenharmony_ci curView->OnPostDraw(*dc_.bufferInfo, curViewRect); 703a3e0fd82Sopenharmony_ci } 704a3e0fd82Sopenharmony_ci 705a3e0fd82Sopenharmony_ci if (enableAnimator && (transViewGroup == nullptr)) { 706a3e0fd82Sopenharmony_ci BlitMapBuffer(origRect, curTransMap, mask); 707a3e0fd82Sopenharmony_ci if (updateMapBufferInfo) { 708a3e0fd82Sopenharmony_ci RestoreMapBufferInfo(); 709a3e0fd82Sopenharmony_ci updateMapBufferInfo = false; 710a3e0fd82Sopenharmony_ci } 711a3e0fd82Sopenharmony_ci curView->GetTransformMap().SetInvalid(false); 712a3e0fd82Sopenharmony_ci enableAnimator = false; 713a3e0fd82Sopenharmony_ci curView->SetPosition(relativeRect.GetX() - curView->GetStyle(STYLE_MARGIN_LEFT), 714a3e0fd82Sopenharmony_ci relativeRect.GetY() - curView->GetStyle(STYLE_MARGIN_TOP)); 715a3e0fd82Sopenharmony_ci } 716a3e0fd82Sopenharmony_ci } 717a3e0fd82Sopenharmony_ci } 718a3e0fd82Sopenharmony_ci curView = curView->GetNextRenderSibling(); 719a3e0fd82Sopenharmony_ci continue; 720a3e0fd82Sopenharmony_ci } 721a3e0fd82Sopenharmony_ci if (--stackCount >= 0) { 722a3e0fd82Sopenharmony_ci curViewRect = par->GetMaskedRect(); 723a3e0fd82Sopenharmony_ci mask = g_maskStack[stackCount]; 724a3e0fd82Sopenharmony_ci if (enableAnimator) { 725a3e0fd82Sopenharmony_ci par->OnPostDraw(*dc_.mapBufferInfo, curViewRect); 726a3e0fd82Sopenharmony_ci } else if (curViewRect.Intersect(curViewRect, mask)) { 727a3e0fd82Sopenharmony_ci par->OnPostDraw(*dc_.bufferInfo, curViewRect); 728a3e0fd82Sopenharmony_ci } 729a3e0fd82Sopenharmony_ci 730a3e0fd82Sopenharmony_ci if (enableAnimator && transViewGroup == g_viewStack[stackCount]) { 731a3e0fd82Sopenharmony_ci BlitMapBuffer(origRect, curTransMap, mask); 732a3e0fd82Sopenharmony_ci if (updateMapBufferInfo) { 733a3e0fd82Sopenharmony_ci RestoreMapBufferInfo(); 734a3e0fd82Sopenharmony_ci updateMapBufferInfo = false; 735a3e0fd82Sopenharmony_ci } 736a3e0fd82Sopenharmony_ci transViewGroup->GetTransformMap().SetInvalid(false); 737a3e0fd82Sopenharmony_ci enableAnimator = false; 738a3e0fd82Sopenharmony_ci transViewGroup->SetPosition(relativeRect.GetX() - transViewGroup->GetStyle(STYLE_MARGIN_LEFT), 739a3e0fd82Sopenharmony_ci relativeRect.GetY() - transViewGroup->GetStyle(STYLE_MARGIN_TOP)); 740a3e0fd82Sopenharmony_ci transViewGroup = nullptr; 741a3e0fd82Sopenharmony_ci } 742a3e0fd82Sopenharmony_ci curView = g_viewStack[stackCount]->GetNextRenderSibling(); 743a3e0fd82Sopenharmony_ci par = par->GetParent(); 744a3e0fd82Sopenharmony_ci continue; 745a3e0fd82Sopenharmony_ci } 746a3e0fd82Sopenharmony_ci stackCount = 0; 747a3e0fd82Sopenharmony_ci curView = par->GetNextRenderSibling(); 748a3e0fd82Sopenharmony_ci if (enableAnimator) { 749a3e0fd82Sopenharmony_ci par->OnPostDraw(*dc_.mapBufferInfo, rect); 750a3e0fd82Sopenharmony_ci } else { 751a3e0fd82Sopenharmony_ci par->OnPostDraw(*dc_.bufferInfo, rect); 752a3e0fd82Sopenharmony_ci } 753a3e0fd82Sopenharmony_ci par = par->GetParent(); 754a3e0fd82Sopenharmony_ci } 755a3e0fd82Sopenharmony_ci} 756a3e0fd82Sopenharmony_ci 757a3e0fd82Sopenharmony_ciUIView* RootView::GetTopUIView(const Rect& rect) 758a3e0fd82Sopenharmony_ci{ 759a3e0fd82Sopenharmony_ci int16_t stackCount = 0; 760a3e0fd82Sopenharmony_ci UIView* currentView = this; 761a3e0fd82Sopenharmony_ci UIView* topView = currentView; 762a3e0fd82Sopenharmony_ci Rect copyRect(rect); 763a3e0fd82Sopenharmony_ci while (stackCount >= 0) { 764a3e0fd82Sopenharmony_ci while (currentView != nullptr) { 765a3e0fd82Sopenharmony_ci if (currentView->GetOrigRect().IsContains(rect) && currentView->IsVisible()) { 766a3e0fd82Sopenharmony_ci if (currentView->GetStyle(STYLE_BACKGROUND_OPA) == OPA_OPAQUE && currentView->OnPreDraw(copyRect) && 767a3e0fd82Sopenharmony_ci currentView->GetOpaScale() == OPA_OPAQUE) { 768a3e0fd82Sopenharmony_ci topView = currentView; 769a3e0fd82Sopenharmony_ci } 770a3e0fd82Sopenharmony_ci if (currentView->IsViewGroup() && stackCount < COMPONENT_NESTING_DEPTH) { 771a3e0fd82Sopenharmony_ci g_viewStack[stackCount++] = currentView; 772a3e0fd82Sopenharmony_ci currentView = static_cast<UIViewGroup*>(currentView)->GetChildrenRenderHead(); 773a3e0fd82Sopenharmony_ci continue; 774a3e0fd82Sopenharmony_ci } 775a3e0fd82Sopenharmony_ci } 776a3e0fd82Sopenharmony_ci currentView = currentView->GetNextRenderSibling(); 777a3e0fd82Sopenharmony_ci } 778a3e0fd82Sopenharmony_ci if (--stackCount >= 0) { 779a3e0fd82Sopenharmony_ci currentView = (g_viewStack[stackCount])->GetNextRenderSibling(); 780a3e0fd82Sopenharmony_ci } 781a3e0fd82Sopenharmony_ci } 782a3e0fd82Sopenharmony_ci UIView* parentView = topView; 783a3e0fd82Sopenharmony_ci while (parentView->GetParent() != nullptr) { 784a3e0fd82Sopenharmony_ci UIView* tempView = parentView; 785a3e0fd82Sopenharmony_ci parentView = parentView->GetParent(); 786a3e0fd82Sopenharmony_ci if (!tempView->IsTransInvalid()) { 787a3e0fd82Sopenharmony_ci topView = parentView; 788a3e0fd82Sopenharmony_ci } 789a3e0fd82Sopenharmony_ci } 790a3e0fd82Sopenharmony_ci return topView; 791a3e0fd82Sopenharmony_ci} 792a3e0fd82Sopenharmony_ci 793a3e0fd82Sopenharmony_cibool RootView::FindSubView(const UIView& parentView, const UIView* subView) 794a3e0fd82Sopenharmony_ci{ 795a3e0fd82Sopenharmony_ci const UIView* root = &parentView; 796a3e0fd82Sopenharmony_ci if (root == subView) { 797a3e0fd82Sopenharmony_ci return true; 798a3e0fd82Sopenharmony_ci } else if (!root->IsViewGroup() || (subView == nullptr)) { 799a3e0fd82Sopenharmony_ci return false; 800a3e0fd82Sopenharmony_ci } 801a3e0fd82Sopenharmony_ci 802a3e0fd82Sopenharmony_ci UIView* currentView = static_cast<const UIViewGroup*>(root)->GetChildrenRenderHead(); 803a3e0fd82Sopenharmony_ci const UIView* parent = root; 804a3e0fd82Sopenharmony_ci int8_t deep = 1; 805a3e0fd82Sopenharmony_ci while (deep > 0) { 806a3e0fd82Sopenharmony_ci if (parent == nullptr) { 807a3e0fd82Sopenharmony_ci return false; 808a3e0fd82Sopenharmony_ci } 809a3e0fd82Sopenharmony_ci if (currentView == subView) { 810a3e0fd82Sopenharmony_ci return true; 811a3e0fd82Sopenharmony_ci } 812a3e0fd82Sopenharmony_ci if (currentView == nullptr) { 813a3e0fd82Sopenharmony_ci currentView = parent->GetNextRenderSibling(); 814a3e0fd82Sopenharmony_ci parent = parent->GetParent(); 815a3e0fd82Sopenharmony_ci deep--; 816a3e0fd82Sopenharmony_ci } else if (currentView->IsViewGroup()) { 817a3e0fd82Sopenharmony_ci parent = currentView; 818a3e0fd82Sopenharmony_ci currentView = static_cast<UIViewGroup*>(currentView)->GetChildrenRenderHead(); 819a3e0fd82Sopenharmony_ci deep++; 820a3e0fd82Sopenharmony_ci } else { 821a3e0fd82Sopenharmony_ci currentView = currentView->GetNextRenderSibling(); 822a3e0fd82Sopenharmony_ci } 823a3e0fd82Sopenharmony_ci } 824a3e0fd82Sopenharmony_ci return false; 825a3e0fd82Sopenharmony_ci} 826a3e0fd82Sopenharmony_ci 827a3e0fd82Sopenharmony_civoid RootView::InitMapBufferInfo(BufferInfo* bufferInfo) 828a3e0fd82Sopenharmony_ci{ 829a3e0fd82Sopenharmony_ci dc_.mapBufferInfo = new BufferInfo(); 830a3e0fd82Sopenharmony_ci if (dc_.mapBufferInfo == nullptr) { 831a3e0fd82Sopenharmony_ci return; 832a3e0fd82Sopenharmony_ci } 833a3e0fd82Sopenharmony_ci 834a3e0fd82Sopenharmony_ci if (memcpy_s(dc_.mapBufferInfo, sizeof(BufferInfo), bufferInfo, sizeof(BufferInfo)) != EOK) { 835a3e0fd82Sopenharmony_ci delete dc_.mapBufferInfo; 836a3e0fd82Sopenharmony_ci dc_.mapBufferInfo = nullptr; 837a3e0fd82Sopenharmony_ci return; 838a3e0fd82Sopenharmony_ci } 839a3e0fd82Sopenharmony_ci dc_.mapBufferInfo->mode = ARGB8888; 840a3e0fd82Sopenharmony_ci dc_.mapBufferInfo->stride = dc_.mapBufferInfo->width * (DrawUtils::GetPxSizeByColorMode(dc_.mapBufferInfo->mode) >> 841a3e0fd82Sopenharmony_ci 3); // 3: Shift right 3 bits 842a3e0fd82Sopenharmony_ci 843a3e0fd82Sopenharmony_ci BaseGfxEngine* baseGfxEngine = BaseGfxEngine::GetInstance(); 844a3e0fd82Sopenharmony_ci baseGfxEngine->AdjustLineStride(*dc_.mapBufferInfo); 845a3e0fd82Sopenharmony_ci uint32_t bufferSize = dc_.mapBufferInfo->stride * dc_.mapBufferInfo->height; 846a3e0fd82Sopenharmony_ci dc_.mapBufferInfo->virAddr = dc_.mapBufferInfo->phyAddr = 847a3e0fd82Sopenharmony_ci baseGfxEngine->AllocBuffer(bufferSize, BUFFER_MAP_SURFACE); 848a3e0fd82Sopenharmony_ci} 849a3e0fd82Sopenharmony_ci 850a3e0fd82Sopenharmony_civoid RootView::DestroyMapBufferInfo() 851a3e0fd82Sopenharmony_ci{ 852a3e0fd82Sopenharmony_ci if (dc_.mapBufferInfo != nullptr) { 853a3e0fd82Sopenharmony_ci BaseGfxEngine::GetInstance()->FreeBuffer(static_cast<uint8_t*>(dc_.mapBufferInfo->virAddr), BUFFER_MAP_SURFACE); 854a3e0fd82Sopenharmony_ci dc_.mapBufferInfo->virAddr = dc_.mapBufferInfo->phyAddr = nullptr; 855a3e0fd82Sopenharmony_ci delete dc_.mapBufferInfo; 856a3e0fd82Sopenharmony_ci dc_.mapBufferInfo = nullptr; 857a3e0fd82Sopenharmony_ci } 858a3e0fd82Sopenharmony_ci} 859a3e0fd82Sopenharmony_ci 860a3e0fd82Sopenharmony_civoid RootView::InitDrawContext() 861a3e0fd82Sopenharmony_ci{ 862a3e0fd82Sopenharmony_ci dc_.bufferInfo = BaseGfxEngine::GetInstance()->GetFBBufferInfo(); 863a3e0fd82Sopenharmony_ci if (dc_.bufferInfo != nullptr) { 864a3e0fd82Sopenharmony_ci InitMapBufferInfo(dc_.bufferInfo); 865a3e0fd82Sopenharmony_ci } 866a3e0fd82Sopenharmony_ci 867a3e0fd82Sopenharmony_ci bakDc_.bufferInfo = nullptr; 868a3e0fd82Sopenharmony_ci bakDc_.mapBufferInfo = nullptr; 869a3e0fd82Sopenharmony_ci} 870a3e0fd82Sopenharmony_ci 871a3e0fd82Sopenharmony_civoid RootView::DestroyDrawContext() 872a3e0fd82Sopenharmony_ci{ 873a3e0fd82Sopenharmony_ci DestroyMapBufferInfo(); 874a3e0fd82Sopenharmony_ci} 875a3e0fd82Sopenharmony_ci 876a3e0fd82Sopenharmony_civoid RootView::UpdateBufferInfo(BufferInfo* fbBufferInfo) 877a3e0fd82Sopenharmony_ci{ 878a3e0fd82Sopenharmony_ci if (dc_.bufferInfo == nullptr) { 879a3e0fd82Sopenharmony_ci dc_.bufferInfo = fbBufferInfo; 880a3e0fd82Sopenharmony_ci InitMapBufferInfo(fbBufferInfo); 881a3e0fd82Sopenharmony_ci } else { 882a3e0fd82Sopenharmony_ci if (dc_.bufferInfo->width != fbBufferInfo->width || dc_.bufferInfo->height != fbBufferInfo->height || 883a3e0fd82Sopenharmony_ci dc_.bufferInfo->mode != fbBufferInfo->mode) { 884a3e0fd82Sopenharmony_ci DestroyMapBufferInfo(); 885a3e0fd82Sopenharmony_ci InitMapBufferInfo(fbBufferInfo); 886a3e0fd82Sopenharmony_ci } 887a3e0fd82Sopenharmony_ci dc_.bufferInfo = fbBufferInfo; 888a3e0fd82Sopenharmony_ci } 889a3e0fd82Sopenharmony_ci} 890a3e0fd82Sopenharmony_ci 891a3e0fd82Sopenharmony_civoid RootView::SaveDrawContext() 892a3e0fd82Sopenharmony_ci{ 893a3e0fd82Sopenharmony_ci bakDc_.bufferInfo = dc_.bufferInfo; 894a3e0fd82Sopenharmony_ci dc_.bufferInfo = nullptr; 895a3e0fd82Sopenharmony_ci 896a3e0fd82Sopenharmony_ci bakDc_.mapBufferInfo = dc_.mapBufferInfo; 897a3e0fd82Sopenharmony_ci dc_.mapBufferInfo = nullptr; 898a3e0fd82Sopenharmony_ci} 899a3e0fd82Sopenharmony_ci 900a3e0fd82Sopenharmony_civoid RootView::RestoreDrawContext() 901a3e0fd82Sopenharmony_ci{ 902a3e0fd82Sopenharmony_ci DestroyDrawContext(); 903a3e0fd82Sopenharmony_ci 904a3e0fd82Sopenharmony_ci dc_.bufferInfo = bakDc_.bufferInfo; 905a3e0fd82Sopenharmony_ci bakDc_.bufferInfo = nullptr; 906a3e0fd82Sopenharmony_ci 907a3e0fd82Sopenharmony_ci dc_.mapBufferInfo = bakDc_.mapBufferInfo; 908a3e0fd82Sopenharmony_ci bakDc_.mapBufferInfo = nullptr; 909a3e0fd82Sopenharmony_ci} 910a3e0fd82Sopenharmony_ci} // namespace OHOS 911