Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: src/core/SkImageFilter.cpp

Issue 452923002: Remove external SkImageFilter cache, and rename UniqueIDCache -> Cache. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkCanvas.cpp ('k') | src/gpu/SkGpuDevice.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2012 The Android Open Source Project 2 * Copyright 2012 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkImageFilter.h" 8 #include "SkImageFilter.h"
9 9
10 #include "SkBitmap.h" 10 #include "SkBitmap.h"
(...skipping 18 matching lines...) Expand all
29 static int32_t gImageFilterUniqueID; 29 static int32_t gImageFilterUniqueID;
30 30
31 // Never return 0. 31 // Never return 0.
32 int32_t id; 32 int32_t id;
33 do { 33 do {
34 id = sk_atomic_inc(&gImageFilterUniqueID) + 1; 34 id = sk_atomic_inc(&gImageFilterUniqueID) + 1;
35 } while (0 == id); 35 } while (0 == id);
36 return id; 36 return id;
37 } 37 }
38 38
39 struct SkImageFilter::UniqueIDCache::Key { 39 struct SkImageFilter::Cache::Key {
40 Key(const uint32_t uniqueID, const SkMatrix& matrix, const SkIRect& clipBoun ds, uint32_t srcGenID) 40 Key(const uint32_t uniqueID, const SkMatrix& matrix, const SkIRect& clipBoun ds, uint32_t srcGenID)
41 : fUniqueID(uniqueID), fMatrix(matrix), fClipBounds(clipBounds), fSrcGenID (srcGenID) { 41 : fUniqueID(uniqueID), fMatrix(matrix), fClipBounds(clipBounds), fSrcGenID (srcGenID) {
42 // Assert that Key is tightly-packed, since it is hashed. 42 // Assert that Key is tightly-packed, since it is hashed.
43 SK_COMPILE_ASSERT(sizeof(Key) == sizeof(uint32_t) + sizeof(SkMatrix) + s izeof(SkIRect) + 43 SK_COMPILE_ASSERT(sizeof(Key) == sizeof(uint32_t) + sizeof(SkMatrix) + s izeof(SkIRect) +
44 sizeof(uint32_t), image_filter_key_tigh t_packing); 44 sizeof(uint32_t), image_filter_key_tigh t_packing);
45 fMatrix.getType(); // force initialization of type, so hashes match 45 fMatrix.getType(); // force initialization of type, so hashes match
46 } 46 }
47 uint32_t fUniqueID; 47 uint32_t fUniqueID;
48 SkMatrix fMatrix; 48 SkMatrix fMatrix;
49 SkIRect fClipBounds; 49 SkIRect fClipBounds;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 if (buffer.isVersionLT(SkReadBuffer::kImageFilterUniqueID_Version)) { 103 if (buffer.isVersionLT(SkReadBuffer::kImageFilterUniqueID_Version)) {
104 fUniqueID = next_image_filter_unique_id(); 104 fUniqueID = next_image_filter_unique_id();
105 } else { 105 } else {
106 fUniqueID = buffer.readUInt(); 106 fUniqueID = buffer.readUInt();
107 } 107 }
108 return buffer.isValid(); 108 return buffer.isValid();
109 } 109 }
110 110
111 //////////////////////////////////////////////////////////////////////////////// /////////////////// 111 //////////////////////////////////////////////////////////////////////////////// ///////////////////
112 112
113 SkImageFilter::Cache* gExternalCache;
114
115 SkImageFilter::SkImageFilter(int inputCount, SkImageFilter** inputs, const CropR ect* cropRect) 113 SkImageFilter::SkImageFilter(int inputCount, SkImageFilter** inputs, const CropR ect* cropRect)
116 : fInputCount(inputCount), 114 : fInputCount(inputCount),
117 fInputs(new SkImageFilter*[inputCount]), 115 fInputs(new SkImageFilter*[inputCount]),
118 fUsesSrcInput(false), 116 fUsesSrcInput(false),
119 fCropRect(cropRect ? *cropRect : CropRect(SkRect(), 0x0)), 117 fCropRect(cropRect ? *cropRect : CropRect(SkRect(), 0x0)),
120 fUniqueID(next_image_filter_unique_id()) { 118 fUniqueID(next_image_filter_unique_id()) {
121 for (int i = 0; i < inputCount; ++i) { 119 for (int i = 0; i < inputCount; ++i) {
122 if (NULL == inputs[i] || inputs[i]->usesSrcInput()) { 120 if (NULL == inputs[i] || inputs[i]->usesSrcInput()) {
123 fUsesSrcInput = true; 121 fUsesSrcInput = true;
124 } 122 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 buffer.writeUInt(fCropRect.flags()); 165 buffer.writeUInt(fCropRect.flags());
168 buffer.writeUInt(fUniqueID); 166 buffer.writeUInt(fUniqueID);
169 } 167 }
170 168
171 bool SkImageFilter::filterImage(Proxy* proxy, const SkBitmap& src, 169 bool SkImageFilter::filterImage(Proxy* proxy, const SkBitmap& src,
172 const Context& context, 170 const Context& context,
173 SkBitmap* result, SkIPoint* offset) const { 171 SkBitmap* result, SkIPoint* offset) const {
174 SkASSERT(result); 172 SkASSERT(result);
175 SkASSERT(offset); 173 SkASSERT(offset);
176 uint32_t srcGenID = fUsesSrcInput ? src.getGenerationID() : 0; 174 uint32_t srcGenID = fUsesSrcInput ? src.getGenerationID() : 0;
177 Cache* externalCache = GetExternalCache(); 175 Cache::Key key(fUniqueID, context.ctm(), context.clipBounds(), srcGenID);
178 UniqueIDCache::Key key(fUniqueID, context.ctm(), context.clipBounds(), srcGe nID); 176 if (context.cache()) {
179 if (NULL != externalCache) {
180 if (externalCache->get(this, result, offset)) {
181 return true;
182 }
183 } else if (context.cache()) {
184 if (context.cache()->get(key, result, offset)) { 177 if (context.cache()->get(key, result, offset)) {
185 return true; 178 return true;
186 } 179 }
187 } 180 }
188 /* 181 /*
189 * Give the proxy first shot at the filter. If it returns false, ask 182 * Give the proxy first shot at the filter. If it returns false, ask
190 * the filter to do it. 183 * the filter to do it.
191 */ 184 */
192 if ((proxy && proxy->filterImage(this, src, context, result, offset)) || 185 if ((proxy && proxy->filterImage(this, src, context, result, offset)) ||
193 this->onFilterImage(proxy, src, context, result, offset)) { 186 this->onFilterImage(proxy, src, context, result, offset)) {
194 if (externalCache) { 187 if (context.cache()) {
195 externalCache->set(this, *result, *offset);
196 } else if (context.cache()) {
197 context.cache()->set(key, *result, *offset); 188 context.cache()->set(key, *result, *offset);
198 } 189 }
199 return true; 190 return true;
200 } 191 }
201 return false; 192 return false;
202 } 193 }
203 194
204 bool SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm, 195 bool SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm,
205 SkIRect* dst) const { 196 SkIRect* dst) const {
206 SkASSERT(&src); 197 SkASSERT(&src);
207 SkASSERT(dst); 198 SkASSERT(dst);
208 if (SkImageFilter::GetExternalCache()) {
209 /*
210 * When the external cache is active, do not intersect the saveLayer
211 * bounds with the clip bounds. This is so that the cached result
212 * is always the full size of the primitive's bounds,
213 * regardless of the clip active on first draw.
214 */
215 *dst = SkIRect::MakeLargest();
216 return true;
217 }
218 return this->onFilterBounds(src, ctm, dst); 199 return this->onFilterBounds(src, ctm, dst);
219 } 200 }
220 201
221 void SkImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const { 202 void SkImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const {
222 if (0 == fInputCount) { 203 if (0 == fInputCount) {
223 *dst = src; 204 *dst = src;
224 return; 205 return;
225 } 206 }
226 if (this->getInput(0)) { 207 if (this->getInput(0)) {
227 this->getInput(0)->computeFastBounds(src, dst); 208 this->getInput(0)->computeFastBounds(src, dst);
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 } 363 }
383 364
384 bool SkImageFilter::asNewEffect(GrEffect**, GrTexture*, const SkMatrix&, const S kIRect&) const { 365 bool SkImageFilter::asNewEffect(GrEffect**, GrTexture*, const SkMatrix&, const S kIRect&) const {
385 return false; 366 return false;
386 } 367 }
387 368
388 bool SkImageFilter::asColorFilter(SkColorFilter**) const { 369 bool SkImageFilter::asColorFilter(SkColorFilter**) const {
389 return false; 370 return false;
390 } 371 }
391 372
392 void SkImageFilter::SetExternalCache(Cache* cache) {
393 SkRefCnt_SafeAssign(gExternalCache, cache);
394 }
395
396 SkImageFilter::Cache* SkImageFilter::GetExternalCache() {
397 return gExternalCache;
398 }
399
400 #if SK_SUPPORT_GPU 373 #if SK_SUPPORT_GPU
401 374
402 void SkImageFilter::WrapTexture(GrTexture* texture, int width, int height, SkBit map* result) { 375 void SkImageFilter::WrapTexture(GrTexture* texture, int width, int height, SkBit map* result) {
403 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); 376 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
404 result->setInfo(info); 377 result->setInfo(info);
405 result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref(); 378 result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref();
406 } 379 }
407 380
408 bool SkImageFilter::getInputResultGPU(SkImageFilter::Proxy* proxy, 381 bool SkImageFilter::getInputResultGPU(SkImageFilter::Proxy* proxy,
409 const SkBitmap& src, const Context& ctx, 382 const SkBitmap& src, const Context& ctx,
(...skipping 17 matching lines...) Expand all
427 GrUnlockAndUnrefCachedBitmapTexture(resultTex); 400 GrUnlockAndUnrefCachedBitmapTexture(resultTex);
428 } 401 }
429 return true; 402 return true;
430 } else { 403 } else {
431 return false; 404 return false;
432 } 405 }
433 } 406 }
434 } 407 }
435 #endif 408 #endif
436 409
410 namespace {
411
437 class CacheImpl : public SkImageFilter::Cache { 412 class CacheImpl : public SkImageFilter::Cache {
438 public: 413 public:
439 explicit CacheImpl(int minChildren) : fMinChildren(minChildren) { 414 CacheImpl(size_t maxBytes) : fMaxBytes(maxBytes), fCurrentBytes(0) {
440 SkASSERT(fMinChildren <= 2);
441 } 415 }
442 416 virtual ~CacheImpl() {
443 virtual ~CacheImpl();
444 bool get(const SkImageFilter* key, SkBitmap* result, SkIPoint* offset) SK_OV ERRIDE;
445 void set(const SkImageFilter* key, const SkBitmap& result, const SkIPoint& o ffset) SK_OVERRIDE;
446 void remove(const SkImageFilter* key) SK_OVERRIDE;
447 private:
448 typedef const SkImageFilter* Key;
449 struct Value {
450 Value(Key key, const SkBitmap& bitmap, const SkIPoint& offset)
451 : fKey(key), fBitmap(bitmap), fOffset(offset) {}
452 Key fKey;
453 SkBitmap fBitmap;
454 SkIPoint fOffset;
455 static const Key& GetKey(const Value& v) {
456 return v.fKey;
457 }
458 static uint32_t Hash(Key key) {
459 return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(&key), sizeof(Key));
460 }
461 };
462 SkTDynamicHash<Value, Key> fData;
463 int fMinChildren;
464 };
465
466 bool CacheImpl::get(const SkImageFilter* key, SkBitmap* result, SkIPoint* offset ) {
467 Value* v = fData.find(key);
468 if (v) {
469 *result = v->fBitmap;
470 *offset = v->fOffset;
471 return true;
472 }
473 return false;
474 }
475
476 void CacheImpl::remove(const SkImageFilter* key) {
477 Value* v = fData.find(key);
478 if (v) {
479 fData.remove(key);
480 delete v;
481 }
482 }
483
484 void CacheImpl::set(const SkImageFilter* key, const SkBitmap& result, const SkIP oint& offset) {
485 if (fMinChildren < 2 || !key->unique()) {
486 // We take !key->unique() as a signal that there are probably at least 2 refs on the key,
487 // meaning this filter probably has at least two children and is worth c aching when
488 // fMinChildren is 2. If fMinChildren is less than two, we'll just alwa ys cache.
489 fData.add(new Value(key, result, offset));
490 }
491 }
492
493 SkImageFilter::Cache* SkImageFilter::Cache::Create(int minChildren) {
494 return new CacheImpl(minChildren);
495 }
496
497 CacheImpl::~CacheImpl() {
498 SkTDynamicHash<Value, Key>::Iter iter(&fData);
499
500 while (!iter.done()) {
501 Value* v = &*iter;
502 ++iter;
503 delete v;
504 }
505 }
506
507 namespace {
508
509 class UniqueIDCacheImpl : public SkImageFilter::UniqueIDCache {
510 public:
511 UniqueIDCacheImpl(size_t maxBytes) : fMaxBytes(maxBytes), fCurrentBytes(0) {
512 }
513 virtual ~UniqueIDCacheImpl() {
514 SkTDynamicHash<Value, Key>::Iter iter(&fLookup); 417 SkTDynamicHash<Value, Key>::Iter iter(&fLookup);
515 418
516 while (!iter.done()) { 419 while (!iter.done()) {
517 Value* v = &*iter; 420 Value* v = &*iter;
518 ++iter; 421 ++iter;
519 delete v; 422 delete v;
520 } 423 }
521 } 424 }
522 struct Value { 425 struct Value {
523 Value(const Key& key, const SkBitmap& bitmap, const SkIPoint& offset) 426 Value(const Key& key, const SkBitmap& bitmap, const SkIPoint& offset)
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
572 delete v; 475 delete v;
573 } 476 }
574 private: 477 private:
575 SkTDynamicHash<Value, Key> fLookup; 478 SkTDynamicHash<Value, Key> fLookup;
576 mutable SkTInternalLList<Value> fLRU; 479 mutable SkTInternalLList<Value> fLRU;
577 size_t fMaxBytes; 480 size_t fMaxBytes;
578 size_t fCurrentBytes; 481 size_t fCurrentBytes;
579 mutable SkMutex fMutex; 482 mutable SkMutex fMutex;
580 }; 483 };
581 484
582 SkImageFilter::UniqueIDCache* CreateCache() { 485 SkImageFilter::Cache* CreateCache() {
583 return SkImageFilter::UniqueIDCache::Create(kDefaultCacheSize); 486 return SkImageFilter::Cache::Create(kDefaultCacheSize);
584 } 487 }
585 488
586 } // namespace 489 } // namespace
587 490
588 SkImageFilter::UniqueIDCache* SkImageFilter::UniqueIDCache::Create(size_t maxByt es) { 491 SkImageFilter::Cache* SkImageFilter::Cache::Create(size_t maxBytes) {
589 return SkNEW_ARGS(UniqueIDCacheImpl, (maxBytes)); 492 return SkNEW_ARGS(CacheImpl, (maxBytes));
590 } 493 }
591 494
592 SkImageFilter::UniqueIDCache* SkImageFilter::UniqueIDCache::Get() { 495 SkImageFilter::Cache* SkImageFilter::Cache::Get() {
593 SK_DECLARE_STATIC_LAZY_PTR(SkImageFilter::UniqueIDCache, cache, CreateCache) ; 496 SK_DECLARE_STATIC_LAZY_PTR(SkImageFilter::Cache, cache, CreateCache);
594 return cache.get(); 497 return cache.get();
595 } 498 }
OLDNEW
« no previous file with comments | « src/core/SkCanvas.cpp ('k') | src/gpu/SkGpuDevice.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698