OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkBitmap.h" | 8 #include "SkBitmap.h" |
9 #include "SkBitmapCache.h" | 9 #include "SkBitmapCache.h" |
10 #include "SkImageCacherator.h" | 10 #include "SkImageCacherator.h" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
44 } else { | 44 } else { |
45 subset = &bounds; | 45 subset = &bounds; |
46 } | 46 } |
47 | 47 |
48 return new SkImageCacherator(gen, gen->getInfo().makeWH(subset->width(), sub set->height()), | 48 return new SkImageCacherator(gen, gen->getInfo().makeWH(subset->width(), sub set->height()), |
49 SkIPoint::Make(subset->x(), subset->y()), uniqu eID); | 49 SkIPoint::Make(subset->x(), subset->y()), uniqu eID); |
50 } | 50 } |
51 | 51 |
52 SkImageCacherator::SkImageCacherator(SkImageGenerator* gen, const SkImageInfo& i nfo, | 52 SkImageCacherator::SkImageCacherator(SkImageGenerator* gen, const SkImageInfo& i nfo, |
53 const SkIPoint& origin, uint32_t uniqueID) | 53 const SkIPoint& origin, uint32_t uniqueID) |
54 : fGenerator(gen) | 54 : fNotThreadSafeGenerator(gen) |
55 , fInfo(info) | 55 , fInfo(info) |
56 , fOrigin(origin) | 56 , fOrigin(origin) |
57 , fUniqueID(uniqueID) | 57 , fUniqueID(uniqueID) |
58 {} | 58 {} |
59 | 59 |
60 SkImageCacherator::~SkImageCacherator() { delete fGenerator; } | 60 SkData* SkImageCacherator::refEncoded() { |
61 ScopedGenerator generator(this); | |
62 return generator->refEncodedData(); | |
63 } | |
61 | 64 |
62 static bool check_output_bitmap(const SkBitmap& bitmap, uint32_t expectedID) { | 65 static bool check_output_bitmap(const SkBitmap& bitmap, uint32_t expectedID) { |
63 SkASSERT(bitmap.getGenerationID() == expectedID); | 66 SkASSERT(bitmap.getGenerationID() == expectedID); |
64 SkASSERT(bitmap.isImmutable()); | 67 SkASSERT(bitmap.isImmutable()); |
65 SkASSERT(bitmap.getPixels()); | 68 SkASSERT(bitmap.getPixels()); |
66 return true; | 69 return true; |
67 } | 70 } |
68 | 71 |
69 static bool generate_bitmap(SkBitmap* bitmap, const SkImageInfo& info, const SkI Point& origin, | 72 bool SkImageCacherator::generateBitmap(SkBitmap* bitmap) { |
70 SkImageGenerator* generator) { | 73 const size_t rowBytes = fInfo.minRowBytes(); |
71 const size_t rowBytes = info.minRowBytes(); | 74 if (!bitmap->tryAllocPixels(fInfo, rowBytes)) { |
72 if (!bitmap->tryAllocPixels(info, rowBytes)) { | |
73 return false; | 75 return false; |
74 } | 76 } |
75 SkASSERT(bitmap->rowBytes() == rowBytes); | 77 SkASSERT(bitmap->rowBytes() == rowBytes); |
76 | 78 |
79 ScopedGenerator generator(this); | |
77 const SkImageInfo& genInfo = generator->getInfo(); | 80 const SkImageInfo& genInfo = generator->getInfo(); |
78 if (info.dimensions() == genInfo.dimensions()) { | 81 if (fInfo.dimensions() == genInfo.dimensions()) { |
79 SkASSERT(origin.x() == 0 && origin.y() == 0); | 82 SkASSERT(fOrigin.x() == 0 && fOrigin.y() == 0); |
80 // fast-case, no copy needed | 83 // fast-case, no copy needed |
81 if (!generator->getPixels(bitmap->info(), bitmap->getPixels(), rowBytes) ) { | 84 if (!generator->getPixels(bitmap->info(), bitmap->getPixels(), rowBytes) ) { |
82 bitmap->reset(); | 85 bitmap->reset(); |
83 return false; | 86 return false; |
84 } | 87 } |
85 } else { | 88 } else { |
86 // need to handle subsetting | 89 // need to handle subsetting |
87 SkBitmap full; | 90 SkBitmap full; |
88 if (!full.tryAllocPixels(genInfo)) { | 91 if (!full.tryAllocPixels(genInfo)) { |
89 return false; | 92 return false; |
90 } | 93 } |
91 if (!generator->getPixels(full.info(), full.getPixels(), full.rowBytes() )) { | 94 if (!generator->getPixels(full.info(), full.getPixels(), full.rowBytes() )) { |
92 bitmap->reset(); | 95 bitmap->reset(); |
93 return false; | 96 return false; |
94 } | 97 } |
95 full.readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), | 98 full.readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), |
96 origin.x(), origin.y()); | 99 fOrigin.x(), fOrigin.y()); |
97 } | 100 } |
98 return true; | 101 return true; |
99 } | 102 } |
100 | 103 |
101 //////////////////////////////////////////////////////////////////////////////// ////////////////// | 104 //////////////////////////////////////////////////////////////////////////////// ////////////////// |
102 | 105 |
103 bool SkImageCacherator::tryLockAsBitmap(SkBitmap* bitmap) { | 106 bool SkImageCacherator::tryLockAsBitmap(SkBitmap* bitmap) { |
104 if (SkBitmapCache::Find(fUniqueID, bitmap)) { | 107 if (SkBitmapCache::Find(fUniqueID, bitmap)) { |
105 return check_output_bitmap(*bitmap, fUniqueID); | 108 return check_output_bitmap(*bitmap, fUniqueID); |
106 } | 109 } |
107 if (!generate_bitmap(bitmap, fInfo, fOrigin, fGenerator)) { | 110 |
111 if (!this->generateBitmap(bitmap)) { | |
108 return false; | 112 return false; |
109 } | 113 } |
110 | 114 |
111 bitmap->pixelRef()->setImmutableWithID(fUniqueID); | 115 bitmap->pixelRef()->setImmutableWithID(fUniqueID); |
112 SkBitmapCache::Add(fUniqueID, *bitmap); | 116 SkBitmapCache::Add(fUniqueID, *bitmap); |
113 return true; | 117 return true; |
114 } | 118 } |
115 | 119 |
116 bool SkImageCacherator::lockAsBitmap(SkBitmap* bitmap) { | 120 bool SkImageCacherator::lockAsBitmap(SkBitmap* bitmap) { |
117 if (this->tryLockAsBitmap(bitmap)) { | 121 if (this->tryLockAsBitmap(bitmap)) { |
118 return check_output_bitmap(*bitmap, fUniqueID); | 122 return check_output_bitmap(*bitmap, fUniqueID); |
119 } | 123 } |
120 | 124 |
121 #if SK_SUPPORT_GPU | 125 #if SK_SUPPORT_GPU |
122 // Try to get a texture and read it back to raster (and then cache that with our ID) | 126 // Try to get a texture and read it back to raster (and then cache that with our ID) |
127 SkAutoTUnref<GrTexture> tex; | |
123 | 128 |
124 SkIRect subset = SkIRect::MakeXYWH(fOrigin.x(), fOrigin.y(), fInfo.width(), fInfo.height()); | 129 { |
125 SkAutoTUnref<GrTexture> tex(fGenerator->generateTexture(nullptr, kUntiled_Sk ImageUsageType, | 130 ScopedGenerator generator(this); |
126 &subset)); | 131 SkIRect subset = SkIRect::MakeXYWH(fOrigin.x(), fOrigin.y(), fInfo.width (), fInfo.height()); |
132 tex.reset(generator->generateTexture(nullptr, kUntiled_SkImageUsageType, &subset)); | |
133 } | |
127 if (!tex) { | 134 if (!tex) { |
128 bitmap->reset(); | 135 bitmap->reset(); |
129 return false; | 136 return false; |
130 } | 137 } |
131 | 138 |
132 if (!bitmap->tryAllocPixels(fInfo)) { | 139 if (!bitmap->tryAllocPixels(fInfo)) { |
133 bitmap->reset(); | 140 bitmap->reset(); |
134 return false; | 141 return false; |
135 } | 142 } |
136 | 143 |
137 const uint32_t pixelOpsFlags = 0; | 144 const uint32_t pixelOpsFlags = 0; |
138 if (!tex->readPixels(0, 0, bitmap->width(), bitmap->height(), SkImageInfo2Gr PixelConfig(fInfo), | 145 if (!tex->readPixels(0, 0, bitmap->width(), bitmap->height(), SkImageInfo2Gr PixelConfig(fInfo), |
139 bitmap->getPixels(), bitmap->rowBytes(), pixelOpsFlags) ) { | 146 bitmap->getPixels(), bitmap->rowBytes(), pixelOpsFlags) ) { |
140 bitmap->reset(); | 147 bitmap->reset(); |
141 return false; | 148 return false; |
142 } | 149 } |
143 | 150 |
144 bitmap->pixelRef()->setImmutableWithID(fUniqueID); | 151 bitmap->pixelRef()->setImmutableWithID(fUniqueID); |
145 SkBitmapCache::Add(fUniqueID, *bitmap); | 152 SkBitmapCache::Add(fUniqueID, *bitmap); |
146 return check_output_bitmap(*bitmap, fUniqueID); | 153 return check_output_bitmap(*bitmap, fUniqueID); |
147 #else | 154 #else |
148 return false; | 155 return false; |
149 #endif | 156 #endif |
150 } | 157 } |
151 | 158 |
152 //////////////////////////////////////////////////////////////////////////////// ////////////////// | 159 //////////////////////////////////////////////////////////////////////////////// ////////////////// |
153 | 160 |
154 GrTexture* SkImageCacherator::tryLockAsTexture(GrContext* ctx, SkImageUsageType usage) { | 161 /* |
155 #if SK_SUPPORT_GPU | 162 * We have a 5 ways to try to return a texture (in sorted order) |
156 GrUniqueKey key; | 163 * |
157 GrMakeKeyFromImageID(&key, fUniqueID, fInfo.width(), fInfo.height(), SkIPoin t::Make(0, 0), | 164 * 1. Check the cache for a pre-existing one |
158 *ctx->caps(), usage); | 165 * 2. Ask the genreator to natively create one |
159 GrTexture* tex = ctx->textureProvider()->findAndRefTextureByUniqueKey(key); | 166 * 3. Ask the generator to return a compressed form that the GPU might support |
160 if (tex) { | 167 * 4. Ask the generator to return YUV planes, which the GPU can convert |
161 return tex; // we got a cache hit! | 168 * 5. Ask the generator to return RGB(A) data, which the GPU can convert |
162 } | 169 */ |
163 | |
164 SkIRect subset = SkIRect::MakeXYWH(fOrigin.x(), fOrigin.y(), fInfo.width(), fInfo.height()); | |
165 tex = fGenerator->generateTexture(ctx, usage, &subset); | |
166 if (tex) { | |
167 tex->resourcePriv().setUniqueKey(key); | |
168 } | |
169 return tex; | |
170 #else | |
171 return nullptr; | |
172 #endif | |
173 } | |
174 | |
175 GrTexture* SkImageCacherator::lockAsTexture(GrContext* ctx, SkImageUsageType usa ge) { | 170 GrTexture* SkImageCacherator::lockAsTexture(GrContext* ctx, SkImageUsageType usa ge) { |
176 #if SK_SUPPORT_GPU | 171 #if SK_SUPPORT_GPU |
177 if (!ctx) { | 172 if (!ctx) { |
178 return nullptr; | 173 return nullptr; |
179 } | 174 } |
180 if (GrTexture* tex = this->tryLockAsTexture(ctx, usage)) { | 175 |
176 GrUniqueKey key; | |
177 GrMakeKeyFromImageID(&key, fUniqueID, fInfo.width(), fInfo.height(), SkIPoin t::Make(0, 0), | |
178 *ctx->caps(), usage); | |
179 | |
180 // 1. Check the cache for a pre-existing one | |
181 if (GrTexture* tex = ctx->textureProvider()->findAndRefTextureByUniqueKey(ke y)) { | |
181 return tex; | 182 return tex; |
182 } | 183 } |
183 | 184 |
184 // Try to get a bitmap and then upload/cache it as a texture | 185 // 2. Ask the genreator to natively create one |
mtklein
2015/08/26 21:20:57
Out of curiosity, will each of these 2-5 lock then
| |
186 { | |
187 ScopedGenerator generator(this); | |
188 SkIRect subset = SkIRect::MakeXYWH(fOrigin.x(), fOrigin.y(), fInfo.width (), fInfo.height()); | |
189 if (GrTexture* tex = generator->generateTexture(ctx, usage, &subset)) { | |
190 tex->resourcePriv().setUniqueKey(key); | |
191 return tex; | |
192 } | |
193 } | |
185 | 194 |
195 // 3. Ask the generator to return a compressed form that the GPU might suppo rt | |
196 // TODO | |
197 | |
198 // 4. Ask the generator to return YUV planes, which the GPU can convert | |
199 // TODO | |
200 | |
201 | |
202 // 5. Ask the generator to return RGB(A) data, which the GPU can convert | |
186 SkBitmap bitmap; | 203 SkBitmap bitmap; |
187 if (!generate_bitmap(&bitmap, fInfo, fOrigin, fGenerator)) { | 204 if (!this->generateBitmap(&bitmap)) { |
188 return nullptr; | 205 return nullptr; |
189 } | 206 } |
190 return GrRefCachedBitmapTexture(ctx, bitmap, usage); | 207 return GrRefCachedBitmapTexture(ctx, bitmap, usage); |
191 #else | 208 #else |
192 return nullptr; | 209 return nullptr; |
193 #endif | 210 #endif |
194 } | 211 } |
195 | 212 |
OLD | NEW |