| OLD | NEW |
| 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" |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 } | 160 } |
| 161 static void flattenFlattenableProc(SkOrderedWriteBuffer& buffer, | 161 static void flattenFlattenableProc(SkOrderedWriteBuffer& buffer, |
| 162 const void* obj) { | 162 const void* obj) { |
| 163 buffer.writeFlattenable((SkFlattenable*)obj); | 163 buffer.writeFlattenable((SkFlattenable*)obj); |
| 164 } | 164 } |
| 165 | 165 |
| 166 }; | 166 }; |
| 167 | 167 |
| 168 /////////////////////////////////////////////////////////////////////////////// | 168 /////////////////////////////////////////////////////////////////////////////// |
| 169 | 169 |
| 170 /** |
| 171 * If SkBitmaps are to be flattened to send to the reader, this class is |
| 172 * provided to the SkBitmapHeap to tell the SkGPipeCanvas to do so. |
| 173 */ |
| 174 class BitmapShuttle : public SkBitmapHeap::ExternalStorage { |
| 175 public: |
| 176 BitmapShuttle(SkGPipeCanvas*); |
| 177 |
| 178 ~BitmapShuttle(); |
| 179 |
| 180 virtual bool insert(const SkBitmap& bitmap, int32_t slot) SK_OVERRIDE; |
| 181 |
| 182 /** |
| 183 * Remove the SkGPipeCanvas used for insertion. After this, calls to |
| 184 * insert will crash. |
| 185 */ |
| 186 void removeCanvas(); |
| 187 |
| 188 private: |
| 189 SkGPipeCanvas* fCanvas; |
| 190 }; |
| 191 |
| 192 /////////////////////////////////////////////////////////////////////////////// |
| 193 |
| 170 class SkGPipeCanvas : public SkCanvas { | 194 class SkGPipeCanvas : public SkCanvas { |
| 171 public: | 195 public: |
| 172 SkGPipeCanvas(SkGPipeController*, SkWriter32*, uint32_t flags, | 196 SkGPipeCanvas(SkGPipeController*, SkWriter32*, uint32_t flags, |
| 173 uint32_t width, uint32_t height); | 197 uint32_t width, uint32_t height); |
| 174 virtual ~SkGPipeCanvas(); | 198 virtual ~SkGPipeCanvas(); |
| 175 | 199 |
| 176 void finish() { | 200 /** |
| 177 if (!fDone) { | 201 * Called when nothing else is to be written to the stream. Any repeated |
| 178 if (this->needOpBytes()) { | 202 * calls are ignored. |
| 179 this->writeOp(kDone_DrawOp); | 203 * |
| 180 this->doNotify(); | 204 * @param notifyReaders Whether to send a message to the reader(s) that |
| 181 if (shouldFlattenBitmaps(fFlags)) { | 205 * the writer is through sending commands. Should generally be true, |
| 182 // In this case, a BitmapShuttle is reffed by the SkBitmapHe
ap | 206 * unless there is an error which prevents further messages from |
| 183 // and refs this canvas. Unref the SkBitmapHeap to end the | 207 * being sent. |
| 184 // circular reference. When shouldFlattenBitmaps is false, | 208 */ |
| 185 // there is no circular reference, so the SkBitmapHeap can b
e | 209 void finish(bool notifyReaders) { |
| 186 // safely unreffed in the destructor. | 210 if (fDone) { |
| 187 fBitmapHeap->unref(); | 211 return; |
| 188 // This eliminates a similar circular reference (Canvas owns | |
| 189 // the FlattenableHeap which holds a ref to the SkBitmapHeap
). | |
| 190 fFlattenableHeap.setBitmapStorage(NULL); | |
| 191 fBitmapHeap = NULL; | |
| 192 } | |
| 193 } | |
| 194 fDone = true; | |
| 195 } | 212 } |
| 213 if (notifyReaders && this->needOpBytes()) { |
| 214 this->writeOp(kDone_DrawOp); |
| 215 this->doNotify(); |
| 216 } |
| 217 if (shouldFlattenBitmaps(fFlags)) { |
| 218 // The following circular references exist: |
| 219 // fFlattenableHeap -> fWriteBuffer -> fBitmapStorage -> fExternalSt
orage -> fCanvas |
| 220 // fBitmapHeap -> fExternalStorage -> fCanvas |
| 221 // fFlattenableHeap -> fBitmapStorage -> fExternalStorage -> fCanvas |
| 222 |
| 223 // Break them all by destroying the final link to this SkGPipeCanvas
. |
| 224 fBitmapShuttle->removeCanvas(); |
| 225 } |
| 226 fDone = true; |
| 196 } | 227 } |
| 197 | 228 |
| 198 void flushRecording(bool detachCurrentBlock); | 229 void flushRecording(bool detachCurrentBlock); |
| 199 size_t freeMemoryIfPossible(size_t bytesToFree); | 230 size_t freeMemoryIfPossible(size_t bytesToFree); |
| 200 | 231 |
| 201 size_t storageAllocatedForRecording() { | 232 size_t storageAllocatedForRecording() { |
| 202 return (NULL == fBitmapHeap) ? 0 : fBitmapHeap->bytesAllocated(); | 233 return (NULL == fBitmapHeap) ? 0 : fBitmapHeap->bytesAllocated(); |
| 203 } | 234 } |
| 204 | 235 |
| 205 // overrides from SkCanvas | 236 // overrides from SkCanvas |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 fController->notifyWritten(bytes); | 330 fController->notifyWritten(bytes); |
| 300 fBytesNotified += bytes; | 331 fBytesNotified += bytes; |
| 301 } | 332 } |
| 302 } | 333 } |
| 303 } | 334 } |
| 304 | 335 |
| 305 // Should be called after any calls to an SkFlatDictionary::findAndReplace | 336 // Should be called after any calls to an SkFlatDictionary::findAndReplace |
| 306 // if a new SkFlatData was added when in cross process mode | 337 // if a new SkFlatData was added when in cross process mode |
| 307 void flattenFactoryNames(); | 338 void flattenFactoryNames(); |
| 308 | 339 |
| 309 FlattenableHeap fFlattenableHeap; | 340 FlattenableHeap fFlattenableHeap; |
| 310 FlatDictionary fFlatDictionary; | 341 FlatDictionary fFlatDictionary; |
| 311 int fCurrFlatIndex[kCount_PaintFlats]; | 342 SkAutoTUnref<BitmapShuttle> fBitmapShuttle; |
| 343 int fCurrFlatIndex[kCount_PaintFlats]; |
| 344 |
| 312 int flattenToIndex(SkFlattenable* obj, PaintFlats); | 345 int flattenToIndex(SkFlattenable* obj, PaintFlats); |
| 313 | 346 |
| 314 // Common code used by drawBitmap*. Behaves differently depending on the | 347 // Common code used by drawBitmap*. Behaves differently depending on the |
| 315 // type of SkBitmapHeap being used, which is determined by the flags used. | 348 // type of SkBitmapHeap being used, which is determined by the flags used. |
| 316 bool commonDrawBitmap(const SkBitmap& bm, DrawOps op, unsigned flags, | 349 bool commonDrawBitmap(const SkBitmap& bm, DrawOps op, unsigned flags, |
| 317 size_t opBytesNeeded, const SkPaint* paint); | 350 size_t opBytesNeeded, const SkPaint* paint); |
| 318 | 351 |
| 319 SkPaint fPaint; | 352 SkPaint fPaint; |
| 320 void writePaint(const SkPaint&); | 353 void writePaint(const SkPaint&); |
| 321 | 354 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 383 } | 416 } |
| 384 } | 417 } |
| 385 if (replaced) { | 418 if (replaced) { |
| 386 index = ~index; | 419 index = ~index; |
| 387 } | 420 } |
| 388 return index; | 421 return index; |
| 389 } | 422 } |
| 390 | 423 |
| 391 /////////////////////////////////////////////////////////////////////////////// | 424 /////////////////////////////////////////////////////////////////////////////// |
| 392 | 425 |
| 393 /** | |
| 394 * If SkBitmaps are to be flattened to send to the reader, this class is | |
| 395 * provided to the SkBitmapHeap to tell the SkGPipeCanvas to do so. | |
| 396 */ | |
| 397 class BitmapShuttle : public SkBitmapHeap::ExternalStorage { | |
| 398 public: | |
| 399 BitmapShuttle(SkGPipeCanvas*); | |
| 400 | |
| 401 ~BitmapShuttle(); | |
| 402 | |
| 403 virtual bool insert(const SkBitmap& bitmap, int32_t slot) SK_OVERRIDE; | |
| 404 | |
| 405 private: | |
| 406 SkGPipeCanvas* fCanvas; | |
| 407 }; | |
| 408 | |
| 409 /////////////////////////////////////////////////////////////////////////////// | |
| 410 | |
| 411 #define MIN_BLOCK_SIZE (16 * 1024) | 426 #define MIN_BLOCK_SIZE (16 * 1024) |
| 412 #define BITMAPS_TO_KEEP 5 | 427 #define BITMAPS_TO_KEEP 5 |
| 413 #define FLATTENABLES_TO_KEEP 10 | 428 #define FLATTENABLES_TO_KEEP 10 |
| 414 | 429 |
| 415 SkGPipeCanvas::SkGPipeCanvas(SkGPipeController* controller, | 430 SkGPipeCanvas::SkGPipeCanvas(SkGPipeController* controller, |
| 416 SkWriter32* writer, uint32_t flags, | 431 SkWriter32* writer, uint32_t flags, |
| 417 uint32_t width, uint32_t height) | 432 uint32_t width, uint32_t height) |
| 418 : fFactorySet(isCrossProcess(flags) ? SkNEW(SkNamedFactorySet) : NULL) | 433 : fFactorySet(isCrossProcess(flags) ? SkNEW(SkNamedFactorySet) : NULL) |
| 419 , fWriter(*writer) | 434 , fWriter(*writer) |
| 420 , fFlags(flags) | 435 , fFlags(flags) |
| (...skipping 12 matching lines...) Expand all Loading... |
| 433 bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height); | 448 bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height); |
| 434 SkBaseDevice* device = SkNEW_ARGS(SkBitmapDevice, (bitmap)); | 449 SkBaseDevice* device = SkNEW_ARGS(SkBitmapDevice, (bitmap)); |
| 435 this->setDevice(device)->unref(); | 450 this->setDevice(device)->unref(); |
| 436 | 451 |
| 437 // Tell the reader the appropriate flags to use. | 452 // Tell the reader the appropriate flags to use. |
| 438 if (this->needOpBytes()) { | 453 if (this->needOpBytes()) { |
| 439 this->writeOp(kReportFlags_DrawOp, fFlags, 0); | 454 this->writeOp(kReportFlags_DrawOp, fFlags, 0); |
| 440 } | 455 } |
| 441 | 456 |
| 442 if (shouldFlattenBitmaps(flags)) { | 457 if (shouldFlattenBitmaps(flags)) { |
| 443 BitmapShuttle* shuttle = SkNEW_ARGS(BitmapShuttle, (this)); | 458 fBitmapShuttle.reset(SkNEW_ARGS(BitmapShuttle, (this))); |
| 444 fBitmapHeap = SkNEW_ARGS(SkBitmapHeap, (shuttle, BITMAPS_TO_KEEP)); | 459 fBitmapHeap = SkNEW_ARGS(SkBitmapHeap, (fBitmapShuttle.get(), BITMAPS_TO
_KEEP)); |
| 445 shuttle->unref(); | |
| 446 } else { | 460 } else { |
| 447 fBitmapHeap = SkNEW_ARGS(SkBitmapHeap, | 461 fBitmapHeap = SkNEW_ARGS(SkBitmapHeap, |
| 448 (BITMAPS_TO_KEEP, controller->numberOfReaders()
)); | 462 (BITMAPS_TO_KEEP, controller->numberOfReaders()
)); |
| 449 if (this->needOpBytes(sizeof(void*))) { | 463 if (this->needOpBytes(sizeof(void*))) { |
| 450 this->writeOp(kShareBitmapHeap_DrawOp); | 464 this->writeOp(kShareBitmapHeap_DrawOp); |
| 451 fWriter.writePtr(static_cast<void*>(fBitmapHeap)); | 465 fWriter.writePtr(static_cast<void*>(fBitmapHeap)); |
| 452 } | 466 } |
| 453 } | 467 } |
| 454 fFlattenableHeap.setBitmapStorage(fBitmapHeap); | 468 fFlattenableHeap.setBitmapStorage(fBitmapHeap); |
| 455 this->doNotify(); | 469 this->doNotify(); |
| 456 } | 470 } |
| 457 | 471 |
| 458 SkGPipeCanvas::~SkGPipeCanvas() { | 472 SkGPipeCanvas::~SkGPipeCanvas() { |
| 459 this->finish(); | 473 this->finish(true); |
| 460 SkSafeUnref(fFactorySet); | 474 SkSafeUnref(fFactorySet); |
| 461 SkSafeUnref(fBitmapHeap); | 475 SkSafeUnref(fBitmapHeap); |
| 462 } | 476 } |
| 463 | 477 |
| 464 bool SkGPipeCanvas::needOpBytes(size_t needed) { | 478 bool SkGPipeCanvas::needOpBytes(size_t needed) { |
| 465 if (fDone) { | 479 if (fDone) { |
| 466 return false; | 480 return false; |
| 467 } | 481 } |
| 468 | 482 |
| 469 needed += 4; // size of DrawOp atom | 483 needed += 4; // size of DrawOp atom |
| 470 if (fWriter.bytesWritten() + needed > fBlockSize) { | 484 if (fWriter.bytesWritten() + needed > fBlockSize) { |
| 471 // Before we wipe out any data that has already been written, read it | 485 // Before we wipe out any data that has already been written, read it |
| 472 // out. | 486 // out. |
| 473 this->doNotify(); | 487 this->doNotify(); |
| 474 size_t blockSize = SkMax32(MIN_BLOCK_SIZE, needed); | 488 size_t blockSize = SkMax32(MIN_BLOCK_SIZE, needed); |
| 475 void* block = fController->requestBlock(blockSize, &fBlockSize); | 489 void* block = fController->requestBlock(blockSize, &fBlockSize); |
| 476 if (NULL == block) { | 490 if (NULL == block) { |
| 477 fDone = true; | 491 // Do not notify the readers, which would call this function again. |
| 492 this->finish(false); |
| 478 return false; | 493 return false; |
| 479 } | 494 } |
| 480 SkASSERT(SkIsAlign4(fBlockSize)); | 495 SkASSERT(SkIsAlign4(fBlockSize)); |
| 481 fWriter.reset(block, fBlockSize); | 496 fWriter.reset(block, fBlockSize); |
| 482 fBytesNotified = 0; | 497 fBytesNotified = 0; |
| 483 } | 498 } |
| 484 return true; | 499 return true; |
| 485 } | 500 } |
| 486 | 501 |
| 487 uint32_t SkGPipeCanvas::getTypefaceID(SkTypeface* face) { | 502 uint32_t SkGPipeCanvas::getTypefaceID(SkTypeface* face) { |
| (...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1172 if (NULL == fCanvas) { | 1187 if (NULL == fCanvas) { |
| 1173 fWriter.reset(NULL, 0); | 1188 fWriter.reset(NULL, 0); |
| 1174 fCanvas = SkNEW_ARGS(SkGPipeCanvas, (controller, &fWriter, flags, width,
height)); | 1189 fCanvas = SkNEW_ARGS(SkGPipeCanvas, (controller, &fWriter, flags, width,
height)); |
| 1175 } | 1190 } |
| 1176 controller->setCanvas(fCanvas); | 1191 controller->setCanvas(fCanvas); |
| 1177 return fCanvas; | 1192 return fCanvas; |
| 1178 } | 1193 } |
| 1179 | 1194 |
| 1180 void SkGPipeWriter::endRecording() { | 1195 void SkGPipeWriter::endRecording() { |
| 1181 if (fCanvas) { | 1196 if (fCanvas) { |
| 1182 fCanvas->finish(); | 1197 fCanvas->finish(true); |
| 1183 fCanvas->unref(); | 1198 fCanvas->unref(); |
| 1184 fCanvas = NULL; | 1199 fCanvas = NULL; |
| 1185 } | 1200 } |
| 1186 } | 1201 } |
| 1187 | 1202 |
| 1188 void SkGPipeWriter::flushRecording(bool detachCurrentBlock) { | 1203 void SkGPipeWriter::flushRecording(bool detachCurrentBlock) { |
| 1189 if (fCanvas) { | 1204 if (fCanvas) { |
| 1190 fCanvas->flushRecording(detachCurrentBlock); | 1205 fCanvas->flushRecording(detachCurrentBlock); |
| 1191 } | 1206 } |
| 1192 } | 1207 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1204 | 1219 |
| 1205 /////////////////////////////////////////////////////////////////////////////// | 1220 /////////////////////////////////////////////////////////////////////////////// |
| 1206 | 1221 |
| 1207 BitmapShuttle::BitmapShuttle(SkGPipeCanvas* canvas) { | 1222 BitmapShuttle::BitmapShuttle(SkGPipeCanvas* canvas) { |
| 1208 SkASSERT(canvas != NULL); | 1223 SkASSERT(canvas != NULL); |
| 1209 fCanvas = canvas; | 1224 fCanvas = canvas; |
| 1210 fCanvas->ref(); | 1225 fCanvas->ref(); |
| 1211 } | 1226 } |
| 1212 | 1227 |
| 1213 BitmapShuttle::~BitmapShuttle() { | 1228 BitmapShuttle::~BitmapShuttle() { |
| 1214 fCanvas->unref(); | 1229 this->removeCanvas(); |
| 1215 } | 1230 } |
| 1216 | 1231 |
| 1217 bool BitmapShuttle::insert(const SkBitmap& bitmap, int32_t slot) { | 1232 bool BitmapShuttle::insert(const SkBitmap& bitmap, int32_t slot) { |
| 1233 SkASSERT(fCanvas != NULL); |
| 1218 return fCanvas->shuttleBitmap(bitmap, slot); | 1234 return fCanvas->shuttleBitmap(bitmap, slot); |
| 1219 } | 1235 } |
| 1236 |
| 1237 void BitmapShuttle::removeCanvas() { |
| 1238 if (NULL == fCanvas) { |
| 1239 return; |
| 1240 } |
| 1241 fCanvas->unref(); |
| 1242 fCanvas = NULL; |
| 1243 } |
| OLD | NEW |