1685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com 2685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com/* 3685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * Copyright 2011 Google Inc. 4685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * 5685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * found in the LICENSE file. 7685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com */ 8bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkPictureRecord.h" 9bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkTSearch.h" 10dc8630fa3915d6b1a6cfef385ac6846cf78e0b94junov@chromium.org#include "SkPixelRef.h" 117a7e655343617093a5eea37c7a556602a1bb0576reed@google.com#include "SkRRect.h" 126e832b50c712743d821e01829b127b86271a7ebbrileya@google.com#include "SkBBoxHierarchy.h" 130ae46d53f7563f38a4c07085a036ac2e5490ce1cjunov@chromium.org#include "SkDevice.h" 146e832b50c712743d821e01829b127b86271a7ebbrileya@google.com#include "SkPictureStateTree.h" 15bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 16bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#define MIN_WRITER_SIZE 16384 17bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#define HEAP_BLOCK_SIZE 4096 18bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 19d84ed564a00a67019a345ea545ca63ab514533f7junov@chromium.orgenum { 20118a6d00c3089c0fcfce67919bbbeb37adda6423reed@google.com // just need a value that save or getSaveCount would never return 21d84ed564a00a67019a345ea545ca63ab514533f7junov@chromium.org kNoInitialSave = -1, 22d84ed564a00a67019a345ea545ca63ab514533f7junov@chromium.org}; 23d84ed564a00a67019a345ea545ca63ab514533f7junov@chromium.org 24f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com// A lot of basic types get stored as a uint32_t: bools, ints, paint indices, etc. 25f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.comstatic int const kUInt32Size = 4; 26f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com 276f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.comstatic const uint32_t kSaveLayerNoBoundsSize = 4 * kUInt32Size; 286f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.comstatic const uint32_t kSaveLayerWithBoundsSize = 4 * kUInt32Size + sizeof(SkRect); 296f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 30118a6d00c3089c0fcfce67919bbbeb37adda6423reed@google.comSkPictureRecord::SkPictureRecord(uint32_t flags, SkDevice* device) : 31118a6d00c3089c0fcfce67919bbbeb37adda6423reed@google.com INHERITED(device), 322ec44813c09bf94914e2baf07ae155ac2366909crobertphillips@google.com fBoundingHierarchy(NULL), 332ec44813c09bf94914e2baf07ae155ac2366909crobertphillips@google.com fStateTree(NULL), 34a9aa73ae674668fe929a04566a17804eefe7938edjsollen@google.com fFlattenableHeap(HEAP_BLOCK_SIZE), 35a9aa73ae674668fe929a04566a17804eefe7938edjsollen@google.com fMatrices(&fFlattenableHeap), 36a9aa73ae674668fe929a04566a17804eefe7938edjsollen@google.com fPaints(&fFlattenableHeap), 37a9aa73ae674668fe929a04566a17804eefe7938edjsollen@google.com fRegions(&fFlattenableHeap), 38ba64210404187e9ef7a9d55135695aa0bd745467djsollen@google.com fWriter(MIN_WRITER_SIZE), 39ba64210404187e9ef7a9d55135695aa0bd745467djsollen@google.com fRecordFlags(flags) { 40bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#ifdef SK_DEBUG_SIZE 41bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fPointBytes = fRectBytes = fTextBytes = 0; 42bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fPointWrites = fRectWrites = fTextWrites = 0; 43bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#endif 44bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 45bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fRestoreOffsetStack.setReserve(32); 46919114813d58933c9d9433b141e0222c34b700b1reed@google.com 473855f87fcb9a9e590b6c94d742395415a3f1b06cdjsollen@google.com fBitmapHeap = SkNEW(SkBitmapHeap); 483855f87fcb9a9e590b6c94d742395415a3f1b06cdjsollen@google.com fFlattenableHeap.setBitmapStorage(fBitmapHeap); 49bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fPathHeap = NULL; // lazy allocate 506bfd74c3d62f40c933ade44051e8a407e017b882junov@chromium.org fFirstSavedLayerIndex = kNoSavedLayerIndex; 51118a6d00c3089c0fcfce67919bbbeb37adda6423reed@google.com 52118a6d00c3089c0fcfce67919bbbeb37adda6423reed@google.com fInitialSaveCount = kNoInitialSave; 53bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 54bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 55bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comSkPictureRecord::~SkPictureRecord() { 563855f87fcb9a9e590b6c94d742395415a3f1b06cdjsollen@google.com SkSafeUnref(fBitmapHeap); 57a9aa73ae674668fe929a04566a17804eefe7938edjsollen@google.com SkSafeUnref(fPathHeap); 586e832b50c712743d821e01829b127b86271a7ebbrileya@google.com SkSafeUnref(fBoundingHierarchy); 596e832b50c712743d821e01829b127b86271a7ebbrileya@google.com SkSafeUnref(fStateTree); 60a9aa73ae674668fe929a04566a17804eefe7938edjsollen@google.com fFlattenableHeap.setBitmapStorage(NULL); 61a9aa73ae674668fe929a04566a17804eefe7938edjsollen@google.com fPictureRefs.unrefAll(); 62bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 63bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 64bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com/////////////////////////////////////////////////////////////////////////////// 65bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 666f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com// Return the offset of the paint inside a given op's byte stream. A zero 676f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com// return value means there is no paint (and you really shouldn't be calling 686f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com// this method) 696f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.comstatic inline uint32_t getPaintOffset(DrawType op, uint32_t opSize) { 706f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com // These offsets are where the paint would be if the op size doesn't overflow 71bb6a8d87c696dade8c4730cd09b55c0ecae06462skia.committer@gmail.com static const uint8_t gPaintOffsets[LAST_DRAWTYPE_ENUM + 1] = { 726f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 0, // UNUSED - no paint 736f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 0, // CLIP_PATH - no paint 746f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 0, // CLIP_REGION - no paint 756f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 0, // CLIP_RECT - no paint 766f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 0, // CLIP_RRECT - no paint 776f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 0, // CONCAT - no paint 786f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 1, // DRAW_BITMAP - right after op code 796f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 1, // DRAW_BITMAP_MATRIX - right after op code 806f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 1, // DRAW_BITMAP_NINE - right after op code 816f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 1, // DRAW_BITMAP_RECT_TO_RECT - right after op code 826f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 0, // DRAW_CLEAR - no paint 836f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 0, // DRAW_DATA - no paint 846f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 1, // DRAW_OVAL - right after op code 856f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 1, // DRAW_PAINT - right after op code 866f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 1, // DRAW_PATH - right after op code 876f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 0, // DRAW_PICTURE - no paint 886f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 1, // DRAW_POINTS - right after op code 896f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 1, // DRAW_POS_TEXT - right after op code 906f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 1, // DRAW_POS_TEXT_TOP_BOTTOM - right after op code 916f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 1, // DRAW_POS_TEXT_H - right after op code 926f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 1, // DRAW_POS_TEXT_H_TOP_BOTTOM - right after op code 936f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 1, // DRAW_RECT - right after op code 946f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 1, // DRAW_RRECT - right after op code 956f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 1, // DRAW_SPRITE - right after op code 966f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 1, // DRAW_TEXT - right after op code 976f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 1, // DRAW_TEXT_ON_PATH - right after op code 986f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 1, // DRAW_TEXT_TOP_BOTTOM - right after op code 996f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 1, // DRAW_VERTICES - right after op code 1006f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 0, // RESTORE - no paint 1016f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 0, // ROTATE - no paint 1026f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 0, // SAVE - no paint 103bb6a8d87c696dade8c4730cd09b55c0ecae06462skia.committer@gmail.com 0, // SAVE_LAYER - see below - this paint's location varies 1046f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 0, // SCALE - no paint 1056f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 0, // SET_MATRIX - no paint 1066f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 0, // SKEW - no paint 1076f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 0, // TRANSLATE - no paint 1086f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 0, // NOOP - no paint 109aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com 0, // BEGIN_GROUP - no paint 110aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com 0, // COMMENT - no paint 111aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com 0, // END_GROUP - no paint 112bb6a8d87c696dade8c4730cd09b55c0ecae06462skia.committer@gmail.com }; 1136f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 1146f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkASSERT(sizeof(gPaintOffsets) == LAST_DRAWTYPE_ENUM + 1); 1156f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkASSERT((unsigned)op <= (unsigned)LAST_DRAWTYPE_ENUM); 1166f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 1176f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com int overflow = 0; 1186f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com if (0 != (opSize & ~MASK_24) || opSize == MASK_24) { 1196f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com // This op's size overflows so an extra uint32_t will be written 1206f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com // after the op code 1216f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com overflow = sizeof(uint32_t); 1226f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com } 1236f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 1246f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com if (SAVE_LAYER == op) { 1256f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com static const uint32_t kSaveLayerNoBoundsPaintOffset = 2 * kUInt32Size; 1266f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com static const uint32_t kSaveLayerWithBoundsPaintOffset = 2 * kUInt32Size + sizeof(SkRect); 1276f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 1286f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com if (kSaveLayerNoBoundsSize == opSize) { 1296f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com return kSaveLayerNoBoundsPaintOffset + overflow; 1306f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com } else { 1316f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkASSERT(kSaveLayerWithBoundsSize == opSize); 1326f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com return kSaveLayerWithBoundsPaintOffset + overflow; 1336f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com } 1346f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com } 1356f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 1366f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkASSERT(0 != gPaintOffsets[op]); // really shouldn't be calling this method 1376f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com return gPaintOffsets[op] * sizeof(uint32_t) + overflow; 1386f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com} 1396f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 140d84ed564a00a67019a345ea545ca63ab514533f7junov@chromium.orgSkDevice* SkPictureRecord::setDevice(SkDevice* device) { 141118a6d00c3089c0fcfce67919bbbeb37adda6423reed@google.com SkASSERT(!"eeek, don't try to change the device on a recording canvas"); 142118a6d00c3089c0fcfce67919bbbeb37adda6423reed@google.com return this->INHERITED::setDevice(device); 143d84ed564a00a67019a345ea545ca63ab514533f7junov@chromium.org} 144d84ed564a00a67019a345ea545ca63ab514533f7junov@chromium.org 145bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comint SkPictureRecord::save(SaveFlags flags) { 1462522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com // record the offset to us, making it non-positive to distinguish a save 1472522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com // from a clip entry. 1482522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com fRestoreOffsetStack.push(-(int32_t)fWriter.size()); 14969a95d1bf40aa3b197983cdb1df79b4441b31de1skia.committer@gmail.com 150f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // op + flags 151f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t size = 2 * kUInt32Size; 152f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset = this->addDraw(SAVE, &size); 153bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addInt(flags); 154919114813d58933c9d9433b141e0222c34b700b1reed@google.com 155f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 156bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return this->INHERITED::save(flags); 157bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 158bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 159bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comint SkPictureRecord::saveLayer(const SkRect* bounds, const SkPaint* paint, 160bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SaveFlags flags) { 1612522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com // record the offset to us, making it non-positive to distinguish a save 1622522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com // from a clip entry. 1632522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com fRestoreOffsetStack.push(-(int32_t)fWriter.size()); 16469a95d1bf40aa3b197983cdb1df79b4441b31de1skia.committer@gmail.com 165f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // op + bool for 'bounds' 1664b7bb5ccda62759133bc13e69f5247c91ef6a61eskia.committer@gmail.com uint32_t size = 2 * kUInt32Size; 167f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com if (NULL != bounds) { 168f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com size += sizeof(*bounds); // + rect 169f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com } 170f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // + paint index + flags 171f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com size += 2 * kUInt32Size; 172f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com 1736f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkASSERT(kSaveLayerNoBoundsSize == size || kSaveLayerWithBoundsSize == size); 1746f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 175f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset = this->addDraw(SAVE_LAYER, &size); 176bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addRectPtr(bounds); 1776f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkASSERT(initialOffset+getPaintOffset(SAVE_LAYER, size) == fWriter.size()); 178bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addPaintPtr(paint); 179bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addInt(flags); 180bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1816bfd74c3d62f40c933ade44051e8a407e017b882junov@chromium.org if (kNoSavedLayerIndex == fFirstSavedLayerIndex) { 1826bfd74c3d62f40c933ade44051e8a407e017b882junov@chromium.org fFirstSavedLayerIndex = fRestoreOffsetStack.count(); 1836bfd74c3d62f40c933ade44051e8a407e017b882junov@chromium.org } 1846bfd74c3d62f40c933ade44051e8a407e017b882junov@chromium.org 185f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 1868c8c0c0b8ef2b3c2266c57fecc3f365ec2ea27c9reed@android.com /* Don't actually call saveLayer, because that will try to allocate an 1878c8c0c0b8ef2b3c2266c57fecc3f365ec2ea27c9reed@android.com offscreen device (potentially very big) which we don't actually need 1888c8c0c0b8ef2b3c2266c57fecc3f365ec2ea27c9reed@android.com at this time (and may not be able to afford since during record our 1898c8c0c0b8ef2b3c2266c57fecc3f365ec2ea27c9reed@android.com clip starts out the size of the picture, which is often much larger 1908c8c0c0b8ef2b3c2266c57fecc3f365ec2ea27c9reed@android.com than the size of the actual device we'll use during playback). 1918c8c0c0b8ef2b3c2266c57fecc3f365ec2ea27c9reed@android.com */ 1921457ba3cbcaa320a1d1dd50bc128fda46e23b9fdjunov@chromium.org int count = this->INHERITED::save(flags); 1931457ba3cbcaa320a1d1dd50bc128fda46e23b9fdjunov@chromium.org this->clipRectBounds(bounds, flags, NULL); 1941457ba3cbcaa320a1d1dd50bc128fda46e23b9fdjunov@chromium.org return count; 195bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 196bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1976bfd74c3d62f40c933ade44051e8a407e017b882junov@chromium.orgbool SkPictureRecord::isDrawingToLayer() const { 1986bfd74c3d62f40c933ade44051e8a407e017b882junov@chromium.org return fFirstSavedLayerIndex != kNoSavedLayerIndex; 1996bfd74c3d62f40c933ade44051e8a407e017b882junov@chromium.org} 2006bfd74c3d62f40c933ade44051e8a407e017b882junov@chromium.org 201f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com/* 202f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com * Read the op code from 'offset' in 'writer' and extract the size too. 203f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com */ 204f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.comstatic DrawType peek_op_and_size(SkWriter32* writer, int32_t offset, uint32_t* size) { 205f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t* peek = writer->peek32(offset); 206f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com 207f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t op; 208f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com UNPACK_8_24(*peek, op, *size); 209f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com if (MASK_24 == *size) { 210f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // size required its own slot right after the op code 2114b7bb5ccda62759133bc13e69f5247c91ef6a61eskia.committer@gmail.com *size = *writer->peek32(offset+kUInt32Size); 212f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com } 213f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com return (DrawType) op; 2142522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com} 2152522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com 2162522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com#ifdef TRACK_COLLAPSE_STATS 2172522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com static int gCollapseCount, gCollapseCalls; 2182522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com#endif 2192522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com 2206f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com// Is the supplied paint simply a color? 2216f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.comstatic bool is_simple(const SkPaint& p) { 222bb6a8d87c696dade8c4730cd09b55c0ecae06462skia.committer@gmail.com intptr_t orAccum = (intptr_t)p.getPathEffect() | 2236f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com (intptr_t)p.getShader() | 2246f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com (intptr_t)p.getXfermode() | 2256f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com (intptr_t)p.getMaskFilter() | 2266f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com (intptr_t)p.getColorFilter() | 2276f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com (intptr_t)p.getRasterizer() | 2286f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com (intptr_t)p.getLooper() | 2296f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com (intptr_t)p.getImageFilter(); 2306f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com return 0 == orAccum; 2316f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com} 2326f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 233ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com// CommandInfos are fed to the 'match' method and filled in with command 234010f1a42e85d8c8587869e436d093d7ed40a4598skia.committer@gmail.com// information. 235ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.comstruct CommandInfo { 236ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com DrawType fActualOp; 237ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com uint32_t fOffset; 238ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com uint32_t fSize; 239ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com}; 240ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com 2412522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com/* 242ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com * Attempt to match the provided pattern of commands starting at 'offset' 243010f1a42e85d8c8587869e436d093d7ed40a4598skia.committer@gmail.com * in the byte stream and stopping at the end of the stream. Upon success, 244ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com * return true with all the pattern information filled out in the result 245ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com * array (i.e., actual ops, offsets and sizes). 246ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com * Note this method skips any NOOPs seen in the stream 247ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com */ 248ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.comstatic bool match(SkWriter32* writer, uint32_t offset, 249ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com int* pattern, CommandInfo* result, int numCommands) { 250003c9cfab8027c666586a7d46c2ac6ca0a18957brobertphillips@google.com SkASSERT(offset < writer->size()); 251ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com 252ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com uint32_t curOffset = offset; 253ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com uint32_t curSize = 0; 254003c9cfab8027c666586a7d46c2ac6ca0a18957brobertphillips@google.com int numMatched; 255003c9cfab8027c666586a7d46c2ac6ca0a18957brobertphillips@google.com for (numMatched = 0; numMatched < numCommands && curOffset < writer->size(); ++numMatched) { 256ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com DrawType op = peek_op_and_size(writer, curOffset, &curSize); 257ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com while (NOOP == op && curOffset < writer->size()) { 258ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com curOffset += curSize; 259ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com op = peek_op_and_size(writer, curOffset, &curSize); 260ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com } 261ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com 262ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com if (curOffset >= writer->size()) { 263ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com return false; // ran out of byte stream 264ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com } 265ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com 266003c9cfab8027c666586a7d46c2ac6ca0a18957brobertphillips@google.com if (kDRAW_BITMAP_FLAVOR == pattern[numMatched]) { 267ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com if (DRAW_BITMAP != op && DRAW_BITMAP_MATRIX != op && 268ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com DRAW_BITMAP_NINE != op && DRAW_BITMAP_RECT_TO_RECT != op) { 269ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com return false; 270ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com } 271003c9cfab8027c666586a7d46c2ac6ca0a18957brobertphillips@google.com } else if (op != pattern[numMatched]) { 272ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com return false; 273ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com } 274ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com 275003c9cfab8027c666586a7d46c2ac6ca0a18957brobertphillips@google.com result[numMatched].fActualOp = op; 276003c9cfab8027c666586a7d46c2ac6ca0a18957brobertphillips@google.com result[numMatched].fOffset = curOffset; 277003c9cfab8027c666586a7d46c2ac6ca0a18957brobertphillips@google.com result[numMatched].fSize = curSize; 278ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com 279ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com curOffset += curSize; 280ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com } 281ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com 282003c9cfab8027c666586a7d46c2ac6ca0a18957brobertphillips@google.com if (numMatched != numCommands) { 283003c9cfab8027c666586a7d46c2ac6ca0a18957brobertphillips@google.com return false; 284003c9cfab8027c666586a7d46c2ac6ca0a18957brobertphillips@google.com } 285003c9cfab8027c666586a7d46c2ac6ca0a18957brobertphillips@google.com 286ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com curOffset += curSize; 287ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com if (curOffset < writer->size()) { 288ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com // Something else between the last command and the end of the stream 289ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com return false; 290ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com } 291ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com 292ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com return true; 293ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com} 294ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com 295ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com// temporarily here to make code review easier 296ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.comstatic bool merge_savelayer_paint_into_drawbitmp(SkWriter32* writer, 297ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com SkPaintDictionary* paintDict, 298ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com const CommandInfo& saveLayerInfo, 299ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com const CommandInfo& dbmInfo); 300ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com 301ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com/* 302010f1a42e85d8c8587869e436d093d7ed40a4598skia.committer@gmail.com * Restore has just been called (but not recorded), look back at the 3036f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com * matching save* and see if we are in the configuration: 3046f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com * SAVE_LAYER 3056f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com * DRAW_BITMAP|DRAW_BITMAP_MATRIX|DRAW_BITMAP_NINE|DRAW_BITMAP_RECT_TO_RECT 3066f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com * RESTORE 3076f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com * where the saveLayer's color can be moved into the drawBitmap*'s paint 3086f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com */ 309bb6a8d87c696dade8c4730cd09b55c0ecae06462skia.committer@gmail.comstatic bool remove_save_layer1(SkWriter32* writer, int32_t offset, 3106f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkPaintDictionary* paintDict) { 3116f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com // back up to the save block 3126f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com // TODO: add a stack to track save*/restore offsets rather than searching backwards 3136f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com while (offset > 0) { 3146f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com offset = *writer->peek32(offset); 3156f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com } 3166f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 317ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com int pattern[] = { SAVE_LAYER, kDRAW_BITMAP_FLAVOR, /* RESTORE */ }; 318ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com CommandInfo result[SK_ARRAY_COUNT(pattern)]; 319ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com 320ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com if (!match(writer, -offset, pattern, result, SK_ARRAY_COUNT(pattern))) { 321ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com return false; 3226f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com } 3236f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 324ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com if (kSaveLayerWithBoundsSize == result[0].fSize) { 3256f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com // The saveLayer's bound can offset where the dbm is drawn 3266f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com return false; 3276f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com } 3286f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 3296f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 330ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com return merge_savelayer_paint_into_drawbitmp(writer, paintDict, 331ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com result[0], result[1]); 332ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com} 3336f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 334ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com/* 335ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com * Convert the command code located at 'offset' to a NOOP. Leave the size 336ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com * field alone so the NOOP can be skipped later. 337ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com */ 338ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.comstatic void convert_command_to_noop(SkWriter32* writer, uint32_t offset) { 339ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com uint32_t* ptr = writer->peek32(offset); 340ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com *ptr = (*ptr & MASK_24) | (NOOP << 24); 341ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com} 3426f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 343ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com/* 344ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com * Attempt to merge the saveLayer's paint into the drawBitmap*'s paint. 345ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com * Return true on success; false otherwise. 346ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com */ 347ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.comstatic bool merge_savelayer_paint_into_drawbitmp(SkWriter32* writer, 348ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com SkPaintDictionary* paintDict, 349ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com const CommandInfo& saveLayerInfo, 350ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com const CommandInfo& dbmInfo) { 351ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com SkASSERT(SAVE_LAYER == saveLayerInfo.fActualOp); 352010f1a42e85d8c8587869e436d093d7ed40a4598skia.committer@gmail.com SkASSERT(DRAW_BITMAP == dbmInfo.fActualOp || 353ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com DRAW_BITMAP_MATRIX == dbmInfo.fActualOp || 354010f1a42e85d8c8587869e436d093d7ed40a4598skia.committer@gmail.com DRAW_BITMAP_NINE == dbmInfo.fActualOp || 355ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com DRAW_BITMAP_RECT_TO_RECT == dbmInfo.fActualOp); 356ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com 357ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com uint32_t dbmPaintOffset = getPaintOffset(dbmInfo.fActualOp, dbmInfo.fSize); 358ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com uint32_t slPaintOffset = getPaintOffset(SAVE_LAYER, saveLayerInfo.fSize); 3596f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 3606f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com // we have a match, now we need to get the paints involved 36144509a03478a28f60b0600a9c86223b43bbc601erobertphillips@google.com uint32_t dbmPaintId = *writer->peek32(dbmInfo.fOffset+dbmPaintOffset); 36244509a03478a28f60b0600a9c86223b43bbc601erobertphillips@google.com uint32_t saveLayerPaintId = *writer->peek32(saveLayerInfo.fOffset+slPaintOffset); 3636f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 3646f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com if (0 == saveLayerPaintId) { 3656f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com // In this case the saveLayer/restore isn't needed at all - just kill the saveLayer 3666f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com // and signal the caller (by returning true) to not add the RESTORE op 367ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com convert_command_to_noop(writer, saveLayerInfo.fOffset); 3686f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com return true; 369bb6a8d87c696dade8c4730cd09b55c0ecae06462skia.committer@gmail.com } 370bb6a8d87c696dade8c4730cd09b55c0ecae06462skia.committer@gmail.com 3716f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com if (0 == dbmPaintId) { 3726f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com // In this case just make the DBM* use the saveLayer's paint, kill the saveLayer 3736f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com // and signal the caller (by returning true) to not add the RESTORE op 374ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com convert_command_to_noop(writer, saveLayerInfo.fOffset); 375ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com uint32_t* ptr = writer->peek32(dbmInfo.fOffset+dbmPaintOffset); 3766f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkASSERT(0 == *ptr); 3776f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com *ptr = saveLayerPaintId; 3786f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com return true; 379bb6a8d87c696dade8c4730cd09b55c0ecae06462skia.committer@gmail.com } 3806f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 3816f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkAutoTDelete<SkPaint> saveLayerPaint(paintDict->unflatten(saveLayerPaintId)); 3826f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com if (NULL == saveLayerPaint.get() || !is_simple(*saveLayerPaint)) { 3836f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com return false; 3846f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com } 3856f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 3866f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com // For this optimization we only fold the saveLayer and drawBitmapRect 3876f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com // together if the saveLayer's draw is simple (i.e., no fancy effects) and 3886f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com // and the only difference in the colors is that the saveLayer's can have 3896f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com // an alpha while the drawBitmapRect's is opaque. 3906f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com // TODO: it should be possible to fold them together even if they both 3916f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com // have different non-255 alphas 3926f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkColor layerColor = saveLayerPaint->getColor() | 0xFF000000; // force opaque 3936f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 3946f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkAutoTDelete<SkPaint> dbmPaint(paintDict->unflatten(dbmPaintId)); 3956f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com if (NULL == dbmPaint.get() || dbmPaint->getColor() != layerColor) { 3966f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com return false; 3976f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com } 398bb6a8d87c696dade8c4730cd09b55c0ecae06462skia.committer@gmail.com 3996f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkColor newColor = SkColorSetA(dbmPaint->getColor(), 4006f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkColorGetA(saveLayerPaint->getColor())); 4016f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com dbmPaint->setColor(newColor); 4026f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 4036f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com const SkFlatData* data = paintDict->findAndReturnFlat(*dbmPaint); 4046f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com if (NULL == data) { 4056f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com return false; 4066f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com } 4076f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 4086f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com // kill the saveLayer and alter the DBMR2R's paint to be the modified one 409ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com convert_command_to_noop(writer, saveLayerInfo.fOffset); 410ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com uint32_t* ptr = writer->peek32(dbmInfo.fOffset+dbmPaintOffset); 411ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com SkASSERT(dbmPaintId == *ptr); 4126f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com *ptr = data->index(); 4136f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com return true; 4146f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com} 4156f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 416ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com/* 417010f1a42e85d8c8587869e436d093d7ed40a4598skia.committer@gmail.com * Restore has just been called (but not recorded), look back at the 418ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com * matching save* and see if we are in the configuration: 4197a4d57dbf30ef4f55f1f763ebfc6a17877712c50robertphillips@google.com * SAVE_LAYER (with NULL == bounds) 420ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com * SAVE 421ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com * CLIP_RECT 422ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com * DRAW_BITMAP|DRAW_BITMAP_MATRIX|DRAW_BITMAP_NINE|DRAW_BITMAP_RECT_TO_RECT 423ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com * RESTORE 424ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com * RESTORE 425ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com * where the saveLayer's color can be moved into the drawBitmap*'s paint 426ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com */ 427ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.comstatic bool remove_save_layer2(SkWriter32* writer, int32_t offset, 428ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com SkPaintDictionary* paintDict) { 429ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com 430ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com // back up to the save block 431ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com // TODO: add a stack to track save*/restore offsets rather than searching backwards 432ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com while (offset > 0) { 433ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com offset = *writer->peek32(offset); 434ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com } 435ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com 436ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com int pattern[] = { SAVE_LAYER, SAVE, CLIP_RECT, kDRAW_BITMAP_FLAVOR, RESTORE, /* RESTORE */ }; 437ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com CommandInfo result[SK_ARRAY_COUNT(pattern)]; 438ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com 439ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com if (!match(writer, -offset, pattern, result, SK_ARRAY_COUNT(pattern))) { 440ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com return false; 441ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com } 442ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com 443ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com if (kSaveLayerWithBoundsSize == result[0].fSize) { 444ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com // The saveLayer's bound can offset where the dbm is drawn 445ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com return false; 446ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com } 447ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com 448ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com return merge_savelayer_paint_into_drawbitmp(writer, paintDict, 449ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com result[0], result[3]); 450ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com} 4516f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com 4526f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com/* 4536f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com * Restore has just been called (but not recorded), so look back at the 4542522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com * matching save(), and see if we can eliminate the pair of them, due to no 4552522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com * intervening matrix/clip calls. 4562522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com * 4572522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com * If so, update the writer and return true, in which case we won't even record 4582522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com * the restore() call. If we still need the restore(), return false. 4592522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com */ 460ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.comstatic bool collapse_save_clip_restore(SkWriter32* writer, int32_t offset, 461ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com SkPaintDictionary* paintDict) { 4622522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com#ifdef TRACK_COLLAPSE_STATS 4632522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com gCollapseCalls += 1; 4642522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com#endif 4652522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com 4662522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com int32_t restoreOffset = (int32_t)writer->size(); 4672522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com 4682522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com // back up to the save block 4692522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com while (offset > 0) { 4702522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com offset = *writer->peek32(offset); 4712522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com } 4722522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com 4732522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com // now offset points to a save 4742522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com offset = -offset; 475f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t opSize; 476f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com DrawType op = peek_op_and_size(writer, offset, &opSize); 477f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com if (SAVE_LAYER == op) { 4782522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com // not ready to cull these out yet (mrr) 4792522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com return false; 4802522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com } 481f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com SkASSERT(SAVE == op); 4822522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com 4832522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com // Walk forward until we get back to either a draw-verb (abort) or we hit 4842522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com // our restore (success). 4852522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com int32_t saveOffset = offset; 4862522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com 487f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com offset += opSize; 4882522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com while (offset < restoreOffset) { 489f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com op = peek_op_and_size(writer, offset, &opSize); 490f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com if ((op > CONCAT && op < ROTATE) || (SAVE_LAYER == op)) { 4912522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com // drawing verb, abort 4922522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com return false; 4932522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com } 4942522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com offset += opSize; 4952522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com } 49669a95d1bf40aa3b197983cdb1df79b4441b31de1skia.committer@gmail.com 4972522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com#ifdef TRACK_COLLAPSE_STATS 4982522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com gCollapseCount += 1; 4992522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com SkDebugf("Collapse [%d out of %d] %g%spn", gCollapseCount, gCollapseCalls, 5002522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com (double)gCollapseCount / gCollapseCalls, "%"); 5012522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com#endif 5022522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com 5032522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com writer->rewindToOffset(saveOffset); 5042522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com return true; 5052522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com} 5062522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com 507ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.comtypedef bool (*PictureRecordOptProc)(SkWriter32* writer, int32_t offset, 508ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com SkPaintDictionary* paintDict); 50947c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.orgenum PictureRecordOptType { 51047c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org kRewind_OptType, // Optimization rewinds the command stream 51147c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org kCollapseSaveLayer_OptType, // Optimization eliminates a save/restore pair 51247c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org}; 513ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com 51447c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.orgstruct PictureRecordOpt { 51547c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org PictureRecordOptProc fProc; 51647c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org PictureRecordOptType fType; 51747c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org}; 518ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com/* 519ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com * A list of the optimizations that are tried upon seeing a restore 520ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com * TODO: add a real API for such optimizations 521ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com * Add the ability to fire optimizations on any op (not just RESTORE) 522ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com */ 52347c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.orgstatic const PictureRecordOpt gPictureRecordOpts[] = { 52447c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org { collapse_save_clip_restore, kRewind_OptType }, 52547c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org { remove_save_layer1, kCollapseSaveLayer_OptType }, 52647c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org { remove_save_layer2, kCollapseSaveLayer_OptType } 527ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com}; 528ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com 52947c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org// This is called after an optimization has been applied to the command stream 53047c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org// in order to adjust the contents and state of the bounding box hierarchy and 53147c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org// state tree to reflect the optimization. 53247c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.orgstatic void apply_optimization_to_bbh(PictureRecordOptType opt, SkPictureStateTree* stateTree, 53347c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org SkBBoxHierarchy* boundingHierarchy) { 53447c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org switch (opt) { 53547c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org case kCollapseSaveLayer_OptType: 53623c343d51379aa187837799d908e039a4f20d176robertphillips@google.com if (NULL != stateTree) { 53723c343d51379aa187837799d908e039a4f20d176robertphillips@google.com stateTree->saveCollapsed(); 53823c343d51379aa187837799d908e039a4f20d176robertphillips@google.com } 53947c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org break; 54047c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org case kRewind_OptType: 54147c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org if (NULL != boundingHierarchy) { 54247c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org boundingHierarchy->rewindInserts(); 54347c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org } 54447c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org // Note: No need to touch the state tree for this to work correctly. 54547c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org // Unused branches do not burden the playback, and pruning the tree 54647c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org // would be O(N^2), so it is best to leave it alone. 54747c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org break; 54847c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org default: 54947c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org SkASSERT(0); 55047c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org } 55147c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org} 55247c2076e9e3b4777af036acfa5ff258a38cca586commit-bot@chromium.org 553bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::restore() { 554d84ed564a00a67019a345ea545ca63ab514533f7junov@chromium.org // FIXME: SkDeferredCanvas needs to be refactored to respect 555d84ed564a00a67019a345ea545ca63ab514533f7junov@chromium.org // save/restore balancing so that the following test can be 556d84ed564a00a67019a345ea545ca63ab514533f7junov@chromium.org // turned on permanently. 557d84ed564a00a67019a345ea545ca63ab514533f7junov@chromium.org#if 0 558d84ed564a00a67019a345ea545ca63ab514533f7junov@chromium.org SkASSERT(fRestoreOffsetStack.count() > 1); 559d84ed564a00a67019a345ea545ca63ab514533f7junov@chromium.org#endif 560d84ed564a00a67019a345ea545ca63ab514533f7junov@chromium.org 561b2c8220d34736e284e0a226a6848698b4734e16areed@android.com // check for underflow 562b2c8220d34736e284e0a226a6848698b4734e16areed@android.com if (fRestoreOffsetStack.count() == 0) { 563b2c8220d34736e284e0a226a6848698b4734e16areed@android.com return; 564b2c8220d34736e284e0a226a6848698b4734e16areed@android.com } 565b2c8220d34736e284e0a226a6848698b4734e16areed@android.com 5666bfd74c3d62f40c933ade44051e8a407e017b882junov@chromium.org if (fRestoreOffsetStack.count() == fFirstSavedLayerIndex) { 5676bfd74c3d62f40c933ade44051e8a407e017b882junov@chromium.org fFirstSavedLayerIndex = kNoSavedLayerIndex; 5686bfd74c3d62f40c933ade44051e8a407e017b882junov@chromium.org } 5696bfd74c3d62f40c933ade44051e8a407e017b882junov@chromium.org 570f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset, size; 5716209598697a786a985fd69fefba7624adbfe9f72robertphillips@google.com size_t opt = 0; 5727a4d57dbf30ef4f55f1f763ebfc6a17877712c50robertphillips@google.com if (!(fRecordFlags & SkPicture::kDisableRecordOptimizations_RecordingFlag)) { 5737a4d57dbf30ef4f55f1f763ebfc6a17877712c50robertphillips@google.com for (opt = 0; opt < SK_ARRAY_COUNT(gPictureRecordOpts); ++opt) { 5747a4d57dbf30ef4f55f1f763ebfc6a17877712c50robertphillips@google.com if ((*gPictureRecordOpts[opt].fProc)(&fWriter, fRestoreOffsetStack.top(), &fPaints)) { 5757a4d57dbf30ef4f55f1f763ebfc6a17877712c50robertphillips@google.com // Some optimization fired so don't add the RESTORE 5767a4d57dbf30ef4f55f1f763ebfc6a17877712c50robertphillips@google.com size = 0; 5777a4d57dbf30ef4f55f1f763ebfc6a17877712c50robertphillips@google.com initialOffset = fWriter.size(); 5787a4d57dbf30ef4f55f1f763ebfc6a17877712c50robertphillips@google.com apply_optimization_to_bbh(gPictureRecordOpts[opt].fType, 5797a4d57dbf30ef4f55f1f763ebfc6a17877712c50robertphillips@google.com fStateTree, fBoundingHierarchy); 5807a4d57dbf30ef4f55f1f763ebfc6a17877712c50robertphillips@google.com break; 5817a4d57dbf30ef4f55f1f763ebfc6a17877712c50robertphillips@google.com } 582ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com } 583a43230c68078db52692a925d272d418eceb1cbf2skia.committer@gmail.com } 584ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com 5857a4d57dbf30ef4f55f1f763ebfc6a17877712c50robertphillips@google.com if ((fRecordFlags & SkPicture::kDisableRecordOptimizations_RecordingFlag) || 5867a4d57dbf30ef4f55f1f763ebfc6a17877712c50robertphillips@google.com SK_ARRAY_COUNT(gPictureRecordOpts) == opt) { 587ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com // No optimization fired so add the RESTORE 5882522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com fillRestoreOffsetPlaceholdersForCurrentStackLevel((uint32_t)fWriter.size()); 589ed26ab55a24455c94c5333540cf654ddea706423robertphillips@google.com size = 1 * kUInt32Size; // RESTORE consists solely of 1 op code 590f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com initialOffset = this->addDraw(RESTORE, &size); 5912522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com } 5922522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com 593b2c8220d34736e284e0a226a6848698b4734e16areed@android.com fRestoreOffsetStack.pop(); 5944d379fa7dc3f3fc20542babdc5861cad0aef5f25reed@android.com 595f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 596bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return this->INHERITED::restore(); 597bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 598bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 599bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.combool SkPictureRecord::translate(SkScalar dx, SkScalar dy) { 600f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // op + dx + dy 601f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); 602f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset = this->addDraw(TRANSLATE, &size); 603bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addScalar(dx); 604bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addScalar(dy); 605f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 606bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return this->INHERITED::translate(dx, dy); 607bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 608bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 609bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.combool SkPictureRecord::scale(SkScalar sx, SkScalar sy) { 610f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // op + sx + sy 611f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); 612f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset = this->addDraw(SCALE, &size); 613bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addScalar(sx); 614bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addScalar(sy); 615f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 616bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return this->INHERITED::scale(sx, sy); 617bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 618bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 619bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.combool SkPictureRecord::rotate(SkScalar degrees) { 620f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // op + degrees 621f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t size = 1 * kUInt32Size + sizeof(SkScalar); 622f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset = this->addDraw(ROTATE, &size); 623919114813d58933c9d9433b141e0222c34b700b1reed@google.com addScalar(degrees); 624f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 625bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return this->INHERITED::rotate(degrees); 626bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 627bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 628bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.combool SkPictureRecord::skew(SkScalar sx, SkScalar sy) { 629f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // op + sx + sy 630f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); 631f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset = this->addDraw(SKEW, &size); 632bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addScalar(sx); 633bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addScalar(sy); 634f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 635bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return this->INHERITED::skew(sx, sy); 636bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 637bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 638bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.combool SkPictureRecord::concat(const SkMatrix& matrix) { 639f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(fWriter.size(), 0); 640f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // op + matrix index 641f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t size = 2 * kUInt32Size; 642f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset = this->addDraw(CONCAT, &size); 643bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addMatrix(matrix); 644f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 645bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return this->INHERITED::concat(matrix); 646bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 647bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 6485605182165ca299f085c4cb7b45a0bf3489cd372reed@android.comvoid SkPictureRecord::setMatrix(const SkMatrix& matrix) { 649f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(fWriter.size(), 0); 650f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // op + matrix index 651f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t size = 2 * kUInt32Size; 652f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset = this->addDraw(SET_MATRIX, &size); 6535605182165ca299f085c4cb7b45a0bf3489cd372reed@android.com addMatrix(matrix); 654f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 6555605182165ca299f085c4cb7b45a0bf3489cd372reed@android.com this->INHERITED::setMatrix(matrix); 6565605182165ca299f085c4cb7b45a0bf3489cd372reed@android.com} 6575605182165ca299f085c4cb7b45a0bf3489cd372reed@android.com 658e4a68b51971c02effb0799213408821930adbac7reed@google.comstatic bool regionOpExpands(SkRegion::Op op) { 659e4a68b51971c02effb0799213408821930adbac7reed@google.com switch (op) { 660e4a68b51971c02effb0799213408821930adbac7reed@google.com case SkRegion::kUnion_Op: 661e4a68b51971c02effb0799213408821930adbac7reed@google.com case SkRegion::kXOR_Op: 662e4a68b51971c02effb0799213408821930adbac7reed@google.com case SkRegion::kReverseDifference_Op: 663e4a68b51971c02effb0799213408821930adbac7reed@google.com case SkRegion::kReplace_Op: 664e4a68b51971c02effb0799213408821930adbac7reed@google.com return true; 665e4a68b51971c02effb0799213408821930adbac7reed@google.com case SkRegion::kIntersect_Op: 666e4a68b51971c02effb0799213408821930adbac7reed@google.com case SkRegion::kDifference_Op: 667e4a68b51971c02effb0799213408821930adbac7reed@google.com return false; 668e4a68b51971c02effb0799213408821930adbac7reed@google.com default: 6692d7de2d243beab591671dfaf535a637b5d305735tomhudson@google.com SkDEBUGFAIL("unknown region op"); 670e4a68b51971c02effb0799213408821930adbac7reed@google.com return false; 671e4a68b51971c02effb0799213408821930adbac7reed@google.com } 672e4a68b51971c02effb0799213408821930adbac7reed@google.com} 673e4a68b51971c02effb0799213408821930adbac7reed@google.com 6746f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.comvoid SkPictureRecord::fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t restoreOffset) { 6752522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com int32_t offset = fRestoreOffsetStack.top(); 6762522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com while (offset > 0) { 677c74b2c43b91702aac3f4f7d1dae4754da3952dbbjunov@chromium.org uint32_t* peek = fWriter.peek32(offset); 678c74b2c43b91702aac3f4f7d1dae4754da3952dbbjunov@chromium.org offset = *peek; 679c74b2c43b91702aac3f4f7d1dae4754da3952dbbjunov@chromium.org *peek = restoreOffset; 680c74b2c43b91702aac3f4f7d1dae4754da3952dbbjunov@chromium.org } 68169a95d1bf40aa3b197983cdb1df79b4441b31de1skia.committer@gmail.com 6822522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com#ifdef SK_DEBUG 6832522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com // assert that the final offset value points to a save verb 684f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t opSize; 685f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com DrawType drawOp = peek_op_and_size(&fWriter, -offset, &opSize); 6862522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com SkASSERT(SAVE == drawOp || SAVE_LAYER == drawOp); 6872522d74ffa4a622327fb1a14c1f0e2482d2466e0reed@google.com#endif 688c74b2c43b91702aac3f4f7d1dae4754da3952dbbjunov@chromium.org} 689c74b2c43b91702aac3f4f7d1dae4754da3952dbbjunov@chromium.org 690118a6d00c3089c0fcfce67919bbbeb37adda6423reed@google.comvoid SkPictureRecord::beginRecording() { 691118a6d00c3089c0fcfce67919bbbeb37adda6423reed@google.com // we have to call this *after* our constructor, to ensure that it gets 692118a6d00c3089c0fcfce67919bbbeb37adda6423reed@google.com // recorded. This is balanced by restoreToCount() call from endRecording, 693118a6d00c3089c0fcfce67919bbbeb37adda6423reed@google.com // which in-turn calls our overridden restore(), so those get recorded too. 694118a6d00c3089c0fcfce67919bbbeb37adda6423reed@google.com fInitialSaveCount = this->save(kMatrixClip_SaveFlag); 695118a6d00c3089c0fcfce67919bbbeb37adda6423reed@google.com} 696118a6d00c3089c0fcfce67919bbbeb37adda6423reed@google.com 6979aa18db116c81f6fbd563a6c28111c65bb56d742junov@chromium.orgvoid SkPictureRecord::endRecording() { 698d84ed564a00a67019a345ea545ca63ab514533f7junov@chromium.org SkASSERT(kNoInitialSave != fInitialSaveCount); 699d84ed564a00a67019a345ea545ca63ab514533f7junov@chromium.org this->restoreToCount(fInitialSaveCount); 7009aa18db116c81f6fbd563a6c28111c65bb56d742junov@chromium.org} 7019aa18db116c81f6fbd563a6c28111c65bb56d742junov@chromium.org 702c74b2c43b91702aac3f4f7d1dae4754da3952dbbjunov@chromium.orgvoid SkPictureRecord::recordRestoreOffsetPlaceholder(SkRegion::Op op) { 70327943ec75fd82ea3c33fc15410fa032a6fcdcf98reed@google.com if (fRestoreOffsetStack.isEmpty()) { 70427943ec75fd82ea3c33fc15410fa032a6fcdcf98reed@google.com return; 70527943ec75fd82ea3c33fc15410fa032a6fcdcf98reed@google.com } 70627943ec75fd82ea3c33fc15410fa032a6fcdcf98reed@google.com 707e4a68b51971c02effb0799213408821930adbac7reed@google.com if (regionOpExpands(op)) { 708e4a68b51971c02effb0799213408821930adbac7reed@google.com // Run back through any previous clip ops, and mark their offset to 709e4a68b51971c02effb0799213408821930adbac7reed@google.com // be 0, disabling their ability to trigger a jump-to-restore, otherwise 710e4a68b51971c02effb0799213408821930adbac7reed@google.com // they could hide this clips ability to expand the clip (i.e. go from 711e4a68b51971c02effb0799213408821930adbac7reed@google.com // empty to non-empty). 712c74b2c43b91702aac3f4f7d1dae4754da3952dbbjunov@chromium.org fillRestoreOffsetPlaceholdersForCurrentStackLevel(0); 713e4a68b51971c02effb0799213408821930adbac7reed@google.com } 7148c331d260c7fe604a69b6ace405a4c6cd160cf17vandebo@chromium.org 715e4a68b51971c02effb0799213408821930adbac7reed@google.com size_t offset = fWriter.size(); 716c74b2c43b91702aac3f4f7d1dae4754da3952dbbjunov@chromium.org // The RestoreOffset field is initially filled with a placeholder 717c74b2c43b91702aac3f4f7d1dae4754da3952dbbjunov@chromium.org // value that points to the offset of the previous RestoreOffset 718c74b2c43b91702aac3f4f7d1dae4754da3952dbbjunov@chromium.org // in the current stack level, thus forming a linked list so that 719935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com // the restore offsets can be filled in when the corresponding 720c74b2c43b91702aac3f4f7d1dae4754da3952dbbjunov@chromium.org // restore command is recorded. 721e4a68b51971c02effb0799213408821930adbac7reed@google.com addInt(fRestoreOffsetStack.top()); 722e4a68b51971c02effb0799213408821930adbac7reed@google.com fRestoreOffsetStack.top() = offset; 723e4a68b51971c02effb0799213408821930adbac7reed@google.com} 724e4a68b51971c02effb0799213408821930adbac7reed@google.com 7257e93ed91c3173a963cc17ef6e34b731b577b1250reed@google.combool SkPictureRecord::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 7269484f707225bfb04a436bf6ba3fdf923b0dadfearobertphillips@google.com // id + rect + clip params 7279484f707225bfb04a436bf6ba3fdf923b0dadfearobertphillips@google.com uint32_t size = 1 * kUInt32Size + sizeof(rect) + 1 * kUInt32Size; 728be48b20dc81e0160a0902207e1a40d042b83d237robertphillips@google.com // recordRestoreOffsetPlaceholder doesn't always write an offset 7299484f707225bfb04a436bf6ba3fdf923b0dadfearobertphillips@google.com if (!fRestoreOffsetStack.isEmpty()) { 7309484f707225bfb04a436bf6ba3fdf923b0dadfearobertphillips@google.com // + restore offset 7319484f707225bfb04a436bf6ba3fdf923b0dadfearobertphillips@google.com size += kUInt32Size; 7329484f707225bfb04a436bf6ba3fdf923b0dadfearobertphillips@google.com } 733f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset = this->addDraw(CLIP_RECT, &size); 734bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addRect(rect); 735c1de2b00dbdaeeb2541041ce2b0b2439fd51f80ereed@google.com addInt(ClipParams_pack(op, doAA)); 736c74b2c43b91702aac3f4f7d1dae4754da3952dbbjunov@chromium.org recordRestoreOffsetPlaceholder(op); 7370edc7a59032f7f611bf6843be47564bc89f247d9skia.committer@gmail.com 738f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 7397954ac06ca868007cae83863c0ba546a85607751reed@google.com return this->INHERITED::clipRect(rect, op, doAA); 740528d8cb43c755e51e09255afced6bd913fa2eabareed@google.com} 741528d8cb43c755e51e09255afced6bd913fa2eabareed@google.com 7427a7e655343617093a5eea37c7a556602a1bb0576reed@google.combool SkPictureRecord::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { 7437a7e655343617093a5eea37c7a556602a1bb0576reed@google.com if (rrect.isRect()) { 7447a7e655343617093a5eea37c7a556602a1bb0576reed@google.com return this->SkPictureRecord::clipRect(rrect.getBounds(), op, doAA); 7457a7e655343617093a5eea37c7a556602a1bb0576reed@google.com } 7467a7e655343617093a5eea37c7a556602a1bb0576reed@google.com 7479484f707225bfb04a436bf6ba3fdf923b0dadfearobertphillips@google.com // op + rrect + clip params 7489484f707225bfb04a436bf6ba3fdf923b0dadfearobertphillips@google.com uint32_t size = 1 * kUInt32Size + SkRRect::kSizeInMemory + 1 * kUInt32Size; 749be48b20dc81e0160a0902207e1a40d042b83d237robertphillips@google.com // recordRestoreOffsetPlaceholder doesn't always write an offset 7509484f707225bfb04a436bf6ba3fdf923b0dadfearobertphillips@google.com if (!fRestoreOffsetStack.isEmpty()) { 7519484f707225bfb04a436bf6ba3fdf923b0dadfearobertphillips@google.com // + restore offset 7529484f707225bfb04a436bf6ba3fdf923b0dadfearobertphillips@google.com size += kUInt32Size; 7539484f707225bfb04a436bf6ba3fdf923b0dadfearobertphillips@google.com } 754f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset = this->addDraw(CLIP_RRECT, &size); 7557a7e655343617093a5eea37c7a556602a1bb0576reed@google.com addRRect(rrect); 7567a7e655343617093a5eea37c7a556602a1bb0576reed@google.com addInt(ClipParams_pack(op, doAA)); 7577a7e655343617093a5eea37c7a556602a1bb0576reed@google.com recordRestoreOffsetPlaceholder(op); 7580edc7a59032f7f611bf6843be47564bc89f247d9skia.committer@gmail.com 759f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 7607a7e655343617093a5eea37c7a556602a1bb0576reed@google.com 7617a7e655343617093a5eea37c7a556602a1bb0576reed@google.com if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { 762e153aa9fb9692ec8b9834da27c6918b8900cce96junov@chromium.org return this->updateClipConservativelyUsingBounds(rrect.getBounds(), op, false); 7637a7e655343617093a5eea37c7a556602a1bb0576reed@google.com } else { 7647a7e655343617093a5eea37c7a556602a1bb0576reed@google.com return this->INHERITED::clipRRect(rrect, op, doAA); 7657a7e655343617093a5eea37c7a556602a1bb0576reed@google.com } 7667a7e655343617093a5eea37c7a556602a1bb0576reed@google.com} 7677a7e655343617093a5eea37c7a556602a1bb0576reed@google.com 7687e93ed91c3173a963cc17ef6e34b731b577b1250reed@google.combool SkPictureRecord::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { 76990520a50d191eaf3ca75b4ed48a3c3b2dd9ff755robertphillips@google.com 77090520a50d191eaf3ca75b4ed48a3c3b2dd9ff755robertphillips@google.com SkRect r; 771a1654bc2d17b9eed2c20cd7d33d18f409a67e64breed@google.com if (!path.isInverseFillType() && path.isRect(&r)) { 77290520a50d191eaf3ca75b4ed48a3c3b2dd9ff755robertphillips@google.com return this->clipRect(r, op, doAA); 77390520a50d191eaf3ca75b4ed48a3c3b2dd9ff755robertphillips@google.com } 77490520a50d191eaf3ca75b4ed48a3c3b2dd9ff755robertphillips@google.com 7759484f707225bfb04a436bf6ba3fdf923b0dadfearobertphillips@google.com // op + path index + clip params 7769484f707225bfb04a436bf6ba3fdf923b0dadfearobertphillips@google.com uint32_t size = 3 * kUInt32Size; 777be48b20dc81e0160a0902207e1a40d042b83d237robertphillips@google.com // recordRestoreOffsetPlaceholder doesn't always write an offset 7789484f707225bfb04a436bf6ba3fdf923b0dadfearobertphillips@google.com if (!fRestoreOffsetStack.isEmpty()) { 7799484f707225bfb04a436bf6ba3fdf923b0dadfearobertphillips@google.com // + restore offset 7809484f707225bfb04a436bf6ba3fdf923b0dadfearobertphillips@google.com size += kUInt32Size; 7819484f707225bfb04a436bf6ba3fdf923b0dadfearobertphillips@google.com } 782f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset = this->addDraw(CLIP_PATH, &size); 783bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addPath(path); 784c1de2b00dbdaeeb2541041ce2b0b2439fd51f80ereed@google.com addInt(ClipParams_pack(op, doAA)); 785c74b2c43b91702aac3f4f7d1dae4754da3952dbbjunov@chromium.org recordRestoreOffsetPlaceholder(op); 786919114813d58933c9d9433b141e0222c34b700b1reed@google.com 787f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 788919114813d58933c9d9433b141e0222c34b700b1reed@google.com 789c4a55d734d36f634765d63b9adfb69ddbc6182fereed@android.com if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { 790e153aa9fb9692ec8b9834da27c6918b8900cce96junov@chromium.org return this->updateClipConservativelyUsingBounds(path.getBounds(), op, 7910ae46d53f7563f38a4c07085a036ac2e5490ce1cjunov@chromium.org path.isInverseFillType()); 792c4a55d734d36f634765d63b9adfb69ddbc6182fereed@android.com } else { 7937e93ed91c3173a963cc17ef6e34b731b577b1250reed@google.com return this->INHERITED::clipPath(path, op, doAA); 794c4a55d734d36f634765d63b9adfb69ddbc6182fereed@android.com } 795bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 796bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 797bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.combool SkPictureRecord::clipRegion(const SkRegion& region, SkRegion::Op op) { 7989484f707225bfb04a436bf6ba3fdf923b0dadfearobertphillips@google.com // op + region index + clip params 7999484f707225bfb04a436bf6ba3fdf923b0dadfearobertphillips@google.com uint32_t size = 3 * kUInt32Size; 800be48b20dc81e0160a0902207e1a40d042b83d237robertphillips@google.com // recordRestoreOffsetPlaceholder doesn't always write an offset 8019484f707225bfb04a436bf6ba3fdf923b0dadfearobertphillips@google.com if (!fRestoreOffsetStack.isEmpty()) { 8029484f707225bfb04a436bf6ba3fdf923b0dadfearobertphillips@google.com // + restore offset 8039484f707225bfb04a436bf6ba3fdf923b0dadfearobertphillips@google.com size += kUInt32Size; 8049484f707225bfb04a436bf6ba3fdf923b0dadfearobertphillips@google.com } 8054b7bb5ccda62759133bc13e69f5247c91ef6a61eskia.committer@gmail.com uint32_t initialOffset = this->addDraw(CLIP_REGION, &size); 806bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addRegion(region); 807c1de2b00dbdaeeb2541041ce2b0b2439fd51f80ereed@google.com addInt(ClipParams_pack(op, false)); 808c74b2c43b91702aac3f4f7d1dae4754da3952dbbjunov@chromium.org recordRestoreOffsetPlaceholder(op); 809919114813d58933c9d9433b141e0222c34b700b1reed@google.com 810f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 811bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return this->INHERITED::clipRegion(region, op); 812bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 813bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 81405e7118ee88a85f068ed6d449d46ed0a41f79320reed@google.comvoid SkPictureRecord::clear(SkColor color) { 815f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // op + color 816f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t size = 2 * kUInt32Size; 817f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset = this->addDraw(DRAW_CLEAR, &size); 81805e7118ee88a85f068ed6d449d46ed0a41f79320reed@google.com addInt(color); 819f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 82005e7118ee88a85f068ed6d449d46ed0a41f79320reed@google.com} 82105e7118ee88a85f068ed6d449d46ed0a41f79320reed@google.com 822bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::drawPaint(const SkPaint& paint) { 823f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // op + paint index 824f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t size = 2 * kUInt32Size; 825f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset = this->addDraw(DRAW_PAINT, &size); 8266f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkASSERT(initialOffset+getPaintOffset(DRAW_PAINT, size) == fWriter.size()); 827bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addPaint(paint); 828f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 829bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 830bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 831bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::drawPoints(PointMode mode, size_t count, const SkPoint pts[], 832f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com const SkPaint& paint) { 833f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // op + paint index + mode + count + point data 834f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t size = 4 * kUInt32Size + count * sizeof(SkPoint); 835f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset = this->addDraw(DRAW_POINTS, &size); 8366f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkASSERT(initialOffset+getPaintOffset(DRAW_POINTS, size) == fWriter.size()); 837bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addPaint(paint); 838bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addInt(mode); 839bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addInt(count); 840bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fWriter.writeMul4(pts, count * sizeof(SkPoint)); 841f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 842bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 843bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 8447a7e655343617093a5eea37c7a556602a1bb0576reed@google.comvoid SkPictureRecord::drawOval(const SkRect& oval, const SkPaint& paint) { 845f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // op + paint index + rect 846f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t size = 2 * kUInt32Size + sizeof(oval); 847f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset = this->addDraw(DRAW_OVAL, &size); 8486f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkASSERT(initialOffset+getPaintOffset(DRAW_OVAL, size) == fWriter.size()); 8497a7e655343617093a5eea37c7a556602a1bb0576reed@google.com addPaint(paint); 8507a7e655343617093a5eea37c7a556602a1bb0576reed@google.com addRect(oval); 851f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 8527a7e655343617093a5eea37c7a556602a1bb0576reed@google.com} 8537a7e655343617093a5eea37c7a556602a1bb0576reed@google.com 854bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::drawRect(const SkRect& rect, const SkPaint& paint) { 855f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // op + paint index + rect 856f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t size = 2 * kUInt32Size + sizeof(rect); 857f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset = this->addDraw(DRAW_RECT, &size); 8586f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkASSERT(initialOffset+getPaintOffset(DRAW_RECT, size) == fWriter.size()); 859bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addPaint(paint); 860bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addRect(rect); 861f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 862bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 863bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 8647a7e655343617093a5eea37c7a556602a1bb0576reed@google.comvoid SkPictureRecord::drawRRect(const SkRRect& rrect, const SkPaint& paint) { 8657a7e655343617093a5eea37c7a556602a1bb0576reed@google.com if (rrect.isRect()) { 8669da4a363fe67d99d18d970b5bab36a8112961bbcjunov@chromium.org this->SkPictureRecord::drawRect(rrect.getBounds(), paint); 8677a7e655343617093a5eea37c7a556602a1bb0576reed@google.com } else if (rrect.isOval()) { 8689da4a363fe67d99d18d970b5bab36a8112961bbcjunov@chromium.org this->SkPictureRecord::drawOval(rrect.getBounds(), paint); 8697a7e655343617093a5eea37c7a556602a1bb0576reed@google.com } else { 870f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // op + paint index + rrect 8719da4a363fe67d99d18d970b5bab36a8112961bbcjunov@chromium.org uint32_t initialOffset, size; 872f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com size = 2 * kUInt32Size + SkRRect::kSizeInMemory; 873f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com initialOffset = this->addDraw(DRAW_RRECT, &size); 8746f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkASSERT(initialOffset+getPaintOffset(DRAW_RRECT, size) == fWriter.size()); 8757a7e655343617093a5eea37c7a556602a1bb0576reed@google.com addPaint(paint); 8767a7e655343617093a5eea37c7a556602a1bb0576reed@google.com addRRect(rrect); 8779da4a363fe67d99d18d970b5bab36a8112961bbcjunov@chromium.org validate(initialOffset, size); 8787a7e655343617093a5eea37c7a556602a1bb0576reed@google.com } 8797a7e655343617093a5eea37c7a556602a1bb0576reed@google.com} 8807a7e655343617093a5eea37c7a556602a1bb0576reed@google.com 881bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::drawPath(const SkPath& path, const SkPaint& paint) { 882f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // op + paint index + path index 883f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t size = 3 * kUInt32Size; 884f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset = this->addDraw(DRAW_PATH, &size); 8856f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkASSERT(initialOffset+getPaintOffset(DRAW_PATH, size) == fWriter.size()); 886bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addPaint(paint); 887bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addPath(path); 888f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 889bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 890bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 891bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, 892bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const SkPaint* paint = NULL) { 893f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // op + paint index + bitmap index + left + top 894f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t size = 3 * kUInt32Size + 2 * sizeof(SkScalar); 895f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset = this->addDraw(DRAW_BITMAP, &size); 8966f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP, size) == fWriter.size()); 897bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addPaintPtr(paint); 898bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addBitmap(bitmap); 899bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addScalar(left); 900bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addScalar(top); 901f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 902bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 903bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 9043b4aeaece7522f100f25bcb2214214acaf7891e8reed@google.comvoid SkPictureRecord::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src, 905bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const SkRect& dst, const SkPaint* paint) { 906f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // id + paint index + bitmap index + bool for 'src' 9074b7bb5ccda62759133bc13e69f5247c91ef6a61eskia.committer@gmail.com uint32_t size = 4 * kUInt32Size; 908f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com if (NULL != src) { 909f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com size += sizeof(*src); // + rect 910f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com } 911f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com size += sizeof(dst); // + rect 912f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com 913f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset = this->addDraw(DRAW_BITMAP_RECT_TO_RECT, &size); 9146f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP_RECT_TO_RECT, size) == fWriter.size()); 915bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addPaintPtr(paint); 916bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addBitmap(bitmap); 9173b4aeaece7522f100f25bcb2214214acaf7891e8reed@google.com addRectPtr(src); // may be null 918bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addRect(dst); 919f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 920bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 921bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 922bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& matrix, 9233f270706ca0ff7302b938355e6d481a6b5f04e4breed@google.com const SkPaint* paint) { 924f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // id + paint index + bitmap index + matrix index 925f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t size = 4 * kUInt32Size; 926f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset = this->addDraw(DRAW_BITMAP_MATRIX, &size); 9276f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP_MATRIX, size) == fWriter.size()); 928bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addPaintPtr(paint); 929bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addBitmap(bitmap); 930bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addMatrix(matrix); 931f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 932bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 933bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 9343f270706ca0ff7302b938355e6d481a6b5f04e4breed@google.comvoid SkPictureRecord::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, 9353f270706ca0ff7302b938355e6d481a6b5f04e4breed@google.com const SkRect& dst, const SkPaint* paint) { 936f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // op + paint index + bitmap id + center + dst rect 9374b7bb5ccda62759133bc13e69f5247c91ef6a61eskia.committer@gmail.com uint32_t size = 3 * kUInt32Size + sizeof(center) + sizeof(dst); 938f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset = this->addDraw(DRAW_BITMAP_NINE, &size); 9396f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP_NINE, size) == fWriter.size()); 9403f270706ca0ff7302b938355e6d481a6b5f04e4breed@google.com addPaintPtr(paint); 9413f270706ca0ff7302b938355e6d481a6b5f04e4breed@google.com addBitmap(bitmap); 9423f270706ca0ff7302b938355e6d481a6b5f04e4breed@google.com addIRect(center); 9433f270706ca0ff7302b938355e6d481a6b5f04e4breed@google.com addRect(dst); 944f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 9453f270706ca0ff7302b938355e6d481a6b5f04e4breed@google.com} 9463f270706ca0ff7302b938355e6d481a6b5f04e4breed@google.com 947bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::drawSprite(const SkBitmap& bitmap, int left, int top, 948bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const SkPaint* paint = NULL) { 949f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // op + paint index + bitmap index + left + top 950f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t size = 5 * kUInt32Size; 951f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset = this->addDraw(DRAW_SPRITE, &size); 9526f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkASSERT(initialOffset+getPaintOffset(DRAW_SPRITE, size) == fWriter.size()); 953bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addPaintPtr(paint); 954bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addBitmap(bitmap); 955bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addInt(left); 956bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addInt(top); 957f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 958bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 959bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 9608878ff132d537e6bd4e682fbcc570f6a8b2ac689reed@google.com// Return fontmetrics.fTop,fBottom in topbot[0,1], after they have been 9618878ff132d537e6bd4e682fbcc570f6a8b2ac689reed@google.com// tweaked by paint.computeFastBounds(). 9628878ff132d537e6bd4e682fbcc570f6a8b2ac689reed@google.com// 9638878ff132d537e6bd4e682fbcc570f6a8b2ac689reed@google.comstatic void computeFontMetricsTopBottom(const SkPaint& paint, SkScalar topbot[2]) { 964bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkPaint::FontMetrics metrics; 965bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com paint.getFontMetrics(&metrics); 966bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkRect bounds; 967bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // construct a rect so we can see any adjustments from the paint. 968bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // we use 0,1 for left,right, just so the rect isn't empty 9698878ff132d537e6bd4e682fbcc570f6a8b2ac689reed@google.com bounds.set(0, metrics.fTop, SK_Scalar1, metrics.fBottom); 970bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com (void)paint.computeFastBounds(bounds, &bounds); 9718878ff132d537e6bd4e682fbcc570f6a8b2ac689reed@google.com topbot[0] = bounds.fTop; 9728878ff132d537e6bd4e682fbcc570f6a8b2ac689reed@google.com topbot[1] = bounds.fBottom; 9738878ff132d537e6bd4e682fbcc570f6a8b2ac689reed@google.com} 9748878ff132d537e6bd4e682fbcc570f6a8b2ac689reed@google.com 975fc8ff2e8e6b71629b28b31e759f3551418f4ea13junov@chromium.orgvoid SkPictureRecord::addFontMetricsTopBottom(const SkPaint& paint, const SkFlatData& flat, 9768878ff132d537e6bd4e682fbcc570f6a8b2ac689reed@google.com SkScalar minY, SkScalar maxY) { 97775714eee0c7480aa4787b976da221739fe5d8977junov@chromium.org if (!flat.isTopBotWritten()) { 97875714eee0c7480aa4787b976da221739fe5d8977junov@chromium.org computeFontMetricsTopBottom(paint, flat.writableTopBot()); 97975714eee0c7480aa4787b976da221739fe5d8977junov@chromium.org SkASSERT(flat.isTopBotWritten()); 9808878ff132d537e6bd4e682fbcc570f6a8b2ac689reed@google.com } 98175714eee0c7480aa4787b976da221739fe5d8977junov@chromium.org addScalar(flat.topBot()[0] + minY); 98275714eee0c7480aa4787b976da221739fe5d8977junov@chromium.org addScalar(flat.topBot()[1] + maxY); 983bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 984bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 985919114813d58933c9d9433b141e0222c34b700b1reed@google.comvoid SkPictureRecord::drawText(const void* text, size_t byteLength, SkScalar x, 986bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkScalar y, const SkPaint& paint) { 9876ec9ab295d7beac041d9751b928a77501cafb46dreed@google.com bool fast = !paint.isVerticalText() && paint.canComputeFastBounds(); 988919114813d58933c9d9433b141e0222c34b700b1reed@google.com 989f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // op + paint index + length + 'length' worth of chars + x + y 990f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 2 * sizeof(SkScalar); 991f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com if (fast) { 992f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com size += 2 * sizeof(SkScalar); // + top & bottom 993f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com } 994f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com 9956f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com DrawType op = fast ? DRAW_TEXT_TOP_BOTTOM : DRAW_TEXT; 9966f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com uint32_t initialOffset = this->addDraw(op, &size); 9976f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkASSERT(initialOffset+getPaintOffset(op, size) == fWriter.size()); 998fc8ff2e8e6b71629b28b31e759f3551418f4ea13junov@chromium.org const SkFlatData* flatPaintData = addPaint(paint); 999fc8ff2e8e6b71629b28b31e759f3551418f4ea13junov@chromium.org SkASSERT(flatPaintData); 1000bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addText(text, byteLength); 1001bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addScalar(x); 1002bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addScalar(y); 1003bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (fast) { 1004fc8ff2e8e6b71629b28b31e759f3551418f4ea13junov@chromium.org addFontMetricsTopBottom(paint, *flatPaintData, y, y); 1005bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 1006f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 1007bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1008bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1009919114813d58933c9d9433b141e0222c34b700b1reed@google.comvoid SkPictureRecord::drawPosText(const void* text, size_t byteLength, 1010bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const SkPoint pos[], const SkPaint& paint) { 1011bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com size_t points = paint.countText(text, byteLength); 1012bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (0 == points) 1013bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return; 1014bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1015bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bool canUseDrawH = true; 1016d9f04f47c2d6f1c3c341d14eae875933fe4242acreed@google.com SkScalar minY = pos[0].fY; 1017d9f04f47c2d6f1c3c341d14eae875933fe4242acreed@google.com SkScalar maxY = pos[0].fY; 1018bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // check if the caller really should have used drawPosTextH() 1019bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com { 1020bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const SkScalar firstY = pos[0].fY; 1021bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com for (size_t index = 1; index < points; index++) { 1022bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (pos[index].fY != firstY) { 1023bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com canUseDrawH = false; 1024d9f04f47c2d6f1c3c341d14eae875933fe4242acreed@google.com if (pos[index].fY < minY) { 1025d9f04f47c2d6f1c3c341d14eae875933fe4242acreed@google.com minY = pos[index].fY; 1026d9f04f47c2d6f1c3c341d14eae875933fe4242acreed@google.com } else if (pos[index].fY > maxY) { 1027d9f04f47c2d6f1c3c341d14eae875933fe4242acreed@google.com maxY = pos[index].fY; 1028d9f04f47c2d6f1c3c341d14eae875933fe4242acreed@google.com } 1029bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 1030bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 1031bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 1032919114813d58933c9d9433b141e0222c34b700b1reed@google.com 10336ec9ab295d7beac041d9751b928a77501cafb46dreed@google.com bool fastBounds = !paint.isVerticalText() && paint.canComputeFastBounds(); 1034d9f04f47c2d6f1c3c341d14eae875933fe4242acreed@google.com bool fast = canUseDrawH && fastBounds; 1035bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1036f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // op + paint index + length + 'length' worth of data + num points 1037f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size; 1038f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com if (canUseDrawH) { 1039f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com if (fast) { 1040f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com size += 2 * sizeof(SkScalar); // + top & bottom 1041f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com } 1042f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // + y-pos + actual x-point data 1043f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com size += sizeof(SkScalar) + points * sizeof(SkScalar); 1044f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com } else { 1045f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // + x&y point data 1046f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com size += points * sizeof(SkPoint); 1047f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com if (fastBounds) { 1048f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com size += 2 * sizeof(SkScalar); // + top & bottom 1049f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com } 1050f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com } 1051f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com 1052f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com DrawType op; 1053bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (fast) { 1054f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com op = DRAW_POS_TEXT_H_TOP_BOTTOM; 1055d9f04f47c2d6f1c3c341d14eae875933fe4242acreed@google.com } else if (canUseDrawH) { 1056f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com op = DRAW_POS_TEXT_H; 1057d9f04f47c2d6f1c3c341d14eae875933fe4242acreed@google.com } else if (fastBounds) { 1058f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com op = DRAW_POS_TEXT_TOP_BOTTOM; 1059bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } else { 1060f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com op = DRAW_POS_TEXT; 1061bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 1062f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset = this->addDraw(op, &size); 10636f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkASSERT(initialOffset+getPaintOffset(op, size) == fWriter.size()); 1064fc8ff2e8e6b71629b28b31e759f3551418f4ea13junov@chromium.org const SkFlatData* flatPaintData = addPaint(paint); 1065fc8ff2e8e6b71629b28b31e759f3551418f4ea13junov@chromium.org SkASSERT(flatPaintData); 1066bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addText(text, byteLength); 1067bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addInt(points); 1068bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1069bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#ifdef SK_DEBUG_SIZE 1070bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com size_t start = fWriter.size(); 1071bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#endif 1072bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (canUseDrawH) { 1073bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (fast) { 1074fc8ff2e8e6b71629b28b31e759f3551418f4ea13junov@chromium.org addFontMetricsTopBottom(paint, *flatPaintData, pos[0].fY, pos[0].fY); 1075bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 1076bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addScalar(pos[0].fY); 1077bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkScalar* xptr = (SkScalar*)fWriter.reserve(points * sizeof(SkScalar)); 1078919114813d58933c9d9433b141e0222c34b700b1reed@google.com for (size_t index = 0; index < points; index++) 1079bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com *xptr++ = pos[index].fX; 1080f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com } else { 1081bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fWriter.writeMul4(pos, points * sizeof(SkPoint)); 1082d9f04f47c2d6f1c3c341d14eae875933fe4242acreed@google.com if (fastBounds) { 1083fc8ff2e8e6b71629b28b31e759f3551418f4ea13junov@chromium.org addFontMetricsTopBottom(paint, *flatPaintData, minY, maxY); 1084d9f04f47c2d6f1c3c341d14eae875933fe4242acreed@google.com } 1085bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 1086bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#ifdef SK_DEBUG_SIZE 1087bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fPointBytes += fWriter.size() - start; 1088bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fPointWrites += points; 1089bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#endif 1090f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 1091bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1092bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1093bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::drawPosTextH(const void* text, size_t byteLength, 1094bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const SkScalar xpos[], SkScalar constY, 1095bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const SkPaint& paint) { 1096bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com size_t points = paint.countText(text, byteLength); 1097bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (0 == points) 1098bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return; 1099919114813d58933c9d9433b141e0222c34b700b1reed@google.com 11006ec9ab295d7beac041d9751b928a77501cafb46dreed@google.com bool fast = !paint.isVerticalText() && paint.canComputeFastBounds(); 1101bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1102f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // op + paint index + length + 'length' worth of data + num points 1103f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size; 1104f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com if (fast) { 1105f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com size += 2 * sizeof(SkScalar); // + top & bottom 1106f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com } 1107f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // + y + the actual points 1108f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com size += 1 * kUInt32Size + points * sizeof(SkScalar); 1109f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com 11104b7bb5ccda62759133bc13e69f5247c91ef6a61eskia.committer@gmail.com uint32_t initialOffset = this->addDraw(fast ? DRAW_POS_TEXT_H_TOP_BOTTOM : DRAW_POS_TEXT_H, 1111f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com &size); 1112fc8ff2e8e6b71629b28b31e759f3551418f4ea13junov@chromium.org const SkFlatData* flatPaintData = addPaint(paint); 1113fc8ff2e8e6b71629b28b31e759f3551418f4ea13junov@chromium.org SkASSERT(flatPaintData); 1114bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addText(text, byteLength); 1115bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addInt(points); 1116919114813d58933c9d9433b141e0222c34b700b1reed@google.com 1117bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#ifdef SK_DEBUG_SIZE 1118bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com size_t start = fWriter.size(); 1119bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#endif 1120bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (fast) { 1121fc8ff2e8e6b71629b28b31e759f3551418f4ea13junov@chromium.org addFontMetricsTopBottom(paint, *flatPaintData, constY, constY); 1122bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 1123bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addScalar(constY); 1124bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fWriter.writeMul4(xpos, points * sizeof(SkScalar)); 1125bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#ifdef SK_DEBUG_SIZE 1126bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fPointBytes += fWriter.size() - start; 1127bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fPointWrites += points; 1128bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#endif 1129f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 1130bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1131bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1132919114813d58933c9d9433b141e0222c34b700b1reed@google.comvoid SkPictureRecord::drawTextOnPath(const void* text, size_t byteLength, 1133919114813d58933c9d9433b141e0222c34b700b1reed@google.com const SkPath& path, const SkMatrix* matrix, 1134bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const SkPaint& paint) { 1135f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // op + paint index + length + 'length' worth of data + path index + matrix index 1136f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 2 * kUInt32Size; 1137f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset = this->addDraw(DRAW_TEXT_ON_PATH, &size); 11386f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkASSERT(initialOffset+getPaintOffset(DRAW_TEXT_ON_PATH, size) == fWriter.size()); 1139bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addPaint(paint); 1140bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addText(text, byteLength); 1141bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addPath(path); 1142bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addMatrixPtr(matrix); 1143f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 1144bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1145bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1146bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::drawPicture(SkPicture& picture) { 1147f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // op + picture index 1148f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t size = 2 * kUInt32Size; 1149f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset = this->addDraw(DRAW_PICTURE, &size); 1150bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addPicture(picture); 1151f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 1152bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1153bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1154bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::drawVertices(VertexMode vmode, int vertexCount, 1155bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const SkPoint vertices[], const SkPoint texs[], 1156bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const SkColor colors[], SkXfermode*, 1157bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const uint16_t indices[], int indexCount, 1158bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const SkPaint& paint) { 1159bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com uint32_t flags = 0; 1160bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (texs) { 1161bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com flags |= DRAW_VERTICES_HAS_TEXS; 1162bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 1163bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (colors) { 1164bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com flags |= DRAW_VERTICES_HAS_COLORS; 1165bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 1166bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (indexCount > 0) { 1167bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com flags |= DRAW_VERTICES_HAS_INDICES; 1168bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 1169bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1170f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // op + paint index + flags + vmode + vCount + vertices 1171f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t size = 5 * kUInt32Size + vertexCount * sizeof(SkPoint); 1172f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com if (flags & DRAW_VERTICES_HAS_TEXS) { 1173f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com size += vertexCount * sizeof(SkPoint); // + uvs 1174f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com } 1175f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com if (flags & DRAW_VERTICES_HAS_COLORS) { 1176f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com size += vertexCount * sizeof(SkColor); // + vert colors 1177f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com } 1178f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com if (flags & DRAW_VERTICES_HAS_INDICES) { 1179f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // + num indices + indices 1180f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com size += 1 * kUInt32Size + SkAlign4(indexCount * sizeof(uint16_t)); 1181f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com } 1182f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com 1183f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t initialOffset = this->addDraw(DRAW_VERTICES, &size); 11846f21d8fcd94955662af7e58c8a02d1a1136a0cf5robertphillips@google.com SkASSERT(initialOffset+getPaintOffset(DRAW_VERTICES, size) == fWriter.size()); 1185bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addPaint(paint); 1186bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addInt(flags); 1187bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addInt(vmode); 1188bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addInt(vertexCount); 1189bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addPoints(vertices, vertexCount); 1190bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (flags & DRAW_VERTICES_HAS_TEXS) { 1191bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addPoints(texs, vertexCount); 1192bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 1193bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (flags & DRAW_VERTICES_HAS_COLORS) { 1194bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fWriter.writeMul4(colors, vertexCount * sizeof(SkColor)); 1195bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 1196bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (flags & DRAW_VERTICES_HAS_INDICES) { 1197bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addInt(indexCount); 1198bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fWriter.writePad(indices, indexCount * sizeof(uint16_t)); 1199bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 1200f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 1201bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1202bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 120345a0456bb1a80d41544bcab2e99aa8648b7eb6careed@android.comvoid SkPictureRecord::drawData(const void* data, size_t length) { 1204f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com // op + length + 'length' worth of data 1205f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com uint32_t size = 2 * kUInt32Size + SkAlign4(length); 12064b7bb5ccda62759133bc13e69f5247c91ef6a61eskia.committer@gmail.com uint32_t initialOffset = this->addDraw(DRAW_DATA, &size); 120745a0456bb1a80d41544bcab2e99aa8648b7eb6careed@android.com addInt(length); 120845a0456bb1a80d41544bcab2e99aa8648b7eb6careed@android.com fWriter.writePad(data, length); 1209f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com validate(initialOffset, size); 121045a0456bb1a80d41544bcab2e99aa8648b7eb6careed@android.com} 121145a0456bb1a80d41544bcab2e99aa8648b7eb6careed@android.com 1212aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.comvoid SkPictureRecord::beginCommentGroup(const char* description) { 1213aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com // op/size + length of string + \0 terminated chars 1214aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com int length = strlen(description); 1215aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com uint32_t size = 2 * kUInt32Size + SkAlign4(length + 1); 1216aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com uint32_t initialOffset = this->addDraw(BEGIN_COMMENT_GROUP, &size); 1217aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com fWriter.writeString(description, length); 1218aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com validate(initialOffset, size); 1219aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com} 1220aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com 1221aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.comvoid SkPictureRecord::addComment(const char* kywd, const char* value) { 1222aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com // op/size + 2x length of string + 2x \0 terminated chars 1223aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com int kywdLen = strlen(kywd); 1224aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com int valueLen = strlen(value); 1225aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com uint32_t size = 3 * kUInt32Size + SkAlign4(kywdLen + 1) + SkAlign4(valueLen + 1); 1226aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com uint32_t initialOffset = this->addDraw(COMMENT, &size); 1227aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com fWriter.writeString(kywd, kywdLen); 1228aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com fWriter.writeString(value, valueLen); 1229aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com validate(initialOffset, size); 1230aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com} 1231aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com 1232aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.comvoid SkPictureRecord::endCommentGroup() { 1233aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com // op/size 1234aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com uint32_t size = 1 * kUInt32Size; 1235aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com uint32_t initialOffset = this->addDraw(END_COMMENT_GROUP, &size); 1236aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com validate(initialOffset, size); 1237aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com} 1238aa62052fd968fb037fc17a1f2a3c1be34b4342bbrobertphillips@google.com 1239bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com/////////////////////////////////////////////////////////////////////////////// 1240919114813d58933c9d9433b141e0222c34b700b1reed@google.com 1241bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::addBitmap(const SkBitmap& bitmap) { 1242735d1a2bef76d58b3fffd06136e24dc96d534f79scroggo@google.com const int index = fBitmapHeap->insert(bitmap); 1243735d1a2bef76d58b3fffd06136e24dc96d534f79scroggo@google.com // In debug builds, a bad return value from insert() will crash, allowing for debugging. In 1244735d1a2bef76d58b3fffd06136e24dc96d534f79scroggo@google.com // release builds, the invalid value will be recorded so that the reader will know that there 1245735d1a2bef76d58b3fffd06136e24dc96d534f79scroggo@google.com // was a problem. 1246735d1a2bef76d58b3fffd06136e24dc96d534f79scroggo@google.com SkASSERT(index != SkBitmapHeap::INVALID_SLOT); 1247735d1a2bef76d58b3fffd06136e24dc96d534f79scroggo@google.com addInt(index); 1248bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1249bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1250bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::addMatrix(const SkMatrix& matrix) { 1251bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addMatrixPtr(&matrix); 1252bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1253bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1254bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::addMatrixPtr(const SkMatrix* matrix) { 125535e986d293340bf8cb8845e1fbf2cf13bfdac9acreed@google.com this->addInt(matrix ? fMatrices.find(*matrix) : 0); 1256bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1257bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1258fc8ff2e8e6b71629b28b31e759f3551418f4ea13junov@chromium.orgconst SkFlatData* SkPictureRecord::addPaintPtr(const SkPaint* paint) { 1259fc8ff2e8e6b71629b28b31e759f3551418f4ea13junov@chromium.org const SkFlatData* data = paint ? fPaints.findAndReturnFlat(*paint) : NULL; 1260fc8ff2e8e6b71629b28b31e759f3551418f4ea13junov@chromium.org int index = data ? data->index() : 0; 12618878ff132d537e6bd4e682fbcc570f6a8b2ac689reed@google.com this->addInt(index); 1262fc8ff2e8e6b71629b28b31e759f3551418f4ea13junov@chromium.org return data; 1263bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1264bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1265bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::addPath(const SkPath& path) { 1266bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (NULL == fPathHeap) { 1267bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fPathHeap = SkNEW(SkPathHeap); 1268bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 1269bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addInt(fPathHeap->append(path)); 1270bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1271bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1272bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::addPicture(SkPicture& picture) { 1273bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int index = fPictureRefs.find(&picture); 1274bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (index < 0) { // not found 1275bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com index = fPictureRefs.count(); 1276bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com *fPictureRefs.append() = &picture; 1277bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com picture.ref(); 1278bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 1279bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // follow the convention of recording a 1-based index 1280bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addInt(index + 1); 1281bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1282bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1283bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::addPoint(const SkPoint& point) { 1284bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#ifdef SK_DEBUG_SIZE 1285bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com size_t start = fWriter.size(); 1286bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#endif 1287bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fWriter.writePoint(point); 1288bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#ifdef SK_DEBUG_SIZE 1289bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fPointBytes += fWriter.size() - start; 1290bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fPointWrites++; 1291bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#endif 1292bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1293919114813d58933c9d9433b141e0222c34b700b1reed@google.com 1294bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::addPoints(const SkPoint pts[], int count) { 1295bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fWriter.writeMul4(pts, count * sizeof(SkPoint)); 1296bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#ifdef SK_DEBUG_SIZE 1297bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fPointBytes += count * sizeof(SkPoint); 1298bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fPointWrites++; 1299bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#endif 1300bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1301bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1302bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::addRect(const SkRect& rect) { 1303bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#ifdef SK_DEBUG_SIZE 1304bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com size_t start = fWriter.size(); 1305bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#endif 1306bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fWriter.writeRect(rect); 1307bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#ifdef SK_DEBUG_SIZE 1308bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fRectBytes += fWriter.size() - start; 1309bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fRectWrites++; 1310bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#endif 1311bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1312bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1313bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::addRectPtr(const SkRect* rect) { 1314bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (fWriter.writeBool(rect != NULL)) { 1315bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fWriter.writeRect(*rect); 1316bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 1317bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1318bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 13193f270706ca0ff7302b938355e6d481a6b5f04e4breed@google.comvoid SkPictureRecord::addIRect(const SkIRect& rect) { 13203f270706ca0ff7302b938355e6d481a6b5f04e4breed@google.com fWriter.write(&rect, sizeof(rect)); 13213f270706ca0ff7302b938355e6d481a6b5f04e4breed@google.com} 13223f270706ca0ff7302b938355e6d481a6b5f04e4breed@google.com 1323bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::addIRectPtr(const SkIRect* rect) { 1324bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (fWriter.writeBool(rect != NULL)) { 1325bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com *(SkIRect*)fWriter.reserve(sizeof(SkIRect)) = *rect; 1326bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 1327bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1328bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 13297a7e655343617093a5eea37c7a556602a1bb0576reed@google.comvoid SkPictureRecord::addRRect(const SkRRect& rrect) { 13307a7e655343617093a5eea37c7a556602a1bb0576reed@google.com fWriter.writeRRect(rrect); 13317a7e655343617093a5eea37c7a556602a1bb0576reed@google.com} 13327a7e655343617093a5eea37c7a556602a1bb0576reed@google.com 1333bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::addRegion(const SkRegion& region) { 133435e986d293340bf8cb8845e1fbf2cf13bfdac9acreed@google.com addInt(fRegions.find(region)); 1335bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1336bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1337bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::addText(const void* text, size_t byteLength) { 1338bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#ifdef SK_DEBUG_SIZE 1339bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com size_t start = fWriter.size(); 1340bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#endif 1341bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com addInt(byteLength); 1342bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fWriter.writePad(text, byteLength); 1343bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#ifdef SK_DEBUG_SIZE 1344bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fTextBytes += fWriter.size() - start; 1345bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fTextWrites++; 1346bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#endif 1347bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1348bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1349bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com/////////////////////////////////////////////////////////////////////////////// 1350bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1351bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#ifdef SK_DEBUG_SIZE 1352bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comsize_t SkPictureRecord::size() const { 1353bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com size_t result = 0; 1354bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com size_t sizeData; 1355bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bitmaps(&sizeData); 1356bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com result += sizeData; 1357bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com matrices(&sizeData); 1358bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com result += sizeData; 1359bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com paints(&sizeData); 1360bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com result += sizeData; 1361bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com paths(&sizeData); 1362bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com result += sizeData; 1363bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com pictures(&sizeData); 1364bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com result += sizeData; 1365bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com regions(&sizeData); 1366bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com result += sizeData; 1367bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com result += streamlen(); 1368bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return result; 1369bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1370bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1371bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comint SkPictureRecord::bitmaps(size_t* size) const { 1372bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com size_t result = 0; 1373bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int count = fBitmaps.count(); 1374919114813d58933c9d9433b141e0222c34b700b1reed@google.com for (int index = 0; index < count; index++) 1375bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com result += sizeof(fBitmaps[index]) + fBitmaps[index]->size(); 1376bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com *size = result; 1377bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return count; 1378bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1379bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1380bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comint SkPictureRecord::matrices(size_t* size) const { 1381bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int count = fMatrices.count(); 1382bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com *size = sizeof(fMatrices[0]) * count; 1383bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return count; 1384bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1385bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1386bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comint SkPictureRecord::paints(size_t* size) const { 1387bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com size_t result = 0; 1388bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int count = fPaints.count(); 1389919114813d58933c9d9433b141e0222c34b700b1reed@google.com for (int index = 0; index < count; index++) 1390bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com result += sizeof(fPaints[index]) + fPaints[index]->size(); 1391bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com *size = result; 1392bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return count; 1393bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1394bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1395bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comint SkPictureRecord::paths(size_t* size) const { 1396bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com size_t result = 0; 1397bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int count = fPaths.count(); 1398919114813d58933c9d9433b141e0222c34b700b1reed@google.com for (int index = 0; index < count; index++) 1399bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com result += sizeof(fPaths[index]) + fPaths[index]->size(); 1400bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com *size = result; 1401bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return count; 1402bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1403bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1404bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comint SkPictureRecord::regions(size_t* size) const { 1405bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com size_t result = 0; 1406bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int count = fRegions.count(); 1407919114813d58933c9d9433b141e0222c34b700b1reed@google.com for (int index = 0; index < count; index++) 1408bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com result += sizeof(fRegions[index]) + fRegions[index]->size(); 1409bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com *size = result; 1410bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return count; 1411bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1412bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1413bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comsize_t SkPictureRecord::streamlen() const { 1414bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return fWriter.size(); 1415bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1416bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#endif 1417bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1418bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#ifdef SK_DEBUG_VALIDATE 1419f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.comvoid SkPictureRecord::validate(uint32_t initialOffset, uint32_t size) const { 1420f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com SkASSERT(fWriter.size() == initialOffset + size); 1421f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com 1422bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com validateBitmaps(); 1423bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com validateMatrices(); 1424bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com validatePaints(); 1425bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com validatePaths(); 1426bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com validateRegions(); 1427bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1428bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1429bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::validateBitmaps() const { 1430f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com int count = fBitmapHeap->count(); 1431bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT((unsigned) count < 0x1000); 1432bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com for (int index = 0; index < count; index++) { 1433f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com const SkBitmap* bitPtr = fBitmapHeap->getBitmap(index); 1434bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(bitPtr); 1435bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bitPtr->validate(); 1436bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 1437bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1438bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1439bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::validateMatrices() const { 1440bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int count = fMatrices.count(); 1441bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT((unsigned) count < 0x1000); 1442bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com for (int index = 0; index < count; index++) { 1443f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com const SkFlatData* matrix = fMatrices[index]; 1444bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(matrix); 1445f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com// matrix->validate(); 1446bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 1447bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1448bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1449bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::validatePaints() const { 1450bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int count = fPaints.count(); 1451bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT((unsigned) count < 0x1000); 1452bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com for (int index = 0; index < count; index++) { 1453f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com const SkFlatData* paint = fPaints[index]; 1454bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(paint); 1455bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com// paint->validate(); 1456bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 1457bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1458bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1459bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::validatePaths() const { 1460f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com if (NULL == fPathHeap) { 1461f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com return; 1462f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com } 1463f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com 1464f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com int count = fPathHeap->count(); 1465bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT((unsigned) count < 0x1000); 1466bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com for (int index = 0; index < count; index++) { 1467f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com const SkPath& path = (*fPathHeap)[index]; 1468f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com path.validate(); 1469bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 1470bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1471bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1472bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkPictureRecord::validateRegions() const { 1473bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int count = fRegions.count(); 1474bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT((unsigned) count < 0x1000); 1475bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com for (int index = 0; index < count; index++) { 1476f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com const SkFlatData* region = fRegions[index]; 1477bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(region); 1478f2a01d9185ed3a378410418de02dfc9fc6ecd725robertphillips@google.com// region->validate(); 1479bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 1480bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 1481bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#endif 1482