Index: src/core/SkPictureRecord.h |
=================================================================== |
--- src/core/SkPictureRecord.h (revision 13658) |
+++ src/core/SkPictureRecord.h (working copy) |
@@ -22,6 +22,95 @@ |
class SkPictureStateTree; |
class SkBBoxHierarchy; |
+// A 2D table of skp offsets. Each row is indexed by an int. This is used |
+// to store the command offsets that reference a particular bitmap using |
+// the bitmap's index in the bitmap heap as the 'id' here. It has to be |
+// ref-countable so SkPicturePlayback can take ownership of it. |
+class SkOffsetTable : public SkRefCnt { |
mtklein
2014/03/06 16:20:38
Give this class its own .h/.cpp pair?
robertphillips
2014/03/06 20:18:26
Will do. I will leave that as a final refactoring
|
+public: |
+ SkOffsetTable() {} |
+ ~SkOffsetTable() { |
+ for (int i = 0; i < fOffsetArrays.count(); ++i) { |
mtklein
2014/03/06 16:20:38
fOffsetArrays.deleteAll(); ?
robertphillips
2014/03/06 20:18:26
Done.
|
+ SkDELETE(fOffsetArrays[i]); |
+ } |
+ } |
+ |
+ void add(int id, size_t offset) { |
mtklein
2014/03/06 16:20:38
// Record that this ID is used by the command star
robertphillips
2014/03/06 20:18:26
Done.
|
+ if (id >= fOffsetArrays.count()) { |
mtklein
2014/03/06 16:20:38
Can you note somewhere, maybe at the top of the cl
robertphillips
2014/03/06 20:18:26
Done.
|
+ int oldCount = fOffsetArrays.count(); |
+ fOffsetArrays.setCount(id+1); |
+ for (int i = oldCount; i <= id; ++i) { |
+ fOffsetArrays[i] = NULL; |
+ } |
+ } |
mtklein
2014/03/06 16:20:38
Are we assuming |IDs| << |offsets|? If there are
robertphillips
2014/03/06 20:18:26
|IDs| is < |offsets| but it varies widely between
|
+ |
+ if (NULL == fOffsetArrays[id]) { |
+ fOffsetArrays[id] = SkNEW(OffsetArray); |
+ } |
+ fOffsetArrays[id]->add(offset); |
+ } |
+ |
+ int numIDs() const { |
+ return fOffsetArrays.count(); |
+ } |
+ |
+ bool overlap(int id, size_t min, size_t max) { |
mtklein
2014/03/06 16:20:38
// Do the offsets of any commands referencing this
robertphillips
2014/03/06 20:18:26
Done.
|
+ SkASSERT(id < fOffsetArrays.count()); |
+ |
+ if (NULL == fOffsetArrays[id]) { |
+ return false; |
+ } |
+ |
+ SkASSERT(fOffsetArrays[id]->count() > 0); |
mtklein
2014/03/06 16:20:38
->front() and ->back() are about to check this any
robertphillips
2014/03/06 20:18:26
I've added a comment. The assert here was basicall
|
+ if (max < fOffsetArrays[id]->front() || min > fOffsetArrays[id]->back()) { |
mtklein
2014/03/06 16:20:38
Might help readability here to rename front to low
robertphillips
2014/03/06 20:18:26
Done.
|
+ return false; |
+ } |
+ |
+ return true; |
+ } |
+ |
+ bool includes(int id, size_t offset) { |
mtklein
2014/03/06 16:20:38
Note that this is linear in the number of commands
robertphillips
2014/03/06 20:18:26
Yep - right now I'm just trying to get it working.
|
+ SkASSERT(id < fOffsetArrays.count()); |
+ |
+ OffsetArray* array = fOffsetArrays[id]; |
+ |
+ for (int i = 0; i < array->fOffsets.count(); ++i) { |
+ if (array->fOffsets[i] == offset) { |
+ return true; |
+ } else if (array->fOffsets[i] > offset) { |
+ return false; |
+ } |
+ } |
+ |
+ SkASSERT(0); |
mtklein
2014/03/06 16:20:38
Why this assert? I guess we don't expect people t
robertphillips
2014/03/06 20:18:26
Given that this should always be guarded by a 'ove
mtklein
2014/03/07 13:04:08
Ah, can you add // We're guarded by an overlap() c
robertphillips
2014/03/07 13:23:00
Done.
|
+ return false; |
+ } |
+ |
+protected: |
+ class OffsetArray { |
+ public: |
+ void add(size_t offset) { *fOffsets.append() = offset; } |
mtklein
2014/03/06 16:20:38
Seems like we'd want to add
SkASSERT(fOffsets.co
robertphillips
2014/03/06 20:18:26
Done.
|
+ size_t front() const { |
+ SkASSERT(fOffsets.count() > 0); |
+ return fOffsets[0]; |
+ } |
+ size_t back() const { |
+ SkASSERT(fOffsets.count() > 0); |
+ return fOffsets[fOffsets.count()-1]; |
+ } |
+ int count() const { |
+ return fOffsets.count(); |
+ } |
+ |
+ SkTDArray<size_t> fOffsets; |
+ }; |
+ |
+ SkTDArray<OffsetArray*> fOffsetArrays; |
+ |
+private: |
+ typedef SkRefCnt INHERITED; |
+}; |
+ |
// These macros help with packing and unpacking a single byte value and |
// a 3 byte value into/out of a uint32_t |
#define MASK_24 0x00FFFFFF |
@@ -164,7 +253,9 @@ |
fWriter.writeScalar(scalar); |
} |
- void addBitmap(const SkBitmap& bitmap); |
+ // The command at 'offset' in the skp uses the specified bitmap |
+ void trackBitmapUse(int bitmapID, size_t offset); |
+ int addBitmap(const SkBitmap& bitmap); |
void addMatrix(const SkMatrix& matrix); |
const SkFlatData* addPaint(const SkPaint& paint) { return this->addPaintPtr(&paint); } |
const SkFlatData* addPaintPtr(const SkPaint* paint); |
@@ -294,6 +385,8 @@ |
bool fOptsEnabled; |
int fInitialSaveCount; |
+ SkOffsetTable* fBitmapUseOffsets; |
mtklein
2014/03/06 16:20:38
SkAutoTUnref<SkOffsetTable> ?
robertphillips
2014/03/06 20:18:26
Done.
|
+ |
friend class SkPicturePlayback; |
friend class SkPictureTester; // for unit testing |