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_GRADIENT_CACHE_H
     18 #define ANDROID_HWUI_GRADIENT_CACHE_H
     19 
     20 #include <memory>
     21 
     22 #include <GLES3/gl3.h>
     23 
     24 #include <SkShader.h>
     25 
     26 #include <utils/LruCache.h>
     27 #include <utils/Mutex.h>
     28 
     29 #include "FloatColor.h"
     30 
     31 namespace android {
     32 namespace uirenderer {
     33 
     34 class Texture;
     35 
     36 struct GradientCacheEntry {
     37     GradientCacheEntry() {
     38         count = 0;
     39         colors = nullptr;
     40         positions = nullptr;
     41     }
     42 
     43     GradientCacheEntry(uint32_t* colors, float* positions, uint32_t count) {
     44         copy(colors, positions, count);
     45     }
     46 
     47     GradientCacheEntry(const GradientCacheEntry& entry) {
     48         copy(entry.colors.get(), entry.positions.get(), entry.count);
     49     }
     50 
     51     GradientCacheEntry& operator=(const GradientCacheEntry& entry) {
     52         if (this != &entry) {
     53             copy(entry.colors.get(), entry.positions.get(), entry.count);
     54         }
     55 
     56         return *this;
     57     }
     58 
     59     hash_t hash() const;
     60 
     61     static int compare(const GradientCacheEntry& lhs, const GradientCacheEntry& rhs);
     62 
     63     bool operator==(const GradientCacheEntry& other) const {
     64         return compare(*this, other) == 0;
     65     }
     66 
     67     bool operator!=(const GradientCacheEntry& other) const {
     68         return compare(*this, other) != 0;
     69     }
     70 
     71     std::unique_ptr<uint32_t[]> colors;
     72     std::unique_ptr<float[]> positions;
     73     uint32_t count;
     74 
     75 private:
     76     void copy(uint32_t* colors, float* positions, uint32_t count) {
     77         this->count = count;
     78         this->colors.reset(new uint32_t[count]);
     79         this->positions.reset(new float[count]);
     80 
     81         memcpy(this->colors.get(), colors, count * sizeof(uint32_t));
     82         memcpy(this->positions.get(), positions, count * sizeof(float));
     83     }
     84 
     85 }; // GradientCacheEntry
     86 
     87 // Caching support
     88 
     89 inline int strictly_order_type(const GradientCacheEntry& lhs, const GradientCacheEntry& rhs) {
     90     return GradientCacheEntry::compare(lhs, rhs) < 0;
     91 }
     92 
     93 inline int compare_type(const GradientCacheEntry& lhs, const GradientCacheEntry& rhs) {
     94     return GradientCacheEntry::compare(lhs, rhs);
     95 }
     96 
     97 inline hash_t hash_type(const GradientCacheEntry& entry) {
     98     return entry.hash();
     99 }
    100 
    101 /**
    102  * A simple LRU gradient cache. The cache has a maximum size expressed in bytes.
    103  * Any texture added to the cache causing the cache to grow beyond the maximum
    104  * allowed size will also cause the oldest texture to be kicked out.
    105  */
    106 class GradientCache: public OnEntryRemoved<GradientCacheEntry, Texture*> {
    107 public:
    108     explicit GradientCache(const Extensions& extensions);
    109     ~GradientCache();
    110 
    111     /**
    112      * Used as a callback when an entry is removed from the cache.
    113      * Do not invoke directly.
    114      */
    115     void operator()(GradientCacheEntry& shader, Texture*& texture) override;
    116 
    117     /**
    118      * Returns the texture associated with the specified shader.
    119      */
    120     Texture* get(uint32_t* colors, float* positions, int count);
    121 
    122     /**
    123      * Clears the cache. This causes all textures to be deleted.
    124      */
    125     void clear();
    126 
    127     /**
    128      * Returns the maximum size of the cache in bytes.
    129      */
    130     uint32_t getMaxSize();
    131     /**
    132      * Returns the current size of the cache in bytes.
    133      */
    134     uint32_t getSize();
    135 
    136 private:
    137     /**
    138      * Adds a new linear gradient to the cache. The generated texture is
    139      * returned.
    140      */
    141     Texture* addLinearGradient(GradientCacheEntry& gradient,
    142             uint32_t* colors, float* positions, int count);
    143 
    144     void generateTexture(uint32_t* colors, float* positions,
    145             const uint32_t width, const uint32_t height, Texture* texture);
    146 
    147     struct GradientInfo {
    148         uint32_t width;
    149         bool hasAlpha;
    150     };
    151 
    152     void getGradientInfo(const uint32_t* colors, const int count, GradientInfo& info);
    153 
    154     size_t bytesPerPixel() const;
    155     size_t sourceBytesPerPixel() const;
    156 
    157     typedef void (GradientCache::*ChannelMixer)(const FloatColor& start, const FloatColor& end,
    158             float amount, uint8_t*& dst) const;
    159 
    160     void mixBytes(const FloatColor& start, const FloatColor& end,
    161             float amount, uint8_t*& dst) const;
    162     void mixFloats(const FloatColor& start, const FloatColor& end,
    163             float amount, uint8_t*& dst) const;
    164 
    165     LruCache<GradientCacheEntry, Texture*> mCache;
    166 
    167     uint32_t mSize;
    168     const uint32_t mMaxSize;
    169 
    170     GLint mMaxTextureSize;
    171     bool mUseFloatTexture;
    172     bool mHasNpot;
    173     bool mHasLinearBlending;
    174 
    175     mutable Mutex mLock;
    176 }; // class GradientCache
    177 
    178 }; // namespace uirenderer
    179 }; // namespace android
    180 
    181 #endif // ANDROID_HWUI_GRADIENT_CACHE_H
    182