gfx/skia/trunk/src/gpu/effects/GrTextureStripAtlas.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /*
michael@0 2 * Copyright 2012 Google Inc.
michael@0 3 *
michael@0 4 * Use of this source code is governed by a BSD-style license that can be
michael@0 5 * found in the LICENSE file.
michael@0 6 */
michael@0 7
michael@0 8 #ifndef GrTextureStripAtlas_DEFINED
michael@0 9 #define GrTextureStripAtlas_DEFINED
michael@0 10
michael@0 11 #include "GrBinHashKey.h"
michael@0 12 #include "GrTHashTable.h"
michael@0 13 #include "SkBitmap.h"
michael@0 14 #include "SkGr.h"
michael@0 15 #include "SkTDArray.h"
michael@0 16 #include "SkTypes.h"
michael@0 17
michael@0 18 /**
michael@0 19 * Maintains a single large texture whose rows store many textures of a small fixed height,
michael@0 20 * stored in rows across the x-axis such that we can safely wrap/repeat them horizontally.
michael@0 21 */
michael@0 22 class GrTextureStripAtlas {
michael@0 23 public:
michael@0 24 /**
michael@0 25 * Descriptor struct which we'll use as a hash table key
michael@0 26 **/
michael@0 27 struct Desc {
michael@0 28 Desc() { memset(this, 0, sizeof(*this)); }
michael@0 29 uint16_t fWidth, fHeight, fRowHeight;
michael@0 30 GrPixelConfig fConfig;
michael@0 31 GrContext* fContext;
michael@0 32 const uint32_t* asKey() const { return reinterpret_cast<const uint32_t*>(this); }
michael@0 33 };
michael@0 34
michael@0 35 /**
michael@0 36 * Try to find an atlas with the required parameters, creates a new one if necessary
michael@0 37 */
michael@0 38 static GrTextureStripAtlas* GetAtlas(const Desc& desc);
michael@0 39
michael@0 40 ~GrTextureStripAtlas();
michael@0 41
michael@0 42 /**
michael@0 43 * Add a texture to the atlas
michael@0 44 * @param data Bitmap data to copy into the row
michael@0 45 * @return The row index we inserted into, or -1 if we failed to find an open row. The caller
michael@0 46 * is responsible for calling unlockRow() with this row index when it's done with it.
michael@0 47 */
michael@0 48 int lockRow(const SkBitmap& data);
michael@0 49 void unlockRow(int row);
michael@0 50
michael@0 51 /**
michael@0 52 * These functions help turn an integer row index in [0, 1, 2, ... numRows] into a scalar y
michael@0 53 * texture coordinate in [0, 1] that we can use in a shader.
michael@0 54 *
michael@0 55 * If a regular texture access without using the atlas looks like:
michael@0 56 *
michael@0 57 * texture2D(sampler, vec2(x, y))
michael@0 58 *
michael@0 59 * Then when using the atlas we'd replace it with:
michael@0 60 *
michael@0 61 * texture2D(sampler, vec2(x, yOffset + y * scaleFactor))
michael@0 62 *
michael@0 63 * Where yOffset, returned by getYOffset(), is the offset to the start of the row within the
michael@0 64 * atlas and scaleFactor, returned by getVerticalScaleFactor(), is the y-scale of the row,
michael@0 65 * relative to the height of the overall atlas texture.
michael@0 66 */
michael@0 67 SkScalar getYOffset(int row) const { return SkIntToScalar(row) / fNumRows; }
michael@0 68 SkScalar getVerticalScaleFactor() const { return SkIntToScalar(fDesc.fRowHeight) / fDesc.fHeight; }
michael@0 69
michael@0 70 GrContext* getContext() const { return fDesc.fContext; }
michael@0 71 GrTexture* getTexture() const { return fTexture; }
michael@0 72
michael@0 73 private:
michael@0 74
michael@0 75 // Key to indicate an atlas row without any meaningful data stored in it
michael@0 76 const static uint32_t kEmptyAtlasRowKey = 0xffffffff;
michael@0 77
michael@0 78 /**
michael@0 79 * The state of a single row in our cache, next/prev pointers allow these to be chained
michael@0 80 * together to represent LRU status
michael@0 81 */
michael@0 82 struct AtlasRow : public SkNoncopyable {
michael@0 83 AtlasRow() : fKey(kEmptyAtlasRowKey), fLocks(0), fNext(NULL), fPrev(NULL) { }
michael@0 84 // GenerationID of the bitmap that is represented by this row, 0xffffffff means "empty"
michael@0 85 uint32_t fKey;
michael@0 86 // How many times this has been locked (0 == unlocked)
michael@0 87 int32_t fLocks;
michael@0 88 // We maintain an LRU linked list between unlocked nodes with these pointers
michael@0 89 AtlasRow* fNext;
michael@0 90 AtlasRow* fPrev;
michael@0 91 };
michael@0 92
michael@0 93 /**
michael@0 94 * We'll only allow construction via the static GrTextureStripAtlas::GetAtlas
michael@0 95 */
michael@0 96 GrTextureStripAtlas(Desc desc);
michael@0 97
michael@0 98 void lockTexture();
michael@0 99 void unlockTexture();
michael@0 100
michael@0 101 /**
michael@0 102 * Initialize our LRU list (if one already exists, clear it and start anew)
michael@0 103 */
michael@0 104 void initLRU();
michael@0 105
michael@0 106 /**
michael@0 107 * Grabs the least recently used free row out of the LRU list, returns NULL if no rows are free.
michael@0 108 */
michael@0 109 AtlasRow* getLRU();
michael@0 110
michael@0 111 void appendLRU(AtlasRow* row);
michael@0 112 void removeFromLRU(AtlasRow* row);
michael@0 113
michael@0 114 /**
michael@0 115 * Searches the key table for a key and returns the index if found; if not found, it returns
michael@0 116 * the bitwise not of the index at which we could insert the key to maintain a sorted list.
michael@0 117 **/
michael@0 118 int searchByKey(uint32_t key);
michael@0 119
michael@0 120 /**
michael@0 121 * Compare two atlas rows by key, so we can sort/search by key
michael@0 122 */
michael@0 123 static bool KeyLess(const AtlasRow& lhs, const AtlasRow& rhs) {
michael@0 124 return lhs.fKey < rhs.fKey;
michael@0 125 }
michael@0 126
michael@0 127 #ifdef SK_DEBUG
michael@0 128 void validate();
michael@0 129 #endif
michael@0 130
michael@0 131 /**
michael@0 132 * Clean up callback registered with GrContext. Allows this class to
michael@0 133 * free up any allocated AtlasEntry and GrTextureStripAtlas objects
michael@0 134 */
michael@0 135 static void CleanUp(const GrContext* context, void* info);
michael@0 136
michael@0 137 // Hash table entry for atlases
michael@0 138 class AtlasEntry;
michael@0 139 class AtlasHashKey : public GrBinHashKey<sizeof(GrTextureStripAtlas::Desc)> {
michael@0 140 public:
michael@0 141 static bool Equals(const AtlasEntry& entry, const AtlasHashKey& key);
michael@0 142 static bool LessThan(const AtlasEntry& entry, const AtlasHashKey& key);
michael@0 143 };
michael@0 144 class AtlasEntry : public ::SkNoncopyable {
michael@0 145 public:
michael@0 146 AtlasEntry() : fAtlas(NULL) {}
michael@0 147 ~AtlasEntry() { SkDELETE(fAtlas); }
michael@0 148 AtlasHashKey fKey;
michael@0 149 GrTextureStripAtlas* fAtlas;
michael@0 150 };
michael@0 151
michael@0 152 static GrTHashTable<AtlasEntry, AtlasHashKey, 8>* gAtlasCache;
michael@0 153
michael@0 154 static GrTHashTable<AtlasEntry, AtlasHashKey, 8>* GetCache();
michael@0 155
michael@0 156 // We increment gCacheCount for each atlas
michael@0 157 static int32_t gCacheCount;
michael@0 158
michael@0 159 // A unique ID for this texture (formed with: gCacheCount++), so we can be sure that if we
michael@0 160 // get a texture back from the texture cache, that it's the same one we last used.
michael@0 161 const int32_t fCacheKey;
michael@0 162
michael@0 163 // Total locks on all rows (when this reaches zero, we can unlock our texture)
michael@0 164 int32_t fLockedRows;
michael@0 165
michael@0 166 const Desc fDesc;
michael@0 167 const uint16_t fNumRows;
michael@0 168 GrTexture* fTexture;
michael@0 169
michael@0 170 // Array of AtlasRows which store the state of all our rows. Stored in a contiguous array, in
michael@0 171 // order that they appear in our texture, this means we can subtract this pointer from a row
michael@0 172 // pointer to get its index in the texture, and can save storing a row number in AtlasRow.
michael@0 173 AtlasRow* fRows;
michael@0 174
michael@0 175 // Head and tail for linked list of least-recently-used rows (front = least recently used).
michael@0 176 // Note that when a texture is locked, it gets removed from this list until it is unlocked.
michael@0 177 AtlasRow* fLRUFront;
michael@0 178 AtlasRow* fLRUBack;
michael@0 179
michael@0 180 // A list of pointers to AtlasRows that currently contain cached images, sorted by key
michael@0 181 SkTDArray<AtlasRow*> fKeyTable;
michael@0 182 };
michael@0 183
michael@0 184 inline bool GrTextureStripAtlas::AtlasHashKey::Equals(const AtlasEntry& entry,
michael@0 185 const AtlasHashKey& key) {
michael@0 186 return entry.fKey == key;
michael@0 187 }
michael@0 188
michael@0 189 inline bool GrTextureStripAtlas::AtlasHashKey::LessThan(const AtlasEntry& entry,
michael@0 190 const AtlasHashKey& key) {
michael@0 191 return entry.fKey < key;
michael@0 192 }
michael@0 193
michael@0 194 #endif

mercurial