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