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