Flutter Engine
 
Loading...
Searching...
No Matches
flutter::DlRegion Class Reference

#include <dl_region.h>

Public Member Functions

 DlRegion ()=default
 Creates an empty region.
 
 DlRegion (const std::vector< DlIRect > &rects)
 
 DlRegion (const DlIRect &rect)
 Creates region covering area of a rectangle.
 
 DlRegion (const DlRegion &)=default
 
 DlRegion (DlRegion &&)=default
 
DlRegionoperator= (const DlRegion &)=default
 
DlRegionoperator= (DlRegion &&)=default
 
std::vector< DlIRectgetRects (bool deband=true) const
 
const DlIRectbounds () const
 
bool intersects (const DlIRect &rect) const
 Returns whether this region intersects with a rectangle.
 
bool intersects (const DlRegion &region) const
 Returns whether this region intersects with another region.
 
bool isEmpty () const
 Returns true if region is empty (contains no rectangles).
 
bool isComplex () const
 Returns true if region is not empty and contains more than one rectangle.
 
bool isSimple () const
 

Static Public Member Functions

static DlRegion MakeUnion (const DlRegion &a, const DlRegion &b)
 
static DlRegion MakeIntersection (const DlRegion &a, const DlRegion &b)
 

Detailed Description

Represents a region as a collection of non-overlapping rectangles. Implements a subset of SkRegion functionality optimized for quickly converting set of overlapping rectangles to non-overlapping rectangles.

Definition at line 18 of file dl_region.h.

Constructor & Destructor Documentation

◆ DlRegion() [1/5]

flutter::DlRegion::DlRegion ( )
default

Creates an empty region.

◆ DlRegion() [2/5]

flutter::DlRegion::DlRegion ( const std::vector< DlIRect > &  rects)
explicit

Creates region by bulk adding the rectangles. Matches SkRegion::op(rect, SkRegion::kUnion_Op) behavior.

Definition at line 97 of file dl_region.cc.

97 {
98 setRects(rects);
99}

◆ DlRegion() [3/5]

flutter::DlRegion::DlRegion ( const DlIRect rect)
explicit

Creates region covering area of a rectangle.

Definition at line 101 of file dl_region.cc.

101 : bounds_(rect) {
102 Span span{rect.GetLeft(), rect.GetRight()};
103 lines_.push_back(makeLine(rect.GetTop(), rect.GetBottom(), &span, &span + 1));
104}
constexpr auto GetLeft() const
Definition rect.h:351

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), and impeller::TRect< T >::GetTop().

◆ DlRegion() [4/5]

flutter::DlRegion::DlRegion ( const DlRegion )
default

◆ DlRegion() [5/5]

flutter::DlRegion::DlRegion ( DlRegion &&  )
default

Member Function Documentation

◆ bounds()

const DlIRect & flutter::DlRegion::bounds ( ) const
inline

Returns maximum and minimum axis values of rectangles in this region. If region is empty returns SKIRect::MakeEmpty().

Definition at line 53 of file dl_region.h.

53{ return bounds_; }

Referenced by flutter::testing::CheckEquality().

◆ getRects()

std::vector< DlIRect > flutter::DlRegion::getRects ( bool  deband = true) const

Returns list of non-overlapping rectangles that cover current region. If |deband| is false, each span line will result in separate rectangles, closely matching SkRegion::Iterator behavior. If |deband| is true, matching rectangles from adjacent span lines will be merged into single rectangle.

Definition at line 560 of file dl_region.cc.

560 {
561 std::vector<DlIRect> rects;
562 if (isEmpty()) {
563 return rects;
564 } else if (isSimple()) {
565 rects.push_back(bounds_);
566 return rects;
567 }
568
569 size_t rect_count = 0;
570 size_t previous_span_end = 0;
571 for (const auto& line : lines_) {
572 rect_count += span_buffer_.getChunkSize(line.chunk_handle);
573 }
574 rects.reserve(rect_count);
575
576 for (const auto& line : lines_) {
577 const Span *span_begin, *span_end;
578 span_buffer_.getSpans(line.chunk_handle, span_begin, span_end);
579 for (const auto* span = span_begin; span < span_end; ++span) {
580 int32_t top = line.top;
581 if (deband) {
582 auto iter = rects.begin() + previous_span_end;
583 // If there is rectangle previously in rects on which this one is a
584 // vertical continuation, remove the previous rectangle and expand
585 // this one vertically to cover the area.
586 while (iter != rects.begin()) {
587 --iter;
588 if (iter->GetBottom() < top) {
589 // Went all the way to previous span line.
590 break;
591 } else if (iter->GetLeft() == span->left &&
592 iter->GetRight() == span->right) {
593 FML_DCHECK(iter->GetBottom() == top);
594 top = iter->GetTop();
595 rects.erase(iter);
596 --previous_span_end;
597 break;
598 }
599 }
600 }
601 rects.push_back(
602 DlIRect::MakeLTRB(span->left, top, span->right, line.bottom));
603 }
604 previous_span_end = rects.size();
605 }
606 return rects;
607}
bool isEmpty() const
Returns true if region is empty (contains no rectangles).
Definition dl_region.h:62
bool isSimple() const
Definition dl_region.h:69
#define FML_DCHECK(condition)
Definition logging.h:122
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition rect.h:129

References FML_DCHECK.

Referenced by flutter::testing::CheckEquality(), flutter::DlRTree::searchAndConsolidateRects(), flutter::RTree::searchNonOverlappingDrawnRects(), flutter::SliceViews(), flutter::testing::TEST(), flutter::testing::TEST(), flutter::testing::TEST(), flutter::testing::TEST(), flutter::testing::TEST(), flutter::testing::TEST(), flutter::testing::TEST(), flutter::testing::TEST(), flutter::testing::TEST(), and flutter::testing::TEST().

◆ intersects() [1/2]

bool flutter::DlRegion::intersects ( const DlIRect rect) const

Returns whether this region intersects with a rectangle.

Definition at line 615 of file dl_region.cc.

615 {
616 if (isEmpty()) {
617 return false;
618 }
619
620 auto bounds_intersect = bounds_.IntersectsWithRect(rect);
621
622 if (isSimple()) {
623 return bounds_intersect;
624 }
625
626 if (!bounds_intersect) {
627 return false;
628 }
629
630 auto it = lines_.begin();
631 auto end = lines_.end();
632 if (lines_.size() > kBinarySearchThreshold &&
633 it[kBinarySearchThreshold].bottom <= rect.GetTop()) {
634 it = std::lower_bound(
635 lines_.begin() + kBinarySearchThreshold + 1, lines_.end(),
636 rect.GetTop(),
637 [](const SpanLine& line, int32_t top) { return line.bottom <= top; });
638 } else {
639 while (it != end && it->bottom <= rect.GetTop()) {
640 ++it;
641 continue;
642 }
643 }
644 while (it != end && it->top < rect.GetBottom()) {
645 FML_DCHECK(rect.GetTop() < it->bottom && it->top < rect.GetBottom());
646 const Span *begin, *end;
647 span_buffer_.getSpans(it->chunk_handle, begin, end);
648 while (begin != end && begin->left < rect.GetRight()) {
649 if (begin->right > rect.GetLeft()) {
650 return true;
651 }
652 ++begin;
653 }
654 ++it;
655 }
656
657 return false;
658}
const int kBinarySearchThreshold
Definition dl_region.cc:13
constexpr bool IntersectsWithRect(const TRect &o) const
Definition rect.h:546
const size_t end

References end, FML_DCHECK, impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), and flutter::kBinarySearchThreshold.

Referenced by intersects(), and flutter::testing::TEST().

◆ intersects() [2/2]

bool flutter::DlRegion::intersects ( const DlRegion region) const

Returns whether this region intersects with another region.

Definition at line 704 of file dl_region.cc.

704 {
705 if (isEmpty() || region.isEmpty()) {
706 return false;
707 }
708
709 auto our_complex = isComplex();
710 auto their_complex = region.isComplex();
711 auto bounds_intersect = bounds_.IntersectsWithRect(region.bounds_);
712
713 if (!our_complex && !their_complex) {
714 return bounds_intersect;
715 }
716
717 if (!bounds_intersect) {
718 return false;
719 }
720
721 if (!our_complex) {
722 return region.intersects(bounds_);
723 }
724
725 if (!their_complex) {
726 return intersects(region.bounds_);
727 }
728
729 std::vector<SpanLine>::const_iterator ours, theirs;
730 getIntersectionIterators(lines_, region.lines_, ours, theirs);
731 auto ours_end = lines_.end();
732 auto theirs_end = region.lines_.end();
733
734 while (ours != ours_end && theirs != theirs_end) {
735 if (ours->bottom <= theirs->top) {
736 ++ours;
737 } else if (theirs->bottom <= ours->top) {
738 ++theirs;
739 } else {
740 FML_DCHECK(ours->top < theirs->bottom && theirs->top < ours->bottom);
741 const Span *ours_begin, *ours_end;
742 span_buffer_.getSpans(ours->chunk_handle, ours_begin, ours_end);
743 const Span *theirs_begin, *theirs_end;
744 region.span_buffer_.getSpans(theirs->chunk_handle, theirs_begin,
745 theirs_end);
746 if (spansIntersect(ours_begin, ours_end, theirs_begin, theirs_end)) {
747 return true;
748 }
749 if (ours->bottom < theirs->bottom) {
750 ++ours;
751 } else {
752 ++theirs;
753 }
754 }
755 }
756 return false;
757}
bool isComplex() const
Returns true if region is not empty and contains more than one rectangle.
Definition dl_region.cc:609
bool intersects(const DlIRect &rect) const
Returns whether this region intersects with a rectangle.
Definition dl_region.cc:615

References FML_DCHECK, intersects(), isComplex(), and isEmpty().

◆ isComplex()

bool flutter::DlRegion::isComplex ( ) const

Returns true if region is not empty and contains more than one rectangle.

Definition at line 609 of file dl_region.cc.

609 {
610 return lines_.size() > 1 ||
611 (lines_.size() == 1 &&
612 span_buffer_.getChunkSize(lines_.front().chunk_handle) > 1);
613}

Referenced by intersects(), and isSimple().

◆ isEmpty()

bool flutter::DlRegion::isEmpty ( ) const
inline

Returns true if region is empty (contains no rectangles).

Definition at line 62 of file dl_region.h.

62{ return lines_.empty(); }

Referenced by intersects(), MakeUnion(), and flutter::testing::TEST().

◆ isSimple()

bool flutter::DlRegion::isSimple ( ) const
inline

Returns true if region can be represented by single rectangle or is empty.

Definition at line 69 of file dl_region.h.

69{ return !isComplex(); }

References isComplex().

Referenced by MakeIntersection(), and MakeUnion().

◆ MakeIntersection()

DlRegion flutter::DlRegion::MakeIntersection ( const DlRegion a,
const DlRegion b 
)
static

Creates intersection region of region a and b. Matches SkRegion a; a.op(b, SkRegion::kIntersect_Op) behavior.

Definition at line 496 of file dl_region.cc.

496 {
497 if (!a.bounds_.IntersectsWithRect(b.bounds_)) {
498 return DlRegion();
499 } else if (a.isSimple() && b.isSimple()) {
500 auto res = a.bounds_.Intersection(b.bounds_);
501 FML_DCHECK(res.has_value());
502 return res.has_value() ? DlRegion(res.value()) : DlRegion();
503 } else if (a.isSimple() && a.bounds_.Contains(b.bounds_)) {
504 return b;
505 } else if (b.isSimple() && b.bounds_.Contains(a.bounds_)) {
506 return a;
507 }
508
509 DlRegion res;
510 res.span_buffer_.reserve(
511 std::max(a.span_buffer_.capacity(), b.span_buffer_.capacity()));
512
513 auto& lines = res.lines_;
514 lines.reserve(std::min(a.lines_.size(), b.lines_.size()));
515
516 std::vector<SpanLine>::const_iterator a_it, b_it;
517 getIntersectionIterators(a.lines_, b.lines_, a_it, b_it);
518
519 auto a_end = a.lines_.end();
520 auto b_end = b.lines_.end();
521
522 auto& a_buffer = a.span_buffer_;
523 auto& b_buffer = b.span_buffer_;
524
525 std::vector<Span> tmp;
526
527 int32_t cur_top = std::numeric_limits<int32_t>::min();
528
529 while (a_it != a_end && b_it != b_end) {
530 auto a_top = std::max(cur_top, a_it->top);
531 auto b_top = std::max(cur_top, b_it->top);
532 if (a_it->bottom <= b_top) {
533 ++a_it;
534 } else if (b_it->bottom <= a_top) {
535 ++b_it;
536 } else {
537 auto top = std::max(a_top, b_top);
538 auto bottom = std::min(a_it->bottom, b_it->bottom);
539 FML_DCHECK(top < bottom);
540 auto size = intersectLineSpans(tmp, a_buffer, a_it->chunk_handle,
541 b_buffer, b_it->chunk_handle);
542 if (size > 0) {
543 res.appendLine(top, bottom, tmp.data(), tmp.data() + size);
544 res.bounds_ = res.bounds_.Union(DlIRect::MakeLTRB(
545 tmp.data()->left, top, (tmp.data() + size - 1)->right, bottom));
546 }
547 cur_top = bottom;
548 if (cur_top == a_it->bottom) {
549 ++a_it;
550 }
551 if (cur_top == b_it->bottom) {
552 ++b_it;
553 }
554 }
555 }
556 FML_DCHECK(a_it == a_end || b_it == b_end);
557 return res;
558}
DlRegion()=default
Creates an empty region.
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size

References impeller::TRect< T >::Contains(), FML_DCHECK, impeller::TRect< T >::Intersection(), impeller::TRect< T >::IntersectsWithRect(), isSimple(), flutter::size, and impeller::TRect< T >::Union().

Referenced by flutter::DlRTree::region(), flutter::EmbedderViewSlice::region(), flutter::testing::TEST(), flutter::testing::TEST(), flutter::testing::TEST(), and flutter::testing::TEST().

◆ MakeUnion()

DlRegion flutter::DlRegion::MakeUnion ( const DlRegion a,
const DlRegion b 
)
static

Creates union region of region a and b. Matches SkRegion a; a.op(b, SkRegion::kUnion_Op) behavior.

Definition at line 405 of file dl_region.cc.

405 {
406 if (a.isEmpty()) {
407 return b;
408 } else if (b.isEmpty()) {
409 return a;
410 } else if (a.isSimple() && a.bounds_.Contains(b.bounds_)) {
411 return a;
412 } else if (b.isSimple() && b.bounds_.Contains(a.bounds_)) {
413 return b;
414 }
415
416 DlRegion res;
417 res.bounds_ = a.bounds_.Union(b.bounds_);
418 res.span_buffer_.reserve(a.span_buffer_.capacity() +
419 b.span_buffer_.capacity());
420
421 auto& lines = res.lines_;
422 lines.reserve(a.lines_.size() + b.lines_.size());
423
424 auto a_it = a.lines_.begin();
425 auto b_it = b.lines_.begin();
426 auto a_end = a.lines_.end();
427 auto b_end = b.lines_.end();
428
429 FML_DCHECK(a_it != a_end && b_it != b_end);
430
431 auto& a_buffer = a.span_buffer_;
432 auto& b_buffer = b.span_buffer_;
433
434 std::vector<Span> tmp;
435
436 int32_t cur_top = std::numeric_limits<int32_t>::min();
437
438 while (a_it != a_end && b_it != b_end) {
439 auto a_top = std::max(cur_top, a_it->top);
440 auto b_top = std::max(cur_top, b_it->top);
441 if (a_it->bottom <= b_top) {
442 res.appendLine(a_top, a_it->bottom, a_buffer, a_it->chunk_handle);
443 ++a_it;
444 } else if (b_it->bottom <= a_top) {
445 res.appendLine(b_top, b_it->bottom, b_buffer, b_it->chunk_handle);
446 ++b_it;
447 } else {
448 if (a_top < b_top) {
449 res.appendLine(a_top, b_top, a_buffer, a_it->chunk_handle);
450 cur_top = b_top;
451 if (cur_top == a_it->bottom) {
452 ++a_it;
453 }
454 } else if (b_top < a_top) {
455 res.appendLine(b_top, a_top, b_buffer, b_it->chunk_handle);
456 cur_top = a_top;
457 if (cur_top == b_it->bottom) {
458 ++b_it;
459 }
460 } else {
461 auto new_bottom = std::min(a_it->bottom, b_it->bottom);
462 FML_DCHECK(a_top == b_top);
463 FML_DCHECK(new_bottom > a_top);
464 FML_DCHECK(new_bottom > b_top);
465 auto size = unionLineSpans(tmp, a_buffer, a_it->chunk_handle, b_buffer,
466 b_it->chunk_handle);
467 res.appendLine(a_top, new_bottom, tmp.data(), tmp.data() + size);
468 cur_top = new_bottom;
469 if (cur_top == a_it->bottom) {
470 ++a_it;
471 }
472 if (cur_top == b_it->bottom) {
473 ++b_it;
474 }
475 }
476 }
477 }
478
479 FML_DCHECK(a_it == a_end || b_it == b_end);
480
481 while (a_it != a_end) {
482 auto a_top = std::max(cur_top, a_it->top);
483 res.appendLine(a_top, a_it->bottom, a_buffer, a_it->chunk_handle);
484 ++a_it;
485 }
486
487 while (b_it != b_end) {
488 auto b_top = std::max(cur_top, b_it->top);
489 res.appendLine(b_top, b_it->bottom, b_buffer, b_it->chunk_handle);
490 ++b_it;
491 }
492
493 return res;
494}

References impeller::TRect< T >::Contains(), FML_DCHECK, isEmpty(), isSimple(), flutter::size, and impeller::TRect< T >::Union().

Referenced by flutter::testing::TEST(), flutter::testing::TEST(), flutter::testing::TEST(), flutter::testing::TEST(), and flutter::testing::TEST().

◆ operator=() [1/2]

DlRegion & flutter::DlRegion::operator= ( const DlRegion )
default

◆ operator=() [2/2]

DlRegion & flutter::DlRegion::operator= ( DlRegion &&  )
default

The documentation for this class was generated from the following files: