GradientCache.h revision 8dcfd5e836341b4a803b04d104a930bb312182d3
1c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy/*
2c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * Copyright (C) 2010 The Android Open Source Project
3c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy *
4c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * Licensed under the Apache License, Version 2.0 (the "License");
5c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * you may not use this file except in compliance with the License.
6c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * You may obtain a copy of the License at
7c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy *
8c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy *      http://www.apache.org/licenses/LICENSE-2.0
9c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy *
10c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * Unless required by applicable law or agreed to in writing, software
11c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * distributed under the License is distributed on an "AS IS" BASIS,
12c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * See the License for the specific language governing permissions and
14c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * limitations under the License.
15c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy */
16c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy
175b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#ifndef ANDROID_HWUI_GRADIENT_CACHE_H
185b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#define ANDROID_HWUI_GRADIENT_CACHE_H
19c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy
208dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy#include <GLES2/gl2.h>
218dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy
22c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy#include <SkShader.h>
23c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy
24029f64303b8fe506ef34c12777da86b830d3bf7aDerek Sollenberger#include <utils/Mutex.h>
25fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy#include <utils/Vector.h>
26fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy
27c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy#include "Texture.h"
286203f6c8147069976342be8f42add797a50f9557Romain Guy#include "utils/Compare.h"
2921b028a44f3e0bd9b0f0432b8b92c45f661d22a4Romain Guy#include "utils/GenerationCache.h"
30c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy
31c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guynamespace android {
32c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guynamespace uirenderer {
33c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy
346203f6c8147069976342be8f42add797a50f9557Romain Guystruct GradientCacheEntry {
356203f6c8147069976342be8f42add797a50f9557Romain Guy    GradientCacheEntry() {
366203f6c8147069976342be8f42add797a50f9557Romain Guy        count = 0;
376203f6c8147069976342be8f42add797a50f9557Romain Guy        colors = NULL;
386203f6c8147069976342be8f42add797a50f9557Romain Guy        positions = NULL;
396203f6c8147069976342be8f42add797a50f9557Romain Guy        tileMode = SkShader::kClamp_TileMode;
406203f6c8147069976342be8f42add797a50f9557Romain Guy    }
416203f6c8147069976342be8f42add797a50f9557Romain Guy
426203f6c8147069976342be8f42add797a50f9557Romain Guy    GradientCacheEntry(uint32_t* colors, float* positions, int count,
436203f6c8147069976342be8f42add797a50f9557Romain Guy            SkShader::TileMode tileMode) {
44e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy        copy(colors, positions, count, tileMode);
456203f6c8147069976342be8f42add797a50f9557Romain Guy    }
466203f6c8147069976342be8f42add797a50f9557Romain Guy
476203f6c8147069976342be8f42add797a50f9557Romain Guy    GradientCacheEntry(const GradientCacheEntry& entry) {
48e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy        copy(entry.colors, entry.positions, entry.count, entry.tileMode);
496203f6c8147069976342be8f42add797a50f9557Romain Guy    }
506203f6c8147069976342be8f42add797a50f9557Romain Guy
516203f6c8147069976342be8f42add797a50f9557Romain Guy    ~GradientCacheEntry() {
52e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy        delete[] colors;
53e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy        delete[] positions;
54e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy    }
55e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy
56e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy    GradientCacheEntry& operator=(const GradientCacheEntry& entry) {
57e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy        if (this != &entry) {
58e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy            delete[] colors;
59e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy            delete[] positions;
60e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy
61e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy            copy(entry.colors, entry.positions, entry.count, entry.tileMode);
62e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy        }
63e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy
64e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy        return *this;
656203f6c8147069976342be8f42add797a50f9557Romain Guy    }
666203f6c8147069976342be8f42add797a50f9557Romain Guy
676203f6c8147069976342be8f42add797a50f9557Romain Guy    bool operator<(const GradientCacheEntry& r) const {
686203f6c8147069976342be8f42add797a50f9557Romain Guy        const GradientCacheEntry& rhs = (const GradientCacheEntry&) r;
696203f6c8147069976342be8f42add797a50f9557Romain Guy        LTE_INT(count) {
706203f6c8147069976342be8f42add797a50f9557Romain Guy            LTE_INT(tileMode) {
716203f6c8147069976342be8f42add797a50f9557Romain Guy                int result = memcmp(colors, rhs.colors, count * sizeof(uint32_t));
726203f6c8147069976342be8f42add797a50f9557Romain Guy                if (result< 0) return true;
736203f6c8147069976342be8f42add797a50f9557Romain Guy                else if (result == 0) {
746203f6c8147069976342be8f42add797a50f9557Romain Guy                    result = memcmp(positions, rhs.positions, count * sizeof(float));
756203f6c8147069976342be8f42add797a50f9557Romain Guy                    if (result < 0) return true;
766203f6c8147069976342be8f42add797a50f9557Romain Guy                }
776203f6c8147069976342be8f42add797a50f9557Romain Guy            }
786203f6c8147069976342be8f42add797a50f9557Romain Guy        }
796203f6c8147069976342be8f42add797a50f9557Romain Guy        return false;
806203f6c8147069976342be8f42add797a50f9557Romain Guy    }
816203f6c8147069976342be8f42add797a50f9557Romain Guy
826203f6c8147069976342be8f42add797a50f9557Romain Guy    uint32_t* colors;
836203f6c8147069976342be8f42add797a50f9557Romain Guy    float* positions;
846203f6c8147069976342be8f42add797a50f9557Romain Guy    int count;
856203f6c8147069976342be8f42add797a50f9557Romain Guy    SkShader::TileMode tileMode;
866203f6c8147069976342be8f42add797a50f9557Romain Guy
87e5df231434357424cea8d2b8d0cdf31253a98110Romain Guyprivate:
88e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy
89e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy    void copy(uint32_t* colors, float* positions, int count, SkShader::TileMode tileMode) {
90e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy        this->count = count;
91e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy        this->colors = new uint32_t[count];
92e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy        this->positions = new float[count];
93e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy        this->tileMode = tileMode;
94e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy
95e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy        memcpy(this->colors, colors, count * sizeof(uint32_t));
96e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy        memcpy(this->positions, positions, count * sizeof(float));
97e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy    }
98e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy
996203f6c8147069976342be8f42add797a50f9557Romain Guy}; // GradientCacheEntry
1006203f6c8147069976342be8f42add797a50f9557Romain Guy
101c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy/**
102c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * A simple LRU gradient cache. The cache has a maximum size expressed in bytes.
103c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * Any texture added to the cache causing the cache to grow beyond the maximum
104c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * allowed size will also cause the oldest texture to be kicked out.
105c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy */
1066203f6c8147069976342be8f42add797a50f9557Romain Guyclass GradientCache: public OnEntryRemoved<GradientCacheEntry, Texture*> {
107c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guypublic:
108fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy    GradientCache();
109c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy    GradientCache(uint32_t maxByteSize);
110c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy    ~GradientCache();
111c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy
112c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy    /**
113c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy     * Used as a callback when an entry is removed from the cache.
114c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy     * Do not invoke directly.
115c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy     */
1166203f6c8147069976342be8f42add797a50f9557Romain Guy    void operator()(GradientCacheEntry& shader, Texture*& texture);
117c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy
118c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy    /**
119c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy     * Returns the texture associated with the specified shader.
120c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy     */
1216203f6c8147069976342be8f42add797a50f9557Romain Guy    Texture* get(uint32_t* colors, float* positions,
1226203f6c8147069976342be8f42add797a50f9557Romain Guy            int count, SkShader::TileMode tileMode = SkShader::kClamp_TileMode);
123fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy    /**
124c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy     * Clears the cache. This causes all textures to be deleted.
125c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy     */
126c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy    void clear();
127c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy
128c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy    /**
129c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy     * Sets the maximum size of the cache in bytes.
130c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy     */
131c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy    void setMaxSize(uint32_t maxSize);
132c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy    /**
133c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy     * Returns the maximum size of the cache in bytes.
134c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy     */
135c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy    uint32_t getMaxSize();
136c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy    /**
137c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy     * Returns the current size of the cache in bytes.
138c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy     */
139c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy    uint32_t getSize();
140c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy
141c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guyprivate:
1426203f6c8147069976342be8f42add797a50f9557Romain Guy    /**
1436203f6c8147069976342be8f42add797a50f9557Romain Guy     * Adds a new linear gradient to the cache. The generated texture is
1446203f6c8147069976342be8f42add797a50f9557Romain Guy     * returned.
1456203f6c8147069976342be8f42add797a50f9557Romain Guy     */
1466203f6c8147069976342be8f42add797a50f9557Romain Guy    Texture* addLinearGradient(GradientCacheEntry& gradient,
1476203f6c8147069976342be8f42add797a50f9557Romain Guy            uint32_t* colors, float* positions, int count,
1486203f6c8147069976342be8f42add797a50f9557Romain Guy            SkShader::TileMode tileMode = SkShader::kClamp_TileMode);
1496203f6c8147069976342be8f42add797a50f9557Romain Guy
150c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy    void generateTexture(SkBitmap* bitmap, Texture* texture);
151c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy
1526203f6c8147069976342be8f42add797a50f9557Romain Guy    GenerationCache<GradientCacheEntry, Texture*> mCache;
153c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy
154c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy    uint32_t mSize;
155c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy    uint32_t mMaxSize;
156a2341a9f6addcd79723965ec5b1a1c5ae0f8bd65Romain Guy
1578dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy    GLint mMaxTextureSize;
1588dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy
159fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy    Vector<SkShader*> mGarbage;
160a2341a9f6addcd79723965ec5b1a1c5ae0f8bd65Romain Guy    mutable Mutex mLock;
161c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy}; // class GradientCache
162c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy
163c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy}; // namespace uirenderer
164c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy}; // namespace android
165c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy
1665b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#endif // ANDROID_HWUI_GRADIENT_CACHE_H
167