Home | History | Annotate | Download | only in hwui
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef ANDROID_HWUI_TEXTURE_CACHE_H
     18 #define ANDROID_HWUI_TEXTURE_CACHE_H
     19 
     20 #include <SkBitmap.h>
     21 
     22 #include <utils/LruCache.h>
     23 #include <utils/Mutex.h>
     24 
     25 #include "Debug.h"
     26 
     27 #include <vector>
     28 #include <unordered_map>
     29 
     30 namespace android {
     31 namespace uirenderer {
     32 
     33 class Texture;
     34 
     35 ///////////////////////////////////////////////////////////////////////////////
     36 // Defines
     37 ///////////////////////////////////////////////////////////////////////////////
     38 
     39 // Debug
     40 #if DEBUG_TEXTURES
     41     #define TEXTURE_LOGD(...) ALOGD(__VA_ARGS__)
     42 #else
     43     #define TEXTURE_LOGD(...)
     44 #endif
     45 
     46 ///////////////////////////////////////////////////////////////////////////////
     47 // Classes
     48 ///////////////////////////////////////////////////////////////////////////////
     49 
     50 class AssetAtlas;
     51 
     52 /**
     53  * A simple LRU texture cache. The cache has a maximum size expressed in bytes.
     54  * Any texture added to the cache causing the cache to grow beyond the maximum
     55  * allowed size will also cause the oldest texture to be kicked out.
     56  */
     57 class TextureCache : public OnEntryRemoved<uint32_t, Texture*> {
     58 public:
     59     TextureCache();
     60     ~TextureCache();
     61 
     62     /**
     63      * Used as a callback when an entry is removed from the cache.
     64      * Do not invoke directly.
     65      */
     66     void operator()(uint32_t&, Texture*& texture) override;
     67 
     68     /**
     69      * Resets all Textures to not be marked as in use
     70      */
     71     void resetMarkInUse(void* ownerToken);
     72 
     73     /**
     74      * Attempts to precache the SkBitmap. Returns true if a Texture was successfully
     75      * acquired for the bitmap, false otherwise. If a Texture was acquired it is
     76      * marked as in use.
     77      */
     78     bool prefetchAndMarkInUse(void* ownerToken, const SkBitmap* bitmap);
     79 
     80     /**
     81      * Returns the texture associated with the specified bitmap from either within the cache, or
     82      * the AssetAtlas. If the texture cannot be found in the cache, a new texture is generated.
     83      */
     84     Texture* get(const SkBitmap* bitmap) {
     85         return get(bitmap, AtlasUsageType::Use);
     86     }
     87 
     88     /**
     89      * Returns the texture associated with the specified bitmap. If the texture cannot be found in
     90      * the cache, a new texture is generated, even if it resides in the AssetAtlas.
     91      */
     92     Texture* getAndBypassAtlas(const SkBitmap* bitmap) {
     93         return get(bitmap, AtlasUsageType::Bypass);
     94     }
     95 
     96     /**
     97      * Removes the texture associated with the specified pixelRef. This is meant
     98      * to be called from threads that are not the EGL context thread.
     99      */
    100     ANDROID_API void releaseTexture(uint32_t pixelRefStableID);
    101     /**
    102      * Process deferred removals.
    103      */
    104     void clearGarbage();
    105 
    106     /**
    107      * Clears the cache. This causes all textures to be deleted.
    108      */
    109     void clear();
    110 
    111     /**
    112      * Returns the maximum size of the cache in bytes.
    113      */
    114     uint32_t getMaxSize();
    115     /**
    116      * Returns the current size of the cache in bytes.
    117      */
    118     uint32_t getSize();
    119 
    120     /**
    121      * Partially flushes the cache. The amount of memory freed by a flush
    122      * is defined by the flush rate.
    123      */
    124     void flush();
    125 
    126     void setAssetAtlas(AssetAtlas* assetAtlas);
    127 
    128 private:
    129     enum class AtlasUsageType {
    130         Use,
    131         Bypass,
    132     };
    133 
    134     bool canMakeTextureFromBitmap(const SkBitmap* bitmap);
    135 
    136     Texture* get(const SkBitmap* bitmap, AtlasUsageType atlasUsageType);
    137     Texture* getCachedTexture(const SkBitmap* bitmap, AtlasUsageType atlasUsageType);
    138 
    139     LruCache<uint32_t, Texture*> mCache;
    140 
    141     uint32_t mSize;
    142     const uint32_t mMaxSize;
    143     GLint mMaxTextureSize;
    144 
    145     const float mFlushRate;
    146 
    147     bool mDebugEnabled;
    148 
    149     std::vector<uint32_t> mGarbage;
    150     mutable Mutex mLock;
    151 
    152     AssetAtlas* mAssetAtlas;
    153 }; // class TextureCache
    154 
    155 }; // namespace uirenderer
    156 }; // namespace android
    157 
    158 #endif // ANDROID_HWUI_TEXTURE_CACHE_H
    159