OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2010 Google Inc. | 2 * Copyright 2010 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 "SkGr.h" | 8 #include "SkGr.h" |
9 #include "SkColorFilter.h" | 9 #include "SkColorFilter.h" |
10 #include "SkConfig8888.h" | 10 #include "SkConfig8888.h" |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
128 } | 128 } |
129 }; | 129 }; |
130 | 130 |
131 } // namespace | 131 } // namespace |
132 | 132 |
133 static void add_genID_listener(GrResourceKey key, SkPixelRef* pixelRef) { | 133 static void add_genID_listener(GrResourceKey key, SkPixelRef* pixelRef) { |
134 SkASSERT(pixelRef); | 134 SkASSERT(pixelRef); |
135 pixelRef->addGenIDChangeListener(SkNEW_ARGS(GrResourceInvalidator, (key))); | 135 pixelRef->addGenIDChangeListener(SkNEW_ARGS(GrResourceInvalidator, (key))); |
136 } | 136 } |
137 | 137 |
138 static GrTexture* sk_gr_allocate_texture(GrContext* ctx, | |
139 bool cache, | |
140 const GrTextureParams* params, | |
141 const SkBitmap& bm, | |
robertphillips
2014/09/10 14:18:12
const GrTextureDesc&
| |
142 GrTextureDesc desc, | |
143 const void* pixels, | |
144 size_t rowBytes) { | |
145 GrTexture* result; | |
146 if (cache) { | |
147 // This texture is likely to be used again so leave it in the cache | |
148 GrCacheID cacheID; | |
149 generate_bitmap_cache_id(bm, &cacheID); | |
150 | |
151 GrResourceKey key; | |
152 result = ctx->createTexture(params, desc, cacheID, pixels, rowBytes, &ke y); | |
153 if (result) { | |
154 add_genID_listener(key, bm.pixelRef()); | |
155 } | |
156 } else { | |
157 // This texture is unlikely to be used again (in its present form) so | |
158 // just use a scratch texture. This will remove the texture from the | |
159 // cache so no one else can find it. Additionally, once unlocked, the | |
160 // scratch texture will go to the end of the list for purging so will | |
161 // likely be available for this volatile bitmap the next time around. | |
162 result = ctx->lockAndRefScratchTexture(desc, GrContext::kExact_ScratchTe xMatch); | |
163 if (pixels) { | |
164 result->writePixels(0, 0, bm.width(), bm.height(), desc.fConfig, pix els, rowBytes); | |
165 } | |
166 } | |
167 return result; | |
168 } | |
169 | |
138 #ifndef SK_IGNORE_ETC1_SUPPORT | 170 #ifndef SK_IGNORE_ETC1_SUPPORT |
139 static GrTexture *load_etc1_texture(GrContext* ctx, | 171 static GrTexture *load_etc1_texture(GrContext* ctx, bool cache, |
140 const GrTextureParams* params, | 172 const GrTextureParams* params, |
141 const SkBitmap &bm, GrTextureDesc desc) { | 173 const SkBitmap &bm, GrTextureDesc desc) { |
142 SkAutoTUnref<SkData> data(bm.pixelRef()->refEncodedData()); | 174 SkAutoTUnref<SkData> data(bm.pixelRef()->refEncodedData()); |
143 | 175 |
144 // Is this even encoded data? | 176 // Is this even encoded data? |
145 if (NULL == data) { | 177 if (NULL == data) { |
146 return NULL; | 178 return NULL; |
147 } | 179 } |
148 | 180 |
149 // Is this a valid PKM encoded data? | 181 // Is this a valid PKM encoded data? |
(...skipping 25 matching lines...) Expand all Loading... | |
175 if (ktx.width() != bm.width() || ktx.height() != bm.height()) { | 207 if (ktx.width() != bm.width() || ktx.height() != bm.height()) { |
176 return NULL; | 208 return NULL; |
177 } | 209 } |
178 | 210 |
179 bytes = ktx.pixelData(); | 211 bytes = ktx.pixelData(); |
180 desc.fConfig = kETC1_GrPixelConfig; | 212 desc.fConfig = kETC1_GrPixelConfig; |
181 } else { | 213 } else { |
182 return NULL; | 214 return NULL; |
183 } | 215 } |
184 | 216 |
185 // This texture is likely to be used again so leave it in the cache | 217 return sk_gr_allocate_texture(ctx, cache, params, bm, desc, bytes, 0); |
186 GrCacheID cacheID; | |
187 generate_bitmap_cache_id(bm, &cacheID); | |
188 | |
189 GrResourceKey key; | |
190 GrTexture* result = ctx->createTexture(params, desc, cacheID, bytes, 0, &key ); | |
191 if (result) { | |
192 add_genID_listener(key, bm.pixelRef()); | |
193 } | |
194 return result; | |
195 } | 218 } |
196 #endif // SK_IGNORE_ETC1_SUPPORT | 219 #endif // SK_IGNORE_ETC1_SUPPORT |
197 | 220 |
198 static GrTexture *load_yuv_texture(GrContext* ctx, const GrTextureParams* params , | 221 static GrTexture *load_yuv_texture(GrContext* ctx, bool cache, const GrTexturePa rams* params, |
199 const SkBitmap& bm, const GrTextureDesc& desc ) { | 222 const SkBitmap& bm, const GrTextureDesc& desc ) { |
200 GrTexture* result = NULL; | |
201 | |
202 SkPixelRef* pixelRef = bm.pixelRef(); | 223 SkPixelRef* pixelRef = bm.pixelRef(); |
203 SkISize yuvSizes[3]; | 224 SkISize yuvSizes[3]; |
204 if ((NULL == pixelRef) || !pixelRef->getYUV8Planes(yuvSizes, NULL, NULL)) { | 225 if ((NULL == pixelRef) || !pixelRef->getYUV8Planes(yuvSizes, NULL, NULL)) { |
205 return NULL; | 226 return NULL; |
206 } | 227 } |
207 | 228 |
208 // Allocate the memory for YUV | 229 // Allocate the memory for YUV |
209 size_t totalSize(0); | 230 size_t totalSize(0); |
210 size_t sizes[3], rowBytes[3]; | 231 size_t sizes[3], rowBytes[3]; |
211 for (int i = 0; i < 3; ++i) { | 232 for (int i = 0; i < 3; ++i) { |
(...skipping 24 matching lines...) Expand all Loading... | |
236 yuvDesc.fConfig, planes[i], rowBytes[i])) { | 257 yuvDesc.fConfig, planes[i], rowBytes[i])) { |
237 return NULL; | 258 return NULL; |
238 } | 259 } |
239 } | 260 } |
240 | 261 |
241 GrTextureDesc rtDesc = desc; | 262 GrTextureDesc rtDesc = desc; |
242 rtDesc.fFlags = rtDesc.fFlags | | 263 rtDesc.fFlags = rtDesc.fFlags | |
243 kRenderTarget_GrTextureFlagBit | | 264 kRenderTarget_GrTextureFlagBit | |
244 kNoStencil_GrTextureFlagBit; | 265 kNoStencil_GrTextureFlagBit; |
245 | 266 |
246 // This texture is likely to be used again so leave it in the cache | 267 GrTexture* result = sk_gr_allocate_texture(ctx, cache, params, bm, rtDesc, N ULL, 0); |
247 GrCacheID cacheID; | |
248 generate_bitmap_cache_id(bm, &cacheID); | |
249 | 268 |
250 GrResourceKey key; | |
251 result = ctx->createTexture(params, rtDesc, cacheID, NULL, 0, &key); | |
252 GrRenderTarget* renderTarget = result ? result->asRenderTarget() : NULL; | 269 GrRenderTarget* renderTarget = result ? result->asRenderTarget() : NULL; |
253 if (renderTarget) { | 270 if (renderTarget) { |
254 add_genID_listener(key, bm.pixelRef()); | |
255 SkAutoTUnref<GrEffect> yuvToRgbEffect(GrYUVtoRGBEffect::Create( | 271 SkAutoTUnref<GrEffect> yuvToRgbEffect(GrYUVtoRGBEffect::Create( |
256 yuvTextures[0].texture(), yuvTextures[1].texture(), yuvTextures[2].t exture())); | 272 yuvTextures[0].texture(), yuvTextures[1].texture(), yuvTextures[2].t exture())); |
257 GrPaint paint; | 273 GrPaint paint; |
258 paint.addColorEffect(yuvToRgbEffect); | 274 paint.addColorEffect(yuvToRgbEffect); |
259 SkRect r = SkRect::MakeWH(SkIntToScalar(yuvSizes[0].fWidth), | 275 SkRect r = SkRect::MakeWH(SkIntToScalar(yuvSizes[0].fWidth), |
260 SkIntToScalar(yuvSizes[0].fHeight)); | 276 SkIntToScalar(yuvSizes[0].fHeight)); |
261 GrContext::AutoRenderTarget autoRT(ctx, renderTarget); | 277 GrContext::AutoRenderTarget autoRT(ctx, renderTarget); |
262 GrContext::AutoMatrix am; | 278 GrContext::AutoMatrix am; |
263 am.setIdentity(ctx); | 279 am.setIdentity(ctx); |
264 GrContext::AutoClip ac(ctx, GrContext::AutoClip::kWideOpen_InitialClip); | 280 GrContext::AutoClip ac(ctx, GrContext::AutoClip::kWideOpen_InitialClip); |
(...skipping 21 matching lines...) Expand all Loading... | |
286 // and paletted textures can't be sub-updated | 302 // and paletted textures can't be sub-updated |
287 if (ctx->supportsIndex8PixelConfig(params, bitmap->width(), bitmap->heig ht())) { | 303 if (ctx->supportsIndex8PixelConfig(params, bitmap->width(), bitmap->heig ht())) { |
288 size_t imageSize = GrCompressedFormatDataSize(kIndex_8_GrPixelConfig , | 304 size_t imageSize = GrCompressedFormatDataSize(kIndex_8_GrPixelConfig , |
289 bitmap->width(), bitma p->height()); | 305 bitmap->width(), bitma p->height()); |
290 SkAutoMalloc storage(imageSize); | 306 SkAutoMalloc storage(imageSize); |
291 | 307 |
292 build_compressed_data(storage.get(), origBitmap); | 308 build_compressed_data(storage.get(), origBitmap); |
293 | 309 |
294 // our compressed data will be trimmed, so pass width() for its | 310 // our compressed data will be trimmed, so pass width() for its |
295 // "rowBytes", since they are the same now. | 311 // "rowBytes", since they are the same now. |
296 | 312 return sk_gr_allocate_texture(ctx, cache, params, origBitmap, |
297 if (cache) { | 313 desc, storage.get(), bitmap->width()); |
298 GrCacheID cacheID; | |
299 generate_bitmap_cache_id(origBitmap, &cacheID); | |
300 | |
301 GrResourceKey key; | |
302 GrTexture* result = ctx->createTexture(params, desc, cacheID, | |
303 storage.get(), bitmap->wi dth(), &key); | |
304 if (result) { | |
305 add_genID_listener(key, origBitmap.pixelRef()); | |
306 } | |
307 return result; | |
308 } else { | |
309 GrTexture* result = ctx->lockAndRefScratchTexture(desc, | |
310 GrContext::kExact_Sc ratchTexMatch); | |
311 result->writePixels(0, 0, bitmap->width(), | |
312 bitmap->height(), desc.fConfig, | |
313 storage.get()); | |
314 return result; | |
315 } | |
316 } else { | 314 } else { |
317 origBitmap.copyTo(&tmpBitmap, kN32_SkColorType); | 315 origBitmap.copyTo(&tmpBitmap, kN32_SkColorType); |
318 // now bitmap points to our temp, which has been promoted to 32bits | 316 // now bitmap points to our temp, which has been promoted to 32bits |
319 bitmap = &tmpBitmap; | 317 bitmap = &tmpBitmap; |
320 desc.fConfig = SkImageInfo2GrPixelConfig(bitmap->info()); | 318 desc.fConfig = SkImageInfo2GrPixelConfig(bitmap->info()); |
321 } | 319 } |
322 } | 320 } |
323 | 321 |
324 // Is this an ETC1 encoded texture? | 322 // Is this an ETC1 encoded texture? |
325 #ifndef SK_IGNORE_ETC1_SUPPORT | 323 #ifndef SK_IGNORE_ETC1_SUPPORT |
326 else if ( | 324 else if ( |
327 // We do not support scratch ETC1 textures, hence they should all be at least | 325 // We do not support scratch ETC1 textures, hence they should all be at least |
328 // trying to go to the cache. | 326 // trying to go to the cache. |
329 cache | 327 cache |
330 // Make sure that the underlying device supports ETC1 textures before we go ahead | 328 // Make sure that the underlying device supports ETC1 textures before we go ahead |
331 // and check the data. | 329 // and check the data. |
332 && ctx->getGpu()->caps()->isConfigTexturable(kETC1_GrPixelConfig) | 330 && ctx->getGpu()->caps()->isConfigTexturable(kETC1_GrPixelConfig) |
333 // If the bitmap had compressed data and was then uncompressed, it'll st ill return | 331 // If the bitmap had compressed data and was then uncompressed, it'll st ill return |
334 // compressed data on 'refEncodedData' and upload it. Probably not good, since if | 332 // compressed data on 'refEncodedData' and upload it. Probably not good, since if |
335 // the bitmap has available pixels, then they might not be what the deco mpressed | 333 // the bitmap has available pixels, then they might not be what the deco mpressed |
336 // data is. | 334 // data is. |
337 && !(bitmap->readyToDraw())) { | 335 && !(bitmap->readyToDraw())) { |
338 GrTexture *texture = load_etc1_texture(ctx, params, *bitmap, desc); | 336 GrTexture *texture = load_etc1_texture(ctx, cache, params, *bitmap, desc ); |
339 if (texture) { | 337 if (texture) { |
340 return texture; | 338 return texture; |
341 } | 339 } |
342 } | 340 } |
343 #endif // SK_IGNORE_ETC1_SUPPORT | 341 #endif // SK_IGNORE_ETC1_SUPPORT |
344 | 342 |
345 else { | 343 else { |
346 GrTexture *texture = load_yuv_texture(ctx, params, *bitmap, desc); | 344 GrTexture *texture = load_yuv_texture(ctx, cache, params, *bitmap, desc) ; |
347 if (texture) { | 345 if (texture) { |
348 return texture; | 346 return texture; |
349 } | 347 } |
350 } | 348 } |
351 SkAutoLockPixels alp(*bitmap); | 349 SkAutoLockPixels alp(*bitmap); |
352 if (!bitmap->readyToDraw()) { | 350 if (!bitmap->readyToDraw()) { |
353 return NULL; | 351 return NULL; |
354 } | 352 } |
355 if (cache) { | |
356 // This texture is likely to be used again so leave it in the cache | |
357 GrCacheID cacheID; | |
358 generate_bitmap_cache_id(origBitmap, &cacheID); | |
359 | 353 |
360 GrResourceKey key; | 354 return sk_gr_allocate_texture(ctx, cache, params, origBitmap, desc, |
361 GrTexture* result = ctx->createTexture(params, desc, cacheID, | 355 bitmap->getPixels(), bitmap->rowBytes()); |
362 bitmap->getPixels(), bitmap->rowB ytes(), &key); | |
363 if (result) { | |
364 add_genID_listener(key, origBitmap.pixelRef()); | |
365 } | |
366 return result; | |
367 } else { | |
368 // This texture is unlikely to be used again (in its present form) so | |
369 // just use a scratch texture. This will remove the texture from the | |
370 // cache so no one else can find it. Additionally, once unlocked, the | |
371 // scratch texture will go to the end of the list for purging so will | |
372 // likely be available for this volatile bitmap the next time around. | |
373 GrTexture* result = ctx->lockAndRefScratchTexture(desc, GrContext::kExac t_ScratchTexMatch); | |
374 result->writePixels(0, 0, | |
375 bitmap->width(), bitmap->height(), | |
376 desc.fConfig, | |
377 bitmap->getPixels(), | |
378 bitmap->rowBytes()); | |
379 return result; | |
380 } | |
381 } | 356 } |
382 | 357 |
383 bool GrIsBitmapInCache(const GrContext* ctx, | 358 bool GrIsBitmapInCache(const GrContext* ctx, |
384 const SkBitmap& bitmap, | 359 const SkBitmap& bitmap, |
385 const GrTextureParams* params) { | 360 const GrTextureParams* params) { |
386 GrCacheID cacheID; | 361 GrCacheID cacheID; |
387 generate_bitmap_cache_id(bitmap, &cacheID); | 362 generate_bitmap_cache_id(bitmap, &cacheID); |
388 | 363 |
389 GrTextureDesc desc; | 364 GrTextureDesc desc; |
390 generate_bitmap_texture_desc(bitmap, &desc); | 365 generate_bitmap_texture_desc(bitmap, &desc); |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
598 if (shader->asNewEffect(context, skPaint, NULL, &paintColor, &effect) && effect) { | 573 if (shader->asNewEffect(context, skPaint, NULL, &paintColor, &effect) && effect) { |
599 grPaint->addColorEffect(effect)->unref(); | 574 grPaint->addColorEffect(effect)->unref(); |
600 constantColor = false; | 575 constantColor = false; |
601 } | 576 } |
602 } | 577 } |
603 | 578 |
604 // The grcolor is automatically set when calling asneweffect. | 579 // The grcolor is automatically set when calling asneweffect. |
605 // If the shader can be seen as an effect it returns true and adds its effec t to the grpaint. | 580 // If the shader can be seen as an effect it returns true and adds its effec t to the grpaint. |
606 SkPaint2GrPaintNoShader(context, skPaint, paintColor, constantColor, grPaint ); | 581 SkPaint2GrPaintNoShader(context, skPaint, paintColor, constantColor, grPaint ); |
607 } | 582 } |
OLD | NEW |