1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/pipe/SkGPipeWrite.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1267 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2011 Google Inc. 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 +#include "SkAnnotation.h" 1.13 +#include "SkBitmapDevice.h" 1.14 +#include "SkBitmapHeap.h" 1.15 +#include "SkCanvas.h" 1.16 +#include "SkColorFilter.h" 1.17 +#include "SkData.h" 1.18 +#include "SkDrawLooper.h" 1.19 +#include "SkGPipe.h" 1.20 +#include "SkGPipePriv.h" 1.21 +#include "SkImageFilter.h" 1.22 +#include "SkMaskFilter.h" 1.23 +#include "SkWriteBuffer.h" 1.24 +#include "SkPaint.h" 1.25 +#include "SkPathEffect.h" 1.26 +#include "SkPictureFlat.h" 1.27 +#include "SkRasterizer.h" 1.28 +#include "SkRRect.h" 1.29 +#include "SkShader.h" 1.30 +#include "SkStream.h" 1.31 +#include "SkTSearch.h" 1.32 +#include "SkTypeface.h" 1.33 +#include "SkWriter32.h" 1.34 + 1.35 +enum { 1.36 + kSizeOfFlatRRect = sizeof(SkRect) + 4 * sizeof(SkVector) 1.37 +}; 1.38 + 1.39 +static bool isCrossProcess(uint32_t flags) { 1.40 + return SkToBool(flags & SkGPipeWriter::kCrossProcess_Flag); 1.41 +} 1.42 + 1.43 +static SkFlattenable* get_paintflat(const SkPaint& paint, unsigned paintFlat) { 1.44 + SkASSERT(paintFlat < kCount_PaintFlats); 1.45 + switch (paintFlat) { 1.46 + case kColorFilter_PaintFlat: return paint.getColorFilter(); 1.47 + case kDrawLooper_PaintFlat: return paint.getLooper(); 1.48 + case kMaskFilter_PaintFlat: return paint.getMaskFilter(); 1.49 + case kPathEffect_PaintFlat: return paint.getPathEffect(); 1.50 + case kRasterizer_PaintFlat: return paint.getRasterizer(); 1.51 + case kShader_PaintFlat: return paint.getShader(); 1.52 + case kImageFilter_PaintFlat: return paint.getImageFilter(); 1.53 + case kXfermode_PaintFlat: return paint.getXfermode(); 1.54 + } 1.55 + SkDEBUGFAIL("never gets here"); 1.56 + return NULL; 1.57 +} 1.58 + 1.59 +static size_t writeTypeface(SkWriter32* writer, SkTypeface* typeface) { 1.60 + SkASSERT(typeface); 1.61 + SkDynamicMemoryWStream stream; 1.62 + typeface->serialize(&stream); 1.63 + size_t size = stream.getOffset(); 1.64 + if (writer) { 1.65 + writer->write32(size); 1.66 + SkAutoDataUnref data(stream.copyToData()); 1.67 + writer->writePad(data->data(), size); 1.68 + } 1.69 + return 4 + SkAlign4(size); 1.70 +} 1.71 + 1.72 +/////////////////////////////////////////////////////////////////////////////// 1.73 + 1.74 +class FlattenableHeap : public SkFlatController { 1.75 +public: 1.76 + FlattenableHeap(int numFlatsToKeep, SkNamedFactorySet* fset, bool isCrossProcess) 1.77 + : INHERITED(isCrossProcess ? SkWriteBuffer::kCrossProcess_Flag : 0) 1.78 + , fNumFlatsToKeep(numFlatsToKeep) { 1.79 + SkASSERT((isCrossProcess && fset != NULL) || (!isCrossProcess && NULL == fset)); 1.80 + if (isCrossProcess) { 1.81 + this->setNamedFactorySet(fset); 1.82 + } 1.83 + } 1.84 + 1.85 + ~FlattenableHeap() { 1.86 + fPointers.freeAll(); 1.87 + } 1.88 + 1.89 + virtual void* allocThrow(size_t bytes) SK_OVERRIDE; 1.90 + 1.91 + virtual void unalloc(void* ptr) SK_OVERRIDE; 1.92 + 1.93 + void setBitmapStorage(SkBitmapHeap* heap) { 1.94 + this->setBitmapHeap(heap); 1.95 + } 1.96 + 1.97 + const SkFlatData* flatToReplace() const; 1.98 + 1.99 + // Mark an SkFlatData as one that should not be returned by flatToReplace. 1.100 + // Takes the result of SkFlatData::index() as its parameter. 1.101 + void markFlatForKeeping(int index) { 1.102 + *fFlatsThatMustBeKept.append() = index; 1.103 + } 1.104 + 1.105 + void markAllFlatsSafeToDelete() { 1.106 + fFlatsThatMustBeKept.reset(); 1.107 + } 1.108 + 1.109 +private: 1.110 + // Keep track of the indices (i.e. the result of SkFlatData::index()) of 1.111 + // flats that must be kept, since they are on the current paint. 1.112 + SkTDArray<int> fFlatsThatMustBeKept; 1.113 + SkTDArray<void*> fPointers; 1.114 + const int fNumFlatsToKeep; 1.115 + 1.116 + typedef SkFlatController INHERITED; 1.117 +}; 1.118 + 1.119 +void FlattenableHeap::unalloc(void* ptr) { 1.120 + int indexToRemove = fPointers.rfind(ptr); 1.121 + if (indexToRemove >= 0) { 1.122 + sk_free(ptr); 1.123 + fPointers.remove(indexToRemove); 1.124 + } 1.125 +} 1.126 + 1.127 +void* FlattenableHeap::allocThrow(size_t bytes) { 1.128 + void* ptr = sk_malloc_throw(bytes); 1.129 + *fPointers.append() = ptr; 1.130 + return ptr; 1.131 +} 1.132 + 1.133 +const SkFlatData* FlattenableHeap::flatToReplace() const { 1.134 + // First, determine whether we should replace one. 1.135 + if (fPointers.count() > fNumFlatsToKeep) { 1.136 + // Look through the flattenable heap. 1.137 + // TODO: Return the LRU flat. 1.138 + for (int i = 0; i < fPointers.count(); i++) { 1.139 + SkFlatData* potential = (SkFlatData*)fPointers[i]; 1.140 + // Make sure that it is not one that must be kept. 1.141 + bool mustKeep = false; 1.142 + for (int j = 0; j < fFlatsThatMustBeKept.count(); j++) { 1.143 + if (potential->index() == fFlatsThatMustBeKept[j]) { 1.144 + mustKeep = true; 1.145 + break; 1.146 + } 1.147 + } 1.148 + if (!mustKeep) { 1.149 + return potential; 1.150 + } 1.151 + } 1.152 + } 1.153 + return NULL; 1.154 +} 1.155 + 1.156 +/////////////////////////////////////////////////////////////////////////////// 1.157 + 1.158 +struct SkFlattenableTraits { 1.159 + static void Flatten(SkWriteBuffer& buffer, const SkFlattenable& flattenable) { 1.160 + buffer.writeFlattenable(&flattenable); 1.161 + } 1.162 + // No need to define unflatten if we never call it. 1.163 +}; 1.164 +typedef SkFlatDictionary<SkFlattenable, SkFlattenableTraits> FlatDictionary; 1.165 + 1.166 +/////////////////////////////////////////////////////////////////////////////// 1.167 + 1.168 +/** 1.169 + * If SkBitmaps are to be flattened to send to the reader, this class is 1.170 + * provided to the SkBitmapHeap to tell the SkGPipeCanvas to do so. 1.171 + */ 1.172 +class BitmapShuttle : public SkBitmapHeap::ExternalStorage { 1.173 +public: 1.174 + BitmapShuttle(SkGPipeCanvas*); 1.175 + 1.176 + ~BitmapShuttle(); 1.177 + 1.178 + virtual bool insert(const SkBitmap& bitmap, int32_t slot) SK_OVERRIDE; 1.179 + 1.180 + /** 1.181 + * Remove the SkGPipeCanvas used for insertion. After this, calls to 1.182 + * insert will crash. 1.183 + */ 1.184 + void removeCanvas(); 1.185 + 1.186 +private: 1.187 + SkGPipeCanvas* fCanvas; 1.188 +}; 1.189 + 1.190 +/////////////////////////////////////////////////////////////////////////////// 1.191 + 1.192 +class SkGPipeCanvas : public SkCanvas { 1.193 +public: 1.194 + SkGPipeCanvas(SkGPipeController*, SkWriter32*, uint32_t flags, 1.195 + uint32_t width, uint32_t height); 1.196 + virtual ~SkGPipeCanvas(); 1.197 + 1.198 + /** 1.199 + * Called when nothing else is to be written to the stream. Any repeated 1.200 + * calls are ignored. 1.201 + * 1.202 + * @param notifyReaders Whether to send a message to the reader(s) that 1.203 + * the writer is through sending commands. Should generally be true, 1.204 + * unless there is an error which prevents further messages from 1.205 + * being sent. 1.206 + */ 1.207 + void finish(bool notifyReaders) { 1.208 + if (fDone) { 1.209 + return; 1.210 + } 1.211 + if (notifyReaders && this->needOpBytes()) { 1.212 + this->writeOp(kDone_DrawOp); 1.213 + this->doNotify(); 1.214 + } 1.215 + if (shouldFlattenBitmaps(fFlags)) { 1.216 + // The following circular references exist: 1.217 + // fFlattenableHeap -> fWriteBuffer -> fBitmapStorage -> fExternalStorage -> fCanvas 1.218 + // fBitmapHeap -> fExternalStorage -> fCanvas 1.219 + // fFlattenableHeap -> fBitmapStorage -> fExternalStorage -> fCanvas 1.220 + 1.221 + // Break them all by destroying the final link to this SkGPipeCanvas. 1.222 + fBitmapShuttle->removeCanvas(); 1.223 + } 1.224 + fDone = true; 1.225 + } 1.226 + 1.227 + void flushRecording(bool detachCurrentBlock); 1.228 + size_t freeMemoryIfPossible(size_t bytesToFree); 1.229 + 1.230 + size_t storageAllocatedForRecording() { 1.231 + return (NULL == fBitmapHeap) ? 0 : fBitmapHeap->bytesAllocated(); 1.232 + } 1.233 + 1.234 + // overrides from SkCanvas 1.235 + virtual bool isDrawingToLayer() const SK_OVERRIDE; 1.236 + virtual void clear(SkColor) SK_OVERRIDE; 1.237 + virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE; 1.238 + virtual void drawPoints(PointMode, size_t count, const SkPoint pts[], 1.239 + const SkPaint&) SK_OVERRIDE; 1.240 + virtual void drawOval(const SkRect&, const SkPaint&) SK_OVERRIDE; 1.241 + virtual void drawRect(const SkRect& rect, const SkPaint&) SK_OVERRIDE; 1.242 + virtual void drawRRect(const SkRRect&, const SkPaint&) SK_OVERRIDE; 1.243 + virtual void drawPath(const SkPath& path, const SkPaint&) SK_OVERRIDE; 1.244 + virtual void drawBitmap(const SkBitmap&, SkScalar left, SkScalar top, 1.245 + const SkPaint*) SK_OVERRIDE; 1.246 + virtual void drawBitmapRectToRect(const SkBitmap&, const SkRect* src, 1.247 + const SkRect& dst, const SkPaint* paint, 1.248 + DrawBitmapRectFlags flags) SK_OVERRIDE; 1.249 + virtual void drawBitmapMatrix(const SkBitmap&, const SkMatrix&, 1.250 + const SkPaint*) SK_OVERRIDE; 1.251 + virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, 1.252 + const SkRect& dst, const SkPaint* paint = NULL) SK_OVERRIDE; 1.253 + virtual void drawSprite(const SkBitmap&, int left, int top, 1.254 + const SkPaint*) SK_OVERRIDE; 1.255 + virtual void drawText(const void* text, size_t byteLength, SkScalar x, 1.256 + SkScalar y, const SkPaint&) SK_OVERRIDE; 1.257 + virtual void drawPosText(const void* text, size_t byteLength, 1.258 + const SkPoint pos[], const SkPaint&) SK_OVERRIDE; 1.259 + virtual void drawPosTextH(const void* text, size_t byteLength, 1.260 + const SkScalar xpos[], SkScalar constY, 1.261 + const SkPaint&) SK_OVERRIDE; 1.262 + virtual void drawTextOnPath(const void* text, size_t byteLength, 1.263 + const SkPath& path, const SkMatrix* matrix, 1.264 + const SkPaint&) SK_OVERRIDE; 1.265 + virtual void drawPicture(SkPicture& picture) SK_OVERRIDE; 1.266 + virtual void drawVertices(VertexMode, int vertexCount, 1.267 + const SkPoint vertices[], const SkPoint texs[], 1.268 + const SkColor colors[], SkXfermode*, 1.269 + const uint16_t indices[], int indexCount, 1.270 + const SkPaint&) SK_OVERRIDE; 1.271 + virtual void drawData(const void*, size_t) SK_OVERRIDE; 1.272 + virtual void beginCommentGroup(const char* description) SK_OVERRIDE; 1.273 + virtual void addComment(const char* kywd, const char* value) SK_OVERRIDE; 1.274 + virtual void endCommentGroup() SK_OVERRIDE; 1.275 + 1.276 + /** 1.277 + * Flatten an SkBitmap to send to the reader, where it will be referenced 1.278 + * according to slot. 1.279 + */ 1.280 + bool shuttleBitmap(const SkBitmap&, int32_t slot); 1.281 + 1.282 +protected: 1.283 + virtual void willSave(SaveFlags) SK_OVERRIDE; 1.284 + virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE; 1.285 + virtual void willRestore() SK_OVERRIDE; 1.286 + 1.287 + virtual void didTranslate(SkScalar, SkScalar) SK_OVERRIDE; 1.288 + virtual void didScale(SkScalar, SkScalar) SK_OVERRIDE; 1.289 + virtual void didRotate(SkScalar) SK_OVERRIDE; 1.290 + virtual void didSkew(SkScalar, SkScalar) SK_OVERRIDE; 1.291 + virtual void didConcat(const SkMatrix&) SK_OVERRIDE; 1.292 + virtual void didSetMatrix(const SkMatrix&) SK_OVERRIDE; 1.293 + 1.294 + virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) SK_OVERRIDE; 1.295 + 1.296 + virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; 1.297 + virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; 1.298 + virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; 1.299 + virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE; 1.300 + 1.301 +private: 1.302 + enum { 1.303 + kNoSaveLayer = -1, 1.304 + }; 1.305 + SkNamedFactorySet* fFactorySet; 1.306 + int fFirstSaveLayerStackLevel; 1.307 + SkBitmapHeap* fBitmapHeap; 1.308 + SkGPipeController* fController; 1.309 + SkWriter32& fWriter; 1.310 + size_t fBlockSize; // amount allocated for writer 1.311 + size_t fBytesNotified; 1.312 + bool fDone; 1.313 + const uint32_t fFlags; 1.314 + 1.315 + SkRefCntSet fTypefaceSet; 1.316 + 1.317 + uint32_t getTypefaceID(SkTypeface*); 1.318 + 1.319 + inline void writeOp(DrawOps op, unsigned flags, unsigned data) { 1.320 + fWriter.write32(DrawOp_packOpFlagData(op, flags, data)); 1.321 + } 1.322 + 1.323 + inline void writeOp(DrawOps op) { 1.324 + fWriter.write32(DrawOp_packOpFlagData(op, 0, 0)); 1.325 + } 1.326 + 1.327 + bool needOpBytes(size_t size = 0); 1.328 + 1.329 + inline void doNotify() { 1.330 + if (!fDone) { 1.331 + size_t bytes = fWriter.bytesWritten() - fBytesNotified; 1.332 + if (bytes > 0) { 1.333 + fController->notifyWritten(bytes); 1.334 + fBytesNotified += bytes; 1.335 + } 1.336 + } 1.337 + } 1.338 + 1.339 + // Should be called after any calls to an SkFlatDictionary::findAndReplace 1.340 + // if a new SkFlatData was added when in cross process mode 1.341 + void flattenFactoryNames(); 1.342 + 1.343 + FlattenableHeap fFlattenableHeap; 1.344 + FlatDictionary fFlatDictionary; 1.345 + SkAutoTUnref<BitmapShuttle> fBitmapShuttle; 1.346 + int fCurrFlatIndex[kCount_PaintFlats]; 1.347 + 1.348 + int flattenToIndex(SkFlattenable* obj, PaintFlats); 1.349 + 1.350 + // Common code used by drawBitmap*. Behaves differently depending on the 1.351 + // type of SkBitmapHeap being used, which is determined by the flags used. 1.352 + bool commonDrawBitmap(const SkBitmap& bm, DrawOps op, unsigned flags, 1.353 + size_t opBytesNeeded, const SkPaint* paint); 1.354 + 1.355 + SkPaint fPaint; 1.356 + void writePaint(const SkPaint&); 1.357 + 1.358 + class AutoPipeNotify { 1.359 + public: 1.360 + AutoPipeNotify(SkGPipeCanvas* canvas) : fCanvas(canvas) {} 1.361 + ~AutoPipeNotify() { fCanvas->doNotify(); } 1.362 + private: 1.363 + SkGPipeCanvas* fCanvas; 1.364 + }; 1.365 + friend class AutoPipeNotify; 1.366 + 1.367 + typedef SkCanvas INHERITED; 1.368 +}; 1.369 + 1.370 +void SkGPipeCanvas::flattenFactoryNames() { 1.371 + const char* name; 1.372 + while ((name = fFactorySet->getNextAddedFactoryName()) != NULL) { 1.373 + size_t len = strlen(name); 1.374 + if (this->needOpBytes(len)) { 1.375 + this->writeOp(kDef_Factory_DrawOp); 1.376 + fWriter.writeString(name, len); 1.377 + } 1.378 + } 1.379 +} 1.380 + 1.381 +bool SkGPipeCanvas::shuttleBitmap(const SkBitmap& bm, int32_t slot) { 1.382 + SkASSERT(shouldFlattenBitmaps(fFlags)); 1.383 + SkWriteBuffer buffer; 1.384 + buffer.setNamedFactoryRecorder(fFactorySet); 1.385 + buffer.writeBitmap(bm); 1.386 + this->flattenFactoryNames(); 1.387 + uint32_t size = buffer.bytesWritten(); 1.388 + if (this->needOpBytes(size)) { 1.389 + this->writeOp(kDef_Bitmap_DrawOp, 0, slot); 1.390 + void* dst = static_cast<void*>(fWriter.reserve(size)); 1.391 + buffer.writeToMemory(dst); 1.392 + return true; 1.393 + } 1.394 + return false; 1.395 +} 1.396 + 1.397 +// return 0 for NULL (or unflattenable obj), or index-base-1 1.398 +// return ~(index-base-1) if an old flattenable was replaced 1.399 +int SkGPipeCanvas::flattenToIndex(SkFlattenable* obj, PaintFlats paintflat) { 1.400 + SkASSERT(!fDone && fBitmapHeap != NULL); 1.401 + if (NULL == obj) { 1.402 + return 0; 1.403 + } 1.404 + 1.405 + fBitmapHeap->deferAddingOwners(); 1.406 + bool added, replaced; 1.407 + const SkFlatData* flat = fFlatDictionary.findAndReplace(*obj, fFlattenableHeap.flatToReplace(), 1.408 + &added, &replaced); 1.409 + fBitmapHeap->endAddingOwnersDeferral(added); 1.410 + int index = flat->index(); 1.411 + if (added) { 1.412 + if (isCrossProcess(fFlags)) { 1.413 + this->flattenFactoryNames(); 1.414 + } 1.415 + size_t flatSize = flat->flatSize(); 1.416 + if (this->needOpBytes(flatSize)) { 1.417 + this->writeOp(kDef_Flattenable_DrawOp, paintflat, index); 1.418 + fWriter.write(flat->data(), flatSize); 1.419 + } 1.420 + } 1.421 + if (replaced) { 1.422 + index = ~index; 1.423 + } 1.424 + return index; 1.425 +} 1.426 + 1.427 +/////////////////////////////////////////////////////////////////////////////// 1.428 + 1.429 +#define MIN_BLOCK_SIZE (16 * 1024) 1.430 +#define BITMAPS_TO_KEEP 5 1.431 +#define FLATTENABLES_TO_KEEP 10 1.432 + 1.433 +SkGPipeCanvas::SkGPipeCanvas(SkGPipeController* controller, 1.434 + SkWriter32* writer, uint32_t flags, 1.435 + uint32_t width, uint32_t height) 1.436 + : SkCanvas(width, height) 1.437 + , fFactorySet(isCrossProcess(flags) ? SkNEW(SkNamedFactorySet) : NULL) 1.438 + , fWriter(*writer) 1.439 + , fFlags(flags) 1.440 + , fFlattenableHeap(FLATTENABLES_TO_KEEP, fFactorySet, isCrossProcess(flags)) 1.441 + , fFlatDictionary(&fFlattenableHeap) 1.442 +{ 1.443 + fController = controller; 1.444 + fDone = false; 1.445 + fBlockSize = 0; // need first block from controller 1.446 + fBytesNotified = 0; 1.447 + fFirstSaveLayerStackLevel = kNoSaveLayer; 1.448 + sk_bzero(fCurrFlatIndex, sizeof(fCurrFlatIndex)); 1.449 + 1.450 + // Tell the reader the appropriate flags to use. 1.451 + if (this->needOpBytes()) { 1.452 + this->writeOp(kReportFlags_DrawOp, fFlags, 0); 1.453 + } 1.454 + 1.455 + if (shouldFlattenBitmaps(flags)) { 1.456 + fBitmapShuttle.reset(SkNEW_ARGS(BitmapShuttle, (this))); 1.457 + fBitmapHeap = SkNEW_ARGS(SkBitmapHeap, (fBitmapShuttle.get(), BITMAPS_TO_KEEP)); 1.458 + } else { 1.459 + fBitmapHeap = SkNEW_ARGS(SkBitmapHeap, 1.460 + (BITMAPS_TO_KEEP, controller->numberOfReaders())); 1.461 + if (this->needOpBytes(sizeof(void*))) { 1.462 + this->writeOp(kShareBitmapHeap_DrawOp); 1.463 + fWriter.writePtr(static_cast<void*>(fBitmapHeap)); 1.464 + } 1.465 + } 1.466 + fFlattenableHeap.setBitmapStorage(fBitmapHeap); 1.467 + this->doNotify(); 1.468 +} 1.469 + 1.470 +SkGPipeCanvas::~SkGPipeCanvas() { 1.471 + this->finish(true); 1.472 + SkSafeUnref(fFactorySet); 1.473 + SkSafeUnref(fBitmapHeap); 1.474 +} 1.475 + 1.476 +bool SkGPipeCanvas::needOpBytes(size_t needed) { 1.477 + if (fDone) { 1.478 + return false; 1.479 + } 1.480 + 1.481 + needed += 4; // size of DrawOp atom 1.482 + if (fWriter.bytesWritten() + needed > fBlockSize) { 1.483 + // Before we wipe out any data that has already been written, read it 1.484 + // out. 1.485 + this->doNotify(); 1.486 + size_t blockSize = SkMax32(MIN_BLOCK_SIZE, needed); 1.487 + void* block = fController->requestBlock(blockSize, &fBlockSize); 1.488 + if (NULL == block) { 1.489 + // Do not notify the readers, which would call this function again. 1.490 + this->finish(false); 1.491 + return false; 1.492 + } 1.493 + SkASSERT(SkIsAlign4(fBlockSize)); 1.494 + fWriter.reset(block, fBlockSize); 1.495 + fBytesNotified = 0; 1.496 + } 1.497 + return true; 1.498 +} 1.499 + 1.500 +uint32_t SkGPipeCanvas::getTypefaceID(SkTypeface* face) { 1.501 + uint32_t id = 0; // 0 means default/null typeface 1.502 + if (face) { 1.503 + id = fTypefaceSet.find(face); 1.504 + if (0 == id) { 1.505 + id = fTypefaceSet.add(face); 1.506 + size_t size = writeTypeface(NULL, face); 1.507 + if (this->needOpBytes(size)) { 1.508 + this->writeOp(kDef_Typeface_DrawOp); 1.509 + writeTypeface(&fWriter, face); 1.510 + } 1.511 + } 1.512 + } 1.513 + return id; 1.514 +} 1.515 + 1.516 +/////////////////////////////////////////////////////////////////////////////// 1.517 + 1.518 +#define NOTIFY_SETUP(canvas) \ 1.519 + AutoPipeNotify apn(canvas) 1.520 + 1.521 +void SkGPipeCanvas::willSave(SaveFlags flags) { 1.522 + NOTIFY_SETUP(this); 1.523 + if (this->needOpBytes()) { 1.524 + this->writeOp(kSave_DrawOp, 0, flags); 1.525 + } 1.526 + 1.527 + this->INHERITED::willSave(flags); 1.528 +} 1.529 + 1.530 +SkCanvas::SaveLayerStrategy SkGPipeCanvas::willSaveLayer(const SkRect* bounds, const SkPaint* paint, 1.531 + SaveFlags saveFlags) { 1.532 + NOTIFY_SETUP(this); 1.533 + size_t size = 0; 1.534 + unsigned opFlags = 0; 1.535 + 1.536 + if (bounds) { 1.537 + opFlags |= kSaveLayer_HasBounds_DrawOpFlag; 1.538 + size += sizeof(SkRect); 1.539 + } 1.540 + if (paint) { 1.541 + opFlags |= kSaveLayer_HasPaint_DrawOpFlag; 1.542 + this->writePaint(*paint); 1.543 + } 1.544 + 1.545 + if (this->needOpBytes(size)) { 1.546 + this->writeOp(kSaveLayer_DrawOp, opFlags, saveFlags); 1.547 + if (bounds) { 1.548 + fWriter.writeRect(*bounds); 1.549 + } 1.550 + } 1.551 + 1.552 + if (kNoSaveLayer == fFirstSaveLayerStackLevel){ 1.553 + fFirstSaveLayerStackLevel = this->getSaveCount(); 1.554 + } 1.555 + 1.556 + this->INHERITED::willSaveLayer(bounds, paint, saveFlags); 1.557 + // we don't create a layer 1.558 + return kNoLayer_SaveLayerStrategy; 1.559 +} 1.560 + 1.561 +void SkGPipeCanvas::willRestore() { 1.562 + NOTIFY_SETUP(this); 1.563 + if (this->needOpBytes()) { 1.564 + this->writeOp(kRestore_DrawOp); 1.565 + } 1.566 + 1.567 + if (this->getSaveCount() - 1 == fFirstSaveLayerStackLevel){ 1.568 + fFirstSaveLayerStackLevel = kNoSaveLayer; 1.569 + } 1.570 + 1.571 + this->INHERITED::willRestore(); 1.572 +} 1.573 + 1.574 +bool SkGPipeCanvas::isDrawingToLayer() const { 1.575 + return kNoSaveLayer != fFirstSaveLayerStackLevel; 1.576 +} 1.577 + 1.578 +void SkGPipeCanvas::didTranslate(SkScalar dx, SkScalar dy) { 1.579 + if (dx || dy) { 1.580 + NOTIFY_SETUP(this); 1.581 + if (this->needOpBytes(2 * sizeof(SkScalar))) { 1.582 + this->writeOp(kTranslate_DrawOp); 1.583 + fWriter.writeScalar(dx); 1.584 + fWriter.writeScalar(dy); 1.585 + } 1.586 + } 1.587 + this->INHERITED::didTranslate(dx, dy); 1.588 +} 1.589 + 1.590 +void SkGPipeCanvas::didScale(SkScalar sx, SkScalar sy) { 1.591 + if (sx || sy) { 1.592 + NOTIFY_SETUP(this); 1.593 + if (this->needOpBytes(2 * sizeof(SkScalar))) { 1.594 + this->writeOp(kScale_DrawOp); 1.595 + fWriter.writeScalar(sx); 1.596 + fWriter.writeScalar(sy); 1.597 + } 1.598 + } 1.599 + this->INHERITED::didScale(sx, sy); 1.600 +} 1.601 + 1.602 +void SkGPipeCanvas::didRotate(SkScalar degrees) { 1.603 + if (degrees) { 1.604 + NOTIFY_SETUP(this); 1.605 + if (this->needOpBytes(sizeof(SkScalar))) { 1.606 + this->writeOp(kRotate_DrawOp); 1.607 + fWriter.writeScalar(degrees); 1.608 + } 1.609 + } 1.610 + this->INHERITED::didRotate(degrees); 1.611 +} 1.612 + 1.613 +void SkGPipeCanvas::didSkew(SkScalar sx, SkScalar sy) { 1.614 + if (sx || sy) { 1.615 + NOTIFY_SETUP(this); 1.616 + if (this->needOpBytes(2 * sizeof(SkScalar))) { 1.617 + this->writeOp(kSkew_DrawOp); 1.618 + fWriter.writeScalar(sx); 1.619 + fWriter.writeScalar(sy); 1.620 + } 1.621 + } 1.622 + this->INHERITED::didSkew(sx, sy); 1.623 +} 1.624 + 1.625 +void SkGPipeCanvas::didConcat(const SkMatrix& matrix) { 1.626 + if (!matrix.isIdentity()) { 1.627 + NOTIFY_SETUP(this); 1.628 + if (this->needOpBytes(matrix.writeToMemory(NULL))) { 1.629 + this->writeOp(kConcat_DrawOp); 1.630 + fWriter.writeMatrix(matrix); 1.631 + } 1.632 + } 1.633 + this->INHERITED::didConcat(matrix); 1.634 +} 1.635 + 1.636 +void SkGPipeCanvas::didSetMatrix(const SkMatrix& matrix) { 1.637 + NOTIFY_SETUP(this); 1.638 + if (this->needOpBytes(matrix.writeToMemory(NULL))) { 1.639 + this->writeOp(kSetMatrix_DrawOp); 1.640 + fWriter.writeMatrix(matrix); 1.641 + } 1.642 + this->INHERITED::didSetMatrix(matrix); 1.643 +} 1.644 + 1.645 +void SkGPipeCanvas::onClipRect(const SkRect& rect, SkRegion::Op rgnOp, 1.646 + ClipEdgeStyle edgeStyle) { 1.647 + NOTIFY_SETUP(this); 1.648 + if (this->needOpBytes(sizeof(SkRect))) { 1.649 + unsigned flags = 0; 1.650 + if (kSoft_ClipEdgeStyle == edgeStyle) { 1.651 + flags = kClip_HasAntiAlias_DrawOpFlag; 1.652 + } 1.653 + this->writeOp(kClipRect_DrawOp, flags, rgnOp); 1.654 + fWriter.writeRect(rect); 1.655 + } 1.656 + this->INHERITED::onClipRect(rect, rgnOp, edgeStyle); 1.657 +} 1.658 + 1.659 +void SkGPipeCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op rgnOp, 1.660 + ClipEdgeStyle edgeStyle) { 1.661 + NOTIFY_SETUP(this); 1.662 + if (this->needOpBytes(kSizeOfFlatRRect)) { 1.663 + unsigned flags = 0; 1.664 + if (kSoft_ClipEdgeStyle == edgeStyle) { 1.665 + flags = kClip_HasAntiAlias_DrawOpFlag; 1.666 + } 1.667 + this->writeOp(kClipRRect_DrawOp, flags, rgnOp); 1.668 + fWriter.writeRRect(rrect); 1.669 + } 1.670 + this->INHERITED::onClipRRect(rrect, rgnOp, edgeStyle); 1.671 +} 1.672 + 1.673 +void SkGPipeCanvas::onClipPath(const SkPath& path, SkRegion::Op rgnOp, 1.674 + ClipEdgeStyle edgeStyle) { 1.675 + NOTIFY_SETUP(this); 1.676 + if (this->needOpBytes(path.writeToMemory(NULL))) { 1.677 + unsigned flags = 0; 1.678 + if (kSoft_ClipEdgeStyle == edgeStyle) { 1.679 + flags = kClip_HasAntiAlias_DrawOpFlag; 1.680 + } 1.681 + this->writeOp(kClipPath_DrawOp, flags, rgnOp); 1.682 + fWriter.writePath(path); 1.683 + } 1.684 + // we just pass on the bounds of the path 1.685 + this->INHERITED::onClipRect(path.getBounds(), rgnOp, edgeStyle); 1.686 +} 1.687 + 1.688 +void SkGPipeCanvas::onClipRegion(const SkRegion& region, SkRegion::Op rgnOp) { 1.689 + NOTIFY_SETUP(this); 1.690 + if (this->needOpBytes(region.writeToMemory(NULL))) { 1.691 + this->writeOp(kClipRegion_DrawOp, 0, rgnOp); 1.692 + fWriter.writeRegion(region); 1.693 + } 1.694 + this->INHERITED::onClipRegion(region, rgnOp); 1.695 +} 1.696 + 1.697 +/////////////////////////////////////////////////////////////////////////////// 1.698 + 1.699 +void SkGPipeCanvas::clear(SkColor color) { 1.700 + NOTIFY_SETUP(this); 1.701 + unsigned flags = 0; 1.702 + if (color) { 1.703 + flags |= kClear_HasColor_DrawOpFlag; 1.704 + } 1.705 + if (this->needOpBytes(sizeof(SkColor))) { 1.706 + this->writeOp(kDrawClear_DrawOp, flags, 0); 1.707 + if (color) { 1.708 + fWriter.write32(color); 1.709 + } 1.710 + } 1.711 +} 1.712 + 1.713 +void SkGPipeCanvas::drawPaint(const SkPaint& paint) { 1.714 + NOTIFY_SETUP(this); 1.715 + this->writePaint(paint); 1.716 + if (this->needOpBytes()) { 1.717 + this->writeOp(kDrawPaint_DrawOp); 1.718 + } 1.719 +} 1.720 + 1.721 +void SkGPipeCanvas::drawPoints(PointMode mode, size_t count, 1.722 + const SkPoint pts[], const SkPaint& paint) { 1.723 + if (count) { 1.724 + NOTIFY_SETUP(this); 1.725 + this->writePaint(paint); 1.726 + if (this->needOpBytes(4 + count * sizeof(SkPoint))) { 1.727 + this->writeOp(kDrawPoints_DrawOp, mode, 0); 1.728 + fWriter.write32(count); 1.729 + fWriter.write(pts, count * sizeof(SkPoint)); 1.730 + } 1.731 + } 1.732 +} 1.733 + 1.734 +void SkGPipeCanvas::drawOval(const SkRect& rect, const SkPaint& paint) { 1.735 + NOTIFY_SETUP(this); 1.736 + this->writePaint(paint); 1.737 + if (this->needOpBytes(sizeof(SkRect))) { 1.738 + this->writeOp(kDrawOval_DrawOp); 1.739 + fWriter.writeRect(rect); 1.740 + } 1.741 +} 1.742 + 1.743 +void SkGPipeCanvas::drawRect(const SkRect& rect, const SkPaint& paint) { 1.744 + NOTIFY_SETUP(this); 1.745 + this->writePaint(paint); 1.746 + if (this->needOpBytes(sizeof(SkRect))) { 1.747 + this->writeOp(kDrawRect_DrawOp); 1.748 + fWriter.writeRect(rect); 1.749 + } 1.750 +} 1.751 + 1.752 +void SkGPipeCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { 1.753 + NOTIFY_SETUP(this); 1.754 + this->writePaint(paint); 1.755 + if (this->needOpBytes(kSizeOfFlatRRect)) { 1.756 + this->writeOp(kDrawRRect_DrawOp); 1.757 + fWriter.writeRRect(rrect); 1.758 + } 1.759 +} 1.760 + 1.761 +void SkGPipeCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, 1.762 + const SkPaint& paint) { 1.763 + NOTIFY_SETUP(this); 1.764 + this->writePaint(paint); 1.765 + if (this->needOpBytes(kSizeOfFlatRRect * 2)) { 1.766 + this->writeOp(kDrawDRRect_DrawOp); 1.767 + fWriter.writeRRect(outer); 1.768 + fWriter.writeRRect(inner); 1.769 + } 1.770 +} 1.771 + 1.772 +void SkGPipeCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 1.773 + NOTIFY_SETUP(this); 1.774 + this->writePaint(paint); 1.775 + if (this->needOpBytes(path.writeToMemory(NULL))) { 1.776 + this->writeOp(kDrawPath_DrawOp); 1.777 + fWriter.writePath(path); 1.778 + } 1.779 +} 1.780 + 1.781 +bool SkGPipeCanvas::commonDrawBitmap(const SkBitmap& bm, DrawOps op, 1.782 + unsigned flags, 1.783 + size_t opBytesNeeded, 1.784 + const SkPaint* paint) { 1.785 + if (paint != NULL) { 1.786 + flags |= kDrawBitmap_HasPaint_DrawOpFlag; 1.787 + this->writePaint(*paint); 1.788 + } 1.789 + if (this->needOpBytes(opBytesNeeded)) { 1.790 + SkASSERT(fBitmapHeap != NULL); 1.791 + int32_t bitmapIndex = fBitmapHeap->insert(bm); 1.792 + if (SkBitmapHeap::INVALID_SLOT == bitmapIndex) { 1.793 + return false; 1.794 + } 1.795 + this->writeOp(op, flags, bitmapIndex); 1.796 + return true; 1.797 + } 1.798 + return false; 1.799 +} 1.800 + 1.801 +void SkGPipeCanvas::drawBitmap(const SkBitmap& bm, SkScalar left, SkScalar top, 1.802 + const SkPaint* paint) { 1.803 + NOTIFY_SETUP(this); 1.804 + size_t opBytesNeeded = sizeof(SkScalar) * 2; 1.805 + 1.806 + if (this->commonDrawBitmap(bm, kDrawBitmap_DrawOp, 0, opBytesNeeded, paint)) { 1.807 + fWriter.writeScalar(left); 1.808 + fWriter.writeScalar(top); 1.809 + } 1.810 +} 1.811 + 1.812 +void SkGPipeCanvas::drawBitmapRectToRect(const SkBitmap& bm, const SkRect* src, 1.813 + const SkRect& dst, const SkPaint* paint, 1.814 + DrawBitmapRectFlags dbmrFlags) { 1.815 + NOTIFY_SETUP(this); 1.816 + size_t opBytesNeeded = sizeof(SkRect); 1.817 + bool hasSrc = src != NULL; 1.818 + unsigned flags; 1.819 + if (hasSrc) { 1.820 + flags = kDrawBitmap_HasSrcRect_DrawOpFlag; 1.821 + opBytesNeeded += sizeof(int32_t) * 4; 1.822 + } else { 1.823 + flags = 0; 1.824 + } 1.825 + if (dbmrFlags & kBleed_DrawBitmapRectFlag) { 1.826 + flags |= kDrawBitmap_Bleed_DrawOpFlag; 1.827 + } 1.828 + 1.829 + if (this->commonDrawBitmap(bm, kDrawBitmapRectToRect_DrawOp, flags, opBytesNeeded, paint)) { 1.830 + if (hasSrc) { 1.831 + fWriter.writeRect(*src); 1.832 + } 1.833 + fWriter.writeRect(dst); 1.834 + } 1.835 +} 1.836 + 1.837 +void SkGPipeCanvas::drawBitmapMatrix(const SkBitmap& bm, const SkMatrix& matrix, 1.838 + const SkPaint* paint) { 1.839 + NOTIFY_SETUP(this); 1.840 + size_t opBytesNeeded = matrix.writeToMemory(NULL); 1.841 + 1.842 + if (this->commonDrawBitmap(bm, kDrawBitmapMatrix_DrawOp, 0, opBytesNeeded, paint)) { 1.843 + fWriter.writeMatrix(matrix); 1.844 + } 1.845 +} 1.846 + 1.847 +void SkGPipeCanvas::drawBitmapNine(const SkBitmap& bm, const SkIRect& center, 1.848 + const SkRect& dst, const SkPaint* paint) { 1.849 + NOTIFY_SETUP(this); 1.850 + size_t opBytesNeeded = sizeof(int32_t) * 4 + sizeof(SkRect); 1.851 + 1.852 + if (this->commonDrawBitmap(bm, kDrawBitmapNine_DrawOp, 0, opBytesNeeded, paint)) { 1.853 + fWriter.write32(center.fLeft); 1.854 + fWriter.write32(center.fTop); 1.855 + fWriter.write32(center.fRight); 1.856 + fWriter.write32(center.fBottom); 1.857 + fWriter.writeRect(dst); 1.858 + } 1.859 +} 1.860 + 1.861 +void SkGPipeCanvas::drawSprite(const SkBitmap& bm, int left, int top, 1.862 + const SkPaint* paint) { 1.863 + NOTIFY_SETUP(this); 1.864 + size_t opBytesNeeded = sizeof(int32_t) * 2; 1.865 + 1.866 + if (this->commonDrawBitmap(bm, kDrawSprite_DrawOp, 0, opBytesNeeded, paint)) { 1.867 + fWriter.write32(left); 1.868 + fWriter.write32(top); 1.869 + } 1.870 +} 1.871 + 1.872 +void SkGPipeCanvas::drawText(const void* text, size_t byteLength, SkScalar x, 1.873 + SkScalar y, const SkPaint& paint) { 1.874 + if (byteLength) { 1.875 + NOTIFY_SETUP(this); 1.876 + this->writePaint(paint); 1.877 + if (this->needOpBytes(4 + SkAlign4(byteLength) + 2 * sizeof(SkScalar))) { 1.878 + this->writeOp(kDrawText_DrawOp); 1.879 + fWriter.write32(byteLength); 1.880 + fWriter.writePad(text, byteLength); 1.881 + fWriter.writeScalar(x); 1.882 + fWriter.writeScalar(y); 1.883 + } 1.884 + } 1.885 +} 1.886 + 1.887 +void SkGPipeCanvas::drawPosText(const void* text, size_t byteLength, 1.888 + const SkPoint pos[], const SkPaint& paint) { 1.889 + if (byteLength) { 1.890 + NOTIFY_SETUP(this); 1.891 + this->writePaint(paint); 1.892 + int count = paint.textToGlyphs(text, byteLength, NULL); 1.893 + if (this->needOpBytes(4 + SkAlign4(byteLength) + 4 + count * sizeof(SkPoint))) { 1.894 + this->writeOp(kDrawPosText_DrawOp); 1.895 + fWriter.write32(byteLength); 1.896 + fWriter.writePad(text, byteLength); 1.897 + fWriter.write32(count); 1.898 + fWriter.write(pos, count * sizeof(SkPoint)); 1.899 + } 1.900 + } 1.901 +} 1.902 + 1.903 +void SkGPipeCanvas::drawPosTextH(const void* text, size_t byteLength, 1.904 + const SkScalar xpos[], SkScalar constY, 1.905 + const SkPaint& paint) { 1.906 + if (byteLength) { 1.907 + NOTIFY_SETUP(this); 1.908 + this->writePaint(paint); 1.909 + int count = paint.textToGlyphs(text, byteLength, NULL); 1.910 + if (this->needOpBytes(4 + SkAlign4(byteLength) + 4 + count * sizeof(SkScalar) + 4)) { 1.911 + this->writeOp(kDrawPosTextH_DrawOp); 1.912 + fWriter.write32(byteLength); 1.913 + fWriter.writePad(text, byteLength); 1.914 + fWriter.write32(count); 1.915 + fWriter.write(xpos, count * sizeof(SkScalar)); 1.916 + fWriter.writeScalar(constY); 1.917 + } 1.918 + } 1.919 +} 1.920 + 1.921 +void SkGPipeCanvas::drawTextOnPath(const void* text, size_t byteLength, 1.922 + const SkPath& path, const SkMatrix* matrix, 1.923 + const SkPaint& paint) { 1.924 + if (byteLength) { 1.925 + NOTIFY_SETUP(this); 1.926 + unsigned flags = 0; 1.927 + size_t size = 4 + SkAlign4(byteLength) + path.writeToMemory(NULL); 1.928 + if (matrix) { 1.929 + flags |= kDrawTextOnPath_HasMatrix_DrawOpFlag; 1.930 + size += matrix->writeToMemory(NULL); 1.931 + } 1.932 + this->writePaint(paint); 1.933 + if (this->needOpBytes(size)) { 1.934 + this->writeOp(kDrawTextOnPath_DrawOp, flags, 0); 1.935 + 1.936 + fWriter.write32(byteLength); 1.937 + fWriter.writePad(text, byteLength); 1.938 + 1.939 + fWriter.writePath(path); 1.940 + if (matrix) { 1.941 + fWriter.writeMatrix(*matrix); 1.942 + } 1.943 + } 1.944 + } 1.945 +} 1.946 + 1.947 +void SkGPipeCanvas::drawPicture(SkPicture& picture) { 1.948 + // we want to playback the picture into individual draw calls 1.949 + this->INHERITED::drawPicture(picture); 1.950 +} 1.951 + 1.952 +void SkGPipeCanvas::drawVertices(VertexMode vmode, int vertexCount, 1.953 + const SkPoint vertices[], const SkPoint texs[], 1.954 + const SkColor colors[], SkXfermode* xfer, 1.955 + const uint16_t indices[], int indexCount, 1.956 + const SkPaint& paint) { 1.957 + if (0 == vertexCount) { 1.958 + return; 1.959 + } 1.960 + 1.961 + NOTIFY_SETUP(this); 1.962 + size_t size = 4 + vertexCount * sizeof(SkPoint); 1.963 + this->writePaint(paint); 1.964 + unsigned flags = 0; 1.965 + if (texs) { 1.966 + flags |= kDrawVertices_HasTexs_DrawOpFlag; 1.967 + size += vertexCount * sizeof(SkPoint); 1.968 + } 1.969 + if (colors) { 1.970 + flags |= kDrawVertices_HasColors_DrawOpFlag; 1.971 + size += vertexCount * sizeof(SkColor); 1.972 + } 1.973 + if (indices && indexCount > 0) { 1.974 + flags |= kDrawVertices_HasIndices_DrawOpFlag; 1.975 + size += 4 + SkAlign4(indexCount * sizeof(uint16_t)); 1.976 + } 1.977 + if (xfer && !SkXfermode::IsMode(xfer, SkXfermode::kModulate_Mode)) { 1.978 + flags |= kDrawVertices_HasXfermode_DrawOpFlag; 1.979 + size += sizeof(int32_t); // mode enum 1.980 + } 1.981 + 1.982 + if (this->needOpBytes(size)) { 1.983 + this->writeOp(kDrawVertices_DrawOp, flags, 0); 1.984 + fWriter.write32(vmode); 1.985 + fWriter.write32(vertexCount); 1.986 + fWriter.write(vertices, vertexCount * sizeof(SkPoint)); 1.987 + if (texs) { 1.988 + fWriter.write(texs, vertexCount * sizeof(SkPoint)); 1.989 + } 1.990 + if (colors) { 1.991 + fWriter.write(colors, vertexCount * sizeof(SkColor)); 1.992 + } 1.993 + if (flags & kDrawVertices_HasXfermode_DrawOpFlag) { 1.994 + SkXfermode::Mode mode = SkXfermode::kModulate_Mode; 1.995 + (void)xfer->asMode(&mode); 1.996 + fWriter.write32(mode); 1.997 + } 1.998 + if (indices && indexCount > 0) { 1.999 + fWriter.write32(indexCount); 1.1000 + fWriter.writePad(indices, indexCount * sizeof(uint16_t)); 1.1001 + } 1.1002 + } 1.1003 +} 1.1004 + 1.1005 +void SkGPipeCanvas::drawData(const void* ptr, size_t size) { 1.1006 + if (size && ptr) { 1.1007 + NOTIFY_SETUP(this); 1.1008 + unsigned data = 0; 1.1009 + if (size < (1 << DRAWOPS_DATA_BITS)) { 1.1010 + data = (unsigned)size; 1.1011 + } 1.1012 + if (this->needOpBytes(4 + SkAlign4(size))) { 1.1013 + this->writeOp(kDrawData_DrawOp, 0, data); 1.1014 + if (0 == data) { 1.1015 + fWriter.write32(size); 1.1016 + } 1.1017 + fWriter.writePad(ptr, size); 1.1018 + } 1.1019 + } 1.1020 +} 1.1021 + 1.1022 +void SkGPipeCanvas::beginCommentGroup(const char* description) { 1.1023 + // ignore for now 1.1024 +} 1.1025 + 1.1026 +void SkGPipeCanvas::addComment(const char* kywd, const char* value) { 1.1027 + // ignore for now 1.1028 +} 1.1029 + 1.1030 +void SkGPipeCanvas::endCommentGroup() { 1.1031 + // ignore for now 1.1032 +} 1.1033 + 1.1034 +void SkGPipeCanvas::flushRecording(bool detachCurrentBlock) { 1.1035 + doNotify(); 1.1036 + if (detachCurrentBlock) { 1.1037 + // force a new block to be requested for the next recorded command 1.1038 + fBlockSize = 0; 1.1039 + } 1.1040 +} 1.1041 + 1.1042 +size_t SkGPipeCanvas::freeMemoryIfPossible(size_t bytesToFree) { 1.1043 + return (NULL == fBitmapHeap) ? 0 : fBitmapHeap->freeMemoryIfPossible(bytesToFree); 1.1044 +} 1.1045 + 1.1046 +/////////////////////////////////////////////////////////////////////////////// 1.1047 + 1.1048 +template <typename T> uint32_t castToU32(T value) { 1.1049 + union { 1.1050 + T fSrc; 1.1051 + uint32_t fDst; 1.1052 + } data; 1.1053 + data.fSrc = value; 1.1054 + return data.fDst; 1.1055 +} 1.1056 + 1.1057 +void SkGPipeCanvas::writePaint(const SkPaint& paint) { 1.1058 + if (fDone) { 1.1059 + return; 1.1060 + } 1.1061 + SkPaint& base = fPaint; 1.1062 + uint32_t storage[32]; 1.1063 + uint32_t* ptr = storage; 1.1064 + 1.1065 + if (base.getFlags() != paint.getFlags()) { 1.1066 + *ptr++ = PaintOp_packOpData(kFlags_PaintOp, paint.getFlags()); 1.1067 + base.setFlags(paint.getFlags()); 1.1068 + } 1.1069 + if (base.getColor() != paint.getColor()) { 1.1070 + *ptr++ = PaintOp_packOp(kColor_PaintOp); 1.1071 + *ptr++ = paint.getColor(); 1.1072 + base.setColor(paint.getColor()); 1.1073 + } 1.1074 + if (base.getStyle() != paint.getStyle()) { 1.1075 + *ptr++ = PaintOp_packOpData(kStyle_PaintOp, paint.getStyle()); 1.1076 + base.setStyle(paint.getStyle()); 1.1077 + } 1.1078 + if (base.getStrokeJoin() != paint.getStrokeJoin()) { 1.1079 + *ptr++ = PaintOp_packOpData(kJoin_PaintOp, paint.getStrokeJoin()); 1.1080 + base.setStrokeJoin(paint.getStrokeJoin()); 1.1081 + } 1.1082 + if (base.getStrokeCap() != paint.getStrokeCap()) { 1.1083 + *ptr++ = PaintOp_packOpData(kCap_PaintOp, paint.getStrokeCap()); 1.1084 + base.setStrokeCap(paint.getStrokeCap()); 1.1085 + } 1.1086 + if (base.getStrokeWidth() != paint.getStrokeWidth()) { 1.1087 + *ptr++ = PaintOp_packOp(kWidth_PaintOp); 1.1088 + *ptr++ = castToU32(paint.getStrokeWidth()); 1.1089 + base.setStrokeWidth(paint.getStrokeWidth()); 1.1090 + } 1.1091 + if (base.getStrokeMiter() != paint.getStrokeMiter()) { 1.1092 + *ptr++ = PaintOp_packOp(kMiter_PaintOp); 1.1093 + *ptr++ = castToU32(paint.getStrokeMiter()); 1.1094 + base.setStrokeMiter(paint.getStrokeMiter()); 1.1095 + } 1.1096 + if (base.getTextEncoding() != paint.getTextEncoding()) { 1.1097 + *ptr++ = PaintOp_packOpData(kEncoding_PaintOp, paint.getTextEncoding()); 1.1098 + base.setTextEncoding(paint.getTextEncoding()); 1.1099 + } 1.1100 + if (base.getHinting() != paint.getHinting()) { 1.1101 + *ptr++ = PaintOp_packOpData(kHinting_PaintOp, paint.getHinting()); 1.1102 + base.setHinting(paint.getHinting()); 1.1103 + } 1.1104 + if (base.getTextAlign() != paint.getTextAlign()) { 1.1105 + *ptr++ = PaintOp_packOpData(kAlign_PaintOp, paint.getTextAlign()); 1.1106 + base.setTextAlign(paint.getTextAlign()); 1.1107 + } 1.1108 + if (base.getTextSize() != paint.getTextSize()) { 1.1109 + *ptr++ = PaintOp_packOp(kTextSize_PaintOp); 1.1110 + *ptr++ = castToU32(paint.getTextSize()); 1.1111 + base.setTextSize(paint.getTextSize()); 1.1112 + } 1.1113 + if (base.getTextScaleX() != paint.getTextScaleX()) { 1.1114 + *ptr++ = PaintOp_packOp(kTextScaleX_PaintOp); 1.1115 + *ptr++ = castToU32(paint.getTextScaleX()); 1.1116 + base.setTextScaleX(paint.getTextScaleX()); 1.1117 + } 1.1118 + if (base.getTextSkewX() != paint.getTextSkewX()) { 1.1119 + *ptr++ = PaintOp_packOp(kTextSkewX_PaintOp); 1.1120 + *ptr++ = castToU32(paint.getTextSkewX()); 1.1121 + base.setTextSkewX(paint.getTextSkewX()); 1.1122 + } 1.1123 + 1.1124 + if (!SkTypeface::Equal(base.getTypeface(), paint.getTypeface())) { 1.1125 + if (isCrossProcess(fFlags)) { 1.1126 + uint32_t id = this->getTypefaceID(paint.getTypeface()); 1.1127 + *ptr++ = PaintOp_packOpData(kTypeface_PaintOp, id); 1.1128 + } else if (this->needOpBytes(sizeof(void*))) { 1.1129 + // Add to the set for ref counting. 1.1130 + fTypefaceSet.add(paint.getTypeface()); 1.1131 + // It is safe to write the typeface to the stream before the rest 1.1132 + // of the paint unless we ever send a kReset_PaintOp, which we 1.1133 + // currently never do. 1.1134 + this->writeOp(kSetTypeface_DrawOp); 1.1135 + fWriter.writePtr(paint.getTypeface()); 1.1136 + } 1.1137 + base.setTypeface(paint.getTypeface()); 1.1138 + } 1.1139 + 1.1140 + // This is a new paint, so all old flats can be safely purged, if necessary. 1.1141 + fFlattenableHeap.markAllFlatsSafeToDelete(); 1.1142 + for (int i = 0; i < kCount_PaintFlats; i++) { 1.1143 + int index = this->flattenToIndex(get_paintflat(paint, i), (PaintFlats)i); 1.1144 + bool replaced = index < 0; 1.1145 + if (replaced) { 1.1146 + index = ~index; 1.1147 + } 1.1148 + // Store the index of any flat that needs to be kept. 0 means no flat. 1.1149 + if (index > 0) { 1.1150 + fFlattenableHeap.markFlatForKeeping(index); 1.1151 + } 1.1152 + SkASSERT(index >= 0 && index <= fFlatDictionary.count()); 1.1153 + if (index != fCurrFlatIndex[i] || replaced) { 1.1154 + *ptr++ = PaintOp_packOpFlagData(kFlatIndex_PaintOp, i, index); 1.1155 + fCurrFlatIndex[i] = index; 1.1156 + } 1.1157 + } 1.1158 + 1.1159 + size_t size = (char*)ptr - (char*)storage; 1.1160 + if (size && this->needOpBytes(size)) { 1.1161 + this->writeOp(kPaintOp_DrawOp, 0, size); 1.1162 + fWriter.write(storage, size); 1.1163 + for (size_t i = 0; i < size/4; i++) { 1.1164 +// SkDebugf("[%d] %08X\n", i, storage[i]); 1.1165 + } 1.1166 + } 1.1167 + 1.1168 + // 1.1169 + // Do these after we've written kPaintOp_DrawOp 1.1170 + 1.1171 + if (base.getAnnotation() != paint.getAnnotation()) { 1.1172 + if (NULL == paint.getAnnotation()) { 1.1173 + if (this->needOpBytes()) { 1.1174 + this->writeOp(kSetAnnotation_DrawOp, 0, 0); 1.1175 + } 1.1176 + } else { 1.1177 + SkWriteBuffer buffer; 1.1178 + paint.getAnnotation()->writeToBuffer(buffer); 1.1179 + const size_t size = buffer.bytesWritten(); 1.1180 + if (this->needOpBytes(size)) { 1.1181 + this->writeOp(kSetAnnotation_DrawOp, 0, size); 1.1182 + buffer.writeToMemory(fWriter.reserve(size)); 1.1183 + } 1.1184 + } 1.1185 + base.setAnnotation(paint.getAnnotation()); 1.1186 + } 1.1187 +} 1.1188 + 1.1189 +/////////////////////////////////////////////////////////////////////////////// 1.1190 + 1.1191 +#include "SkGPipe.h" 1.1192 + 1.1193 +SkGPipeController::~SkGPipeController() { 1.1194 + SkSafeUnref(fCanvas); 1.1195 +} 1.1196 + 1.1197 +void SkGPipeController::setCanvas(SkGPipeCanvas* canvas) { 1.1198 + SkRefCnt_SafeAssign(fCanvas, canvas); 1.1199 +} 1.1200 + 1.1201 +/////////////////////////////////////////////////////////////////////////////// 1.1202 + 1.1203 +SkGPipeWriter::SkGPipeWriter() 1.1204 +: fWriter(0) { 1.1205 + fCanvas = NULL; 1.1206 +} 1.1207 + 1.1208 +SkGPipeWriter::~SkGPipeWriter() { 1.1209 + this->endRecording(); 1.1210 +} 1.1211 + 1.1212 +SkCanvas* SkGPipeWriter::startRecording(SkGPipeController* controller, uint32_t flags, 1.1213 + uint32_t width, uint32_t height) { 1.1214 + if (NULL == fCanvas) { 1.1215 + fWriter.reset(NULL, 0); 1.1216 + fCanvas = SkNEW_ARGS(SkGPipeCanvas, (controller, &fWriter, flags, width, height)); 1.1217 + } 1.1218 + controller->setCanvas(fCanvas); 1.1219 + return fCanvas; 1.1220 +} 1.1221 + 1.1222 +void SkGPipeWriter::endRecording() { 1.1223 + if (fCanvas) { 1.1224 + fCanvas->finish(true); 1.1225 + fCanvas->unref(); 1.1226 + fCanvas = NULL; 1.1227 + } 1.1228 +} 1.1229 + 1.1230 +void SkGPipeWriter::flushRecording(bool detachCurrentBlock) { 1.1231 + if (fCanvas) { 1.1232 + fCanvas->flushRecording(detachCurrentBlock); 1.1233 + } 1.1234 +} 1.1235 + 1.1236 +size_t SkGPipeWriter::freeMemoryIfPossible(size_t bytesToFree) { 1.1237 + if (fCanvas) { 1.1238 + return fCanvas->freeMemoryIfPossible(bytesToFree); 1.1239 + } 1.1240 + return 0; 1.1241 +} 1.1242 + 1.1243 +size_t SkGPipeWriter::storageAllocatedForRecording() const { 1.1244 + return NULL == fCanvas ? 0 : fCanvas->storageAllocatedForRecording(); 1.1245 +} 1.1246 + 1.1247 +/////////////////////////////////////////////////////////////////////////////// 1.1248 + 1.1249 +BitmapShuttle::BitmapShuttle(SkGPipeCanvas* canvas) { 1.1250 + SkASSERT(canvas != NULL); 1.1251 + fCanvas = canvas; 1.1252 + fCanvas->ref(); 1.1253 +} 1.1254 + 1.1255 +BitmapShuttle::~BitmapShuttle() { 1.1256 + this->removeCanvas(); 1.1257 +} 1.1258 + 1.1259 +bool BitmapShuttle::insert(const SkBitmap& bitmap, int32_t slot) { 1.1260 + SkASSERT(fCanvas != NULL); 1.1261 + return fCanvas->shuttleBitmap(bitmap, slot); 1.1262 +} 1.1263 + 1.1264 +void BitmapShuttle::removeCanvas() { 1.1265 + if (NULL == fCanvas) { 1.1266 + return; 1.1267 + } 1.1268 + fCanvas->unref(); 1.1269 + fCanvas = NULL; 1.1270 +}