Clean up buffering and serializatoin.

BUG=skia:7515

Change-Id: Id580e8f464c6263fa32a5d6347f505b00bba29d7
Reviewed-on: https://skia-review.googlesource.com/118460
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
Herb Derby 2018-04-03 18:44:34 -04:00 committed by Skia Commit-Bot
parent 62473ad906
commit 46117c83d2
3 changed files with 220 additions and 219 deletions

View File

@ -15,8 +15,6 @@
#include "SkFindAndPlaceGlyph.h" #include "SkFindAndPlaceGlyph.h"
#include "SkTypeface_remote.h" #include "SkTypeface_remote.h"
static const size_t kPageSize = 4096;
template <typename T> template <typename T>
class ArraySlice final : public std::tuple<const T*, size_t> { class ArraySlice final : public std::tuple<const T*, size_t> {
public: public:
@ -45,21 +43,43 @@ private:
size_t fSize; size_t fSize;
}; };
// -- SkRemoteStrikeTransport ---------------------------------------------------------------------------------- // -- SkRemoteStrikeTransport ----------------------------------------------------------------------
static SkRemoteStrikeTransport::IOResult write_data(
size_t size, const uint8_t* data, SkRemoteStrikeTransport* t) {
if (t->write(&size, sizeof(size)) == SkRemoteStrikeTransport::kFail) {
return SkRemoteStrikeTransport::kFail;
}
if (t->write(data, size) == SkRemoteStrikeTransport::kFail) {
return SkRemoteStrikeTransport::kFail;
}
return SkRemoteStrikeTransport::kSuccess;
}
static SkRemoteStrikeTransport::IOResult read_data(
size_t size, uint8_t* data, SkRemoteStrikeTransport* t) {
size_t totalRead = 0;
while (totalRead < size) {
size_t sizeRead;
SkRemoteStrikeTransport::IOResult result;
std::tie(sizeRead, result) = t->read(&data[totalRead], size - totalRead);
if (result == SkRemoteStrikeTransport::kFail || sizeRead == 0) {
return SkRemoteStrikeTransport::kFail;
}
totalRead += sizeRead;
}
return SkRemoteStrikeTransport::kSuccess;
}
SkRemoteStrikeTransport::IOResult SkRemoteStrikeTransport::writeSkData(const SkData& data) { SkRemoteStrikeTransport::IOResult SkRemoteStrikeTransport::writeSkData(const SkData& data) {
size_t size = data.size(); return write_data(data.size(), (uint8_t*)data.data(), this);
if (this->write(&size, sizeof(size)) == kFail) {
return kFail;
}
if (this->write(data.data(), size) == kFail) {
return kFail;
}
return kSuccess;
} }
sk_sp<SkData> SkRemoteStrikeTransport::readSkData() { sk_sp<SkData> SkRemoteStrikeTransport::readSkData() {
size_t size; size_t size;
if(std::get<1>(this->read(&size, sizeof(size))) == kFail) { if(std::get<1>(this->read(&size, sizeof(size))) == kFail) {
@ -67,164 +87,112 @@ sk_sp<SkData> SkRemoteStrikeTransport::readSkData() {
} }
auto data = std::unique_ptr<uint8_t[]>{new uint8_t[size]}; auto data = std::unique_ptr<uint8_t[]>{new uint8_t[size]};
size_t totalRead = 0; if (read_data(size, data.get(), this) == kFail) {
while (totalRead < size) {
size_t sizeRead;
IOResult result;
std::tie(sizeRead, result) = this->read(&data[totalRead], size - totalRead);
if (result == kFail || sizeRead == 0) {
return nullptr; return nullptr;
} }
totalRead += sizeRead;
}
return SkData::MakeWithCopy(data.get(), size); return SkData::MakeWithCopy(data.get(), size);
} }
SkRemoteStrikeTransport::IOResult SkRemoteStrikeTransport::writeVector(
const std::vector<uint8_t>& vector) {
return write_data(vector.size(), vector.data(), this);
}
SkRemoteStrikeTransport::IOResult SkRemoteStrikeTransport::readVector(
std::vector<uint8_t>* vector) {
size_t vectorSize = 0;
size_t readSize = 0;
SkRemoteStrikeTransport::IOResult result;
std::tie(readSize, result) = this->read(&vectorSize, sizeof(vectorSize));
if(result == kFail || readSize == 0) {
return kFail;
}
vector->resize(vectorSize);
return read_data(vectorSize, vector->data(), this);
}
// -- Serializer ---------------------------------------------------------------------------------- // -- Serializer ----------------------------------------------------------------------------------
static size_t pad(size_t size, size_t alignment) {
return (size + (alignment - 1)) & ~(alignment - 1);
}
// N.B. pointers are only valid until the next call.
class Serializer { class Serializer {
public: public:
void startWrite() { Serializer(std::vector<uint8_t>* buffer) : fBuffer{buffer} { }
fCursor = 0;
}
template <typename T> template <typename T>
void startWrite(const T& data) { T* push_back(const T& data) {
this->startWrite(); auto result = allocate(sizeof(T), alignof(T));
this->write<T>(data); return new (result) T(data);
} }
template <typename T, typename... Args> template <typename T, typename... Args>
T* startEmplace(Args&&... args) { T* emplace_back(Args&& ... args) {
this->startWrite(); auto result = allocate(sizeof(T), alignof(T));
return this->emplace<T>(std::forward<Args>(args)...); return new (result) T{std::forward<Args>(args)...};
}
template <typename T, typename... Args>
T* emplace(Args&&... args) {
T* result = new (&fBuffer[fCursor]) T{std::forward<Args>(args)...};
fCursor += sizeof(T);
return result;
}
template <typename T>
void write(const T& data) {
// TODO: guard against bad T.
memcpy(&fBuffer[fCursor], &data, sizeof(data));
fCursor += sizeof(data);
}
template <typename T>
T* allocate() {
// TODO: guard against bad T.
T* result = (T*)&fBuffer[fCursor];
fCursor += sizeof(T);
return result;
} }
void writeDescriptor(const SkDescriptor& desc) { void writeDescriptor(const SkDescriptor& desc) {
memcpy(&fBuffer[fCursor], &desc, desc.getLength()); auto result = allocate(desc.getLength(), alignof(SkDescriptor));
fCursor += desc.getLength(); memcpy(result, &desc, desc.getLength());
} }
template <typename T> template <typename T>
T* allocateArray(int count) { T* allocateArray(int count) {
T* result = (T*)&fBuffer[fCursor]; auto result = allocate(sizeof(T) * count, alignof(T));
fCursor += count * sizeof(T); return new (result) T[count];
return result;
}
SkRemoteStrikeTransport::IOResult endWrite(SkRemoteStrikeTransport* transport) {
return transport->write(fBuffer.get(), fCursor);
} }
private: private:
static constexpr size_t kBufferSize = kPageSize * 2000; void* allocate(size_t size, size_t alignment) {
std::unique_ptr<uint8_t[]> fBuffer{new uint8_t[kBufferSize]}; size_t aligned = pad(fBuffer->size(), alignment);
size_t fCursor{0}; fBuffer->resize(aligned + size);
//size_t fEnd{0}; return &(*fBuffer)[aligned];
}
std::vector<uint8_t>* fBuffer;
}; };
// -- Deserializer ------------------------------------------------------------------------------- // -- Deserializer -------------------------------------------------------------------------------
class Deserializer { class Deserializer {
public: public:
void startRead(SkRemoteStrikeTransport* transport) { Deserializer(const std::vector<uint8_t>& buffer) : fBuffer{buffer} { }
fCursor = 0;
fEnd = 0;
fTransport = transport;
}
template <typename T>
T* startRead(SkRemoteStrikeTransport* transport) {
this->startRead(transport);
return this->read<T>();
}
template <typename T> template <typename T>
T* read() { T* read() {
T* result = (T*)this->ensureAtLeast(sizeof(T)); size_t padded = pad(fCursor, alignof(T));
fCursor += sizeof(T); fCursor = padded + sizeof(T);
return result; return (T*)&fBuffer[padded];
} }
SkDescriptor* readDescriptor() { SkDescriptor* readDescriptor() {
SkDescriptor* result = (SkDescriptor*)this->ensureAtLeast(sizeof(SkDescriptor)); size_t padded = pad(fCursor, alignof(SkDescriptor));
size_t size = result->getLength(); SkDescriptor* result = (SkDescriptor*)&fBuffer[padded];
this->ensureAtLeast(size); fCursor = padded + result->getLength();
fCursor += size;
return result; return result;
} }
template <typename T> template <typename T>
ArraySlice<T> readArray(int count) { ArraySlice<T> readArray(int count) {
size_t padded = pad(fCursor, alignof(T));
size_t size = count * sizeof(T); size_t size = count * sizeof(T);
const T* base = (const T*)this->ensureAtLeast(size); const T* base = (const T*)&fBuffer[padded];
ArraySlice<T> result = ArraySlice<T>{base, (uint32_t)count}; ArraySlice<T> result = ArraySlice<T>{base, (uint32_t)count};
fCursor += size; fCursor = padded + size;
return result; return result;
} }
size_t endRead() {
fTransport = nullptr;
return size();
}
size_t size() {return fCursor;} size_t size() {return fCursor;}
private: private:
void* ensureAtLeast(size_t size) { const std::vector<uint8_t>& fBuffer;
if (size > fEnd - fCursor) {
if (readAtLeast(size) == SkRemoteStrikeTransport::kFail) {
return nullptr;
}
}
return &fBuffer[fCursor];
}
SkRemoteStrikeTransport::IOResult readAtLeast(size_t size) {
size_t readSoFar = 0;
size_t bufferLeft = kBufferSize - fCursor;
size_t needed = size - (fEnd - fCursor);
while (readSoFar < needed) {
SkRemoteStrikeTransport::IOResult result;
size_t readSize;
std::tie(readSize, result) =
fTransport->read(&fBuffer[fEnd+readSoFar], bufferLeft - readSoFar);
if (result == SkRemoteStrikeTransport::kFail || readSize == 0) {return SkRemoteStrikeTransport::kFail;}
readSoFar += readSize;
}
fEnd += readSoFar;
return SkRemoteStrikeTransport::kSuccess;
}
SkRemoteStrikeTransport* fTransport;
static constexpr size_t kBufferSize = kPageSize * 2000;
std::unique_ptr<uint8_t[]> fBuffer{new uint8_t[kBufferSize]};
size_t fCursor{0}; size_t fCursor{0};
size_t fEnd{0};
}; };
// -- TrackLayerDevice ----------------------------------------------------------------------------- // -- TrackLayerDevice -----------------------------------------------------------------------------
@ -259,7 +227,8 @@ SkStrikeCacheDifferenceSpec::findStrikeDifferences(const SkDescriptor& desc,
auto newDescPtr = newDesc.get(); auto newDescPtr = newDesc.get();
StrikeDifferences strikeDiffs{typefaceID, std::move(newDesc)}; StrikeDifferences strikeDiffs{typefaceID, std::move(newDesc)};
mapIter = fDescriptorToDifferencesMap.emplace_hint(mapIter, newDescPtr, std::move(strikeDiffs)); mapIter = fDescriptorToDifferencesMap.emplace_hint(
mapIter, newDescPtr, std::move(strikeDiffs));
} }
return mapIter->second; return mapIter->second;
@ -462,22 +431,12 @@ enum class OpCode : int32_t {
kPrepopulateCache = 3, kPrepopulateCache = 3,
}; };
class Op { struct StrikeDiffHeader {
public: StrikeDiffHeader() {}
Op(OpCode opCode, SkFontID typefaceId, const SkScalerContextRec& rec) StrikeDiffHeader(int strikeCount_) : strikeCount{strikeCount_} {}
: opCode{opCode} int strikeCount;
, typefaceId{typefaceId}
, descriptor{rec} { }
const OpCode opCode;
const SkFontID typefaceId;
const SkScalerContextRecDescriptor descriptor;
SkPackedGlyphID glyphID;
}; };
struct Header {
Header(int strikeCount_) : strikeCount{strikeCount_} {}
const int strikeCount;
};
struct StrikeSpec { struct StrikeSpec {
StrikeSpec(SkFontID typefaceID_, uint32_t descLength_, int glyphCount_) StrikeSpec(SkFontID typefaceID_, uint32_t descLength_, int glyphCount_)
: typefaceID{typefaceID_} : typefaceID{typefaceID_}
@ -491,54 +450,85 @@ struct StrikeSpec {
}; };
struct WireTypeface { struct WireTypeface {
// std::thread::id thread_id; // TODO:need to figure a good solution
SkFontID typefaceID; SkFontID typefaceID;
int glyphCount; int glyphCount;
SkFontStyle style; SkFontStyle style;
bool isFixed; bool isFixed;
}; };
static void write_strikes_spec(const SkStrikeCacheDifferenceSpec &spec, class Op {
Serializer* serializer, public:
SkRemoteStrikeTransport* transport) { Op(OpCode opCode, SkFontID typefaceId, const SkScalerContextRec& rec)
serializer->startEmplace<Op>(OpCode::kPrepopulateCache, SkFontID{0}, SkScalerContextRec{}); : opCode{opCode}
, typefaceId{typefaceId}
, descriptor{rec} { }
const OpCode opCode;
const SkFontID typefaceId;
const SkScalerContextRecDescriptor descriptor;
union {
// kGlyphPath and kGlyphMetricsAndImage
SkPackedGlyphID glyphID;
// kPrepopulateCache
StrikeDiffHeader strikeSpecHeader;
};
};
serializer->emplace<Header>(spec.strikeCount()); class Result {
union {
SkPaint::FontMetrics fontMetrics;
SkGlyph glyph;
StrikeDiffHeader strikeDiffHeader;
};
};
size_t SkStrikeCacheDifferenceSpec::sizeBytes() const {
size_t sum = sizeof(Op) + sizeof(StrikeDiffHeader);
for (auto& pair : fDescriptorToDifferencesMap) {
const auto& strike = pair.second;
sum += sizeof(StrikeSpec)
+ strike.fDesc->getLength()
+ strike.fGlyphIDs->count() * sizeof(SkPackedGlyphID);
}
return sum;
}
static void write_strikes_spec(const SkStrikeCacheDifferenceSpec &spec,
Serializer* serializer) {
serializer->emplace_back<Op>(OpCode::kPrepopulateCache, SkFontID{0}, SkScalerContextRec{});
serializer->emplace_back<StrikeDiffHeader>(spec.strikeCount());
auto perStrike = [serializer](SkFontID typefaceID, const SkDescriptor& desc, int glyphCount) { auto perStrike = [serializer](SkFontID typefaceID, const SkDescriptor& desc, int glyphCount) {
serializer->emplace<StrikeSpec>(typefaceID, desc.getLength(), glyphCount); serializer->emplace_back<StrikeSpec>(typefaceID, desc.getLength(), glyphCount);
serializer->writeDescriptor(desc); serializer->writeDescriptor(desc);
}; };
auto perGlyph = [serializer](SkPackedGlyphID glyphID) { auto perGlyph = [serializer](SkPackedGlyphID glyphID) {
serializer->write<SkPackedGlyphID>(glyphID); serializer->push_back<SkPackedGlyphID>(glyphID);
}; };
spec.iterateDifferences(perStrike, perGlyph); spec.iterateDifferences(perStrike, perGlyph);
serializer->endWrite(transport);
} }
static void read_strikes_spec_write_strikes_data( static void read_strikes_spec_write_strikes_data(
Deserializer* deserializer, Serializer* serializer, SkRemoteStrikeTransport* transport, Deserializer* deserializer, Serializer* serializer, SkStrikeServer* server)
SkStrikeServer* rc)
{ {
// Don't start because the op started this deserialization. // Don't start because the op started this deserialization.
auto header = deserializer->read<Header>(); auto header = deserializer->read<StrikeDiffHeader>();
serializer->startWrite<Header>(*header); serializer->push_back<StrikeDiffHeader>(*header);
for (int i = 0; i < header->strikeCount; i++) { for (int i = 0; i < header->strikeCount; i++) {
auto spec = deserializer->read<StrikeSpec>(); auto spec = deserializer->read<StrikeSpec>();
auto desc = deserializer->readDescriptor(); auto desc = deserializer->readDescriptor();
serializer->write<StrikeSpec>(*spec); serializer->push_back<StrikeSpec>(*spec);
serializer->writeDescriptor(*desc); serializer->writeDescriptor(*desc);
SkScalerContextRecDescriptor recDesc{*desc}; SkScalerContextRecDescriptor recDesc{*desc};
auto scaler = rc->generateScalerContext(recDesc, spec->typefaceID); auto scaler = server->generateScalerContext(recDesc, spec->typefaceID);
SkPaint::FontMetrics fontMetrics; SkPaint::FontMetrics fontMetrics;
scaler->getFontMetrics(&fontMetrics); scaler->getFontMetrics(&fontMetrics);
serializer->write<SkPaint::FontMetrics>(fontMetrics); serializer->push_back<SkPaint::FontMetrics>(fontMetrics);
auto glyphIDs = deserializer->readArray<SkPackedGlyphID>(spec->glyphCount); auto glyphIDs = deserializer->readArray<SkPackedGlyphID>(spec->glyphCount);
for (auto glyphID : glyphIDs) { for (auto glyphID : glyphIDs) {
auto glyph = serializer->allocate<SkGlyph>(); auto glyph = serializer->emplace_back<SkGlyph>();
glyph->initWithGlyphID(glyphID); glyph->initWithGlyphID(glyphID);
scaler->getMetrics(glyph); scaler->getMetrics(glyph);
auto imageSize = glyph->computeImageSize(); auto imageSize = glyph->computeImageSize();
@ -546,20 +536,18 @@ static void read_strikes_spec_write_strikes_data(
glyph->fImage = nullptr; glyph->fImage = nullptr;
if (imageSize > 0) { if (imageSize > 0) {
glyph->fImage = serializer->allocateArray<uint8_t>(imageSize); // Since the allocateArray can move glyph, make one that stays in one place.
scaler->getImage(*glyph); SkGlyph stationaryGlyph = *glyph;
stationaryGlyph.fImage = serializer->allocateArray<uint8_t>(imageSize);
scaler->getImage(stationaryGlyph);
} }
} }
} }
deserializer->endRead();
serializer->endWrite(transport);
} }
static void update_caches_from_strikes_data(SkStrikeClient *client, static void update_caches_from_strikes_data(SkStrikeClient *client,
Deserializer *deserializer, Deserializer *deserializer) {
SkRemoteStrikeTransport *transport) { auto header = deserializer->read<StrikeDiffHeader>();
deserializer->startRead(transport);
auto header = deserializer->read<Header>();
for (int i = 0; i < header->strikeCount; i++) { for (int i = 0; i < header->strikeCount; i++) {
auto spec = deserializer->read<StrikeSpec>(); auto spec = deserializer->read<StrikeSpec>();
auto desc = deserializer->readDescriptor(); auto desc = deserializer->readDescriptor();
@ -586,7 +574,6 @@ static void update_caches_from_strikes_data(SkStrikeClient *client,
memcpy(allocatedGlyph->fImage, image.data(), image.size()); memcpy(allocatedGlyph->fImage, image.data(), image.size());
} }
} }
deserializer->endRead();
} }
// -- SkStrikeServer ------------------------------------------------------------------------------- // -- SkStrikeServer -------------------------------------------------------------------------------
@ -599,22 +586,30 @@ SkStrikeServer::~SkStrikeServer() {
int SkStrikeServer::serve() { int SkStrikeServer::serve() {
auto serializer = skstd::make_unique<Serializer>(); std::vector<uint8_t> inBuffer;
auto deserializer = skstd::make_unique<Deserializer>();; std::vector<uint8_t> outBuffer;
while (true) { while (true) {
Op* op = deserializer->startRead<Op>(fTransport); inBuffer.clear();
if (op == nullptr) { break; } auto result = fTransport->readVector(&inBuffer);
if (result == SkRemoteStrikeTransport::kFail) {
break;
}
Deserializer deserializer{inBuffer};
Op* op = deserializer.read<Op>();
fOpCount += 1; fOpCount += 1;
outBuffer.clear();
Serializer serializer{&outBuffer};
switch (op->opCode) { switch (op->opCode) {
case OpCode::kFontMetrics : { case OpCode::kFontMetrics : {
auto sc = this->generateScalerContext(op->descriptor, op->typefaceId); auto sc = this->generateScalerContext(op->descriptor, op->typefaceId);
SkPaint::FontMetrics metrics; SkPaint::FontMetrics metrics;
sc->getFontMetrics(&metrics); sc->getFontMetrics(&metrics);
serializer->startWrite<SkPaint::FontMetrics>(metrics); serializer.push_back<SkPaint::FontMetrics>(metrics);
serializer->endWrite(fTransport);
break; break;
} }
case OpCode::kGlyphPath : { case OpCode::kGlyphPath : {
@ -623,41 +618,41 @@ int SkStrikeServer::serve() {
SkPath path; SkPath path;
sc->getPath(op->glyphID, &path); sc->getPath(op->glyphID, &path);
size_t pathSize = path.writeToMemory(nullptr); size_t pathSize = path.writeToMemory(nullptr);
serializer->startWrite<size_t>(pathSize); serializer.push_back<size_t>(pathSize);
auto pathData = serializer->allocateArray<uint8_t>(pathSize); auto pathData = serializer.allocateArray<uint8_t>(pathSize);
path.writeToMemory(pathData); path.writeToMemory(pathData);
serializer->endWrite(fTransport);
break; break;
} }
case OpCode::kGlyphMetricsAndImage : { case OpCode::kGlyphMetricsAndImage : {
auto sc = this->generateScalerContext(op->descriptor, op->typefaceId); auto scaler = this->generateScalerContext(op->descriptor, op->typefaceId);
serializer->startWrite(); auto glyph = serializer.emplace_back<SkGlyph>();
auto glyph = serializer->allocate<SkGlyph>();
// TODO: check for buffer overflow. // TODO: check for buffer overflow.
glyph->initWithGlyphID(op->glyphID); glyph->initWithGlyphID(op->glyphID);
sc->getMetrics(glyph); scaler->getMetrics(glyph);
auto imageSize = glyph->computeImageSize(); auto imageSize = glyph->computeImageSize();
glyph->fPathData = nullptr; glyph->fPathData = nullptr;
glyph->fImage = nullptr; glyph->fImage = nullptr;
if (imageSize > 0) { if (imageSize > 0) {
glyph->fImage = serializer->allocateArray<uint8_t>(imageSize); // Since the allocateArray can move glyph, make one that stays in one place.
sc->getImage(*glyph); SkGlyph stationaryGlyph = *glyph;
stationaryGlyph.fImage = serializer.allocateArray<uint8_t>(imageSize);
scaler->getImage(stationaryGlyph);
} }
serializer->endWrite(fTransport);
break; break;
} }
case OpCode::kPrepopulateCache : { case OpCode::kPrepopulateCache : {
read_strikes_spec_write_strikes_data( read_strikes_spec_write_strikes_data(
deserializer.get(), serializer.get(), fTransport, this); &deserializer, &serializer, this);
break; break;
} }
default: default:
SK_ABORT("Bad op"); SK_ABORT("Bad op");
} }
fTransport->writeVector(outBuffer);
} }
return 0; return 0;
} }
@ -709,13 +704,8 @@ sk_sp<SkData> SkStrikeServer::encodeTypeface(SkTypeface* tf) {
// -- SkStrikeClient ------------------------------------------------------------------------------- // -- SkStrikeClient -------------------------------------------------------------------------------
static Op* start_op_write( SkStrikeClient::SkStrikeClient(SkRemoteStrikeTransport* transport)
OpCode opCode, const SkTypefaceProxy& tf, const SkScalerContextRec& rec, Serializer* serializer) : fTransport{transport} { }
{
return serializer->startEmplace<Op>(opCode, tf.remoteTypefaceID(), rec);
}
SkStrikeClient::SkStrikeClient(SkRemoteStrikeTransport* transport) : fTransport{transport} { }
void SkStrikeClient::generateFontMetrics( void SkStrikeClient::generateFontMetrics(
const SkTypefaceProxy& typefaceProxy, const SkTypefaceProxy& typefaceProxy,
@ -723,18 +713,18 @@ void SkStrikeClient::generateFontMetrics(
SkPaint::FontMetrics* metrics) { SkPaint::FontMetrics* metrics) {
// Send generateFontMetrics // Send generateFontMetrics
{ {
Serializer serializer; fBuffer.clear();
serializer.startEmplace<Op>(OpCode::kFontMetrics, typefaceProxy.remoteTypefaceID(), rec); Serializer serializer{&fBuffer};
start_op_write(OpCode::kFontMetrics, typefaceProxy, rec, &serializer); serializer.emplace_back<Op>(OpCode::kFontMetrics, typefaceProxy.remoteTypefaceID(), rec);
serializer.endWrite(fTransport); fTransport->writeVector(fBuffer);
} }
// Receive generateFontMetrics // Receive generateFontMetrics
{ {
Deserializer deserializer; fBuffer.clear();
deserializer.startRead(fTransport); fTransport->readVector(&fBuffer);
Deserializer deserializer(fBuffer);
*metrics = *deserializer.read<SkPaint::FontMetrics>(); *metrics = *deserializer.read<SkPaint::FontMetrics>();
deserializer.endRead();
} }
} }
@ -743,20 +733,21 @@ void SkStrikeClient::generateMetricsAndImage(
const SkScalerContextRec& rec, const SkScalerContextRec& rec,
SkArenaAlloc* alloc, SkArenaAlloc* alloc,
SkGlyph* glyph) { SkGlyph* glyph) {
SkScalerContextRecDescriptor rd{rec};
{ {
Serializer serializer; fBuffer.clear();
Op *op = serializer.startEmplace<Op>( Serializer serializer(&fBuffer);
Op *op = serializer.emplace_back<Op>(
OpCode::kGlyphMetricsAndImage, typefaceProxy.remoteTypefaceID(), rec); OpCode::kGlyphMetricsAndImage, typefaceProxy.remoteTypefaceID(), rec);
op->glyphID = glyph->getPackedID(); op->glyphID = glyph->getPackedID();
serializer.endWrite(fTransport); fTransport->writeVector(fBuffer);
} }
// Receive generateMetricsAndImage // Receive generateMetricsAndImage
{ {
Deserializer deserializer; fBuffer.clear();
*glyph = *deserializer.startRead<SkGlyph>(fTransport); fTransport->readVector(&fBuffer);
Deserializer deserializer(fBuffer);
*glyph = *deserializer.read<SkGlyph>();
auto imageSize = glyph->computeImageSize(); auto imageSize = glyph->computeImageSize();
glyph->fPathData = nullptr; glyph->fPathData = nullptr;
glyph->fImage = nullptr; glyph->fImage = nullptr;
@ -766,7 +757,6 @@ void SkStrikeClient::generateMetricsAndImage(
glyph->allocImage(alloc); glyph->allocImage(alloc);
memcpy(glyph->fImage, image.data(), imageSize); memcpy(glyph->fImage, image.data(), imageSize);
} }
deserializer.endRead();
} }
} }
@ -776,30 +766,37 @@ void SkStrikeClient::generatePath(
SkGlyphID glyphID, SkGlyphID glyphID,
SkPath* path) { SkPath* path) {
{ {
Serializer serializer; fBuffer.clear();
Op *op = serializer.startEmplace<Op>( Serializer serializer{&fBuffer};
Op *op = serializer.emplace_back<Op>(
OpCode::kGlyphPath, typefaceProxy.remoteTypefaceID(), rec); OpCode::kGlyphPath, typefaceProxy.remoteTypefaceID(), rec);
op->glyphID = glyphID; op->glyphID = glyphID;
serializer.endWrite(fTransport); fTransport->writeVector(fBuffer);
} }
{ {
Deserializer deserializer; fBuffer.clear();
size_t pathSize = *deserializer.startRead<size_t>(fTransport); fTransport->readVector(&fBuffer);
Deserializer deserializer{fBuffer};
size_t pathSize = *deserializer.read<size_t>();
auto rawPath = deserializer.readArray<uint8_t>(pathSize); auto rawPath = deserializer.readArray<uint8_t>(pathSize);
path->readFromMemory(rawPath.data(), rawPath.size()); path->readFromMemory(rawPath.data(), rawPath.size());
deserializer.endRead();
} }
} }
void SkStrikeClient::primeStrikeCache(const SkStrikeCacheDifferenceSpec& strikeDifferences) { void SkStrikeClient::primeStrikeCache(const SkStrikeCacheDifferenceSpec& strikeDifferences) {
{ {
auto serializer = skstd::make_unique<Serializer>(); fBuffer.clear();
write_strikes_spec(strikeDifferences, serializer.get(), fTransport); fBuffer.reserve(strikeDifferences.sizeBytes());
Serializer serializer{&fBuffer};
write_strikes_spec(strikeDifferences, &serializer);
fTransport->writeVector(fBuffer);
} }
{ {
auto deserializer = skstd::make_unique<Deserializer>();; fBuffer.clear();
update_caches_from_strikes_data(this, deserializer.get(), fTransport); fTransport->readVector(&fBuffer);
Deserializer deserializer{fBuffer};
update_caches_from_strikes_data(this, &deserializer);
} }
} }

View File

@ -36,6 +36,8 @@ public:
virtual std::tuple<size_t, IOResult> read(void*, size_t) = 0; virtual std::tuple<size_t, IOResult> read(void*, size_t) = 0;
IOResult writeSkData(const SkData&); IOResult writeSkData(const SkData&);
sk_sp<SkData> readSkData(); sk_sp<SkData> readSkData();
IOResult writeVector(const std::vector<uint8_t>&);
IOResult readVector(std::vector<uint8_t>*);
}; };
class SkScalerContextRecDescriptor { class SkScalerContextRecDescriptor {
@ -98,6 +100,7 @@ class SkStrikeCacheDifferenceSpec {
public: public:
StrikeDifferences& findStrikeDifferences(const SkDescriptor& desc, SkFontID typefaceID); StrikeDifferences& findStrikeDifferences(const SkDescriptor& desc, SkFontID typefaceID);
int strikeCount() const { return fDescriptorToDifferencesMap.size(); } int strikeCount() const { return fDescriptorToDifferencesMap.size(); }
size_t sizeBytes() const;
template <typename PerStrike, typename PerGlyph> template <typename PerStrike, typename PerGlyph>
void iterateDifferences(PerStrike perStrike, PerGlyph perGlyph) const; void iterateDifferences(PerStrike perStrike, PerGlyph perGlyph) const;
@ -211,6 +214,8 @@ private:
SkTHashMap<SkFontID, sk_sp<SkTypefaceProxy>> fMapIdToTypeface; SkTHashMap<SkFontID, sk_sp<SkTypefaceProxy>> fMapIdToTypeface;
SkRemoteStrikeTransport* const fTransport; SkRemoteStrikeTransport* const fTransport;
std::vector<uint8_t> fBuffer;
}; };
#endif // SkRemoteGlyphCache_DEFINED #endif // SkRemoteGlyphCache_DEFINED

View File

@ -90,7 +90,6 @@ static void build_prime_cache_spec(const SkIRect &bounds,
} }
static void final_draw(std::string outFilename, static void final_draw(std::string outFilename,
SkRemoteStrikeTransport* transport,
SkDeserialProcs* procs, SkDeserialProcs* procs,
SkData* picData, SkData* picData,
SkStrikeClient* client) { SkStrikeClient* client) {
@ -146,7 +145,7 @@ static void gpu(int readFd, int writeFd) {
SkDeserialProcs procs; SkDeserialProcs procs;
client.prepareDeserializeProcs(&procs); client.prepareDeserializeProcs(&procs);
final_draw("test.png", &rwTransport, &procs, picData.get(), &client); final_draw("test.png", &procs, picData.get(), &client);
} }
printf("GPU is exiting\n"); printf("GPU is exiting\n");
@ -177,7 +176,7 @@ static int renderer(
return server.serve(); return server.serve();
} else { } else {
stream = skpData; stream = skpData;
final_draw("test-correct.png", &rwTransport, nullptr, stream.get(), nullptr); final_draw("test-correct.png", nullptr, stream.get(), nullptr);
return 0; return 0;
} }
} }