Remove all notion of transport from the API - V2.
There is only a need to pass buffers in and out of the system. All transport is external to the system. BUG=skia:7515 Change-Id: Ie50cbc3fa1b9776e56dab8e49e91ce640e0b3954 Reviewed-on: https://skia-review.googlesource.com/119893 Reviewed-by: Herb Derby <herb@google.com> Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
parent
0c5108ce59
commit
209a5f3bea
@ -43,77 +43,6 @@ private:
|
||||
size_t fSize;
|
||||
};
|
||||
|
||||
// -- 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) {
|
||||
return write_data(data.size(), (uint8_t*)data.data(), this);
|
||||
}
|
||||
|
||||
sk_sp<SkData> SkRemoteStrikeTransport::readSkData() {
|
||||
size_t size;
|
||||
if(std::get<1>(this->read(&size, sizeof(size))) == kFail) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto data = std::unique_ptr<uint8_t[]>{new uint8_t[size]};
|
||||
if (read_data(size, data.get(), this) == kFail) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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 ----------------------------------------------------------------------------------
|
||||
|
||||
static size_t pad(size_t size, size_t alignment) {
|
||||
@ -162,18 +91,20 @@ private:
|
||||
|
||||
class Deserializer {
|
||||
public:
|
||||
Deserializer(const std::vector<uint8_t>& buffer) : fBuffer{buffer} { }
|
||||
Deserializer(const SkData& buffer) : fBuffer{buffer} { }
|
||||
|
||||
template <typename T>
|
||||
T* read() {
|
||||
size_t padded = pad(fCursor, alignof(T));
|
||||
fCursor = padded + sizeof(T);
|
||||
return (T*)&fBuffer[padded];
|
||||
auto data = (uint8_t*)fBuffer.data();
|
||||
return (T*)&data[padded];
|
||||
}
|
||||
|
||||
SkDescriptor* readDescriptor() {
|
||||
size_t padded = pad(fCursor, alignof(SkDescriptor));
|
||||
SkDescriptor* result = (SkDescriptor*)&fBuffer[padded];
|
||||
auto data = (uint8_t*)fBuffer.data();
|
||||
SkDescriptor* result = (SkDescriptor*)&data[padded];
|
||||
fCursor = padded + result->getLength();
|
||||
return result;
|
||||
}
|
||||
@ -182,7 +113,8 @@ public:
|
||||
ArraySlice<T> readArray(int count) {
|
||||
size_t padded = pad(fCursor, alignof(T));
|
||||
size_t size = count * sizeof(T);
|
||||
const T* base = (const T*)&fBuffer[padded];
|
||||
auto data = (uint8_t*)fBuffer.data();
|
||||
const T* base = (const T*)&data[padded];
|
||||
ArraySlice<T> result = ArraySlice<T>{base, (uint32_t)count};
|
||||
fCursor = padded + size;
|
||||
return result;
|
||||
@ -191,31 +123,31 @@ public:
|
||||
size_t size() {return fCursor;}
|
||||
|
||||
private:
|
||||
const std::vector<uint8_t>& fBuffer;
|
||||
size_t fCursor{0};
|
||||
const SkData& fBuffer;
|
||||
size_t fCursor{0};
|
||||
};
|
||||
|
||||
|
||||
// -- SkStrikeCacheDifferenceSpec ------------------------------------------------------------------
|
||||
|
||||
SkStrikeCacheDifferenceSpec::StrikeDifferences::StrikeDifferences(
|
||||
SkStrikeDifferences::SkStrikeDifferences(
|
||||
SkFontID typefaceID, std::unique_ptr<SkDescriptor> desc)
|
||||
: fTypefaceID{typefaceID}
|
||||
, fDesc{std::move(desc)} { }
|
||||
|
||||
void SkStrikeCacheDifferenceSpec::StrikeDifferences::operator()(uint16_t glyphID, SkIPoint pos) {
|
||||
void SkStrikeDifferences::operator()(uint16_t glyphID, SkIPoint pos) {
|
||||
SkPackedGlyphID packedGlyphID{glyphID, pos.x(), pos.y()};
|
||||
fGlyphIDs->add(packedGlyphID);
|
||||
}
|
||||
|
||||
SkStrikeCacheDifferenceSpec::StrikeDifferences&
|
||||
SkStrikeCacheDifferenceSpec::findStrikeDifferences(const SkDescriptor& desc,
|
||||
SkFontID typefaceID) {
|
||||
SkStrikeDifferences& SkStrikeCacheDifferenceSpec::findStrikeDifferences(
|
||||
const SkDescriptor& desc, SkFontID typefaceID)
|
||||
{
|
||||
auto mapIter = fDescriptorToDifferencesMap.find(&desc);
|
||||
if (mapIter == fDescriptorToDifferencesMap.end()) {
|
||||
auto newDesc = desc.copy();
|
||||
auto newDescPtr = newDesc.get();
|
||||
StrikeDifferences strikeDiffs{typefaceID, std::move(newDesc)};
|
||||
SkStrikeDifferences strikeDiffs{typefaceID, std::move(newDesc)};
|
||||
|
||||
mapIter = fDescriptorToDifferencesMap.emplace_hint(
|
||||
mapIter, newDescPtr, std::move(strikeDiffs));
|
||||
@ -486,14 +418,6 @@ public:
|
||||
};
|
||||
};
|
||||
|
||||
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) {
|
||||
@ -590,85 +514,67 @@ static void update_caches_from_strikes_data(SkStrikeClient *client,
|
||||
}
|
||||
|
||||
// -- SkStrikeServer -------------------------------------------------------------------------------
|
||||
SkStrikeServer::SkStrikeServer(SkRemoteStrikeTransport* transport)
|
||||
: fTransport{transport} { }
|
||||
SkStrikeServer::SkStrikeServer() { }
|
||||
|
||||
SkStrikeServer::~SkStrikeServer() {
|
||||
printf("Strike server - ops: %d\n", fOpCount);
|
||||
}
|
||||
|
||||
int SkStrikeServer::serve() {
|
||||
void SkStrikeServer::serve(const SkData& inBuffer, std::vector<uint8_t>* outBuffer) {
|
||||
|
||||
std::vector<uint8_t> inBuffer;
|
||||
std::vector<uint8_t> outBuffer;
|
||||
fOpCount += 1;
|
||||
|
||||
while (true) {
|
||||
inBuffer.clear();
|
||||
auto result = fTransport->readVector(&inBuffer);
|
||||
if (result == SkRemoteStrikeTransport::kFail) {
|
||||
Serializer serializer{outBuffer};
|
||||
Deserializer deserializer{inBuffer};
|
||||
Op* op = deserializer.read<Op>();
|
||||
|
||||
switch (op->opCode) {
|
||||
case OpCode::kFontMetrics : {
|
||||
auto scaler = this->generateScalerContext(op->descriptor, op->typefaceId);
|
||||
SkPaint::FontMetrics metrics;
|
||||
scaler->getFontMetrics(&metrics);
|
||||
serializer.push_back<SkPaint::FontMetrics>(metrics);
|
||||
break;
|
||||
}
|
||||
case OpCode::kGlyphPath : {
|
||||
auto sc = this->generateScalerContext(op->descriptor, op->typefaceId);
|
||||
// TODO: check for buffer overflow.
|
||||
SkPath path;
|
||||
if (sc->getPath(op->glyphID, &path)) {
|
||||
size_t pathSize = path.writeToMemory(nullptr);
|
||||
serializer.push_back<size_t>(pathSize);
|
||||
auto pathData = serializer.allocateArray<uint8_t>(pathSize);
|
||||
path.writeToMemory(pathData);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OpCode::kGlyphMetricsAndImage : {
|
||||
auto scaler = this->generateScalerContext(op->descriptor, op->typefaceId);
|
||||
|
||||
auto glyph = serializer.emplace_back<SkGlyph>();
|
||||
// TODO: check for buffer overflow.
|
||||
glyph->initWithGlyphID(op->glyphID);
|
||||
scaler->getMetrics(glyph);
|
||||
auto imageSize = glyph->computeImageSize();
|
||||
glyph->fPathData = nullptr;
|
||||
glyph->fImage = nullptr;
|
||||
if (imageSize > 0) {
|
||||
// Since the allocateArray can move glyph, make one that stays in one place.
|
||||
SkGlyph stationaryGlyph = *glyph;
|
||||
stationaryGlyph.fImage = serializer.allocateArray<uint8_t>(imageSize);
|
||||
scaler->getImage(stationaryGlyph);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OpCode::kPrepopulateCache : {
|
||||
read_strikes_spec_write_strikes_data(
|
||||
&deserializer, &serializer, this);
|
||||
break;
|
||||
}
|
||||
|
||||
Deserializer deserializer{inBuffer};
|
||||
Op* op = deserializer.read<Op>();
|
||||
|
||||
fOpCount += 1;
|
||||
|
||||
outBuffer.clear();
|
||||
Serializer serializer{&outBuffer};
|
||||
|
||||
switch (op->opCode) {
|
||||
case OpCode::kFontMetrics : {
|
||||
auto sc = this->generateScalerContext(op->descriptor, op->typefaceId);
|
||||
SkPaint::FontMetrics metrics;
|
||||
sc->getFontMetrics(&metrics);
|
||||
serializer.push_back<SkPaint::FontMetrics>(metrics);
|
||||
break;
|
||||
}
|
||||
case OpCode::kGlyphPath : {
|
||||
auto sc = this->generateScalerContext(op->descriptor, op->typefaceId);
|
||||
// TODO: check for buffer overflow.
|
||||
SkPath path;
|
||||
if (sc->getPath(op->glyphID, &path)) {
|
||||
size_t pathSize = path.writeToMemory(nullptr);
|
||||
serializer.push_back<size_t>(pathSize);
|
||||
auto pathData = serializer.allocateArray<uint8_t>(pathSize);
|
||||
path.writeToMemory(pathData);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OpCode::kGlyphMetricsAndImage : {
|
||||
auto scaler = this->generateScalerContext(op->descriptor, op->typefaceId);
|
||||
|
||||
auto glyph = serializer.emplace_back<SkGlyph>();
|
||||
// TODO: check for buffer overflow.
|
||||
glyph->initWithGlyphID(op->glyphID);
|
||||
scaler->getMetrics(glyph);
|
||||
auto imageSize = glyph->computeImageSize();
|
||||
glyph->fPathData = nullptr;
|
||||
glyph->fImage = nullptr;
|
||||
|
||||
if (imageSize > 0) {
|
||||
// Since the allocateArray can move glyph, make one that stays in one place.
|
||||
SkGlyph stationaryGlyph = *glyph;
|
||||
stationaryGlyph.fImage = serializer.allocateArray<uint8_t>(imageSize);
|
||||
scaler->getImage(stationaryGlyph);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OpCode::kPrepopulateCache : {
|
||||
read_strikes_spec_write_strikes_data(
|
||||
&deserializer, &serializer, this);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
SK_ABORT("Bad op");
|
||||
}
|
||||
|
||||
fTransport->writeVector(outBuffer);
|
||||
default:
|
||||
SK_ABORT("Bad op");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SkStrikeServer::prepareSerializeProcs(SkSerialProcs* procs) {
|
||||
@ -717,105 +623,88 @@ sk_sp<SkData> SkStrikeServer::encodeTypeface(SkTypeface* tf) {
|
||||
}
|
||||
|
||||
// -- SkStrikeClient -------------------------------------------------------------------------------
|
||||
|
||||
SkStrikeClient::SkStrikeClient(SkRemoteStrikeTransport* transport)
|
||||
: fTransport{transport} { }
|
||||
SkStrikeClient::SkStrikeClient(SkStrikeCacheClientRPC clientRPC)
|
||||
: fClientRPC{clientRPC} { }
|
||||
|
||||
void SkStrikeClient::generateFontMetrics(
|
||||
const SkTypefaceProxy& typefaceProxy,
|
||||
const SkScalerContextRec& rec,
|
||||
SkPaint::FontMetrics* metrics) {
|
||||
// Send generateFontMetrics
|
||||
{
|
||||
fBuffer.clear();
|
||||
Serializer serializer{&fBuffer};
|
||||
serializer.emplace_back<Op>(OpCode::kFontMetrics, typefaceProxy.remoteTypefaceID(), rec);
|
||||
fTransport->writeVector(fBuffer);
|
||||
}
|
||||
const SkTypefaceProxy& typefaceProxy,
|
||||
const SkScalerContextRec& rec,
|
||||
SkPaint::FontMetrics* metrics)
|
||||
{
|
||||
fBuffer.clear();
|
||||
|
||||
// Receive generateFontMetrics
|
||||
{
|
||||
fBuffer.clear();
|
||||
fTransport->readVector(&fBuffer);
|
||||
Deserializer deserializer(fBuffer);
|
||||
*metrics = *deserializer.read<SkPaint::FontMetrics>();
|
||||
}
|
||||
Serializer serializer{&fBuffer};
|
||||
serializer.emplace_back<Op>(OpCode::kFontMetrics, typefaceProxy.remoteTypefaceID(), rec);
|
||||
|
||||
auto outBuffer = SkData::MakeWithoutCopy(fBuffer.data(), fBuffer.size());
|
||||
auto inbuffer = fClientRPC(*outBuffer);
|
||||
Deserializer deserializer(*inbuffer);
|
||||
*metrics = *deserializer.read<SkPaint::FontMetrics>();
|
||||
}
|
||||
|
||||
void SkStrikeClient::generateMetricsAndImage(
|
||||
const SkTypefaceProxy& typefaceProxy,
|
||||
const SkScalerContextRec& rec,
|
||||
SkArenaAlloc* alloc,
|
||||
SkGlyph* glyph) {
|
||||
{
|
||||
const SkTypefaceProxy& typefaceProxy,
|
||||
const SkScalerContextRec& rec,
|
||||
SkArenaAlloc* alloc,
|
||||
SkGlyph* glyph)
|
||||
{
|
||||
fBuffer.clear();
|
||||
Serializer serializer(&fBuffer);
|
||||
Op *op = serializer.emplace_back<Op>(
|
||||
OpCode::kGlyphMetricsAndImage, typefaceProxy.remoteTypefaceID(), rec);
|
||||
op->glyphID = glyph->getPackedID();
|
||||
fTransport->writeVector(fBuffer);
|
||||
}
|
||||
op->glyphID = glyph->getPackedID();
|
||||
|
||||
// Receive generateMetricsAndImage
|
||||
{
|
||||
fBuffer.clear();
|
||||
fTransport->readVector(&fBuffer);
|
||||
Deserializer deserializer(fBuffer);
|
||||
*glyph = *deserializer.read<SkGlyph>();
|
||||
auto imageSize = glyph->computeImageSize();
|
||||
glyph->fPathData = nullptr;
|
||||
glyph->fImage = nullptr;
|
||||
if (imageSize > 0) {
|
||||
auto image = deserializer.readArray<uint8_t>(imageSize);
|
||||
SkASSERT(imageSize == image.size());
|
||||
glyph->allocImage(alloc);
|
||||
memcpy(glyph->fImage, image.data(), imageSize);
|
||||
}
|
||||
auto outBuffer = SkData::MakeWithoutCopy(fBuffer.data(), fBuffer.size());
|
||||
auto inbuffer = fClientRPC(*outBuffer);
|
||||
Deserializer deserializer(*inbuffer);
|
||||
*glyph = *deserializer.read<SkGlyph>();
|
||||
auto imageSize = glyph->computeImageSize();
|
||||
glyph->fPathData = nullptr;
|
||||
glyph->fImage = nullptr;
|
||||
if (imageSize > 0) {
|
||||
auto image = deserializer.readArray<uint8_t>(imageSize);
|
||||
SkASSERT(imageSize == image.size());
|
||||
glyph->allocImage(alloc);
|
||||
memcpy(glyph->fImage, image.data(), imageSize);
|
||||
}
|
||||
|
||||
}
|
||||
bool SkStrikeClient::generatePath(
|
||||
const SkTypefaceProxy& typefaceProxy,
|
||||
const SkScalerContextRec& rec,
|
||||
SkGlyphID glyphID,
|
||||
SkPath* path) {
|
||||
{
|
||||
fBuffer.clear();
|
||||
Serializer serializer{&fBuffer};
|
||||
Op *op = serializer.emplace_back<Op>(
|
||||
OpCode::kGlyphPath, typefaceProxy.remoteTypefaceID(), rec);
|
||||
op->glyphID = glyphID;
|
||||
fTransport->writeVector(fBuffer);
|
||||
}
|
||||
|
||||
{
|
||||
fBuffer.clear();
|
||||
fTransport->readVector(&fBuffer);
|
||||
Deserializer deserializer{fBuffer};
|
||||
size_t pathSize = *deserializer.read<size_t>();
|
||||
if (pathSize == 0) {
|
||||
return false;
|
||||
}
|
||||
auto rawPath = deserializer.readArray<uint8_t>(pathSize);
|
||||
path->readFromMemory(rawPath.data(), rawPath.size());
|
||||
bool SkStrikeClient::generatePath(
|
||||
const SkTypefaceProxy& typefaceProxy,
|
||||
const SkScalerContextRec& rec,
|
||||
SkGlyphID glyphID,
|
||||
SkPath* path)
|
||||
{
|
||||
fBuffer.clear();
|
||||
|
||||
Serializer serializer{&fBuffer};
|
||||
Op *op = serializer.emplace_back<Op>(
|
||||
OpCode::kGlyphPath, typefaceProxy.remoteTypefaceID(), rec);
|
||||
op->glyphID = glyphID;
|
||||
|
||||
auto outBuffer = SkData::MakeWithoutCopy(fBuffer.data(), fBuffer.size());
|
||||
auto inbuffer = fClientRPC(*outBuffer);
|
||||
Deserializer deserializer(*inbuffer);
|
||||
size_t pathSize = *deserializer.read<size_t>();
|
||||
if (pathSize == 0) {
|
||||
return false;
|
||||
}
|
||||
auto rawPath = deserializer.readArray<uint8_t>(pathSize);
|
||||
path->readFromMemory(rawPath.data(), rawPath.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
void SkStrikeClient::primeStrikeCache(const SkStrikeCacheDifferenceSpec& strikeDifferences) {
|
||||
{
|
||||
fBuffer.clear();
|
||||
fBuffer.reserve(strikeDifferences.sizeBytes());
|
||||
Serializer serializer{&fBuffer};
|
||||
write_strikes_spec(strikeDifferences, &serializer);
|
||||
fTransport->writeVector(fBuffer);
|
||||
}
|
||||
{
|
||||
fBuffer.clear();
|
||||
fTransport->readVector(&fBuffer);
|
||||
Deserializer deserializer{fBuffer};
|
||||
update_caches_from_strikes_data(this, &deserializer);
|
||||
}
|
||||
fBuffer.clear();
|
||||
fBuffer.reserve(strikeDifferences.sizeBytes());
|
||||
|
||||
Serializer serializer{&fBuffer};
|
||||
write_strikes_spec(strikeDifferences, &serializer);
|
||||
|
||||
auto outBuffer = SkData::MakeWithoutCopy(fBuffer.data(), fBuffer.size());
|
||||
auto inbuffer = fClientRPC(*outBuffer);
|
||||
Deserializer deserializer(*inbuffer);
|
||||
update_caches_from_strikes_data(this, &deserializer);
|
||||
}
|
||||
|
||||
void SkStrikeClient::prepareDeserializeProcs(SkDeserialProcs* procs) {
|
||||
|
@ -19,26 +19,15 @@
|
||||
#include "SkGlyphCache.h"
|
||||
#include "SkMakeUnique.h"
|
||||
#include "SkNoDrawCanvas.h"
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkSerialProcs.h"
|
||||
#include "SkTextBlobRunIterator.h"
|
||||
#include "SkTHash.h"
|
||||
#include "SkTypeface.h"
|
||||
#include "SkTypeface_remote.h"
|
||||
|
||||
class SkScalerContextRecDescriptor;
|
||||
|
||||
class SkRemoteStrikeTransport {
|
||||
public:
|
||||
enum IOResult : bool {kFail = false, kSuccess = true};
|
||||
|
||||
virtual ~SkRemoteStrikeTransport() {}
|
||||
virtual IOResult write(const void*, size_t) = 0;
|
||||
virtual std::tuple<size_t, IOResult> read(void*, size_t) = 0;
|
||||
IOResult writeSkData(const SkData&);
|
||||
sk_sp<SkData> readSkData();
|
||||
IOResult writeVector(const std::vector<uint8_t>&);
|
||||
IOResult readVector(std::vector<uint8_t>*);
|
||||
};
|
||||
// The client uses a SkStrikeCacheClientRPC to send and receive data.
|
||||
using SkStrikeCacheClientRPC = std::function<sk_sp<SkData>(const SkData&)>;
|
||||
|
||||
class SkScalerContextRecDescriptor {
|
||||
public:
|
||||
@ -94,27 +83,25 @@ private:
|
||||
} fDescriptor;
|
||||
};
|
||||
|
||||
class SkStrikeCacheDifferenceSpec {
|
||||
class StrikeDifferences;
|
||||
|
||||
class SkStrikeDifferences {
|
||||
public:
|
||||
StrikeDifferences& findStrikeDifferences(const SkDescriptor& desc, SkFontID typefaceID);
|
||||
SkStrikeDifferences(SkFontID typefaceID, std::unique_ptr<SkDescriptor> desc);
|
||||
void operator()(uint16_t glyphID, SkIPoint pos);
|
||||
SkFontID fTypefaceID;
|
||||
std::unique_ptr<SkDescriptor> fDesc;
|
||||
std::unique_ptr<SkTHashSet<SkPackedGlyphID>> fGlyphIDs =
|
||||
skstd::make_unique<SkTHashSet<SkPackedGlyphID>>();
|
||||
};
|
||||
|
||||
class SkStrikeCacheDifferenceSpec {
|
||||
public:
|
||||
SkStrikeDifferences& findStrikeDifferences(const SkDescriptor& desc, SkFontID typefaceID);
|
||||
int strikeCount() const { return fDescriptorToDifferencesMap.size(); }
|
||||
size_t sizeBytes() const;
|
||||
template <typename PerStrike, typename PerGlyph>
|
||||
void iterateDifferences(PerStrike perStrike, PerGlyph perGlyph) const;
|
||||
|
||||
private:
|
||||
class StrikeDifferences {
|
||||
public:
|
||||
StrikeDifferences(SkFontID typefaceID, std::unique_ptr<SkDescriptor> desc);
|
||||
void operator()(uint16_t glyphID, SkIPoint pos);
|
||||
SkFontID fTypefaceID;
|
||||
std::unique_ptr<SkDescriptor> fDesc;
|
||||
std::unique_ptr<SkTHashSet<SkPackedGlyphID>> fGlyphIDs =
|
||||
skstd::make_unique<SkTHashSet<SkPackedGlyphID>>();
|
||||
};
|
||||
|
||||
struct DescHash {
|
||||
size_t operator()(const SkDescriptor* key) const {
|
||||
return key->getChecksum();
|
||||
@ -127,7 +114,7 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
using DescMap = std::unordered_map<const SkDescriptor*, StrikeDifferences, DescHash, DescEq>;
|
||||
using DescMap = std::unordered_map<const SkDescriptor*, SkStrikeDifferences, DescHash, DescEq>;
|
||||
DescMap fDescriptorToDifferencesMap{16, DescHash(), DescEq()};
|
||||
};
|
||||
|
||||
@ -166,11 +153,12 @@ private:
|
||||
|
||||
class SkStrikeServer {
|
||||
public:
|
||||
SkStrikeServer(SkRemoteStrikeTransport* transport);
|
||||
SkStrikeServer();
|
||||
~SkStrikeServer();
|
||||
|
||||
// embedding clients call these methods
|
||||
int serve(); // very negotiable
|
||||
void serve(const SkData&, std::vector<uint8_t>*);
|
||||
|
||||
void prepareSerializeProcs(SkSerialProcs* procs);
|
||||
|
||||
// mostly called internally by Skia
|
||||
@ -185,14 +173,13 @@ private:
|
||||
sk_sp<SkData> encodeTypeface(SkTypeface* tf);
|
||||
|
||||
int fOpCount = 0;
|
||||
SkRemoteStrikeTransport* const fTransport;
|
||||
SkTHashMap<SkFontID, sk_sp<SkTypeface>> fTypefaceMap;
|
||||
DescriptorToContextMap fScalerContextMap;
|
||||
};
|
||||
|
||||
class SkStrikeClient {
|
||||
public:
|
||||
SkStrikeClient(SkRemoteStrikeTransport*);
|
||||
SkStrikeClient(SkStrikeCacheClientRPC);
|
||||
|
||||
// embedding clients call these methods
|
||||
void primeStrikeCache(const SkStrikeCacheDifferenceSpec&);
|
||||
@ -213,7 +200,7 @@ private:
|
||||
// TODO: Figure out how to manage the entries for the following maps.
|
||||
SkTHashMap<SkFontID, sk_sp<SkTypefaceProxy>> fMapIdToTypeface;
|
||||
|
||||
SkRemoteStrikeTransport* const fTransport;
|
||||
SkStrikeCacheClientRPC fClientRPC;
|
||||
|
||||
std::vector<uint8_t> fBuffer;
|
||||
};
|
||||
|
@ -25,35 +25,52 @@ static bool gUseGpu = true;
|
||||
static bool gPurgeFontCaches = true;
|
||||
static bool gUseProcess = true;
|
||||
|
||||
class ReadWriteTransport : public SkRemoteStrikeTransport {
|
||||
public:
|
||||
ReadWriteTransport(int readFd, int writeFd) : fReadFd{readFd}, fWriteFd{writeFd} {}
|
||||
~ReadWriteTransport() override {
|
||||
close(fWriteFd);
|
||||
close(fReadFd);
|
||||
}
|
||||
IOResult write(const void* buffer, size_t size) override {
|
||||
ssize_t writeSize = ::write(fWriteFd, buffer, size);
|
||||
if (writeSize < 0) {
|
||||
err(1,"Failed write %zu", size);
|
||||
return kFail;
|
||||
}
|
||||
return kSuccess;
|
||||
static bool write_SkData(int fd, const SkData& data) {
|
||||
size_t size = data.size();
|
||||
ssize_t bytesWritten = ::write(fd, &size, sizeof(size));
|
||||
if (bytesWritten < 0) {
|
||||
err(1,"Failed write %zu", size);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::tuple<size_t, IOResult> read(void* buffer, size_t size) override {
|
||||
ssize_t readSize = ::read(fReadFd, buffer, size);
|
||||
bytesWritten = ::write(fd, data.data(), data.size());
|
||||
if (bytesWritten < 0) {
|
||||
err(1,"Failed write %zu", size);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static sk_sp<SkData> read_SkData(int fd) {
|
||||
|
||||
size_t size;
|
||||
ssize_t readSize = ::read(fd, &size, sizeof(size));
|
||||
if (readSize <= 0) {
|
||||
if (readSize < 0) {
|
||||
err(1,"Failed read %zu", size);
|
||||
return {size, kFail};
|
||||
err(1, "Failed read %zu", size);
|
||||
}
|
||||
return {readSize, kSuccess};
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
const int fReadFd,
|
||||
fWriteFd;
|
||||
};
|
||||
auto out = SkData::MakeUninitialized(size);
|
||||
auto data = (uint8_t*)out->data();
|
||||
|
||||
size_t totalRead = 0;
|
||||
while (totalRead < size) {
|
||||
ssize_t sizeRead;
|
||||
sizeRead = ::read(fd, &data[totalRead], size - totalRead);
|
||||
if (sizeRead <= 0) {
|
||||
if (readSize < 0) {
|
||||
err(1, "Failed read %zu", size);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
totalRead += sizeRead;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
class Timer {
|
||||
public:
|
||||
@ -133,14 +150,17 @@ static void final_draw(std::string outFilename,
|
||||
static void gpu(int readFd, int writeFd) {
|
||||
|
||||
if (gUseGpu) {
|
||||
ReadWriteTransport rwTransport{readFd, writeFd};
|
||||
auto clientRPC = [readFd, writeFd](const SkData& inBuffer) {
|
||||
write_SkData(writeFd, inBuffer);
|
||||
return read_SkData(readFd);
|
||||
};
|
||||
|
||||
auto picData = rwTransport.readSkData();
|
||||
auto picData = read_SkData(readFd);
|
||||
if (picData == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
SkStrikeClient client{&rwTransport};
|
||||
SkStrikeClient client{clientRPC};
|
||||
|
||||
SkDeserialProcs procs;
|
||||
client.prepareDeserializeProcs(&procs);
|
||||
@ -148,14 +168,20 @@ static void gpu(int readFd, int writeFd) {
|
||||
final_draw("test.png", &procs, picData.get(), &client);
|
||||
}
|
||||
|
||||
::close(writeFd);
|
||||
::close(readFd);
|
||||
|
||||
printf("GPU is exiting\n");
|
||||
}
|
||||
|
||||
static int renderer(
|
||||
const std::string& skpName, int readFd, int writeFd)
|
||||
{
|
||||
ReadWriteTransport rwTransport{readFd, writeFd};
|
||||
SkStrikeServer server{&rwTransport};
|
||||
SkStrikeServer server{};
|
||||
auto closeAll = [readFd, writeFd]() {
|
||||
::close(writeFd);
|
||||
::close(readFd);
|
||||
};
|
||||
|
||||
auto skpData = SkData::MakeFromFileName(skpName.c_str());
|
||||
std::cout << "skp stream is " << skpData->size() << " bytes long " << std::endl;
|
||||
@ -167,16 +193,28 @@ static int renderer(
|
||||
server.prepareSerializeProcs(&procs);
|
||||
stream = pic->serialize(&procs);
|
||||
|
||||
if (rwTransport.writeSkData(*stream) == SkRemoteStrikeTransport::kFail) {
|
||||
if (!write_SkData(writeFd, *stream)) {
|
||||
closeAll();
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "Waiting for scaler context ops." << std::endl;
|
||||
std::vector<uint8_t> tmpBuffer;
|
||||
while (true) {
|
||||
auto inBuffer = read_SkData(readFd);
|
||||
if (inBuffer == nullptr) {
|
||||
closeAll();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return server.serve();
|
||||
tmpBuffer.clear();
|
||||
server.serve(*inBuffer, &tmpBuffer);
|
||||
auto outBuffer = SkData::MakeWithoutCopy(tmpBuffer.data(), tmpBuffer.size());
|
||||
write_SkData(writeFd, *outBuffer);
|
||||
}
|
||||
} else {
|
||||
stream = skpData;
|
||||
final_draw("test-correct.png", nullptr, stream.get(), nullptr);
|
||||
closeAll();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user