Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
AtlasTypes.h
Go to the documentation of this file.
1/*
2 * Copyright 2022 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef skgpu_AtlasTypes_DEFINED
9#define skgpu_AtlasTypes_DEFINED
10
13#include "include/core/SkRect.h"
20#include "src/core/SkIPoint16.h"
22
23#include <array>
24#include <cstdint>
25#include <cstring>
26#include <utility>
27
28class GrOpFlushState;
31namespace skgpu::graphite { class RecorderPriv; }
32
33/**
34 * This file includes internal types that are used by all of our gpu backends for atlases.
35 */
36
37namespace skgpu {
38
39struct IRect16 {
41
42 [[nodiscard]] static IRect16 MakeEmpty() {
43 IRect16 r;
44 r.setEmpty();
45 return r;
46 }
47
48 [[nodiscard]] static IRect16 MakeWH(int16_t w, int16_t h) {
49 IRect16 r;
50 r.set(0, 0, w, h);
51 return r;
52 }
53
54 [[nodiscard]] static IRect16 MakeXYWH(int16_t x, int16_t y, int16_t w, int16_t h) {
55 IRect16 r;
56 r.set(x, y, x + w, y + h);
57 return r;
58 }
59
60 [[nodiscard]] static IRect16 Make(const SkIRect& ir) {
61 IRect16 r;
62 r.set(ir);
63 return r;
64 }
65
66 int width() const { return fRight - fLeft; }
67 int height() const { return fBottom - fTop; }
68 int area() const { return this->width() * this->height(); }
69 bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
70
71 void setEmpty() { memset(this, 0, sizeof(*this)); }
72
73 void set(int16_t left, int16_t top, int16_t right, int16_t bottom) {
74 fLeft = left;
75 fTop = top;
76 fRight = right;
77 fBottom = bottom;
78 }
79
80 void set(const SkIRect& r) {
81 fLeft = SkToS16(r.fLeft);
82 fTop = SkToS16(r.fTop);
85 }
86
87 void offset(int16_t dx, int16_t dy) {
88 fLeft += dx;
89 fTop += dy;
90 fRight += dx;
91 fBottom += dy;
92 }
93};
94
95/**
96 * Formats for masks, used by the font cache. Important that these are 0-based.
97 */
98enum class MaskFormat : int {
99 kA8, //!< 1-byte per pixel
100 kA565, //!< 2-bytes per pixel, RGB represent 3-channel LCD coverage
101 kARGB, //!< 4-bytes per pixel, color format
102
103 kLast = kARGB
104};
105static const int kMaskFormatCount = static_cast<int>(MaskFormat::kLast) + 1;
106
107/**
108 * Return the number of bytes-per-pixel for the specified mask format.
109 */
111 SkASSERT(static_cast<int>(format) < kMaskFormatCount);
112 // kA8 (0) -> 1
113 // kA565 (1) -> 2
114 // kARGB (2) -> 4
115 static_assert(static_cast<int>(MaskFormat::kA8) == 0, "enum_order_dependency");
116 static_assert(static_cast<int>(MaskFormat::kA565) == 1, "enum_order_dependency");
117 static_assert(static_cast<int>(MaskFormat::kARGB) == 2, "enum_order_dependency");
118
119 return SkTo<int>(1u << static_cast<int>(format));
120}
121
123 switch (format) {
124 case MaskFormat::kA8:
126 case MaskFormat::kA565:
128 case MaskFormat::kARGB:
130 }
132}
133
134/**
135 * Keep track of generation number for atlases and Plots.
136 */
138public:
139 inline static constexpr uint64_t kInvalidGeneration = 0;
140 uint64_t next() {
141 return fGeneration++;
142 }
143
144private:
145 uint64_t fGeneration{1};
146};
147
148/**
149 * AtlasToken is used to sequence uploads relative to each other and to batches of draws.
150 */
152public:
153 static AtlasToken InvalidToken() { return AtlasToken(0); }
154
155 AtlasToken(const AtlasToken&) = default;
156 AtlasToken& operator=(const AtlasToken&) = default;
157
158 bool operator==(const AtlasToken& that) const {
159 return fSequenceNumber == that.fSequenceNumber;
160 }
161 bool operator!=(const AtlasToken& that) const { return !(*this == that); }
162 bool operator<(const AtlasToken that) const {
163 return fSequenceNumber < that.fSequenceNumber;
164 }
165 bool operator<=(const AtlasToken that) const {
166 return fSequenceNumber <= that.fSequenceNumber;
167 }
168 bool operator>(const AtlasToken that) const {
169 return fSequenceNumber > that.fSequenceNumber;
170 }
171 bool operator>=(const AtlasToken that) const {
172 return fSequenceNumber >= that.fSequenceNumber;
173 }
174
176 ++fSequenceNumber;
177 return *this;
178 }
180 auto old = fSequenceNumber;
181 ++fSequenceNumber;
182 return AtlasToken(old);
183 }
184
185 AtlasToken next() const { return AtlasToken(fSequenceNumber + 1); }
186
187 /** Is this token in the [start, end] inclusive interval? */
188 bool inInterval(const AtlasToken& start, const AtlasToken& end) {
189 return *this >= start && *this <= end;
190 }
191
192private:
193 AtlasToken() = delete;
194 explicit AtlasToken(uint64_t sequenceNumber) : fSequenceNumber(sequenceNumber) {}
195 uint64_t fSequenceNumber;
196};
197
198/**
199 * The TokenTracker encapsulates the incrementing and distribution of AtlasTokens.
200 */
202public:
203 /**
204 * Gets the token one beyond the last token that has been flushed,
205 * either in GrDrawingManager::flush() or Device::flushPendingWorkToRecorder()
206 */
207 AtlasToken nextFlushToken() const { return fCurrentFlushToken.next(); }
208
209 /**
210 * Gets the next draw token. This can be used to record that the next draw
211 * issued will use a resource (e.g. texture) while preparing that draw.
212 * Not used by Graphite.
213 */
214 AtlasToken nextDrawToken() const { return fCurrentDrawToken.next(); }
215
216private:
217 // Only these classes get to increment the token counters
218 friend class ::GrOpFlushState;
219 friend class ::TestingUploadTarget;
221
222 // Issues the next token for a draw.
223 AtlasToken issueDrawToken() { return ++fCurrentDrawToken; }
224
225 // Advances the next token for a flush.
226 AtlasToken issueFlushToken() { return ++fCurrentFlushToken; }
227
228 AtlasToken fCurrentDrawToken = AtlasToken::InvalidToken();
229 AtlasToken fCurrentFlushToken = AtlasToken::InvalidToken();
230};
231
232/**
233 * A PlotLocator specifies the plot and is analogous to a directory path:
234 * page/plot/plotGeneration
235 *
236 * In fact PlotLocator is a portion of a glyph image location in the atlas fully specified by:
237 * format/atlasGeneration/page/plot/plotGeneration/rect
238 */
240public:
241 // These are both restricted by the space they occupy in the PlotLocator.
242 // maxPages is also limited by being crammed into the glyph uvs.
243 // maxPlots is also limited by the fPlotAlreadyUpdated bitfield in
244 // GrDrawOpAtlas::BulkUseTokenUpdater.
245 inline static constexpr auto kMaxMultitexturePages = 4;
246 inline static constexpr int kMaxPlots = 32;
247
248 PlotLocator(uint32_t pageIdx, uint32_t plotIdx, uint64_t generation)
249 : fGenID(generation)
250 , fPlotIndex(plotIdx)
251 , fPageIndex(pageIdx) {
253 SkASSERT(plotIdx < kMaxPlots);
254 SkASSERT(generation < ((uint64_t)1 << 48));
255 }
256
258 : fGenID(AtlasGenerationCounter::kInvalidGeneration)
259 , fPlotIndex(0)
260 , fPageIndex(0) {}
261
262 bool isValid() const {
264 fPlotIndex != 0 || fPageIndex != 0;
265 }
266
267 void makeInvalid() {
269 fPlotIndex = 0;
270 fPageIndex = 0;
271 }
272
273 bool operator==(const PlotLocator& other) const {
274 return fGenID == other.fGenID &&
275 fPlotIndex == other.fPlotIndex &&
276 fPageIndex == other.fPageIndex; }
277
278 uint32_t pageIndex() const { return fPageIndex; }
279 uint32_t plotIndex() const { return fPlotIndex; }
280 uint64_t genID() const { return fGenID; }
281
282private:
283 uint64_t fGenID:48;
284 uint64_t fPlotIndex:8;
285 uint64_t fPageIndex:8;
286};
287
288// AtlasLocator handles atlas position information. It keeps a left-top, right-bottom pair of
289// encoded UV coordinates. The bits 13 & 14 of the U coordinates hold the atlas page index.
290// This information is handed directly as is from fUVs. This encoding has the nice property
291// that width = fUVs[2] - fUVs[0]; the page encoding in the top bits subtracts to zero.
293public:
294 std::array<uint16_t, 4> getUVs() const {
295 return fUVs;
296 }
297
298 void invalidatePlotLocator() { fPlotLocator.makeInvalid(); }
299
300 // TODO: Remove the small path renderer's use of this for eviction
301 PlotLocator plotLocator() const { return fPlotLocator; }
302
303 uint32_t pageIndex() const { return fPlotLocator.pageIndex(); }
304
305 uint32_t plotIndex() const { return fPlotLocator.plotIndex(); }
306
307 uint64_t genID() const { return fPlotLocator.genID(); }
308
310 return {fUVs[0] & 0x1FFF, fUVs[1]};
311 }
312
314 auto width = fUVs[2] - fUVs[0],
315 height = fUVs[3] - fUVs[1];
316 return SkPoint::Make(width, height);
317 }
318
319 uint16_t width() const {
320 return fUVs[2] - fUVs[0];
321 }
322
323 uint16_t height() const {
324 return fUVs[3] - fUVs[1];
325 }
326
327 void insetSrc(int padding) {
328 SkASSERT(2 * padding <= this->width());
329 SkASSERT(2 * padding <= this->height());
330
331 fUVs[0] += padding;
332 fUVs[1] += padding;
333 fUVs[2] -= padding;
334 fUVs[3] -= padding;
335 }
336
338 fPlotLocator = p;
339 SkASSERT(fPlotLocator.pageIndex() <= 3);
340 uint16_t page = fPlotLocator.pageIndex() << 13;
341 fUVs[0] = (fUVs[0] & 0x1FFF) | page;
342 fUVs[2] = (fUVs[2] & 0x1FFF) | page;
343 }
344
346 SkASSERT(rect.fLeft <= rect.fRight);
347 SkASSERT(rect.fRight <= 0x1FFF);
348 fUVs[0] = (fUVs[0] & 0xE000) | rect.fLeft;
349 fUVs[1] = rect.fTop;
350 fUVs[2] = (fUVs[2] & 0xE000) | rect.fRight;
351 fUVs[3] = rect.fBottom;
352 }
353
354private:
356
357 // The inset padded bounds in the atlas in the lower 13 bits, and page index in bits 13 &
358 // 14 of the Us.
359 std::array<uint16_t, 4> fUVs{0, 0, 0, 0};
360};
361
362/**
363 * An interface for eviction callbacks. Whenever an atlas evicts a specific PlotLocator,
364 * it will call all of the registered listeners so they can process the eviction.
365 */
367public:
368 virtual ~PlotEvictionCallback() = default;
369 virtual void evict(PlotLocator) = 0;
370};
371
372/**
373 * A class which can be handed back to an atlas for updating plots in bulk. The
374 * current max number of plots per page an atlas can handle is 32. If in the future
375 * this is insufficient then we can move to a 64 bit int.
376 */
378public:
380 memset(fPlotAlreadyUpdated, 0, sizeof(fPlotAlreadyUpdated));
381 }
383 : fPlotsToUpdate(that.fPlotsToUpdate) {
384 memcpy(fPlotAlreadyUpdated, that.fPlotAlreadyUpdated, sizeof(fPlotAlreadyUpdated));
385 }
386
387 bool add(const skgpu::AtlasLocator& atlasLocator) {
388 int plotIdx = atlasLocator.plotIndex();
389 int pageIdx = atlasLocator.pageIndex();
390 if (this->find(pageIdx, plotIdx)) {
391 return false;
392 }
393 this->set(pageIdx, plotIdx);
394 return true;
395 }
396
397 void reset() {
398 fPlotsToUpdate.clear();
399 memset(fPlotAlreadyUpdated, 0, sizeof(fPlotAlreadyUpdated));
400 }
401
402 struct PlotData {
403 PlotData(int pageIdx, int plotIdx) : fPageIndex(pageIdx), fPlotIndex(plotIdx) {}
404 uint32_t fPageIndex;
405 uint32_t fPlotIndex;
406 };
407
408 int count() const { return fPlotsToUpdate.size(); }
409
410 const PlotData& plotData(int index) const { return fPlotsToUpdate[index]; }
411
412private:
413 bool find(int pageIdx, int index) const {
415 return (fPlotAlreadyUpdated[pageIdx] >> index) & 1;
416 }
417
418 void set(int pageIdx, int index) {
419 SkASSERT(!this->find(pageIdx, index));
420 fPlotAlreadyUpdated[pageIdx] |= (1 << index);
421 fPlotsToUpdate.push_back(PlotData(pageIdx, index));
422 }
423
424 inline static constexpr int kMinItems = 4;
426 // TODO: increase this to uint64_t to allow more plots per page
427 uint32_t fPlotAlreadyUpdated[skgpu::PlotLocator::kMaxMultitexturePages];
428};
429
430/**
431 * The backing texture for an atlas is broken into a spatial grid of Plots. The Plots
432 * keep track of subimage placement via their Rectanizer. A Plot may be subclassed if
433 * the atlas class needs to track additional information.
434 */
435class Plot : public SkRefCnt {
437
438public:
439 Plot(int pageIndex, int plotIndex, AtlasGenerationCounter* generationCounter,
440 int offX, int offY, int width, int height, SkColorType colorType, size_t bpp);
441
442 uint32_t pageIndex() const { return fPageIndex; }
443
444 /** plotIndex() is a unique id for the plot relative to the owning GrAtlas and page. */
445 uint32_t plotIndex() const { return fPlotIndex; }
446 /**
447 * genID() is incremented when the plot is evicted due to a atlas spill. It is used to
448 * know if a particular subimage is still present in the atlas.
449 */
450 uint64_t genID() const { return fGenID; }
452 SkASSERT(fPlotLocator.isValid());
453 return fPlotLocator;
454 }
455 SkDEBUGCODE(size_t bpp() const { return fBytesPerPixel; })
456
457 /**
458 * To add data to the Plot, first call addRect to see if it's possible. If successful,
459 * use the atlasLocator to get a pointer to the location in the atlas via dataAt() and render to
460 * that location, or if you already have data use copySubImage().
461 */
462 bool addRect(int width, int height, AtlasLocator* atlasLocator);
463 void* dataAt(const AtlasLocator& atlasLocator);
464 void copySubImage(const AtlasLocator& atlasLocator, const void* image);
465 // Reset Pixmap to point to backing data for this Plot,
466 // and return render location specified by AtlasLocator but relative to this Plot.
468 // TODO: Utility method for Ganesh, consider removing
469 bool addSubImage(int width, int height, const void* image, AtlasLocator* atlasLocator);
470
471 /**
472 * To manage the lifetime of a plot, we use two tokens. We use the last upload token to
473 * know when we can 'piggy back' uploads, i.e. if the last upload hasn't been flushed to
474 * the gpu, we don't need to issue a new upload even if we update the cpu backing store. We
475 * use lastUse to determine when we can evict a plot from the cache, i.e. if the last use
476 * has already flushed through the gpu then we can reuse the plot.
477 */
478 skgpu::AtlasToken lastUploadToken() const { return fLastUpload; }
479 skgpu::AtlasToken lastUseToken() const { return fLastUse; }
480 void setLastUploadToken(skgpu::AtlasToken token) { fLastUpload = token; }
481 void setLastUseToken(skgpu::AtlasToken token) { fLastUse = token; }
482
483 int flushesSinceLastUsed() { return fFlushesSinceLastUse; }
484 void resetFlushesSinceLastUsed() { fFlushesSinceLastUse = 0; }
485 void incFlushesSinceLastUsed() { fFlushesSinceLastUse++; }
486
487 bool needsUpload() { return !fDirtyRect.isEmpty(); }
488 std::pair<const void*, SkIRect> prepareForUpload();
489 void resetRects();
490
491 /**
492 * Create a clone of this plot. The cloned plot will take the place of the current plot in
493 * the atlas
494 */
496 return sk_sp<Plot>(new Plot(
497 fPageIndex, fPlotIndex, fGenerationCounter, fX, fY, fWidth, fHeight, fColorType,
498 fBytesPerPixel));
499 }
500
501#ifdef SK_DEBUG
502 void resetListPtrs() {
503 fPrev = fNext = nullptr;
504 fList = nullptr;
505 }
506#endif
507
508private:
509 ~Plot() override;
510
511 skgpu::AtlasToken fLastUpload;
512 skgpu::AtlasToken fLastUse;
513 int fFlushesSinceLastUse;
514
515 struct {
516 const uint32_t fPageIndex : 16;
517 const uint32_t fPlotIndex : 16;
518 };
519 AtlasGenerationCounter* const fGenerationCounter;
520 uint64_t fGenID;
521 PlotLocator fPlotLocator;
522 unsigned char* fData;
523 const int fWidth;
524 const int fHeight;
525 const int fX;
526 const int fY;
527 skgpu::RectanizerSkyline fRectanizer;
528 const SkIPoint16 fOffset; // the offset of the plot in the backing texture
529 const SkColorType fColorType;
530 const size_t fBytesPerPixel;
531 SkIRect fDirtyRect; // area in the Plot that needs to be uploaded
532 SkDEBUGCODE(bool fDirty;)
533};
534
536
537} // namespace skgpu
538
539#endif // skgpu_AtlasTypes_DEFINED
Instance * fNext
#define SkUNREACHABLE
Definition SkAssert.h:135
#define SkASSERT(cond)
Definition SkAssert.h:116
SkColorType
Definition SkColorType.h:19
@ kAlpha_8_SkColorType
pixel with alpha in 8-bit byte
Definition SkColorType.h:21
@ kRGB_565_SkColorType
pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
Definition SkColorType.h:22
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition SkColorType.h:24
#define SkDEBUGCODE(...)
Definition SkDebug.h:23
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
#define SK_DECLARE_INTERNAL_LLIST_INTERFACE(ClassName)
constexpr int16_t SkToS16(S x)
Definition SkTo.h:23
static constexpr uint64_t kInvalidGeneration
Definition AtlasTypes.h:139
uint16_t height() const
Definition AtlasTypes.h:323
uint32_t plotIndex() const
Definition AtlasTypes.h:305
void updateRect(skgpu::IRect16 rect)
Definition AtlasTypes.h:345
void invalidatePlotLocator()
Definition AtlasTypes.h:298
SkIPoint topLeft() const
Definition AtlasTypes.h:309
std::array< uint16_t, 4 > getUVs() const
Definition AtlasTypes.h:294
void insetSrc(int padding)
Definition AtlasTypes.h:327
SkPoint widthHeight() const
Definition AtlasTypes.h:313
PlotLocator plotLocator() const
Definition AtlasTypes.h:301
uint16_t width() const
Definition AtlasTypes.h:319
void updatePlotLocator(PlotLocator p)
Definition AtlasTypes.h:337
uint64_t genID() const
Definition AtlasTypes.h:307
uint32_t pageIndex() const
Definition AtlasTypes.h:303
AtlasToken next() const
Definition AtlasTypes.h:185
bool operator>(const AtlasToken that) const
Definition AtlasTypes.h:168
static AtlasToken InvalidToken()
Definition AtlasTypes.h:153
bool operator>=(const AtlasToken that) const
Definition AtlasTypes.h:171
bool inInterval(const AtlasToken &start, const AtlasToken &end)
Definition AtlasTypes.h:188
AtlasToken(const AtlasToken &)=default
bool operator!=(const AtlasToken &that) const
Definition AtlasTypes.h:161
AtlasToken & operator=(const AtlasToken &)=default
bool operator<=(const AtlasToken that) const
Definition AtlasTypes.h:165
AtlasToken & operator++()
Definition AtlasTypes.h:175
bool operator<(const AtlasToken that) const
Definition AtlasTypes.h:162
AtlasToken operator++(int)
Definition AtlasTypes.h:179
bool operator==(const AtlasToken &that) const
Definition AtlasTypes.h:158
const PlotData & plotData(int index) const
Definition AtlasTypes.h:410
bool add(const skgpu::AtlasLocator &atlasLocator)
Definition AtlasTypes.h:387
BulkUsePlotUpdater(const BulkUsePlotUpdater &that)
Definition AtlasTypes.h:382
virtual void evict(PlotLocator)=0
virtual ~PlotEvictionCallback()=default
static constexpr auto kMaxMultitexturePages
Definition AtlasTypes.h:245
bool operator==(const PlotLocator &other) const
Definition AtlasTypes.h:273
uint64_t genID() const
Definition AtlasTypes.h:280
uint32_t plotIndex() const
Definition AtlasTypes.h:279
PlotLocator(uint32_t pageIdx, uint32_t plotIdx, uint64_t generation)
Definition AtlasTypes.h:248
static constexpr int kMaxPlots
Definition AtlasTypes.h:246
bool isValid() const
Definition AtlasTypes.h:262
uint32_t pageIndex() const
Definition AtlasTypes.h:278
bool addSubImage(int width, int height, const void *image, AtlasLocator *atlasLocator)
~Plot() override
int flushesSinceLastUsed()
Definition AtlasTypes.h:483
void incFlushesSinceLastUsed()
Definition AtlasTypes.h:485
int AtlasLocator * atlasLocator
Definition AtlasTypes.h:462
skgpu::AtlasToken lastUseToken() const
Definition AtlasTypes.h:479
bool needsUpload()
Definition AtlasTypes.h:487
SkDEBUGCODE(size_t bpp() const { return fBytesPerPixel;}) bool addRect(int width
SkIPoint prepForRender(const AtlasLocator &, SkAutoPixmapStorage *)
const uint32_t fPageIndex
Definition AtlasTypes.h:516
void * dataAt(const AtlasLocator &atlasLocator)
PlotLocator plotLocator() const
Definition AtlasTypes.h:451
uint64_t genID() const
Definition AtlasTypes.h:450
std::pair< const void *, SkIRect > prepareForUpload()
skgpu::AtlasToken lastUploadToken() const
Definition AtlasTypes.h:478
void resetRects()
void setLastUseToken(skgpu::AtlasToken token)
Definition AtlasTypes.h:481
void setLastUploadToken(skgpu::AtlasToken token)
Definition AtlasTypes.h:480
void resetFlushesSinceLastUsed()
Definition AtlasTypes.h:484
uint32_t pageIndex() const
Definition AtlasTypes.h:442
sk_sp< Plot > clone() const
Definition AtlasTypes.h:495
void copySubImage(const AtlasLocator &atlasLocator, const void *image)
const uint32_t fPlotIndex
Definition AtlasTypes.h:517
uint32_t plotIndex() const
Definition AtlasTypes.h:445
AtlasToken nextFlushToken() const
Definition AtlasTypes.h:207
AtlasToken nextDrawToken() const
Definition AtlasTypes.h:214
sk_sp< SkImage > image
Definition examples.cpp:29
glong glong end
uint32_t uint32_t * format
double y
double x
constexpr int MaskFormatBytesPerPixel(MaskFormat format)
Definition AtlasTypes.h:110
static constexpr SkColorType MaskFormatToColorType(MaskFormat format)
Definition AtlasTypes.h:122
SkTInternalLList< Plot > PlotList
Definition AtlasTypes.h:535
static const int kMaskFormatCount
Definition AtlasTypes.h:105
@ kA565
2-bytes per pixel, RGB represent 3-channel LCD coverage
@ kA8
1-byte per pixel
@ kARGB
4-bytes per pixel, color format
SkScalar w
SkScalar h
int32_t width
int32_t fBottom
larger y-axis bounds
Definition SkRect.h:36
int32_t fTop
smaller y-axis bounds
Definition SkRect.h:34
bool isEmpty() const
Definition SkRect.h:202
int32_t fLeft
smaller x-axis bounds
Definition SkRect.h:33
int32_t fRight
larger x-axis bounds
Definition SkRect.h:35
static constexpr SkPoint Make(float x, float y)
PlotData(int pageIdx, int plotIdx)
Definition AtlasTypes.h:403
void offset(int16_t dx, int16_t dy)
Definition AtlasTypes.h:87
static IRect16 MakeEmpty()
Definition AtlasTypes.h:42
static IRect16 Make(const SkIRect &ir)
Definition AtlasTypes.h:60
int16_t fLeft
Definition AtlasTypes.h:40
void set(int16_t left, int16_t top, int16_t right, int16_t bottom)
Definition AtlasTypes.h:73
static IRect16 MakeWH(int16_t w, int16_t h)
Definition AtlasTypes.h:48
int16_t fRight
Definition AtlasTypes.h:40
void setEmpty()
Definition AtlasTypes.h:71
bool isEmpty() const
Definition AtlasTypes.h:69
int area() const
Definition AtlasTypes.h:68
int height() const
Definition AtlasTypes.h:67
int16_t fBottom
Definition AtlasTypes.h:40
int width() const
Definition AtlasTypes.h:66
static IRect16 MakeXYWH(int16_t x, int16_t y, int16_t w, int16_t h)
Definition AtlasTypes.h:54
void set(const SkIRect &r)
Definition AtlasTypes.h:80