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

Side by Side 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: Pass TypefaceBuffer by ptr 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 unified diff | Download patch
« no previous file with comments | « src/pipe/SkGPipeRead.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2011 Google Inc. 3 * Copyright 2011 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include "SkAnnotation.h" 9 #include "SkAnnotation.h"
10 #include "SkBitmapDevice.h" 10 #include "SkBitmapDevice.h"
11 #include "SkBitmapHeap.h" 11 #include "SkBitmapHeap.h"
12 #include "SkCanvas.h" 12 #include "SkCanvas.h"
13 #include "SkColorFilter.h" 13 #include "SkColorFilter.h"
14 #include "SkData.h" 14 #include "SkData.h"
15 #include "SkDrawLooper.h" 15 #include "SkDrawLooper.h"
16 #include "SkGPipe.h" 16 #include "SkGPipe.h"
17 #include "SkGPipePriv.h" 17 #include "SkGPipePriv.h"
18 #include "SkImageFilter.h" 18 #include "SkImageFilter.h"
19 #include "SkMaskFilter.h" 19 #include "SkMaskFilter.h"
20 #include "SkWriteBuffer.h" 20 #include "SkWriteBuffer.h"
21 #include "SkPaint.h" 21 #include "SkPaint.h"
22 #include "SkPatchUtils.h" 22 #include "SkPatchUtils.h"
23 #include "SkPathEffect.h" 23 #include "SkPathEffect.h"
24 #include "SkPictureFlat.h" 24 #include "SkPictureFlat.h"
25 #include "SkPtrRecorder.h"
25 #include "SkRasterizer.h" 26 #include "SkRasterizer.h"
26 #include "SkRRect.h" 27 #include "SkRRect.h"
27 #include "SkShader.h" 28 #include "SkShader.h"
28 #include "SkStream.h" 29 #include "SkStream.h"
29 #include "SkTextBlob.h" 30 #include "SkTextBlob.h"
30 #include "SkTSearch.h" 31 #include "SkTSearch.h"
31 #include "SkTypeface.h" 32 #include "SkTypeface.h"
32 #include "SkWriter32.h" 33 #include "SkWriter32.h"
33 34
34 enum { 35 enum {
35 kSizeOfFlatRRect = sizeof(SkRect) + 4 * sizeof(SkVector) 36 kSizeOfFlatRRect = sizeof(SkRect) + 4 * sizeof(SkVector)
36 }; 37 };
37 38
38 static bool isCrossProcess(uint32_t flags) { 39 static bool is_cross_process(uint32_t flags) {
39 return SkToBool(flags & SkGPipeWriter::kCrossProcess_Flag); 40 return SkToBool(flags & SkGPipeWriter::kCrossProcess_Flag);
40 } 41 }
41 42
42 static SkFlattenable* get_paintflat(const SkPaint& paint, unsigned paintFlat) { 43 static SkFlattenable* get_paintflat(const SkPaint& paint, unsigned paintFlat) {
43 SkASSERT(paintFlat < kCount_PaintFlats); 44 SkASSERT(paintFlat < kCount_PaintFlats);
44 switch (paintFlat) { 45 switch (paintFlat) {
45 case kColorFilter_PaintFlat: return paint.getColorFilter(); 46 case kColorFilter_PaintFlat: return paint.getColorFilter();
46 case kDrawLooper_PaintFlat: return paint.getLooper(); 47 case kDrawLooper_PaintFlat: return paint.getLooper();
47 case kMaskFilter_PaintFlat: return paint.getMaskFilter(); 48 case kMaskFilter_PaintFlat: return paint.getMaskFilter();
48 case kPathEffect_PaintFlat: return paint.getPathEffect(); 49 case kPathEffect_PaintFlat: return paint.getPathEffect();
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 inline void doNotify() { 332 inline void doNotify() {
332 if (!fDone) { 333 if (!fDone) {
333 size_t bytes = fWriter.bytesWritten() - fBytesNotified; 334 size_t bytes = fWriter.bytesWritten() - fBytesNotified;
334 if (bytes > 0) { 335 if (bytes > 0) {
335 fController->notifyWritten(bytes); 336 fController->notifyWritten(bytes);
336 fBytesNotified += bytes; 337 fBytesNotified += bytes;
337 } 338 }
338 } 339 }
339 } 340 }
340 341
342 typedef SkAutoSTMalloc<128, uint8_t> TypefaceBuffer;
343 size_t getInProcessTypefaces(const SkRefCntSet& typefaceSet, TypefaceBuffer* );
344 size_t getCrossProcessTypefaces(const SkRefCntSet& typefaceSet, TypefaceBuff er*);
345
341 // Should be called after any calls to an SkFlatDictionary::findAndReplace 346 // Should be called after any calls to an SkFlatDictionary::findAndReplace
342 // if a new SkFlatData was added when in cross process mode 347 // if a new SkFlatData was added when in cross process mode
343 void flattenFactoryNames(); 348 void flattenFactoryNames();
344 349
345 FlattenableHeap fFlattenableHeap; 350 FlattenableHeap fFlattenableHeap;
346 FlatDictionary fFlatDictionary; 351 FlatDictionary fFlatDictionary;
347 SkAutoTUnref<BitmapShuttle> fBitmapShuttle; 352 SkAutoTUnref<BitmapShuttle> fBitmapShuttle;
348 int fCurrFlatIndex[kCount_PaintFlats]; 353 int fCurrFlatIndex[kCount_PaintFlats];
349 354
350 int flattenToIndex(SkFlattenable* obj, PaintFlats); 355 int flattenToIndex(SkFlattenable* obj, PaintFlats);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 return 0; 409 return 0;
405 } 410 }
406 411
407 fBitmapHeap->deferAddingOwners(); 412 fBitmapHeap->deferAddingOwners();
408 bool added, replaced; 413 bool added, replaced;
409 const SkFlatData* flat = fFlatDictionary.findAndReplace(*obj, fFlattenableHe ap.flatToReplace(), 414 const SkFlatData* flat = fFlatDictionary.findAndReplace(*obj, fFlattenableHe ap.flatToReplace(),
410 &added, &replaced); 415 &added, &replaced);
411 fBitmapHeap->endAddingOwnersDeferral(added); 416 fBitmapHeap->endAddingOwnersDeferral(added);
412 int index = flat->index(); 417 int index = flat->index();
413 if (added) { 418 if (added) {
414 if (isCrossProcess(fFlags)) { 419 if (is_cross_process(fFlags)) {
415 this->flattenFactoryNames(); 420 this->flattenFactoryNames();
416 } 421 }
417 size_t flatSize = flat->flatSize(); 422 size_t flatSize = flat->flatSize();
418 if (this->needOpBytes(flatSize)) { 423 if (this->needOpBytes(flatSize)) {
419 this->writeOp(kDef_Flattenable_DrawOp, paintflat, index); 424 this->writeOp(kDef_Flattenable_DrawOp, paintflat, index);
420 fWriter.write(flat->data(), flatSize); 425 fWriter.write(flat->data(), flatSize);
421 } 426 }
422 } 427 }
423 if (replaced) { 428 if (replaced) {
424 index = ~index; 429 index = ~index;
425 } 430 }
426 return index; 431 return index;
427 } 432 }
428 433
429 /////////////////////////////////////////////////////////////////////////////// 434 ///////////////////////////////////////////////////////////////////////////////
430 435
431 #define MIN_BLOCK_SIZE (16 * 1024) 436 #define MIN_BLOCK_SIZE (16 * 1024)
432 #define BITMAPS_TO_KEEP 5 437 #define BITMAPS_TO_KEEP 5
433 #define FLATTENABLES_TO_KEEP 10 438 #define FLATTENABLES_TO_KEEP 10
434 439
435 SkGPipeCanvas::SkGPipeCanvas(SkGPipeController* controller, 440 SkGPipeCanvas::SkGPipeCanvas(SkGPipeController* controller,
436 SkWriter32* writer, uint32_t flags, 441 SkWriter32* writer, uint32_t flags,
437 uint32_t width, uint32_t height) 442 uint32_t width, uint32_t height)
438 : SkCanvas(width, height) 443 : SkCanvas(width, height)
439 , fFactorySet(isCrossProcess(flags) ? SkNEW(SkNamedFactorySet) : NULL) 444 , fFactorySet(is_cross_process(flags) ? SkNEW(SkNamedFactorySet) : NULL)
440 , fWriter(*writer) 445 , fWriter(*writer)
441 , fFlags(flags) 446 , fFlags(flags)
442 , fFlattenableHeap(FLATTENABLES_TO_KEEP, fFactorySet, isCrossProcess(flags)) 447 , fFlattenableHeap(FLATTENABLES_TO_KEEP, fFactorySet, is_cross_process(flags ))
443 , fFlatDictionary(&fFlattenableHeap) 448 , fFlatDictionary(&fFlattenableHeap)
444 { 449 {
445 fController = controller; 450 fController = controller;
446 fDone = false; 451 fDone = false;
447 fBlockSize = 0; // need first block from controller 452 fBlockSize = 0; // need first block from controller
448 fBytesNotified = 0; 453 fBytesNotified = 0;
449 fFirstSaveLayerStackLevel = kNoSaveLayer; 454 fFirstSaveLayerStackLevel = kNoSaveLayer;
450 sk_bzero(fCurrFlatIndex, sizeof(fCurrFlatIndex)); 455 sk_bzero(fCurrFlatIndex, sizeof(fCurrFlatIndex));
451 456
452 // Tell the reader the appropriate flags to use. 457 // Tell the reader the appropriate flags to use.
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
931 fWriter.writePad(text, byteLength); 936 fWriter.writePad(text, byteLength);
932 937
933 fWriter.writePath(path); 938 fWriter.writePath(path);
934 if (matrix) { 939 if (matrix) {
935 fWriter.writeMatrix(*matrix); 940 fWriter.writeMatrix(*matrix);
936 } 941 }
937 } 942 }
938 } 943 }
939 } 944 }
940 945
946 size_t SkGPipeCanvas::getInProcessTypefaces(const SkRefCntSet& typefaceSet,
947 TypefaceBuffer* buffer) {
948 // When in-process, we simply write out the typeface pointers.
949 size_t size = typefaceSet.count() * sizeof(SkTypeface*);
950 buffer->reset(size);
951 typefaceSet.copyToArray(reinterpret_cast<SkRefCnt**>(buffer->get()));
952
953 return size;
954 }
955
956 size_t SkGPipeCanvas::getCrossProcessTypefaces(const SkRefCntSet& typefaceSet,
957 TypefaceBuffer* buffer) {
958 // For cross-process we use typeface IDs.
959 size_t size = typefaceSet.count() * sizeof(uint32_t);
960 buffer->reset(size);
961
962 uint32_t* idBuffer = reinterpret_cast<uint32_t*>(buffer->get());
963 SkRefCntSet::Iter iter(typefaceSet);
964 int i = 0;
965
966 for (void* setPtr = iter.next(); setPtr; setPtr = iter.next()) {
967 idBuffer[i++] = this->getTypefaceID(reinterpret_cast<SkTypeface*>(setPtr ));
968 }
969
970 SkASSERT(i == typefaceSet.count());
971
972 return size;
973 }
974
941 void SkGPipeCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 975 void SkGPipeCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
942 const SkPaint& paint) { 976 const SkPaint& paint) {
943 NOTIFY_SETUP(this); 977 NOTIFY_SETUP(this);
944 this->writePaint(paint); 978 this->writePaint(paint);
945 979
946 // FIXME: this is inefficient but avoids duplicating the blob serialization logic. 980 // FIXME: this is inefficient but avoids duplicating the blob serialization logic.
981 SkRefCntSet typefaceSet;
947 SkWriteBuffer blobBuffer; 982 SkWriteBuffer blobBuffer;
983 blobBuffer.setTypefaceRecorder(&typefaceSet);
948 blob->flatten(blobBuffer); 984 blob->flatten(blobBuffer);
949 985
950 size_t size = sizeof(uint32_t) + 2 * sizeof(SkScalar) + blobBuffer.bytesWrit ten(); 986 // Unlike most draw ops (which only use one paint/typeface), text blobs may reference
987 // an arbitrary number of typefaces. Since the one-paint-per-op model is not applicable,
988 // we need to serialize these explicitly.
989 TypefaceBuffer typefaceBuffer;
990 size_t typefaceSize = is_cross_process(fFlags)
991 ? this->getCrossProcessTypefaces(typefaceSet, &typefaceBuffer)
992 : this->getInProcessTypefaces(typefaceSet, &typefaceBuffer);
993
994 // blob byte count + typeface count + x + y + blob data + an index (cross-pr ocess)
995 // or pointer (in-process) for each typeface
996 size_t size = 2 * sizeof(uint32_t)
997 + 2 * sizeof(SkScalar)
998 + blobBuffer.bytesWritten()
999 + typefaceSize;
1000
951 if (this->needOpBytes(size)) { 1001 if (this->needOpBytes(size)) {
952 this->writeOp(kDrawTextBlob_DrawOp); 1002 this->writeOp(kDrawTextBlob_DrawOp);
1003 SkDEBUGCODE(size_t initialOffset = fWriter.bytesWritten();)
1004
953 fWriter.writeScalar(x); 1005 fWriter.writeScalar(x);
954 fWriter.writeScalar(y); 1006 fWriter.writeScalar(y);
1007
1008 fWriter.write32(typefaceSet.count());
1009 fWriter.write(typefaceBuffer.get(), typefaceSize);
1010
955 fWriter.write32(SkToU32(blobBuffer.bytesWritten())); 1011 fWriter.write32(SkToU32(blobBuffer.bytesWritten()));
956 uint32_t* pad = fWriter.reservePad(blobBuffer.bytesWritten()); 1012 uint32_t* pad = fWriter.reservePad(blobBuffer.bytesWritten());
957 blobBuffer.writeToMemory(pad); 1013 blobBuffer.writeToMemory(pad);
1014
1015 SkASSERT(initialOffset + size == fWriter.bytesWritten());
958 } 1016 }
959 } 1017 }
960 1018
961 void SkGPipeCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matr ix, 1019 void SkGPipeCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matr ix,
962 const SkPaint* paint) { 1020 const SkPaint* paint) {
963 // we want to playback the picture into individual draw calls 1021 // we want to playback the picture into individual draw calls
964 // 1022 //
965 // todo: do we always have to unroll? If the pipe is not cross-process, seem s like 1023 // todo: do we always have to unroll? If the pipe is not cross-process, seem s like
966 // we could just ref the picture and move on...? <reed, scroggo> 1024 // we could just ref the picture and move on...? <reed, scroggo>
967 // 1025 //
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
1190 *ptr++ = castToU32(paint.getTextScaleX()); 1248 *ptr++ = castToU32(paint.getTextScaleX());
1191 base.setTextScaleX(paint.getTextScaleX()); 1249 base.setTextScaleX(paint.getTextScaleX());
1192 } 1250 }
1193 if (base.getTextSkewX() != paint.getTextSkewX()) { 1251 if (base.getTextSkewX() != paint.getTextSkewX()) {
1194 *ptr++ = PaintOp_packOp(kTextSkewX_PaintOp); 1252 *ptr++ = PaintOp_packOp(kTextSkewX_PaintOp);
1195 *ptr++ = castToU32(paint.getTextSkewX()); 1253 *ptr++ = castToU32(paint.getTextSkewX());
1196 base.setTextSkewX(paint.getTextSkewX()); 1254 base.setTextSkewX(paint.getTextSkewX());
1197 } 1255 }
1198 1256
1199 if (!SkTypeface::Equal(base.getTypeface(), paint.getTypeface())) { 1257 if (!SkTypeface::Equal(base.getTypeface(), paint.getTypeface())) {
1200 if (isCrossProcess(fFlags)) { 1258 if (is_cross_process(fFlags)) {
1201 uint32_t id = this->getTypefaceID(paint.getTypeface()); 1259 uint32_t id = this->getTypefaceID(paint.getTypeface());
1202 *ptr++ = PaintOp_packOpData(kTypeface_PaintOp, id); 1260 *ptr++ = PaintOp_packOpData(kTypeface_PaintOp, id);
1203 } else if (this->needOpBytes(sizeof(void*))) { 1261 } else if (this->needOpBytes(sizeof(void*))) {
1204 // Add to the set for ref counting. 1262 // Add to the set for ref counting.
1205 fTypefaceSet.add(paint.getTypeface()); 1263 fTypefaceSet.add(paint.getTypeface());
1206 // It is safe to write the typeface to the stream before the rest 1264 // It is safe to write the typeface to the stream before the rest
1207 // of the paint unless we ever send a kReset_PaintOp, which we 1265 // of the paint unless we ever send a kReset_PaintOp, which we
1208 // currently never do. 1266 // currently never do.
1209 this->writeOp(kSetTypeface_DrawOp); 1267 this->writeOp(kSetTypeface_DrawOp);
1210 fWriter.writePtr(paint.getTypeface()); 1268 fWriter.writePtr(paint.getTypeface());
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1336 return fCanvas->shuttleBitmap(bitmap, slot); 1394 return fCanvas->shuttleBitmap(bitmap, slot);
1337 } 1395 }
1338 1396
1339 void BitmapShuttle::removeCanvas() { 1397 void BitmapShuttle::removeCanvas() {
1340 if (NULL == fCanvas) { 1398 if (NULL == fCanvas) {
1341 return; 1399 return;
1342 } 1400 }
1343 fCanvas->unref(); 1401 fCanvas->unref();
1344 fCanvas = NULL; 1402 fCanvas = NULL;
1345 } 1403 }
OLDNEW
« 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