Flutter Engine
The Flutter Engine
Classes | Functions | Variables
SkCompressedDataUtils.cpp File Reference
#include "src/core/SkCompressedDataUtils.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorPriv.h"
#include "include/core/SkData.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/private/SkColorData.h"
#include "include/private/base/SkTPin.h"
#include "include/private/base/SkTo.h"
#include "src/base/SkMathPriv.h"
#include "src/core/SkMipmap.h"
#include <algorithm>
#include <cstdint>

Go to the source code of this file.

Classes

struct  ETC1Block
 
struct  IColor
 
struct  BC1Block
 

Functions

static int extend_4To8bits (int b)
 
static int extend_5To8bits (int b)
 
static int extend_5plus3To8Bits (int base, int diff)
 
static int num_4x4_blocks (int size)
 
static int xy_to_subblock_index (int x, int y, bool flip)
 
static SkPMColor add_delta_and_clamp (const IColor &col, int delta)
 
static bool decompress_etc1 (SkISize dimensions, const uint8_t *srcData, SkBitmap *dst)
 
static SkPMColor from565 (uint16_t rgb565)
 
static SkPMColor lerp (float t, SkPMColor col0, SkPMColor col1)
 
static bool decompress_bc1 (SkISize dimensions, const uint8_t *srcData, bool isOpaque, SkBitmap *dst)
 
bool SkDecompress (sk_sp< SkData > data, SkISize dimensions, SkTextureCompressionType compressionType, SkBitmap *dst)
 
size_t SkCompressedDataSize (SkTextureCompressionType type, SkISize dimensions, TArray< size_t > *individualMipOffsets, bool mipmapped)
 
size_t SkCompressedBlockSize (SkTextureCompressionType type)
 
size_t SkCompressedFormatDataSize (SkTextureCompressionType compressionType, SkISize dimensions, bool mipmapped)
 

Variables

constexpr uint32_t kFlipBit = 0x1
 
constexpr uint32_t kDiffBit = 0x2
 
static const int kNumETC1ModifierTables = 8
 
static const int kNumETC1PixelIndices = 4
 
static const int kETC1ModifierTables [kNumETC1ModifierTables][kNumETC1PixelIndices]
 

Function Documentation

◆ add_delta_and_clamp()

static SkPMColor add_delta_and_clamp ( const IColor col,
int  delta 
)
static

Definition at line 87 of file SkCompressedDataUtils.cpp.

87 {
88 int r8 = SkTPin(col.fR + delta, 0, 255);
89 int g8 = SkTPin(col.fG + delta, 0, 255);
90 int b8 = SkTPin(col.fB + delta, 0, 255);
91
92 return SkPackARGB32(0xFF, r8, g8, b8);
93}
static SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
Definition: SkColorPriv.h:106
static constexpr const T & SkTPin(const T &x, const T &lo, const T &hi)
Definition: SkTPin.h:19

◆ decompress_bc1()

static bool decompress_bc1 ( SkISize  dimensions,
const uint8_t *  srcData,
bool  isOpaque,
SkBitmap dst 
)
static

Definition at line 189 of file SkCompressedDataUtils.cpp.

190 {
191 const BC1Block* srcBlocks = reinterpret_cast<const BC1Block*>(srcData);
192
193 int numXBlocks = num_4x4_blocks(dimensions.width());
194 int numYBlocks = num_4x4_blocks(dimensions.height());
195
196 SkPMColor colors[4];
197
198 for (int y = 0; y < numYBlocks; ++y) {
199 for (int x = 0; x < numXBlocks; ++x) {
200 const BC1Block* curBlock = &srcBlocks[y * numXBlocks + x];
201
202 colors[0] = from565(curBlock->fColor0);
203 colors[1] = from565(curBlock->fColor1);
204 if (curBlock->fColor0 <= curBlock->fColor1) { // signal for a transparent block
205 colors[2] = SkPackARGB32(
206 0xFF,
209 (SkGetPackedB32(colors[0]) + SkGetPackedB32(colors[1])) >> 1);
210 // The opacity of the overall texture trumps the per-block transparency
211 colors[3] = SkPackARGB32(isOpaque ? 0xFF : 0, 0, 0, 0);
212 } else {
213 colors[2] = lerp(2.0f/3.0f, colors[0], colors[1]);
214 colors[3] = lerp(1.0f/3.0f, colors[0], colors[1]);
215 }
216
217 int shift = 0;
218 int offsetX = 4 * x, offsetY = 4 * y;
219 for (int i = 0; i < 4; ++i) {
220 for (int j = 0; j < 4; ++j, shift += 2) {
221 if (offsetX + j >= dst->width() || offsetY + i >= dst->height()) {
222 // This can happen for the topmost levels of a mipmap and for
223 // non-multiple of 4 textures
224 continue;
225 }
226
227 int index = (curBlock->fIndices >> shift) & 0x3;
228 *dst->getAddr32(offsetX + j, offsetY + i) = colors[index];
229 }
230 }
231 }
232 }
233
234 return true;
235}
#define SkGetPackedB32(packed)
Definition: SkColorPriv.h:95
#define SkGetPackedR32(packed)
Definition: SkColorPriv.h:93
#define SkGetPackedG32(packed)
Definition: SkColorPriv.h:94
uint32_t SkPMColor
Definition: SkColor.h:205
static SkPMColor lerp(float t, SkPMColor col0, SkPMColor col1)
static int num_4x4_blocks(int size)
static SkPMColor from565(uint16_t rgb565)
double y
double x
PODArray< SkColor > colors
Definition: SkRecords.h:276
dst
Definition: cp.py:12
SkScalar offsetX
SkScalar offsetY
uint16_t fColor0
uint32_t fIndices
uint16_t fColor1
constexpr int32_t width() const
Definition: SkSize.h:36
constexpr int32_t height() const
Definition: SkSize.h:37

◆ decompress_etc1()

static bool decompress_etc1 ( SkISize  dimensions,
const uint8_t *  srcData,
SkBitmap dst 
)
static

Definition at line 95 of file SkCompressedDataUtils.cpp.

95 {
96 const ETC1Block* srcBlocks = reinterpret_cast<const ETC1Block*>(srcData);
97
98 int numXBlocks = num_4x4_blocks(dimensions.width());
99 int numYBlocks = num_4x4_blocks(dimensions.height());
100
101 for (int y = 0; y < numYBlocks; ++y) {
102 for (int x = 0; x < numXBlocks; ++x) {
103 const ETC1Block* curBlock1 = &srcBlocks[y * numXBlocks + x];
104 uint32_t high = SkBSwap32(curBlock1->fHigh);
105 uint32_t low = SkBSwap32(curBlock1->fLow);
106
107 bool flipped = SkToBool(high & kFlipBit);
108 bool differential = SkToBool(high & kDiffBit);
109
110 IColor colors[2];
111
112 if (differential) {
113 colors[0].fR = extend_5To8bits(high >> 27);
114 colors[1].fR = extend_5plus3To8Bits(high >> 27, high >> 24);
115 colors[0].fG = extend_5To8bits(high >> 19);
116 colors[1].fG = extend_5plus3To8Bits(high >> 19, high >> 16);
117 colors[0].fB = extend_5To8bits(high >> 11);
118 colors[1].fB = extend_5plus3To8Bits(high >> 11, high >> 8);
119 } else {
120 colors[0].fR = extend_4To8bits(high >> 28);
121 colors[1].fR = extend_4To8bits(high >> 24);
122 colors[0].fG = extend_4To8bits(high >> 20);
123 colors[1].fG = extend_4To8bits(high >> 16);
124 colors[0].fB = extend_4To8bits(high >> 12);
125 colors[1].fB = extend_4To8bits(high >> 8);
126 }
127
128 int tableIndex0 = (high >> 5) & 0x7;
129 int tableIndex1 = (high >> 2) & 0x7;
130 const int* tables[2] = {
131 kETC1ModifierTables[tableIndex0],
132 kETC1ModifierTables[tableIndex1]
133 };
134
135 int baseShift = 0;
136 int offsetX = 4 * x, offsetY = 4 * y;
137 for (int i = 0; i < 4; ++i, ++baseShift) {
138 for (int j = 0; j < 4; ++j) {
139 if (offsetX + j >= dst->width() || offsetY + i >= dst->height()) {
140 // This can happen for the topmost levels of a mipmap and for
141 // non-multiple of 4 textures
142 continue;
143 }
144
145 int subBlockIndex = xy_to_subblock_index(j, i, flipped);
146 int pixelIndex = ((low >> (baseShift+(j*4))) & 0x1) |
147 (low >> (baseShift+(j*4)+15) & 0x2);
148
149 SkASSERT(subBlockIndex == 0 || subBlockIndex == 1);
150 SkASSERT(pixelIndex >= 0 && pixelIndex < 4);
151
152 int delta = tables[subBlockIndex][pixelIndex];
153 *dst->getAddr32(offsetX + j, offsetY + i) =
154 add_delta_and_clamp(colors[subBlockIndex], delta);
155 }
156 }
157 }
158 }
159
160 return true;
161}
#define SkASSERT(cond)
Definition: SkAssert.h:116
static int extend_5To8bits(int b)
static int xy_to_subblock_index(int x, int y, bool flip)
static SkPMColor add_delta_and_clamp(const IColor &col, int delta)
constexpr uint32_t kDiffBit
static int extend_4To8bits(int b)
static const int kETC1ModifierTables[kNumETC1ModifierTables][kNumETC1PixelIndices]
static int extend_5plus3To8Bits(int base, int diff)
constexpr uint32_t kFlipBit
static uint32_t SkBSwap32(uint32_t v)
Definition: SkMathPriv.h:123
static constexpr bool SkToBool(const T &x)
Definition: SkTo.h:35

◆ extend_4To8bits()

static int extend_4To8bits ( int  b)
inlinestatic

Definition at line 35 of file SkCompressedDataUtils.cpp.

35 {
36 int c = b & 0xf;
37 return (c << 4) | c;
38}
static bool b

◆ extend_5plus3To8Bits()

static int extend_5plus3To8Bits ( int  base,
int  diff 
)
inlinestatic

Definition at line 45 of file SkCompressedDataUtils.cpp.

45 {
46 static const int kLookup[8] = { 0, 1, 2, 3, -4, -3, -2, -1 };
47
48 return extend_5To8bits((0x1f & base) + kLookup[0x7 & diff]);
49}
static const int kLookup[8]
Definition: etc1.cpp:128

◆ extend_5To8bits()

static int extend_5To8bits ( int  b)
inlinestatic

Definition at line 40 of file SkCompressedDataUtils.cpp.

40 {
41 int c = b & 0x1f;
42 return (c << 3) | (c >> 2);
43}

◆ from565()

static SkPMColor from565 ( uint16_t  rgb565)
static

Definition at line 170 of file SkCompressedDataUtils.cpp.

170 {
171 uint8_t r8 = SkR16ToR32((rgb565 >> 11) & 0x1F);
172 uint8_t g8 = SkG16ToG32((rgb565 >> 5) & 0x3F);
173 uint8_t b8 = SkB16ToB32(rgb565 & 0x1F);
174
175 return SkPackARGB32(0xFF, r8, g8, b8);
176}
static const uint16_t rgb565[kNumPixels]
static unsigned SkB16ToB32(unsigned b)
Definition: SkColorData.h:42
static unsigned SkG16ToG32(unsigned g)
Definition: SkColorData.h:38
static unsigned SkR16ToR32(unsigned r)
Definition: SkColorData.h:34

◆ lerp()

static SkPMColor lerp ( float  t,
SkPMColor  col0,
SkPMColor  col1 
)
static

Definition at line 179 of file SkCompressedDataUtils.cpp.

179 {
180 SkASSERT(SkGetPackedA32(col0) == 0xFF && SkGetPackedA32(col1) == 0xFF);
181
182 // TODO: given 't' is only either 1/3 or 2/3 this could be done faster
183 uint8_t r8 = SkScalarRoundToInt(t * SkGetPackedR32(col0) + (1.0f - t) * SkGetPackedR32(col1));
184 uint8_t g8 = SkScalarRoundToInt(t * SkGetPackedG32(col0) + (1.0f - t) * SkGetPackedG32(col1));
185 uint8_t b8 = SkScalarRoundToInt(t * SkGetPackedB32(col0) + (1.0f - t) * SkGetPackedB32(col1));
186 return SkPackARGB32(0xFF, r8, g8, b8);
187}
#define SkGetPackedA32(packed)
Definition: SkColorPriv.h:92
#define SkScalarRoundToInt(x)
Definition: SkScalar.h:37

◆ num_4x4_blocks()

static int num_4x4_blocks ( int  size)
static

Definition at line 67 of file SkCompressedDataUtils.cpp.

67 {
68 return ((size + 3) & ~3) >> 2;
69}
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

◆ SkCompressedBlockSize()

size_t SkCompressedBlockSize ( SkTextureCompressionType  type)

Definition at line 290 of file SkCompressedDataUtils.cpp.

◆ SkCompressedDataSize()

size_t SkCompressedDataSize ( SkTextureCompressionType  type,
SkISize  dimensions,
TArray< size_t > *  individualMipOffsets,
bool  mipmapped 
)

Definition at line 254 of file SkCompressedDataUtils.cpp.

255 {
256 SkASSERT(!individualMipOffsets || individualMipOffsets->empty());
257
258 int numMipLevels = 1;
259 if (mipmapped) {
260 numMipLevels = SkMipmap::ComputeLevelCount(dimensions.width(), dimensions.height()) + 1;
261 }
262
263 size_t totalSize = 0;
264 switch (type) {
266 break;
270 for (int i = 0; i < numMipLevels; ++i) {
271 int numBlocks = num_4x4_blocks(dimensions.width()) *
272 num_4x4_blocks(dimensions.height());
273
274 if (individualMipOffsets) {
275 individualMipOffsets->push_back(totalSize);
276 }
277
278 static_assert(sizeof(ETC1Block) == sizeof(BC1Block));
279 totalSize += numBlocks * sizeof(ETC1Block);
280
281 dimensions = {std::max(1, dimensions.width()/2), std::max(1, dimensions.height()/2)};
282 }
283 break;
284 }
285 }
286
287 return totalSize;
288}
static int ComputeLevelCount(int baseWidth, int baseHeight)
Definition: SkMipmap.cpp:134
bool empty() const
Definition: SkTArray.h:199
static float max(float r, float g, float b)
Definition: hsl.cpp:49

◆ SkCompressedFormatDataSize()

size_t SkCompressedFormatDataSize ( SkTextureCompressionType  compressionType,
SkISize  dimensions,
bool  mipmapped 
)

Returns the data size for the given SkTextureCompressionType

Definition at line 303 of file SkCompressedDataUtils.cpp.

304 {
305 return SkCompressedDataSize(compressionType, dimensions, nullptr, mipmapped);
306}
size_t SkCompressedDataSize(SkTextureCompressionType type, SkISize dimensions, TArray< size_t > *individualMipOffsets, bool mipmapped)

◆ SkDecompress()

bool SkDecompress ( sk_sp< SkData data,
SkISize  dimensions,
SkTextureCompressionType  compressionType,
SkBitmap dst 
)

Definition at line 237 of file SkCompressedDataUtils.cpp.

240 {
242
243 const uint8_t* bytes = data->bytes();
244 switch (compressionType) {
245 case Type::kNone: return false;
246 case Type::kETC2_RGB8_UNORM: return decompress_etc1(dimensions, bytes, dst);
247 case Type::kBC1_RGB8_UNORM: return decompress_bc1(dimensions, bytes, true, dst);
248 case Type::kBC1_RGBA8_UNORM: return decompress_bc1(dimensions, bytes, false, dst);
249 }
250
252}
static bool decompress_bc1(SkISize dimensions, const uint8_t *srcData, bool isOpaque, SkBitmap *dst)
static bool decompress_etc1(SkISize dimensions, const uint8_t *srcData, SkBitmap *dst)
SkTextureCompressionType
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63

◆ xy_to_subblock_index()

static int xy_to_subblock_index ( int  x,
int  y,
bool  flip 
)
static

Definition at line 72 of file SkCompressedDataUtils.cpp.

72 {
73 SkASSERT(x >= 0 && x < 4);
74 SkASSERT(y >= 0 && y < 4);
75
76 if (flip) {
77 return y < 2 ? 0 : 1; // sub-block 1 is on top of sub-block 2
78 } else {
79 return x < 2 ? 0 : 1; // sub-block 1 is to the left of sub-block 2
80 }
81}

Variable Documentation

◆ kDiffBit

constexpr uint32_t kDiffBit = 0x2
constexpr

Definition at line 33 of file SkCompressedDataUtils.cpp.

◆ kETC1ModifierTables

const int kETC1ModifierTables[kNumETC1ModifierTables][kNumETC1PixelIndices]
static
Initial value:
= {
{ 2, 8, -2, -8 },
{ 5, 17, -5, -17 },
{ 9, 29, -9, -29 },
{ 13, 42, -13, -42 },
{ 18, 60, -18, -60 },
{ 24, 80, -24, -80 },
{ 33, 106, -33, -106 },
{ 47, 183, -47, -183 }
}

Definition at line 56 of file SkCompressedDataUtils.cpp.

◆ kFlipBit

constexpr uint32_t kFlipBit = 0x1
constexpr

Definition at line 32 of file SkCompressedDataUtils.cpp.

◆ kNumETC1ModifierTables

const int kNumETC1ModifierTables = 8
static

Definition at line 51 of file SkCompressedDataUtils.cpp.

◆ kNumETC1PixelIndices

const int kNumETC1PixelIndices = 4
static

Definition at line 52 of file SkCompressedDataUtils.cpp.