blob: 086921cbaa91cf5470f6229079ef035538130918 [file] [log] [blame]
Romain Guyc0ac1932010-07-19 18:43:02 -07001/*
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
Romain Guy5b3b3522010-10-27 18:57:51 -070017#ifndef ANDROID_HWUI_GRADIENT_CACHE_H
18#define ANDROID_HWUI_GRADIENT_CACHE_H
Romain Guyc0ac1932010-07-19 18:43:02 -070019
20#include <SkShader.h>
21
Romain Guyfe48f652010-11-11 15:36:56 -080022#include <utils/Vector.h>
23
Romain Guyc0ac1932010-07-19 18:43:02 -070024#include "Texture.h"
Romain Guy6203f6c2011-08-01 18:56:21 -070025#include "utils/Compare.h"
Romain Guy21b028a2010-10-08 18:43:58 -070026#include "utils/GenerationCache.h"
Romain Guyc0ac1932010-07-19 18:43:02 -070027
28namespace android {
29namespace uirenderer {
30
Romain Guy6203f6c2011-08-01 18:56:21 -070031struct GradientCacheEntry {
32 GradientCacheEntry() {
33 count = 0;
34 colors = NULL;
35 positions = NULL;
36 tileMode = SkShader::kClamp_TileMode;
37 }
38
39 GradientCacheEntry(uint32_t* colors, float* positions, int count,
40 SkShader::TileMode tileMode) {
41 this->count = count;
42 this->colors = new uint32_t[count];
43 this->positions = new float[count];
44 this->tileMode = tileMode;
45
46 memcpy(this->colors, colors, count * sizeof(uint32_t));
47 memcpy(this->positions, positions, count * sizeof(float));
48 }
49
50 GradientCacheEntry(const GradientCacheEntry& entry) {
51 this->count = entry.count;
52 this->colors = new uint32_t[count];
53 this->positions = new float[count];
54 this->tileMode = entry.tileMode;
55
56 memcpy(this->colors, entry.colors, count * sizeof(uint32_t));
57 memcpy(this->positions, entry.positions, count * sizeof(float));
58 }
59
60 ~GradientCacheEntry() {
61 delete[] colors;
62 delete[] positions;
63 }
64
65 bool operator<(const GradientCacheEntry& r) const {
66 const GradientCacheEntry& rhs = (const GradientCacheEntry&) r;
67 LTE_INT(count) {
68 LTE_INT(tileMode) {
69 int result = memcmp(colors, rhs.colors, count * sizeof(uint32_t));
70 if (result< 0) return true;
71 else if (result == 0) {
72 result = memcmp(positions, rhs.positions, count * sizeof(float));
73 if (result < 0) return true;
74 }
75 }
76 }
77 return false;
78 }
79
80 uint32_t* colors;
81 float* positions;
82 int count;
83 SkShader::TileMode tileMode;
84
85}; // GradientCacheEntry
86
Romain Guyc0ac1932010-07-19 18:43:02 -070087/**
88 * A simple LRU gradient cache. The cache has a maximum size expressed in bytes.
89 * Any texture added to the cache causing the cache to grow beyond the maximum
90 * allowed size will also cause the oldest texture to be kicked out.
91 */
Romain Guy6203f6c2011-08-01 18:56:21 -070092class GradientCache: public OnEntryRemoved<GradientCacheEntry, Texture*> {
Romain Guyc0ac1932010-07-19 18:43:02 -070093public:
Romain Guyfb8b7632010-08-23 21:05:08 -070094 GradientCache();
Romain Guyc0ac1932010-07-19 18:43:02 -070095 GradientCache(uint32_t maxByteSize);
96 ~GradientCache();
97
98 /**
99 * Used as a callback when an entry is removed from the cache.
100 * Do not invoke directly.
101 */
Romain Guy6203f6c2011-08-01 18:56:21 -0700102 void operator()(GradientCacheEntry& shader, Texture*& texture);
Romain Guyc0ac1932010-07-19 18:43:02 -0700103
104 /**
Romain Guyc0ac1932010-07-19 18:43:02 -0700105 * Returns the texture associated with the specified shader.
106 */
Romain Guy6203f6c2011-08-01 18:56:21 -0700107 Texture* get(uint32_t* colors, float* positions,
108 int count, SkShader::TileMode tileMode = SkShader::kClamp_TileMode);
Romain Guyfe48f652010-11-11 15:36:56 -0800109 /**
Romain Guyc0ac1932010-07-19 18:43:02 -0700110 * Clears the cache. This causes all textures to be deleted.
111 */
112 void clear();
113
114 /**
115 * Sets the maximum size of the cache in bytes.
116 */
117 void setMaxSize(uint32_t maxSize);
118 /**
119 * Returns the maximum size of the cache in bytes.
120 */
121 uint32_t getMaxSize();
122 /**
123 * Returns the current size of the cache in bytes.
124 */
125 uint32_t getSize();
126
127private:
Romain Guy6203f6c2011-08-01 18:56:21 -0700128 /**
129 * Adds a new linear gradient to the cache. The generated texture is
130 * returned.
131 */
132 Texture* addLinearGradient(GradientCacheEntry& gradient,
133 uint32_t* colors, float* positions, int count,
134 SkShader::TileMode tileMode = SkShader::kClamp_TileMode);
135
Romain Guyc0ac1932010-07-19 18:43:02 -0700136 void generateTexture(SkBitmap* bitmap, Texture* texture);
137
Romain Guy6203f6c2011-08-01 18:56:21 -0700138 GenerationCache<GradientCacheEntry, Texture*> mCache;
Romain Guyc0ac1932010-07-19 18:43:02 -0700139
140 uint32_t mSize;
141 uint32_t mMaxSize;
Romain Guya2341a92010-09-08 18:04:33 -0700142
Romain Guyfe48f652010-11-11 15:36:56 -0800143 Vector<SkShader*> mGarbage;
Romain Guya2341a92010-09-08 18:04:33 -0700144 mutable Mutex mLock;
Romain Guyc0ac1932010-07-19 18:43:02 -0700145}; // class GradientCache
146
147}; // namespace uirenderer
148}; // namespace android
149
Romain Guy5b3b3522010-10-27 18:57:51 -0700150#endif // ANDROID_HWUI_GRADIENT_CACHE_H