Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
AtlasTypes.cpp
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
9
15
16namespace skgpu {
17
18Plot::Plot(int pageIndex, int plotIndex, AtlasGenerationCounter* generationCounter,
19 int offX, int offY, int width, int height, SkColorType colorType, size_t bpp)
20 : fLastUpload(AtlasToken::InvalidToken())
21 , fLastUse(AtlasToken::InvalidToken())
22 , fFlushesSinceLastUse(0)
23 , fPageIndex(pageIndex)
24 , fPlotIndex(plotIndex)
25 , fGenerationCounter(generationCounter)
26 , fGenID(fGenerationCounter->next())
27 , fPlotLocator(fPageIndex, fPlotIndex, fGenID)
28 , fData(nullptr)
29 , fWidth(width)
30 , fHeight(height)
31 , fX(offX)
32 , fY(offY)
33 , fRectanizer(width, height)
34 , fOffset(SkIPoint16::Make(fX * fWidth, fY * fHeight))
36 , fBytesPerPixel(bpp)
37#ifdef SK_DEBUG
38 , fDirty(false)
39#endif
40{
41 // We expect the allocated dimensions to be a multiple of 4 bytes
42 SkASSERT(((width*fBytesPerPixel) & 0x3) == 0);
43 // The padding for faster uploads only works for 1, 2 and 4 byte texels
44 SkASSERT(fBytesPerPixel != 3 && fBytesPerPixel <= 4);
45 fDirtyRect.setEmpty();
46}
47
49 sk_free(fData);
50}
51
52bool Plot::addRect(int width, int height, AtlasLocator* atlasLocator) {
53 SkASSERT(width <= fWidth && height <= fHeight);
54
55 SkIPoint16 loc;
56 if (!fRectanizer.addRect(width, height, &loc)) {
57 return false;
58 }
59
60 auto rect = skgpu::IRect16::MakeXYWH(loc.fX, loc.fY, width, height);
61 fDirtyRect.join({rect.fLeft, rect.fTop, rect.fRight, rect.fBottom});
62
63 rect.offset(fOffset.fX, fOffset.fY);
65 SkDEBUGCODE(fDirty = true;)
66
67 return true;
68}
69
70void* Plot::dataAt(const AtlasLocator& atlasLocator) {
71 if (!fData) {
72 fData = reinterpret_cast<unsigned char*>(
73 sk_calloc_throw(fBytesPerPixel * fWidth * fHeight));
74 }
75 // point ourselves at the right starting spot
76 unsigned char* dataPtr = fData;
77 SkIPoint topLeft = atlasLocator.topLeft();
78 // Assert if we're not accessing the correct Plot
79 SkASSERT(topLeft.fX >= fOffset.fX && topLeft.fX < fOffset.fX + fWidth &&
80 topLeft.fY >= fOffset.fY && topLeft.fY < fOffset.fY + fHeight);
81 topLeft -= SkIPoint::Make(fOffset.fX, fOffset.fY);
82 dataPtr += fBytesPerPixel * fWidth * topLeft.fY;
83 dataPtr += fBytesPerPixel * topLeft.fX;
84
85 return dataPtr;
86}
87
89 if (!fData) {
90 fData = reinterpret_cast<unsigned char*>(
91 sk_calloc_throw(fBytesPerPixel * fWidth * fHeight));
92 }
93 pixmap->reset(SkImageInfo::Make(fWidth, fHeight, fColorType, kOpaque_SkAlphaType),
94 fData, fBytesPerPixel * fWidth);
95 return al.topLeft() - SkIPoint::Make(fOffset.fX, fOffset.fY);
96}
97
98void Plot::copySubImage(const AtlasLocator& al, const void* image) {
99 const unsigned char* imagePtr = (const unsigned char*)image;
100 unsigned char* dataPtr = (unsigned char*)this->dataAt(al);
101 int width = al.width();
102 int height = al.height();
103 size_t rowBytes = width * fBytesPerPixel;
104
105 // copy into the data buffer, swizzling as we go if this is ARGB data
106 constexpr bool kBGRAIsNative = kN32_SkColorType == kBGRA_8888_SkColorType;
107 if (4 == fBytesPerPixel && kBGRAIsNative) {
108 for (int i = 0; i < height; ++i) {
109 SkOpts::RGBA_to_BGRA((uint32_t*)dataPtr, (const uint32_t*)imagePtr, width);
110 dataPtr += fBytesPerPixel * fWidth;
111 imagePtr += rowBytes;
112 }
113 } else {
114 for (int i = 0; i < height; ++i) {
115 memcpy(dataPtr, imagePtr, rowBytes);
116 dataPtr += fBytesPerPixel * fWidth;
117 imagePtr += rowBytes;
118 }
119 }
120}
121
122bool Plot::addSubImage(int width, int height, const void* image, AtlasLocator* atlasLocator) {
123 if (!this->addRect(width, height, atlasLocator)) {
124 return false;
125 }
126 this->copySubImage(*atlasLocator, image);
127
128 return true;
129}
130
131std::pair<const void*, SkIRect> Plot::prepareForUpload() {
132 // We should only be issuing uploads if we are dirty
133 SkASSERT(fDirty);
134 if (!fData) {
135 return {nullptr, {}};
136 }
137 size_t rowBytes = fBytesPerPixel * fWidth;
138 const unsigned char* dataPtr;
139 SkIRect offsetRect;
140 // Clamp to 4-byte aligned boundaries
141 unsigned int clearBits = 0x3 / fBytesPerPixel;
142 fDirtyRect.fLeft &= ~clearBits;
143 fDirtyRect.fRight += clearBits;
144 fDirtyRect.fRight &= ~clearBits;
145 SkASSERT(fDirtyRect.fRight <= fWidth);
146 // Set up dataPtr
147 dataPtr = fData;
148 dataPtr += rowBytes * fDirtyRect.fTop;
149 dataPtr += fBytesPerPixel * fDirtyRect.fLeft;
150 offsetRect = fDirtyRect.makeOffset(fOffset.fX, fOffset.fY);
151
152 fDirtyRect.setEmpty();
153 SkDEBUGCODE(fDirty = false);
154
155 return { dataPtr, offsetRect };
156}
157
159 fRectanizer.reset();
160 fGenID = fGenerationCounter->next();
161 fPlotLocator = PlotLocator(fPageIndex, fPlotIndex, fGenID);
162 fLastUpload = AtlasToken::InvalidToken();
163 fLastUse = AtlasToken::InvalidToken();
164
165 // zero out the plot
166 if (fData) {
167 sk_bzero(fData, fBytesPerPixel * fWidth * fHeight);
168 }
169
170 fDirtyRect.setEmpty();
171 SkDEBUGCODE(fDirty = false;)
172}
173
174} // namespace skgpu
static float next(float f)
SkColorType fColorType
@ kOpaque_SkAlphaType
pixel is opaque
Definition SkAlphaType.h:28
#define SkASSERT(cond)
Definition SkAssert.h:116
SkColorType
Definition SkColorType.h:19
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
Definition SkColorType.h:26
#define SkDEBUGCODE(...)
Definition SkDebug.h:23
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
static std::unique_ptr< SkEncoder > Make(SkWStream *dst, const SkPixmap *src, const SkYUVAPixmaps *srcYUVA, const SkColorSpace *srcYUVAColorSpace, const SkJpegEncoder::Options &options)
#define SK_DEBUG
static void * sk_calloc_throw(size_t size)
Definition SkMalloc.h:71
static void sk_bzero(void *buffer, size_t size)
Definition SkMalloc.h:105
SK_API void sk_free(void *)
uint16_t height() const
Definition AtlasTypes.h:323
void updateRect(skgpu::IRect16 rect)
Definition AtlasTypes.h:345
SkIPoint topLeft() const
Definition AtlasTypes.h:309
uint16_t width() const
Definition AtlasTypes.h:319
static AtlasToken InvalidToken()
Definition AtlasTypes.h:153
Plot(int pageIndex, int plotIndex, AtlasGenerationCounter *generationCounter, int offX, int offY, int width, int height, SkColorType colorType, size_t bpp)
bool addSubImage(int width, int height, const void *image, AtlasLocator *atlasLocator)
~Plot() override
int AtlasLocator * atlasLocator
Definition AtlasTypes.h:462
SkIPoint prepForRender(const AtlasLocator &, SkAutoPixmapStorage *)
const uint32_t fPageIndex
Definition AtlasTypes.h:516
void * dataAt(const AtlasLocator &atlasLocator)
std::pair< const void *, SkIRect > prepareForUpload()
void resetRects()
void copySubImage(const AtlasLocator &atlasLocator, const void *image)
const uint32_t fPlotIndex
Definition AtlasTypes.h:517
bool addRect(int w, int h, SkIPoint16 *loc) final
sk_sp< SkImage > image
Definition examples.cpp:29
Swizzle_8888_u32 RGBA_to_BGRA
sk_sp< SkBlender > blender SkRect rect
Definition SkRecords.h:350
int32_t height
int32_t width
int16_t fY
y-axis value used by SkIPoint16
Definition SkIPoint16.h:20
int16_t fX
x-axis value used by SkIPoint16
Definition SkIPoint16.h:18
int32_t fX
x-axis value
int32_t fY
y-axis value
static constexpr SkIPoint Make(int32_t x, int32_t y)
int32_t fTop
smaller y-axis bounds
Definition SkRect.h:34
void join(const SkIRect &r)
Definition SkRect.cpp:31
void setEmpty()
Definition SkRect.h:242
constexpr SkIRect makeOffset(int32_t dx, int32_t dy) const
Definition SkRect.h:300
int32_t fLeft
smaller x-axis bounds
Definition SkRect.h:33
int32_t fRight
larger x-axis bounds
Definition SkRect.h:35
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
static IRect16 MakeXYWH(int16_t x, int16_t y, int16_t w, int16_t h)
Definition AtlasTypes.h:54