Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Public Member Functions | Friends | List of all members
SkAAClip Class Reference

#include <SkAAClip.h>

Classes

class  Builder
 
struct  RunHead
 

Public Member Functions

 SkAAClip ()
 
 SkAAClip (const SkAAClip &)
 
 ~SkAAClip ()
 
SkAAClipoperator= (const SkAAClip &)
 
bool isEmpty () const
 
const SkIRectgetBounds () const
 
bool isRect () const
 
bool setEmpty ()
 
bool setRect (const SkIRect &)
 
bool setPath (const SkPath &, const SkIRect &bounds, bool doAA=true)
 
bool setRegion (const SkRegion &)
 
bool op (const SkIRect &, SkClipOp)
 
bool op (const SkRect &, SkClipOp, bool doAA)
 
bool op (const SkAAClip &, SkClipOp)
 
bool translate (int dx, int dy, SkAAClip *dst) const
 
void copyToMask (SkMaskBuilder *) const
 
bool quickContains (const SkIRect &r) const
 
void validate () const
 
void debug (bool compress_y=false) const
 

Friends

class SkAAClipBlitter
 

Detailed Description

Definition at line 24 of file SkAAClip.h.

Constructor & Destructor Documentation

◆ SkAAClip() [1/2]

SkAAClip::SkAAClip ( )

Definition at line 1234 of file SkAAClip.cpp.

1234 {
1235 fBounds.setEmpty();
1236 fRunHead = nullptr;
1237}
void setEmpty()
Definition SkRect.h:242

◆ SkAAClip() [2/2]

SkAAClip::SkAAClip ( const SkAAClip src)

Definition at line 1239 of file SkAAClip.cpp.

1239 {
1240 SkDEBUGCODE(fBounds.setEmpty();) // need this for validate
1241 fRunHead = nullptr;
1242 *this = src;
1243}
#define SkDEBUGCODE(...)
Definition SkDebug.h:23

◆ ~SkAAClip()

SkAAClip::~SkAAClip ( )

Definition at line 1245 of file SkAAClip.cpp.

1245 {
1246 this->freeRuns();
1247}

Member Function Documentation

◆ copyToMask()

void SkAAClip::copyToMask ( SkMaskBuilder mask) const

Allocates a mask the size of the aaclip, and expands its data into the mask, using kA8_Format. Used for tests and visualization purposes.

Definition at line 851 of file SkAAClip.cpp.

851 {
852 auto expandRowToMask = [](uint8_t* dst, const uint8_t* row, int width) {
853 while (width > 0) {
854 int n = row[0];
855 SkASSERT(width >= n);
856 memset(dst, row[1], n);
857 dst += n;
858 row += 2;
859 width -= n;
860 }
861 SkASSERT(0 == width);
862 };
863
864 mask->format() = SkMask::kA8_Format;
865 if (this->isEmpty()) {
866 mask->bounds().setEmpty();
867 mask->image() = nullptr;
868 mask->rowBytes() = 0;
869 return;
870 }
871
872 mask->bounds() = fBounds;
873 mask->rowBytes() = fBounds.width();
874 size_t size = mask->computeImageSize();
875 mask->image() = SkMaskBuilder::AllocImage(size);
876
877 Iter iter = RunHead::Iterate(*this);
878 uint8_t* dst = mask->image();
879 const int width = fBounds.width();
880
881 int y = fBounds.fTop;
882 while (!iter.done()) {
883 do {
884 expandRowToMask(dst, iter.data(), width);
885 dst += mask->fRowBytes;
886 } while (++y < iter.bottom());
887 iter.next();
888 }
889}
#define SkASSERT(cond)
Definition SkAssert.h:116
bool isEmpty() const
Definition SkAAClip.h:32
double y
it will be possible to load the file into Perfetto s trace viewer 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
Definition switches.h:259
dst
Definition cp.py:12
int32_t width
static Iter Iterate(const SkAAClip &clip)
Definition SkAAClip.cpp:232
int32_t fTop
smaller y-axis bounds
Definition SkRect.h:34
constexpr int32_t width() const
Definition SkRect.h:158
Format & format()
Definition SkMask.h:239
uint32_t & rowBytes()
Definition SkMask.h:238
static uint8_t * AllocImage(size_t bytes, AllocType=kUninit_Alloc)
Definition SkMask.cpp:45
SkIRect & bounds()
Definition SkMask.h:237
uint8_t *& image()
Definition SkMask.h:236
const uint32_t fRowBytes
Definition SkMask.h:43
@ kA8_Format
8bits per pixel mask (e.g. antialiasing)
Definition SkMask.h:28
size_t computeImageSize() const
Definition SkMask.cpp:30

◆ debug()

void SkAAClip::debug ( bool  compress_y = false) const
inline

Definition at line 65 of file SkAAClip.h.

65{}

◆ getBounds()

const SkIRect & SkAAClip::getBounds ( ) const
inline

Definition at line 33 of file SkAAClip.h.

33{ return fBounds; }

◆ isEmpty()

bool SkAAClip::isEmpty ( ) const
inline

Definition at line 32 of file SkAAClip.h.

32{ return nullptr == fRunHead; }

◆ isRect()

bool SkAAClip::isRect ( ) const

Definition at line 1285 of file SkAAClip.cpp.

1285 {
1286 if (this->isEmpty()) {
1287 return false;
1288 }
1289
1290 const RunHead* head = fRunHead;
1291 if (head->fRowCount != 1) {
1292 return false;
1293 }
1294 const YOffset* yoff = head->yoffsets();
1295 if (yoff->fY != fBounds.fBottom - 1) {
1296 return false;
1297 }
1298
1299 const uint8_t* row = head->data() + yoff->fOffset;
1300 int width = fBounds.width();
1301 do {
1302 if (row[1] != 0xFF) {
1303 return false;
1304 }
1305 int n = row[0];
1306 SkASSERT(n <= width);
1307 width -= n;
1308 row += 2;
1309 } while (width > 0);
1310 return true;
1311}
int32_t fBottom
larger y-axis bounds
Definition SkRect.h:36

◆ op() [1/3]

bool SkAAClip::op ( const SkAAClip other,
SkClipOp  op 
)

Definition at line 1426 of file SkAAClip.cpp.

1426 {
1427 AUTO_AACLIP_VALIDATE(*this);
1428
1429 if (this->isEmpty()) {
1430 // Once the clip is empty, it cannot become un-empty.
1431 return false;
1432 }
1433
1434 SkIRect bounds = fBounds;
1435 switch(op) {
1437 if (other.isEmpty() || !SkIRect::Intersects(fBounds, other.fBounds)) {
1438 // this remains unmodified and isn't empty
1439 return true;
1440 }
1441 break;
1442
1444 if (other.isEmpty() || !bounds.intersect(other.fBounds)) {
1445 // the intersected clip becomes empty
1446 return this->setEmpty();
1447 }
1448 break;
1449 }
1450
1451
1452 SkASSERT(SkIRect::Intersects(bounds, fBounds));
1453 SkASSERT(SkIRect::Intersects(bounds, other.fBounds));
1454
1455 Builder builder(bounds);
1456 return builder.applyClipOp(this, other, op);
1457}
#define AUTO_AACLIP_VALIDATE(clip)
Definition SkAAClip.cpp:47
bool setEmpty()
bool op(const SkIRect &, SkClipOp)
Optional< SkRect > bounds
Definition SkRecords.h:189
DlVertices::Builder Builder
static bool Intersects(const SkIRect &a, const SkIRect &b)
Definition SkRect.h:535

◆ op() [2/3]

bool SkAAClip::op ( const SkIRect rect,
SkClipOp  op 
)

Definition at line 1459 of file SkAAClip.cpp.

1459 {
1460 // It can be expensive to build a local aaclip before applying the op, so
1461 // we first see if we can restrict the bounds of new rect to our current
1462 // bounds, or note that the new rect subsumes our current clip.
1463 SkIRect pixelBounds = fBounds;
1464 if (!pixelBounds.intersect(rect)) {
1465 // No change or clip becomes empty depending on 'op'
1466 switch(op) {
1467 case SkClipOp::kDifference: return !this->isEmpty();
1468 case SkClipOp::kIntersect: return this->setEmpty();
1469 }
1471 } else if (pixelBounds == fBounds) {
1472 // Wholly inside 'rect', so clip becomes empty or remains unchanged
1473 switch(op) {
1474 case SkClipOp::kDifference: return this->setEmpty();
1475 case SkClipOp::kIntersect: return !this->isEmpty();
1476 }
1478 } else if (op == SkClipOp::kIntersect && this->quickContains(pixelBounds)) {
1479 // We become just the remaining rectangle
1480 return this->setRect(pixelBounds);
1481 } else {
1482 SkAAClip clip;
1483 clip.setRect(rect);
1484 return this->op(clip, op);
1485 }
1486}
#define SkUNREACHABLE
Definition SkAssert.h:135
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition SkPath.cpp:3824
bool setRect(const SkIRect &)
bool quickContains(const SkIRect &r) const
Definition SkAAClip.h:56
bool intersect(const SkIRect &r)
Definition SkRect.h:513

◆ op() [3/3]

bool SkAAClip::op ( const SkRect rect,
SkClipOp  op,
bool  doAA 
)

Definition at line 1488 of file SkAAClip.cpp.

1488 {
1489 if (!doAA) {
1490 return this->op(rect.round(), op);
1491 } else {
1492 // Tighten bounds for "path" aaclip of the rect
1493 SkIRect pixelBounds = fBounds;
1494 if (!pixelBounds.intersect(rect.roundOut())) {
1495 // No change or clip becomes empty depending on 'op'
1496 switch(op) {
1497 case SkClipOp::kDifference: return !this->isEmpty();
1498 case SkClipOp::kIntersect: return this->setEmpty();
1499 }
1501 } else if (rect.contains(SkRect::Make(fBounds))) {
1502 // Wholly inside 'rect', so clip becomes empty or remains unchanged
1503 switch(op) {
1504 case SkClipOp::kDifference: return this->setEmpty();
1505 case SkClipOp::kIntersect: return !this->isEmpty();
1506 }
1508 } else if (op == SkClipOp::kIntersect && this->quickContains(pixelBounds)) {
1509 // We become just the rect intersected with pixel bounds (preserving fractional coords
1510 // for AA edges).
1511 return this->setPath(SkPath::Rect(rect), pixelBounds, /*doAA=*/true);
1512 } else {
1513 SkAAClip rectClip;
1514 rectClip.setPath(SkPath::Rect(rect),
1515 op == SkClipOp::kDifference ? fBounds : pixelBounds,
1516 /*doAA=*/true);
1517 return this->op(rectClip, op);
1518 }
1519 }
1520}
bool setPath(const SkPath &, const SkIRect &bounds, bool doAA=true)
static SkPath Rect(const SkRect &, SkPathDirection=SkPathDirection::kCW, unsigned startIndex=0)
Definition SkPath.cpp:3518
sk_sp< SkBlender > blender SkRect rect
Definition SkRecords.h:350
static SkRect Make(const SkISize &size)
Definition SkRect.h:669
bool contains(SkScalar x, SkScalar y) const
Definition extension.cpp:19
void round(SkIRect *dst) const
Definition SkRect.h:1228

◆ operator=()

SkAAClip & SkAAClip::operator= ( const SkAAClip src)

Definition at line 1249 of file SkAAClip.cpp.

1249 {
1250 AUTO_AACLIP_VALIDATE(*this);
1251 src.validate();
1252
1253 if (this != &src) {
1254 this->freeRuns();
1255 fBounds = src.fBounds;
1256 fRunHead = src.fRunHead;
1257 if (fRunHead) {
1258 fRunHead->fRefCnt++;
1259 }
1260 }
1261 return *this;
1262}
std::atomic< int32_t > fRefCnt
Definition SkAAClip.cpp:176

◆ quickContains()

bool SkAAClip::quickContains ( const SkIRect r) const
inline

Definition at line 56 of file SkAAClip.h.

56 {
57 return this->quickContains(r.fLeft, r.fTop, r.fRight, r.fBottom);
58 }
int32_t fLeft
smaller x-axis bounds
Definition SkRect.h:33
int32_t fRight
larger x-axis bounds
Definition SkRect.h:35

◆ setEmpty()

bool SkAAClip::setEmpty ( )

Definition at line 1264 of file SkAAClip.cpp.

1264 {
1265 this->freeRuns();
1266 fBounds.setEmpty();
1267 fRunHead = nullptr;
1268 return false;
1269}

◆ setPath()

bool SkAAClip::setPath ( const SkPath path,
const SkIRect bounds,
bool  doAA = true 
)

Definition at line 1401 of file SkAAClip.cpp.

1401 {
1402 AUTO_AACLIP_VALIDATE(*this);
1403
1404 if (clip.isEmpty()) {
1405 return this->setEmpty();
1406 }
1407
1408 SkIRect ibounds;
1409 // Since we assert that the BuilderBlitter will never blit outside the intersection
1410 // of clip and ibounds, we create the builder with the snug bounds.
1411 if (path.isInverseFillType()) {
1412 ibounds = clip;
1413 } else {
1414 path.getBounds().roundOut(&ibounds);
1415 if (ibounds.isEmpty() || !ibounds.intersect(clip)) {
1416 return this->setEmpty();
1417 }
1418 }
1419
1420 Builder builder(ibounds);
1421 return builder.blitPath(this, path, doAA);
1422}
bool isEmpty() const
Definition SkPath.cpp:406
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition switches.h:57
bool isEmpty() const
Definition SkRect.h:202

◆ setRect()

bool SkAAClip::setRect ( const SkIRect bounds)

Definition at line 1271 of file SkAAClip.cpp.

1271 {
1272 if (bounds.isEmpty()) {
1273 return this->setEmpty();
1274 }
1275
1276 AUTO_AACLIP_VALIDATE(*this);
1277
1278 this->freeRuns();
1279 fBounds = bounds;
1280 fRunHead = RunHead::AllocRect(bounds);
1281 SkASSERT(!this->isEmpty());
1282 return true;
1283}
static RunHead * AllocRect(const SkIRect &bounds)
Definition SkAAClip.cpp:213

◆ setRegion()

bool SkAAClip::setRegion ( const SkRegion rgn)

Definition at line 1313 of file SkAAClip.cpp.

1313 {
1314 if (rgn.isEmpty()) {
1315 return this->setEmpty();
1316 }
1317 if (rgn.isRect()) {
1318 return this->setRect(rgn.getBounds());
1319 }
1320
1321
1322 const SkIRect& bounds = rgn.getBounds();
1323 const int offsetX = bounds.fLeft;
1324 const int offsetY = bounds.fTop;
1325
1326 SkTDArray<YOffset> yArray;
1327 SkTDArray<uint8_t> xArray;
1328
1329 yArray.reserve(std::min(bounds.height(), 1024));
1330 xArray.reserve(std::min(bounds.width(), 512) * 128);
1331
1332 auto appendXRun = [&xArray](uint8_t value, int count) {
1333 SkASSERT(count >= 0);
1334 while (count > 0) {
1335 int n = count;
1336 if (n > 255) {
1337 n = 255;
1338 }
1339 uint8_t* data = xArray.append(2);
1340 data[0] = n;
1341 data[1] = value;
1342 count -= n;
1343 }
1344 };
1345
1346 SkRegion::Iterator iter(rgn);
1347 int prevRight = 0;
1348 int prevBot = 0;
1349 YOffset* currY = nullptr;
1350
1351 for (; !iter.done(); iter.next()) {
1352 const SkIRect& r = iter.rect();
1353 SkASSERT(bounds.contains(r));
1354
1355 int bot = r.fBottom - offsetY;
1356 SkASSERT(bot >= prevBot);
1357 if (bot > prevBot) {
1358 if (currY) {
1359 // flush current row
1360 appendXRun(0, bounds.width() - prevRight);
1361 }
1362 // did we introduce an empty-gap from the prev row?
1363 int top = r.fTop - offsetY;
1364 if (top > prevBot) {
1365 currY = yArray.append();
1366 currY->fY = top - 1;
1367 currY->fOffset = xArray.size();
1368 appendXRun(0, bounds.width());
1369 }
1370 // create a new record for this Y value
1371 currY = yArray.append();
1372 currY->fY = bot - 1;
1373 currY->fOffset = xArray.size();
1374 prevRight = 0;
1375 prevBot = bot;
1376 }
1377
1378 int x = r.fLeft - offsetX;
1379 appendXRun(0, x - prevRight);
1380
1381 int w = r.fRight - r.fLeft;
1382 appendXRun(0xFF, w);
1383 prevRight = x + w;
1384 SkASSERT(prevRight <= bounds.width());
1385 }
1386 // flush last row
1387 appendXRun(0, bounds.width() - prevRight);
1388
1389 // now pack everything into a RunHead
1390 RunHead* head = RunHead::Alloc(yArray.size(), xArray.size_bytes());
1391 memcpy(head->yoffsets(), yArray.begin(), yArray.size_bytes());
1392 memcpy(head->data(), xArray.begin(), xArray.size_bytes());
1393
1394 this->setEmpty();
1395 fBounds = bounds;
1396 fRunHead = head;
1397 this->validate();
1398 return true;
1399}
int count
void validate() const
Definition SkAAClip.h:64
bool isRect() const
Definition SkRegion.h:152
const SkIRect & getBounds() const
Definition SkRegion.h:165
bool isEmpty() const
Definition SkRegion.h:146
int size() const
Definition SkTDArray.h:138
void reserve(int n)
Definition SkTDArray.h:187
T * begin()
Definition SkTDArray.h:150
T * append()
Definition SkTDArray.h:191
size_t size_bytes() const
Definition SkTDArray.h:146
uint8_t value
double x
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switches.h:41
SkScalar offsetX
SkScalar w
SkScalar offsetY
static RunHead * Alloc(int rowCount, size_t dataSize)
Definition SkAAClip.cpp:193

◆ translate()

bool SkAAClip::translate ( int  dx,
int  dy,
SkAAClip dst 
) const

Definition at line 1524 of file SkAAClip.cpp.

1524 {
1525 if (nullptr == dst) {
1526 return !this->isEmpty();
1527 }
1528
1529 if (this->isEmpty()) {
1530 return dst->setEmpty();
1531 }
1532
1533 if (this != dst) {
1534 fRunHead->fRefCnt++;
1535 dst->freeRuns();
1536 dst->fRunHead = fRunHead;
1537 dst->fBounds = fBounds;
1538 }
1539 dst->fBounds.offset(dx, dy);
1540 return true;
1541}

◆ validate()

void SkAAClip::validate ( ) const
inline

Definition at line 64 of file SkAAClip.h.

64{}

Friends And Related Symbol Documentation

◆ SkAAClipBlitter

friend class SkAAClipBlitter
friend

Definition at line 71 of file SkAAClip.h.


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