1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/core/SkOffsetTable.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,115 @@ 1.4 +/* 1.5 + * Copyright 2014 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#ifndef SkOffsetTable_DEFINED 1.12 +#define SkOffsetTable_DEFINED 1.13 + 1.14 +#include "SkRefCnt.h" 1.15 +#include "SkTDArray.h" 1.16 + 1.17 +// A 2D table of skp offsets. Each row is indexed by an int. This is used 1.18 +// to store the command offsets that reference a particular bitmap using 1.19 +// the bitmap's index in the bitmap heap as the 'id' here. It has to be 1.20 +// ref-countable so SkPicturePlayback can take ownership of it. 1.21 +// Note that this class assumes that the ids are densely packed. 1.22 + 1.23 +// TODO: This needs to be sped up. We could replace the offset table with 1.24 +// a hash table. 1.25 +class SkOffsetTable : public SkRefCnt { 1.26 +public: 1.27 + SkOffsetTable() {} 1.28 + ~SkOffsetTable() { 1.29 + fOffsetArrays.deleteAll(); 1.30 + } 1.31 + 1.32 + // Record that this 'id' is used by the command starting at this 'offset'. 1.33 + // Offsets for a given 'id' should always be added in increasing order. 1.34 + void add(int id, size_t offset) { 1.35 + if (id >= fOffsetArrays.count()) { 1.36 + int oldCount = fOffsetArrays.count(); 1.37 + fOffsetArrays.setCount(id+1); 1.38 + for (int i = oldCount; i <= id; ++i) { 1.39 + fOffsetArrays[i] = NULL; 1.40 + } 1.41 + } 1.42 + 1.43 + if (NULL == fOffsetArrays[id]) { 1.44 + fOffsetArrays[id] = SkNEW(OffsetArray); 1.45 + } 1.46 + fOffsetArrays[id]->add(offset); 1.47 + } 1.48 + 1.49 + int numIDs() const { 1.50 + return fOffsetArrays.count(); 1.51 + } 1.52 + 1.53 + // Do the offsets of any commands referencing this ID fall in the 1.54 + // range [min, max] (both inclusive) 1.55 + bool overlap(int id, size_t min, size_t max) { 1.56 + SkASSERT(id < fOffsetArrays.count()); 1.57 + 1.58 + if (NULL == fOffsetArrays[id]) { 1.59 + return false; 1.60 + } 1.61 + 1.62 + // If this id has an offset array it should have at least one use 1.63 + SkASSERT(fOffsetArrays[id]->count() > 0); 1.64 + if (max < fOffsetArrays[id]->min() || min > fOffsetArrays[id]->max()) { 1.65 + return false; 1.66 + } 1.67 + 1.68 + return true; 1.69 + } 1.70 + 1.71 + bool includes(int id, size_t offset) { 1.72 + SkASSERT(id < fOffsetArrays.count()); 1.73 + 1.74 + OffsetArray* array = fOffsetArrays[id]; 1.75 + 1.76 + for (int i = 0; i < array->fOffsets.count(); ++i) { 1.77 + if (array->fOffsets[i] == offset) { 1.78 + return true; 1.79 + } else if (array->fOffsets[i] > offset) { 1.80 + return false; 1.81 + } 1.82 + } 1.83 + 1.84 + // Calls to 'includes' should be gaurded by an overlap() call, so we 1.85 + // should always find something. 1.86 + SkASSERT(0); 1.87 + return false; 1.88 + } 1.89 + 1.90 +protected: 1.91 + class OffsetArray { 1.92 + public: 1.93 + void add(size_t offset) { 1.94 + SkASSERT(fOffsets.count() == 0 || offset > this->max()); 1.95 + *fOffsets.append() = offset; 1.96 + } 1.97 + size_t min() const { 1.98 + SkASSERT(fOffsets.count() > 0); 1.99 + return fOffsets[0]; 1.100 + } 1.101 + size_t max() const { 1.102 + SkASSERT(fOffsets.count() > 0); 1.103 + return fOffsets[fOffsets.count()-1]; 1.104 + } 1.105 + int count() const { 1.106 + return fOffsets.count(); 1.107 + } 1.108 + 1.109 + SkTDArray<size_t> fOffsets; 1.110 + }; 1.111 + 1.112 + SkTDArray<OffsetArray*> fOffsetArrays; 1.113 + 1.114 +private: 1.115 + typedef SkRefCnt INHERITED; 1.116 +}; 1.117 + 1.118 +#endif