change paint serialization to exclude font-related fields
This is slightly preemptive, since paint still has getters/setters for these fields, but skia no longer looks at them, so... Reduces serial size by 20-bytes + size of a typeface Bug: skia:2664 Change-Id: If1997c823db5b3d83b04cb7e1bc1d6787795b70a Reviewed-on: https://skia-review.googlesource.com/c/181174 Commit-Queue: Mike Reed <reed@google.com> Reviewed-by: Florin Malita <fmalita@chromium.org>
This commit is contained in:
parent
dde2a376f7
commit
74b767777c
@ -266,10 +266,11 @@ private:
|
||||
// V65: Float4 paint color
|
||||
// V66: Add saveBehind
|
||||
// V67: Blobs serialize fonts instead of paints
|
||||
// V68: Paint doesn't serialize font-related stuff
|
||||
|
||||
// Only SKPs within the min/current picture version range (inclusive) can be read.
|
||||
static const uint32_t MIN_PICTURE_VERSION = 56; // august 2017
|
||||
static const uint32_t CURRENT_PICTURE_VERSION = 67;
|
||||
static const uint32_t CURRENT_PICTURE_VERSION = 68;
|
||||
|
||||
static_assert(MIN_PICTURE_VERSION <= 62, "Remove kFontAxes_bad from SkFontDescriptor.cpp");
|
||||
|
||||
|
@ -357,14 +357,6 @@ static uintptr_t asint(const void* p) {
|
||||
return reinterpret_cast<uintptr_t>(p);
|
||||
}
|
||||
|
||||
static uint32_t pack_4(unsigned a, unsigned b, unsigned c, unsigned d) {
|
||||
SkASSERT(a == (uint8_t)a);
|
||||
SkASSERT(b == (uint8_t)b);
|
||||
SkASSERT(c == (uint8_t)c);
|
||||
SkASSERT(d == (uint8_t)d);
|
||||
return (a << 24) | (b << 16) | (c << 8) | d;
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
static void ASSERT_FITS_IN(uint32_t value, int bitCount) {
|
||||
SkASSERT(bitCount > 0 && bitCount <= 32);
|
||||
@ -394,20 +386,6 @@ static inline int BPF_Mask(int bits) {
|
||||
return (1 << bits) - 1;
|
||||
}
|
||||
|
||||
static uint32_t pack_paint_flags(unsigned flags, unsigned hint, unsigned filter,
|
||||
unsigned flatFlags) {
|
||||
ASSERT_FITS_IN(flags, kFlags_BPF);
|
||||
ASSERT_FITS_IN(hint, kHint_BPF);
|
||||
ASSERT_FITS_IN(filter, kFilter_BPF);
|
||||
ASSERT_FITS_IN(flatFlags, kFlatFlags_BPF);
|
||||
|
||||
unsigned was_align = 0; // used to be textalign [0..2]
|
||||
|
||||
// left-align the fields of "known" size, and right-align the last (flatFlags) so it can easly
|
||||
// add more bits in the future.
|
||||
return (flags << 16) | (hint << 14) | (was_align << 12) | (filter << 10) | flatFlags;
|
||||
}
|
||||
|
||||
static FlatFlags unpack_paint_flags(SkPaint* paint, uint32_t packed) {
|
||||
paint->setFlags(packed >> 16);
|
||||
paint->setHinting((SkFontHinting)((packed >> 14) & BPF_Mask(kHint_BPF)));
|
||||
@ -415,16 +393,58 @@ static FlatFlags unpack_paint_flags(SkPaint* paint, uint32_t packed) {
|
||||
return (FlatFlags)(packed & kFlatFlagMask);
|
||||
}
|
||||
|
||||
template <typename T> uint32_t shift_bits(T value, unsigned shift, unsigned bits) {
|
||||
SkASSERT(shift + bits <= 32);
|
||||
uint32_t v = static_cast<uint32_t>(value);
|
||||
ASSERT_FITS_IN(v, bits);
|
||||
return v << shift;
|
||||
}
|
||||
|
||||
/* Packing the paint
|
||||
flags : 8 // 2...
|
||||
blend : 8 // 30+
|
||||
cap : 2 // 3
|
||||
join : 2 // 3
|
||||
style : 2 // 3
|
||||
filter: 2 // 4
|
||||
flat : 8 // 1...
|
||||
total : 32
|
||||
*/
|
||||
static uint32_t pack_v68(const SkPaint& paint, unsigned flatFlags) {
|
||||
uint32_t packed = 0;
|
||||
packed |= shift_bits(((unsigned)paint.isDither() << 1) |
|
||||
(unsigned)paint.isAntiAlias(), 0, 8);
|
||||
packed |= shift_bits(paint.getBlendMode(), 8, 8);
|
||||
packed |= shift_bits(paint.getStrokeCap(), 16, 2);
|
||||
packed |= shift_bits(paint.getStrokeJoin(), 18, 2);
|
||||
packed |= shift_bits(paint.getStyle(), 20, 2);
|
||||
packed |= shift_bits(paint.getFilterQuality(), 22, 2);
|
||||
packed |= shift_bits(flatFlags, 24, 8);
|
||||
return packed;
|
||||
}
|
||||
|
||||
static uint32_t unpack_v68(SkPaint* paint, uint32_t packed, SkSafeRange& safe) {
|
||||
paint->setAntiAlias((packed & 1) != 0);
|
||||
paint->setDither((packed & 2) != 0);
|
||||
packed >>= 8;
|
||||
paint->setBlendMode(safe.checkLE(packed & 0xFF, SkBlendMode::kLastMode));
|
||||
packed >>= 8;
|
||||
paint->setStrokeCap(safe.checkLE(packed & 0x3, SkPaint::kLast_Cap));
|
||||
packed >>= 2;
|
||||
paint->setStrokeJoin(safe.checkLE(packed & 0x3, SkPaint::kLast_Join));
|
||||
packed >>= 2;
|
||||
paint->setStyle(safe.checkLE(packed & 0x3, SkPaint::kStrokeAndFill_Style));
|
||||
packed >>= 2;
|
||||
paint->setFilterQuality(safe.checkLE(packed & 0x3, kLast_SkFilterQuality));
|
||||
packed >>= 2;
|
||||
return packed;
|
||||
}
|
||||
|
||||
/* To save space/time, we analyze the paint, and write a truncated version of
|
||||
it if there are not tricky elements like shaders, etc.
|
||||
*/
|
||||
void SkPaintPriv::Flatten(const SkPaint& paint, SkWriteBuffer& buffer) {
|
||||
// We force recording our typeface, even if its "default" since the receiver process
|
||||
// may have a different notion of default.
|
||||
SkTypeface* tf = SkPaintPriv::GetTypefaceOrDefault(paint);
|
||||
SkASSERT(tf);
|
||||
|
||||
uint8_t flatFlags = kHasTypeface_FlatFlag;
|
||||
uint8_t flatFlags = 0;
|
||||
|
||||
if (asint(paint.getPathEffect()) |
|
||||
asint(paint.getShader()) |
|
||||
@ -435,33 +455,23 @@ void SkPaintPriv::Flatten(const SkPaint& paint, SkWriteBuffer& buffer) {
|
||||
flatFlags |= kHasEffects_FlatFlag;
|
||||
}
|
||||
|
||||
buffer.writeScalar(paint.getTextSize());
|
||||
buffer.writeScalar(paint.getTextScaleX());
|
||||
buffer.writeScalar(paint.getTextSkewX());
|
||||
buffer.writeScalar(paint.getStrokeWidth());
|
||||
buffer.writeScalar(paint.getStrokeMiter());
|
||||
buffer.writeColor4f(paint.getColor4f());
|
||||
|
||||
buffer.writeUInt(pack_paint_flags(paint.getFlags(), static_cast<unsigned>(paint.getHinting()),
|
||||
paint.getFilterQuality(), flatFlags));
|
||||
buffer.writeUInt(pack_4(paint.getStrokeCap(), paint.getStrokeJoin(),
|
||||
(paint.getStyle() << 4) | (unsigned)paint.getTextEncoding(),
|
||||
paint.fBlendMode));
|
||||
|
||||
buffer.writeTypeface(tf);
|
||||
buffer.write32(pack_v68(paint, flatFlags));
|
||||
|
||||
if (flatFlags & kHasEffects_FlatFlag) {
|
||||
buffer.writeFlattenable(paint.getPathEffect());
|
||||
buffer.writeFlattenable(paint.getShader());
|
||||
buffer.writeFlattenable(paint.getMaskFilter());
|
||||
buffer.writeFlattenable(paint.getColorFilter());
|
||||
buffer.write32(0); // use to be SkRasterizer
|
||||
buffer.writeFlattenable(paint.getLooper());
|
||||
buffer.writeFlattenable(paint.getImageFilter());
|
||||
}
|
||||
}
|
||||
|
||||
bool SkPaintPriv::Unflatten(SkPaint* paint, SkReadBuffer& buffer) {
|
||||
bool SkPaintPriv::Unflatten_PreV68(SkPaint* paint, SkReadBuffer& buffer) {
|
||||
SkSafeRange safe;
|
||||
|
||||
paint->setTextSize(buffer.readScalar());
|
||||
@ -516,6 +526,46 @@ bool SkPaintPriv::Unflatten(SkPaint* paint, SkReadBuffer& buffer) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SkPaintPriv::Unflatten(SkPaint* paint, SkReadBuffer& buffer) {
|
||||
if (buffer.isVersionLT(SkReadBuffer::kPaintDoesntSerializeFonts_Version)) {
|
||||
return Unflatten_PreV68(paint, buffer);
|
||||
}
|
||||
|
||||
SkSafeRange safe;
|
||||
|
||||
paint->setStrokeWidth(buffer.readScalar());
|
||||
paint->setStrokeMiter(buffer.readScalar());
|
||||
{
|
||||
SkColor4f color;
|
||||
buffer.readColor4f(&color);
|
||||
paint->setColor4f(color, sk_srgb_singleton());
|
||||
}
|
||||
|
||||
unsigned flatFlags = unpack_v68(paint, buffer.readUInt(), safe);
|
||||
|
||||
if (flatFlags & kHasEffects_FlatFlag) {
|
||||
paint->setPathEffect(buffer.readPathEffect());
|
||||
paint->setShader(buffer.readShader());
|
||||
paint->setMaskFilter(buffer.readMaskFilter());
|
||||
paint->setColorFilter(buffer.readColorFilter());
|
||||
paint->setLooper(buffer.readDrawLooper());
|
||||
paint->setImageFilter(buffer.readImageFilter());
|
||||
} else {
|
||||
paint->setPathEffect(nullptr);
|
||||
paint->setShader(nullptr);
|
||||
paint->setMaskFilter(nullptr);
|
||||
paint->setColorFilter(nullptr);
|
||||
paint->setLooper(nullptr);
|
||||
paint->setImageFilter(nullptr);
|
||||
}
|
||||
|
||||
if (!buffer.validate(safe)) {
|
||||
paint->reset();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool SkPaint::getFillPath(const SkPath& src, SkPath* dst, const SkRect* cullRect,
|
||||
|
@ -97,6 +97,8 @@ public:
|
||||
*/
|
||||
static bool Unflatten(SkPaint* paint, SkReadBuffer& buffer);
|
||||
|
||||
private:
|
||||
static bool Unflatten_PreV68(SkPaint* paint, SkReadBuffer& buffer);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -45,6 +45,7 @@ public:
|
||||
kFloat4PaintColor_Version = 65,
|
||||
kSaveBehind_Version = 66,
|
||||
kSerializeFonts_Version = 67,
|
||||
kPaintDoesntSerializeFonts_Version = 68,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -249,6 +250,7 @@ public:
|
||||
kFloat4PaintColor_Version = 65,
|
||||
kSaveBehind_Version = 66,
|
||||
kSerializeFonts_Version = 67,
|
||||
kPaintDoesntSerializeFonts_Version = 68,
|
||||
};
|
||||
|
||||
bool isVersionLT(Version) const { return false; }
|
||||
|
@ -202,12 +202,6 @@ DEF_TEST(Paint_flattening, reporter) {
|
||||
kMedium_SkFilterQuality,
|
||||
kHigh_SkFilterQuality,
|
||||
};
|
||||
const SkFontHinting hinting[] = {
|
||||
kNo_SkFontHinting,
|
||||
kSlight_SkFontHinting,
|
||||
kNormal_SkFontHinting,
|
||||
kFull_SkFontHinting,
|
||||
};
|
||||
const SkPaint::Cap caps[] = {
|
||||
SkPaint::kButt_Cap,
|
||||
SkPaint::kRound_Cap,
|
||||
@ -218,12 +212,6 @@ DEF_TEST(Paint_flattening, reporter) {
|
||||
SkPaint::kRound_Join,
|
||||
SkPaint::kBevel_Join,
|
||||
};
|
||||
const SkTextEncoding encodings[] = {
|
||||
kUTF8_SkTextEncoding,
|
||||
kUTF16_SkTextEncoding,
|
||||
kUTF32_SkTextEncoding,
|
||||
kGlyphID_SkTextEncoding,
|
||||
};
|
||||
const SkPaint::Style styles[] = {
|
||||
SkPaint::kFill_Style,
|
||||
SkPaint::kStroke_Style,
|
||||
@ -232,16 +220,16 @@ DEF_TEST(Paint_flattening, reporter) {
|
||||
|
||||
#define FOR_SETUP(index, array, setter) \
|
||||
for (size_t index = 0; index < SK_ARRAY_COUNT(array); ++index) { \
|
||||
paint.setter(array[index]); \
|
||||
paint.setter(array[index]);
|
||||
|
||||
SkPaint paint;
|
||||
paint.setFlags(0x1234);
|
||||
paint.setAntiAlias(true);
|
||||
|
||||
// we don't serialize hinting or encoding -- soon to be removed from paint
|
||||
|
||||
FOR_SETUP(i, levels, setFilterQuality)
|
||||
FOR_SETUP(j, hinting, setHinting)
|
||||
FOR_SETUP(l, caps, setStrokeCap)
|
||||
FOR_SETUP(m, joins, setStrokeJoin)
|
||||
FOR_SETUP(n, encodings, setTextEncoding)
|
||||
FOR_SETUP(p, styles, setStyle)
|
||||
|
||||
SkBinaryWriteBuffer writer;
|
||||
@ -255,7 +243,7 @@ DEF_TEST(Paint_flattening, reporter) {
|
||||
SkPaintPriv::Unflatten(&paint2, reader);
|
||||
REPORTER_ASSERT(reporter, paint2 == paint);
|
||||
|
||||
}}}}}}
|
||||
}}}}
|
||||
#undef FOR_SETUP
|
||||
|
||||
}
|
||||
@ -297,8 +285,6 @@ DEF_TEST(Paint_MoreFlattening, r) {
|
||||
|
||||
// No matter the encoding, these must always hold.
|
||||
ASSERT(other.getColor() == paint.getColor());
|
||||
ASSERT(other.getTextScaleX() == paint.getTextScaleX());
|
||||
ASSERT(other.getTextSize() == paint.getTextSize());
|
||||
ASSERT(other.getLooper() == paint.getLooper());
|
||||
ASSERT(other.getBlendMode() == paint.getBlendMode());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user