Home | History | Annotate | Download | only in tools
      1 /*
      2  * Copyright 2013 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "LazyDecodeBitmap.h"
      9 
     10 #include "PictureRenderingFlags.h"  // --deferImageDecoding is defined here.
     11 #include "SkBitmap.h"
     12 #include "SkData.h"
     13 #include "SkImageDecoder.h"
     14 #include "SkForceLinking.h"
     15 #include "SkLruImageCache.h"
     16 #include "SkPurgeableImageCache.h"
     17 #include "SkCommandLineFlags.h"
     18 
     19 __SK_FORCE_IMAGE_DECODER_LINKING;
     20 
     21 DEFINE_bool(useVolatileCache, false, "Use a volatile cache for deferred image decoding pixels. "
     22             "Only meaningful if --deferImageDecoding is set to true and the platform has an "
     23             "implementation.");
     24 
     25 SkLruImageCache gLruImageCache(1024 * 1024);
     26 
     27 namespace sk_tools {
     28 
     29 // Simple cache selector to choose between a purgeable cache for large images and the standard one
     30 // for smaller images.
     31 //
     32 class CacheSelector : public SkBitmapFactory::CacheSelector {
     33 
     34 public:
     35     CacheSelector() {
     36         fPurgeableImageCache = SkPurgeableImageCache::Create();
     37     }
     38 
     39     ~CacheSelector() {
     40         SkSafeUnref(fPurgeableImageCache);
     41     }
     42 
     43     virtual SkImageCache* selectCache(const SkImage::Info& info) SK_OVERRIDE {
     44         if (info.fWidth * info.fHeight > 32 * 1024 && fPurgeableImageCache != NULL) {
     45             return fPurgeableImageCache;
     46         }
     47         return &gLruImageCache;
     48     }
     49 private:
     50     SkImageCache* fPurgeableImageCache;
     51 };
     52 
     53 static CacheSelector gCacheSelector;
     54 static SkBitmapFactory gFactory(&SkImageDecoder::DecodeMemoryToTarget);
     55 
     56 bool LazyDecodeBitmap(const void* buffer, size_t size, SkBitmap* bitmap) {
     57     void* copiedBuffer = sk_malloc_throw(size);
     58     memcpy(copiedBuffer, buffer, size);
     59     SkAutoDataUnref data(SkData::NewFromMalloc(copiedBuffer, size));
     60 
     61     static bool gOnce;
     62     if (!gOnce) {
     63         // Only use the cache selector if there is a purgeable image cache to use for large
     64         // images.
     65         if (FLAGS_useVolatileCache && SkAutoTUnref<SkImageCache>(
     66                 SkPurgeableImageCache::Create()).get() != NULL) {
     67             gFactory.setCacheSelector(&gCacheSelector);
     68         } else {
     69             gFactory.setImageCache(&gLruImageCache);
     70         }
     71         gOnce = true;
     72     }
     73     return gFactory.installPixelRef(data, bitmap);
     74 }
     75 
     76 }  // namespace sk_tools
     77