Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(484)

Unified Diff: src/pipe/SkGPipeWrite.cpp

Issue 563783003: Ensure blob typeface information survives SkGPipe serialization. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Comments + win build fix Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/pipe/SkGPipeRead.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/pipe/SkGPipeWrite.cpp
diff --git a/src/pipe/SkGPipeWrite.cpp b/src/pipe/SkGPipeWrite.cpp
index f361e5ed67ecf092b4fd3a10f41f793e4f5cac69..c99b6259bd3498d689261be1de1fc3a135f4a3b1 100644
--- a/src/pipe/SkGPipeWrite.cpp
+++ b/src/pipe/SkGPipeWrite.cpp
@@ -22,6 +22,7 @@
#include "SkPatchUtils.h"
#include "SkPathEffect.h"
#include "SkPictureFlat.h"
+#include "SkPtrRecorder.h"
#include "SkRasterizer.h"
#include "SkRRect.h"
#include "SkShader.h"
@@ -35,7 +36,7 @@ enum {
kSizeOfFlatRRect = sizeof(SkRect) + 4 * sizeof(SkVector)
};
-static bool isCrossProcess(uint32_t flags) {
+static bool is_cross_process(uint32_t flags) {
return SkToBool(flags & SkGPipeWriter::kCrossProcess_Flag);
}
@@ -338,6 +339,9 @@ private:
}
}
+ size_t prepareInProcessTypefaceBuffer(const SkRefCntSet& typefaceSet, void* buffer);
+ size_t prepareCrossProcessTypefaceBuffer(const SkRefCntSet& typefaceSet, void* buffer);
+
// Should be called after any calls to an SkFlatDictionary::findAndReplace
// if a new SkFlatData was added when in cross process mode
void flattenFactoryNames();
@@ -411,7 +415,7 @@ int SkGPipeCanvas::flattenToIndex(SkFlattenable* obj, PaintFlats paintflat) {
fBitmapHeap->endAddingOwnersDeferral(added);
int index = flat->index();
if (added) {
- if (isCrossProcess(fFlags)) {
+ if (is_cross_process(fFlags)) {
this->flattenFactoryNames();
}
size_t flatSize = flat->flatSize();
@@ -436,10 +440,10 @@ SkGPipeCanvas::SkGPipeCanvas(SkGPipeController* controller,
SkWriter32* writer, uint32_t flags,
uint32_t width, uint32_t height)
: SkCanvas(width, height)
- , fFactorySet(isCrossProcess(flags) ? SkNEW(SkNamedFactorySet) : NULL)
+ , fFactorySet(is_cross_process(flags) ? SkNEW(SkNamedFactorySet) : NULL)
, fWriter(*writer)
, fFlags(flags)
- , fFlattenableHeap(FLATTENABLES_TO_KEEP, fFactorySet, isCrossProcess(flags))
+ , fFlattenableHeap(FLATTENABLES_TO_KEEP, fFactorySet, is_cross_process(flags))
, fFlatDictionary(&fFlattenableHeap)
{
fController = controller;
@@ -938,23 +942,68 @@ void SkGPipeCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const
}
}
+size_t SkGPipeCanvas::prepareInProcessTypefaceBuffer(const SkRefCntSet& typefaceSet, void* buffer) {
+ // When in-process, we simply write out the typeface pointers.
+ typefaceSet.copyToArray((SkRefCnt**)buffer);
+
+ return typefaceSet.count() * sizeof(SkTypeface*);
+}
+
+size_t SkGPipeCanvas::prepareCrossProcessTypefaceBuffer(const SkRefCntSet& typefaceSet,
+ void* buffer) {
+ // For cross-process we use typeface IDs.
+ typefaceSet.copyToArray((SkRefCnt**)buffer);
mtklein 2014/09/15 22:13:14 Is there any hope for writing typefaceSet.copyIDsT
+
+ uint32_t* ids = reinterpret_cast<uint32_t*>(buffer);
+ SkTypeface** typefaces = reinterpret_cast<SkTypeface**>(buffer);
+ for (int i = 0; i < typefaceSet.count(); ++i) {
+ ids[i] = this->getTypefaceID(typefaces[i]);
+ }
+
+ return typefaceSet.count() * sizeof(uint32_t);
+}
+
void SkGPipeCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
const SkPaint& paint) {
NOTIFY_SETUP(this);
this->writePaint(paint);
// FIXME: this is inefficient but avoids duplicating the blob serialization logic.
+ SkRefCntSet typefaceSet;
SkWriteBuffer blobBuffer;
+ blobBuffer.setTypefaceRecorder(&typefaceSet);
blob->flatten(blobBuffer);
- size_t size = sizeof(uint32_t) + 2 * sizeof(SkScalar) + blobBuffer.bytesWritten();
+ // Unlike most draw ops (which only use one paint/typeface), text blobs may reference
+ // an arbitrary number of typefaces. Since the one-paint-per-op model is not applicable,
+ // we need to serialize these explicitly.
+ SkAutoSTMalloc<128, uint8_t> storage(typefaceSet.count() * sizeof(SkTypeface*));
+ size_t typefaceSize = is_cross_process(fFlags)
+ ? this->prepareCrossProcessTypefaceBuffer(typefaceSet, storage.get())
+ : this->prepareInProcessTypefaceBuffer(typefaceSet, storage.get());
+
+ // blob byte count + typeface count + x + y + blob data + an index (cross-process)
+ // or pointer (in-process) for each typeface
+ size_t size = 2 * sizeof(uint32_t)
+ + 2 * sizeof(SkScalar)
+ + blobBuffer.bytesWritten()
+ + typefaceSize;
+
if (this->needOpBytes(size)) {
this->writeOp(kDrawTextBlob_DrawOp);
+ SkDEBUGCODE(size_t initialOffset = fWriter.bytesWritten();)
+
fWriter.writeScalar(x);
fWriter.writeScalar(y);
+
+ fWriter.write32(typefaceSet.count());
+ fWriter.write(storage.get(), typefaceSize);
+
fWriter.write32(SkToU32(blobBuffer.bytesWritten()));
uint32_t* pad = fWriter.reservePad(blobBuffer.bytesWritten());
blobBuffer.writeToMemory(pad);
+
+ SkASSERT(initialOffset + size == fWriter.bytesWritten());
}
}
@@ -1197,7 +1246,7 @@ void SkGPipeCanvas::writePaint(const SkPaint& paint) {
}
if (!SkTypeface::Equal(base.getTypeface(), paint.getTypeface())) {
- if (isCrossProcess(fFlags)) {
+ if (is_cross_process(fFlags)) {
uint32_t id = this->getTypefaceID(paint.getTypeface());
*ptr++ = PaintOp_packOpData(kTypeface_PaintOp, id);
} else if (this->needOpBytes(sizeof(void*))) {
« no previous file with comments | « src/pipe/SkGPipeRead.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698