| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 #include "GrTextureStripAtlas.h" | 9 #include "GrTextureStripAtlas.h" |
| 10 #include "SkPixelRef.h" | 10 #include "SkPixelRef.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 | 28 |
| 29 if (NULL == gAtlasCache) { | 29 if (NULL == gAtlasCache) { |
| 30 gAtlasCache = SkNEW((GrTHashTable<AtlasEntry, AtlasHashKey, 8>)); | 30 gAtlasCache = SkNEW((GrTHashTable<AtlasEntry, AtlasHashKey, 8>)); |
| 31 } | 31 } |
| 32 | 32 |
| 33 return gAtlasCache; | 33 return gAtlasCache; |
| 34 } | 34 } |
| 35 | 35 |
| 36 // Remove the specified atlas from the cache | 36 // Remove the specified atlas from the cache |
| 37 void GrTextureStripAtlas::CleanUp(const GrContext*, void* info) { | 37 void GrTextureStripAtlas::CleanUp(const GrContext*, void* info) { |
| 38 GrAssert(NULL != info); | 38 SkASSERT(NULL != info); |
| 39 | 39 |
| 40 AtlasEntry* entry = static_cast<AtlasEntry*>(info); | 40 AtlasEntry* entry = static_cast<AtlasEntry*>(info); |
| 41 | 41 |
| 42 // remove the cache entry | 42 // remove the cache entry |
| 43 GetCache()->remove(entry->fKey, entry); | 43 GetCache()->remove(entry->fKey, entry); |
| 44 | 44 |
| 45 // remove the actual entry | 45 // remove the actual entry |
| 46 SkDELETE(entry); | 46 SkDELETE(entry); |
| 47 | 47 |
| 48 if (0 == GetCache()->count()) { | 48 if (0 == GetCache()->count()) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 71 | 71 |
| 72 GrTextureStripAtlas::GrTextureStripAtlas(GrTextureStripAtlas::Desc desc) | 72 GrTextureStripAtlas::GrTextureStripAtlas(GrTextureStripAtlas::Desc desc) |
| 73 : fCacheKey(sk_atomic_inc(&gCacheCount)) | 73 : fCacheKey(sk_atomic_inc(&gCacheCount)) |
| 74 , fLockedRows(0) | 74 , fLockedRows(0) |
| 75 , fDesc(desc) | 75 , fDesc(desc) |
| 76 , fNumRows(desc.fHeight / desc.fRowHeight) | 76 , fNumRows(desc.fHeight / desc.fRowHeight) |
| 77 , fTexture(NULL) | 77 , fTexture(NULL) |
| 78 , fRows(SkNEW_ARRAY(AtlasRow, fNumRows)) | 78 , fRows(SkNEW_ARRAY(AtlasRow, fNumRows)) |
| 79 , fLRUFront(NULL) | 79 , fLRUFront(NULL) |
| 80 , fLRUBack(NULL) { | 80 , fLRUBack(NULL) { |
| 81 GrAssert(fNumRows * fDesc.fRowHeight == fDesc.fHeight); | 81 SkASSERT(fNumRows * fDesc.fRowHeight == fDesc.fHeight); |
| 82 this->initLRU(); | 82 this->initLRU(); |
| 83 VALIDATE; | 83 VALIDATE; |
| 84 } | 84 } |
| 85 | 85 |
| 86 GrTextureStripAtlas::~GrTextureStripAtlas() { | 86 GrTextureStripAtlas::~GrTextureStripAtlas() { |
| 87 SkDELETE_ARRAY(fRows); | 87 SkDELETE_ARRAY(fRows); |
| 88 } | 88 } |
| 89 | 89 |
| 90 int GrTextureStripAtlas::lockRow(const SkBitmap& data) { | 90 int GrTextureStripAtlas::lockRow(const SkBitmap& data) { |
| 91 VALIDATE; | 91 VALIDATE; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 // that is not currently in use | 157 // that is not currently in use |
| 158 fDesc.fContext->writeTexturePixels(fTexture, | 158 fDesc.fContext->writeTexturePixels(fTexture, |
| 159 0, rowNumber * fDesc.fRowHeight, | 159 0, rowNumber * fDesc.fRowHeight, |
| 160 fDesc.fWidth, fDesc.fRowHeight, | 160 fDesc.fWidth, fDesc.fRowHeight, |
| 161 SkBitmapConfig2GrPixelConfig(data.con
fig()), | 161 SkBitmapConfig2GrPixelConfig(data.con
fig()), |
| 162 data.getPixels(), | 162 data.getPixels(), |
| 163 data.rowBytes(), | 163 data.rowBytes(), |
| 164 GrContext::kDontFlush_PixelOpsFlag); | 164 GrContext::kDontFlush_PixelOpsFlag); |
| 165 } | 165 } |
| 166 | 166 |
| 167 GrAssert(rowNumber >= 0); | 167 SkASSERT(rowNumber >= 0); |
| 168 VALIDATE; | 168 VALIDATE; |
| 169 return rowNumber; | 169 return rowNumber; |
| 170 } | 170 } |
| 171 | 171 |
| 172 void GrTextureStripAtlas::unlockRow(int row) { | 172 void GrTextureStripAtlas::unlockRow(int row) { |
| 173 VALIDATE; | 173 VALIDATE; |
| 174 --fRows[row].fLocks; | 174 --fRows[row].fLocks; |
| 175 --fLockedRows; | 175 --fLockedRows; |
| 176 GrAssert(fRows[row].fLocks >= 0 && fLockedRows >= 0); | 176 SkASSERT(fRows[row].fLocks >= 0 && fLockedRows >= 0); |
| 177 if (0 == fRows[row].fLocks) { | 177 if (0 == fRows[row].fLocks) { |
| 178 this->appendLRU(fRows + row); | 178 this->appendLRU(fRows + row); |
| 179 } | 179 } |
| 180 if (0 == fLockedRows) { | 180 if (0 == fLockedRows) { |
| 181 this->unlockTexture(); | 181 this->unlockTexture(); |
| 182 } | 182 } |
| 183 VALIDATE; | 183 VALIDATE; |
| 184 } | 184 } |
| 185 | 185 |
| 186 GrTextureStripAtlas::AtlasRow* GrTextureStripAtlas::getLRU() { | 186 GrTextureStripAtlas::AtlasRow* GrTextureStripAtlas::getLRU() { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 202 memset(key.fData32 + 1, 0, sizeof(key) - sizeof(uint32_t)); | 202 memset(key.fData32 + 1, 0, sizeof(key) - sizeof(uint32_t)); |
| 203 GrCacheID cacheID(gTextureStripAtlasDomain, key); | 203 GrCacheID cacheID(gTextureStripAtlasDomain, key); |
| 204 | 204 |
| 205 fTexture = fDesc.fContext->findAndRefTexture(texDesc, cacheID, ¶ms); | 205 fTexture = fDesc.fContext->findAndRefTexture(texDesc, cacheID, ¶ms); |
| 206 if (NULL == fTexture) { | 206 if (NULL == fTexture) { |
| 207 fTexture = fDesc.fContext->createTexture(¶ms, texDesc, cacheID, NULL
, 0); | 207 fTexture = fDesc.fContext->createTexture(¶ms, texDesc, cacheID, NULL
, 0); |
| 208 // This is a new texture, so all of our cache info is now invalid | 208 // This is a new texture, so all of our cache info is now invalid |
| 209 this->initLRU(); | 209 this->initLRU(); |
| 210 fKeyTable.rewind(); | 210 fKeyTable.rewind(); |
| 211 } | 211 } |
| 212 GrAssert(NULL != fTexture); | 212 SkASSERT(NULL != fTexture); |
| 213 } | 213 } |
| 214 | 214 |
| 215 void GrTextureStripAtlas::unlockTexture() { | 215 void GrTextureStripAtlas::unlockTexture() { |
| 216 GrAssert(NULL != fTexture && 0 == fLockedRows); | 216 SkASSERT(NULL != fTexture && 0 == fLockedRows); |
| 217 fTexture->unref(); | 217 fTexture->unref(); |
| 218 fTexture = NULL; | 218 fTexture = NULL; |
| 219 fDesc.fContext->purgeCache(); | 219 fDesc.fContext->purgeCache(); |
| 220 } | 220 } |
| 221 | 221 |
| 222 void GrTextureStripAtlas::initLRU() { | 222 void GrTextureStripAtlas::initLRU() { |
| 223 fLRUFront = NULL; | 223 fLRUFront = NULL; |
| 224 fLRUBack = NULL; | 224 fLRUBack = NULL; |
| 225 // Initially all the rows are in the LRU list | 225 // Initially all the rows are in the LRU list |
| 226 for (int i = 0; i < fNumRows; ++i) { | 226 for (int i = 0; i < fNumRows; ++i) { |
| 227 fRows[i].fKey = kEmptyAtlasRowKey; | 227 fRows[i].fKey = kEmptyAtlasRowKey; |
| 228 fRows[i].fNext = NULL; | 228 fRows[i].fNext = NULL; |
| 229 fRows[i].fPrev = NULL; | 229 fRows[i].fPrev = NULL; |
| 230 this->appendLRU(fRows + i); | 230 this->appendLRU(fRows + i); |
| 231 } | 231 } |
| 232 GrAssert(NULL == fLRUFront || NULL == fLRUFront->fPrev); | 232 SkASSERT(NULL == fLRUFront || NULL == fLRUFront->fPrev); |
| 233 GrAssert(NULL == fLRUBack || NULL == fLRUBack->fNext); | 233 SkASSERT(NULL == fLRUBack || NULL == fLRUBack->fNext); |
| 234 } | 234 } |
| 235 | 235 |
| 236 void GrTextureStripAtlas::appendLRU(AtlasRow* row) { | 236 void GrTextureStripAtlas::appendLRU(AtlasRow* row) { |
| 237 GrAssert(NULL == row->fPrev && NULL == row->fNext); | 237 SkASSERT(NULL == row->fPrev && NULL == row->fNext); |
| 238 if (NULL == fLRUFront && NULL == fLRUBack) { | 238 if (NULL == fLRUFront && NULL == fLRUBack) { |
| 239 fLRUFront = row; | 239 fLRUFront = row; |
| 240 fLRUBack = row; | 240 fLRUBack = row; |
| 241 } else { | 241 } else { |
| 242 row->fPrev = fLRUBack; | 242 row->fPrev = fLRUBack; |
| 243 fLRUBack->fNext = row; | 243 fLRUBack->fNext = row; |
| 244 fLRUBack = row; | 244 fLRUBack = row; |
| 245 } | 245 } |
| 246 } | 246 } |
| 247 | 247 |
| 248 void GrTextureStripAtlas::removeFromLRU(AtlasRow* row) { | 248 void GrTextureStripAtlas::removeFromLRU(AtlasRow* row) { |
| 249 GrAssert(NULL != row); | 249 SkASSERT(NULL != row); |
| 250 if (NULL != row->fNext && NULL != row->fPrev) { | 250 if (NULL != row->fNext && NULL != row->fPrev) { |
| 251 row->fPrev->fNext = row->fNext; | 251 row->fPrev->fNext = row->fNext; |
| 252 row->fNext->fPrev = row->fPrev; | 252 row->fNext->fPrev = row->fPrev; |
| 253 } else { | 253 } else { |
| 254 if (NULL == row->fNext) { | 254 if (NULL == row->fNext) { |
| 255 GrAssert(row == fLRUBack); | 255 SkASSERT(row == fLRUBack); |
| 256 fLRUBack = row->fPrev; | 256 fLRUBack = row->fPrev; |
| 257 if (fLRUBack) { | 257 if (fLRUBack) { |
| 258 fLRUBack->fNext = NULL; | 258 fLRUBack->fNext = NULL; |
| 259 } | 259 } |
| 260 } | 260 } |
| 261 if (NULL == row->fPrev) { | 261 if (NULL == row->fPrev) { |
| 262 GrAssert(row == fLRUFront); | 262 SkASSERT(row == fLRUFront); |
| 263 fLRUFront = row->fNext; | 263 fLRUFront = row->fNext; |
| 264 if (fLRUFront) { | 264 if (fLRUFront) { |
| 265 fLRUFront->fPrev = NULL; | 265 fLRUFront->fPrev = NULL; |
| 266 } | 266 } |
| 267 } | 267 } |
| 268 } | 268 } |
| 269 row->fNext = NULL; | 269 row->fNext = NULL; |
| 270 row->fPrev = NULL; | 270 row->fPrev = NULL; |
| 271 } | 271 } |
| 272 | 272 |
| 273 int GrTextureStripAtlas::searchByKey(uint32_t key) { | 273 int GrTextureStripAtlas::searchByKey(uint32_t key) { |
| 274 AtlasRow target; | 274 AtlasRow target; |
| 275 target.fKey = key; | 275 target.fKey = key; |
| 276 return SkTSearch<const AtlasRow, | 276 return SkTSearch<const AtlasRow, |
| 277 GrTextureStripAtlas::KeyLess>((const AtlasRow**)fKeyTable.b
egin(), | 277 GrTextureStripAtlas::KeyLess>((const AtlasRow**)fKeyTable.b
egin(), |
| 278 fKeyTable.count(), | 278 fKeyTable.count(), |
| 279 &target, | 279 &target, |
| 280 sizeof(AtlasRow*)); | 280 sizeof(AtlasRow*)); |
| 281 } | 281 } |
| 282 | 282 |
| 283 #ifdef SK_DEBUG | 283 #ifdef SK_DEBUG |
| 284 void GrTextureStripAtlas::validate() { | 284 void GrTextureStripAtlas::validate() { |
| 285 | 285 |
| 286 // Our key table should be sorted | 286 // Our key table should be sorted |
| 287 uint32_t prev = 1 > fKeyTable.count() ? 0 : fKeyTable[0]->fKey; | 287 uint32_t prev = 1 > fKeyTable.count() ? 0 : fKeyTable[0]->fKey; |
| 288 for (int i = 1; i < fKeyTable.count(); ++i) { | 288 for (int i = 1; i < fKeyTable.count(); ++i) { |
| 289 GrAssert(prev < fKeyTable[i]->fKey); | 289 SkASSERT(prev < fKeyTable[i]->fKey); |
| 290 GrAssert(fKeyTable[i]->fKey != kEmptyAtlasRowKey); | 290 SkASSERT(fKeyTable[i]->fKey != kEmptyAtlasRowKey); |
| 291 prev = fKeyTable[i]->fKey; | 291 prev = fKeyTable[i]->fKey; |
| 292 } | 292 } |
| 293 | 293 |
| 294 int lruCount = 0; | 294 int lruCount = 0; |
| 295 // Validate LRU pointers, and count LRU entries | 295 // Validate LRU pointers, and count LRU entries |
| 296 GrAssert(NULL == fLRUFront || NULL == fLRUFront->fPrev); | 296 SkASSERT(NULL == fLRUFront || NULL == fLRUFront->fPrev); |
| 297 GrAssert(NULL == fLRUBack || NULL == fLRUBack->fNext); | 297 SkASSERT(NULL == fLRUBack || NULL == fLRUBack->fNext); |
| 298 for (AtlasRow* r = fLRUFront; r != NULL; r = r->fNext) { | 298 for (AtlasRow* r = fLRUFront; r != NULL; r = r->fNext) { |
| 299 if (NULL == r->fNext) { | 299 if (NULL == r->fNext) { |
| 300 GrAssert(r == fLRUBack); | 300 SkASSERT(r == fLRUBack); |
| 301 } else { | 301 } else { |
| 302 GrAssert(r->fNext->fPrev == r); | 302 SkASSERT(r->fNext->fPrev == r); |
| 303 } | 303 } |
| 304 ++lruCount; | 304 ++lruCount; |
| 305 } | 305 } |
| 306 | 306 |
| 307 int rowLocks = 0; | 307 int rowLocks = 0; |
| 308 int freeRows = 0; | 308 int freeRows = 0; |
| 309 | 309 |
| 310 for (int i = 0; i < fNumRows; ++i) { | 310 for (int i = 0; i < fNumRows; ++i) { |
| 311 rowLocks += fRows[i].fLocks; | 311 rowLocks += fRows[i].fLocks; |
| 312 if (0 == fRows[i].fLocks) { | 312 if (0 == fRows[i].fLocks) { |
| 313 ++freeRows; | 313 ++freeRows; |
| 314 bool inLRU = false; | 314 bool inLRU = false; |
| 315 // Step through the LRU and make sure it's present | 315 // Step through the LRU and make sure it's present |
| 316 for (AtlasRow* r = fLRUFront; r != NULL; r = r->fNext) { | 316 for (AtlasRow* r = fLRUFront; r != NULL; r = r->fNext) { |
| 317 if (r == &fRows[i]) { | 317 if (r == &fRows[i]) { |
| 318 inLRU = true; | 318 inLRU = true; |
| 319 break; | 319 break; |
| 320 } | 320 } |
| 321 } | 321 } |
| 322 GrAssert(inLRU); | 322 SkASSERT(inLRU); |
| 323 } else { | 323 } else { |
| 324 // If we are locked, we should have a key | 324 // If we are locked, we should have a key |
| 325 GrAssert(kEmptyAtlasRowKey != fRows[i].fKey); | 325 SkASSERT(kEmptyAtlasRowKey != fRows[i].fKey); |
| 326 } | 326 } |
| 327 | 327 |
| 328 // If we have a key != kEmptyAtlasRowKey, it should be in the key table | 328 // If we have a key != kEmptyAtlasRowKey, it should be in the key table |
| 329 GrAssert(fRows[i].fKey == kEmptyAtlasRowKey || this->searchByKey(fRows[i
].fKey) >= 0); | 329 SkASSERT(fRows[i].fKey == kEmptyAtlasRowKey || this->searchByKey(fRows[i
].fKey) >= 0); |
| 330 } | 330 } |
| 331 | 331 |
| 332 // Our count of locks should equal the sum of row locks, unless we ran out o
f rows and flushed, | 332 // Our count of locks should equal the sum of row locks, unless we ran out o
f rows and flushed, |
| 333 // in which case we'll have one more lock than recorded in the rows (to repr
esent the pending | 333 // in which case we'll have one more lock than recorded in the rows (to repr
esent the pending |
| 334 // lock of a row; which ensures we don't unlock the texture prematurely). | 334 // lock of a row; which ensures we don't unlock the texture prematurely). |
| 335 GrAssert(rowLocks == fLockedRows || rowLocks + 1 == fLockedRows); | 335 SkASSERT(rowLocks == fLockedRows || rowLocks + 1 == fLockedRows); |
| 336 | 336 |
| 337 // We should have one lru entry for each free row | 337 // We should have one lru entry for each free row |
| 338 GrAssert(freeRows == lruCount); | 338 SkASSERT(freeRows == lruCount); |
| 339 | 339 |
| 340 // If we have locked rows, we should have a locked texture, otherwise | 340 // If we have locked rows, we should have a locked texture, otherwise |
| 341 // it should be unlocked | 341 // it should be unlocked |
| 342 if (fLockedRows == 0) { | 342 if (fLockedRows == 0) { |
| 343 GrAssert(NULL == fTexture); | 343 SkASSERT(NULL == fTexture); |
| 344 } else { | 344 } else { |
| 345 GrAssert(NULL != fTexture); | 345 SkASSERT(NULL != fTexture); |
| 346 } | 346 } |
| 347 } | 347 } |
| 348 #endif | 348 #endif |
| OLD | NEW |