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 | 9 |
10 #include "GrDrawTargetCaps.h" | 10 #include "GrDrawTargetCaps.h" |
11 #include "GrGpu.h" | 11 #include "GrGpu.h" |
12 #include "GrGpuResourceCacheAccess.h" | |
13 #include "GrXferProcessor.h" | 12 #include "GrXferProcessor.h" |
14 #include "SkColorFilter.h" | 13 #include "SkColorFilter.h" |
15 #include "SkConfig8888.h" | 14 #include "SkConfig8888.h" |
16 #include "SkData.h" | 15 #include "SkData.h" |
17 #include "SkMessageBus.h" | 16 #include "SkMessageBus.h" |
18 #include "SkPixelRef.h" | 17 #include "SkPixelRef.h" |
19 #include "SkResourceCache.h" | 18 #include "SkResourceCache.h" |
20 #include "SkTextureCompressor.h" | 19 #include "SkTextureCompressor.h" |
21 #include "SkYUVPlanesCache.h" | 20 #include "SkYUVPlanesCache.h" |
22 #include "effects/GrDitherEffect.h" | 21 #include "effects/GrDitherEffect.h" |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 for (int y = 0; y < bitmap.height(); y++) { | 79 for (int y = 0; y < bitmap.height(); y++) { |
81 memcpy(dst, src, width); | 80 memcpy(dst, src, width); |
82 src += rowBytes; | 81 src += rowBytes; |
83 dst += width; | 82 dst += width; |
84 } | 83 } |
85 } | 84 } |
86 } | 85 } |
87 | 86 |
88 //////////////////////////////////////////////////////////////////////////////// | 87 //////////////////////////////////////////////////////////////////////////////// |
89 | 88 |
90 enum Stretch { | 89 static void generate_bitmap_key(const SkBitmap& bitmap, GrContentKey* key) { |
91 kNo_Stretch, | |
92 kBilerp_Stretch, | |
93 kNearest_Stretch | |
94 }; | |
95 | |
96 static Stretch get_stretch_type(const GrContext* ctx, int width, int height, | |
97 const GrTextureParams* params) { | |
98 if (params && params->isTiled()) { | |
99 const GrDrawTargetCaps* caps = ctx->getGpu()->caps(); | |
100 if (!caps->npotTextureTileSupport() && (!SkIsPow2(width) || !SkIsPow2(he
ight))) { | |
101 switch(params->filterMode()) { | |
102 case GrTextureParams::kNone_FilterMode: | |
103 return kNearest_Stretch; | |
104 case GrTextureParams::kBilerp_FilterMode: | |
105 case GrTextureParams::kMipMap_FilterMode: | |
106 return kBilerp_Stretch; | |
107 } | |
108 } | |
109 } | |
110 return kNo_Stretch; | |
111 } | |
112 | |
113 static bool make_resize_key(const GrContentKey& origKey, Stretch stretch, GrCont
entKey* resizeKey) { | |
114 if (origKey.isValid() && kNo_Stretch != stretch) { | |
115 static const GrContentKey::Domain kDomain = GrContentKey::GenerateDomain
(); | |
116 GrContentKey::Builder builder(resizeKey, origKey, kDomain, 1); | |
117 builder[0] = stretch; | |
118 builder.finish(); | |
119 return true; | |
120 } | |
121 SkASSERT(!resizeKey->isValid()); | |
122 return false; | |
123 } | |
124 | |
125 static void generate_bitmap_keys(const SkBitmap& bitmap, | |
126 Stretch stretch, | |
127 GrContentKey* key, | |
128 GrContentKey* resizedKey) { | |
129 // Our id includes the offset, width, and height so that bitmaps created by
extractSubset() | 90 // Our id includes the offset, width, and height so that bitmaps created by
extractSubset() |
130 // are unique. | 91 // are unique. |
131 uint32_t genID = bitmap.getGenerationID(); | 92 uint32_t genID = bitmap.getGenerationID(); |
132 SkIPoint origin = bitmap.pixelRefOrigin(); | 93 SkIPoint origin = bitmap.pixelRefOrigin(); |
133 uint32_t width = SkToU16(bitmap.width()); | 94 uint32_t width = SkToU16(bitmap.width()); |
134 uint32_t height = SkToU16(bitmap.height()); | 95 uint32_t height = SkToU16(bitmap.height()); |
135 | 96 |
136 static const GrContentKey::Domain kDomain = GrContentKey::GenerateDomain(); | 97 static const GrContentKey::Domain kDomain = GrContentKey::GenerateDomain(); |
137 GrContentKey::Builder builder(key, kDomain, 4); | 98 GrContentKey::Builder builder(key, kDomain, 4); |
138 builder[0] = genID; | 99 builder[0] = genID; |
139 builder[1] = origin.fX; | 100 builder[1] = origin.fX; |
140 builder[2] = origin.fY; | 101 builder[2] = origin.fY; |
141 builder[3] = width | (height << 16); | 102 builder[3] = width | (height << 16); |
142 builder.finish(); | |
143 | |
144 if (kNo_Stretch != stretch) { | |
145 make_resize_key(*key, stretch, resizedKey); | |
146 } | |
147 } | 103 } |
148 | 104 |
149 static void generate_bitmap_texture_desc(const SkBitmap& bitmap, GrSurfaceDesc*
desc) { | 105 static void generate_bitmap_texture_desc(const SkBitmap& bitmap, GrSurfaceDesc*
desc) { |
150 desc->fFlags = kNone_GrSurfaceFlags; | 106 desc->fFlags = kNone_GrSurfaceFlags; |
151 desc->fWidth = bitmap.width(); | 107 desc->fWidth = bitmap.width(); |
152 desc->fHeight = bitmap.height(); | 108 desc->fHeight = bitmap.height(); |
153 desc->fConfig = SkImageInfo2GrPixelConfig(bitmap.info()); | 109 desc->fConfig = SkImageInfo2GrPixelConfig(bitmap.info()); |
154 desc->fSampleCnt = 0; | 110 desc->fSampleCnt = 0; |
155 } | 111 } |
156 | 112 |
157 namespace { | 113 namespace { |
158 | 114 |
159 // When the SkPixelRef genID changes, invalidate a corresponding GrResource desc
ribed by key. | 115 // When the SkPixelRef genID changes, invalidate a corresponding GrResource desc
ribed by key. |
160 class GrResourceInvalidator : public SkPixelRef::GenIDChangeListener { | 116 class GrResourceInvalidator : public SkPixelRef::GenIDChangeListener { |
161 public: | 117 public: |
162 explicit GrResourceInvalidator(const GrContentKey& key) : fKey(key) {} | 118 explicit GrResourceInvalidator(const GrContentKey& key) : fKey(key) {} |
163 private: | 119 private: |
164 GrContentKey fKey; | 120 GrContentKey fKey; |
165 | 121 |
166 void onChange() SK_OVERRIDE { | 122 void onChange() SK_OVERRIDE { |
167 const GrResourceInvalidatedMessage message = { fKey }; | 123 const GrResourceInvalidatedMessage message = { fKey }; |
168 SkMessageBus<GrResourceInvalidatedMessage>::Post(message); | 124 SkMessageBus<GrResourceInvalidatedMessage>::Post(message); |
169 } | 125 } |
170 }; | 126 }; |
171 | 127 |
172 } // namespace | 128 } // namespace |
173 | 129 |
174 #if 0 // TODO: plug this back up | |
175 static void add_genID_listener(const GrContentKey& key, SkPixelRef* pixelRef) { | 130 static void add_genID_listener(const GrContentKey& key, SkPixelRef* pixelRef) { |
176 SkASSERT(pixelRef); | 131 SkASSERT(pixelRef); |
177 pixelRef->addGenIDChangeListener(SkNEW_ARGS(GrResourceInvalidator, (key))); | 132 pixelRef->addGenIDChangeListener(SkNEW_ARGS(GrResourceInvalidator, (key))); |
178 } | 133 } |
179 #endif | |
180 | |
181 // creates a new texture that is the input texture scaled up to the next power o
f two in | |
182 // width or height. If optionalKey is valid it will be set on the new texture. s
tretch | |
183 // controls whether the scaling is done using nearest or bilerp filtering. | |
184 GrTexture* resize_texture(GrTexture* inputTexture, Stretch stretch, | |
185 const GrContentKey& optionalKey) { | |
186 SkASSERT(kNo_Stretch != stretch); | |
187 | |
188 GrContext* context = inputTexture->getContext(); | |
189 SkASSERT(context); | |
190 | |
191 // Either it's a cache miss or the original wasn't cached to begin with. | |
192 GrSurfaceDesc rtDesc = inputTexture->desc(); | |
193 rtDesc.fFlags = rtDesc.fFlags | | |
194 kRenderTarget_GrSurfaceFlag | | |
195 kNoStencil_GrSurfaceFlag; | |
196 rtDesc.fWidth = GrNextPow2(rtDesc.fWidth); | |
197 rtDesc.fHeight = GrNextPow2(rtDesc.fHeight); | |
198 rtDesc.fConfig = GrMakePixelConfigUncompressed(rtDesc.fConfig); | |
199 | |
200 // If the config isn't renderable try converting to either A8 or an 32 bit c
onfig. Otherwise, | |
201 // fail. | |
202 if (!context->isConfigRenderable(rtDesc.fConfig, false)) { | |
203 if (GrPixelConfigIsAlphaOnly(rtDesc.fConfig)) { | |
204 if (context->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) { | |
205 rtDesc.fConfig = kAlpha_8_GrPixelConfig; | |
206 } else if (context->isConfigRenderable(kSkia8888_GrPixelConfig, fals
e)) { | |
207 rtDesc.fConfig = kSkia8888_GrPixelConfig; | |
208 } else { | |
209 return NULL; | |
210 } | |
211 } else if (kRGB_GrColorComponentFlags == | |
212 (kRGB_GrColorComponentFlags & GrPixelConfigComponentMask(rtDe
sc.fConfig))) { | |
213 if (context->isConfigRenderable(kSkia8888_GrPixelConfig, false)) { | |
214 rtDesc.fConfig = kSkia8888_GrPixelConfig; | |
215 } else { | |
216 return NULL; | |
217 } | |
218 } else { | |
219 return NULL; | |
220 } | |
221 } | |
222 | |
223 GrTexture* resized = context->getGpu()->createTexture(rtDesc, true, NULL, 0)
; | |
224 | |
225 if (!resized) { | |
226 return NULL; | |
227 } | |
228 GrPaint paint; | |
229 | |
230 // If filtering is not desired then we want to ensure all texels in the resa
mpled image are | |
231 // copies of texels from the original. | |
232 GrTextureParams params(SkShader::kClamp_TileMode, | |
233 kBilerp_Stretch == stretch ? GrTextureParams::kBilerp
_FilterMode : | |
234 GrTextureParams::kNone_F
ilterMode); | |
235 paint.addColorTextureProcessor(inputTexture, SkMatrix::I(), params); | |
236 | |
237 SkRect rect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtD
esc.fHeight)); | |
238 SkRect localRect = SkRect::MakeWH(1.f, 1.f); | |
239 | |
240 GrContext::AutoRenderTarget autoRT(context, resized->asRenderTarget()); | |
241 GrContext::AutoClip ac(context, GrContext::AutoClip::kWideOpen_InitialClip); | |
242 context->drawNonAARectToRect(paint, SkMatrix::I(), rect, localRect); | |
243 | |
244 if (optionalKey.isValid()) { | |
245 SkASSERT(context->addResourceToCache(optionalKey, resized)); | |
246 } | |
247 | |
248 return resized; | |
249 } | |
250 | 134 |
251 static GrTexture* sk_gr_allocate_texture(GrContext* ctx, | 135 static GrTexture* sk_gr_allocate_texture(GrContext* ctx, |
252 const GrContentKey& optionalKey, | 136 bool cache, |
| 137 const GrTextureParams* params, |
| 138 const SkBitmap& bm, |
253 GrSurfaceDesc desc, | 139 GrSurfaceDesc desc, |
254 const void* pixels, | 140 const void* pixels, |
255 size_t rowBytes) { | 141 size_t rowBytes) { |
256 GrTexture* result; | 142 GrTexture* result; |
257 if (optionalKey.isValid()) { | 143 if (cache) { |
258 result = ctx->createTexture(desc, pixels, rowBytes); | 144 // This texture is likely to be used again so leave it in the cache |
| 145 GrContentKey key; |
| 146 generate_bitmap_key(bm, &key); |
| 147 |
| 148 result = ctx->createTexture(params, desc, key, pixels, rowBytes, &key); |
259 if (result) { | 149 if (result) { |
260 SkASSERT(ctx->addResourceToCache(optionalKey, result)); | 150 add_genID_listener(key, bm.pixelRef()); |
261 } | 151 } |
262 | 152 } else { |
263 } else { | 153 // This texture is unlikely to be used again (in its present form) so |
| 154 // just use a scratch texture. This will remove the texture from the |
| 155 // cache so no one else can find it. Additionally, once unlocked, the |
| 156 // scratch texture will go to the end of the list for purging so will |
| 157 // likely be available for this volatile bitmap the next time around. |
264 result = ctx->refScratchTexture(desc, GrContext::kExact_ScratchTexMatch)
; | 158 result = ctx->refScratchTexture(desc, GrContext::kExact_ScratchTexMatch)
; |
265 if (pixels && result) { | 159 if (pixels) { |
266 result->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig, p
ixels, rowBytes); | 160 result->writePixels(0, 0, bm.width(), bm.height(), desc.fConfig, pix
els, rowBytes); |
267 } | 161 } |
268 } | 162 } |
269 return result; | 163 return result; |
270 } | 164 } |
271 | 165 |
272 #ifndef SK_IGNORE_ETC1_SUPPORT | 166 #ifndef SK_IGNORE_ETC1_SUPPORT |
273 static GrTexture *load_etc1_texture(GrContext* ctx, const GrContentKey& optional
Key, | 167 static GrTexture *load_etc1_texture(GrContext* ctx, bool cache, |
| 168 const GrTextureParams* params, |
274 const SkBitmap &bm, GrSurfaceDesc desc) { | 169 const SkBitmap &bm, GrSurfaceDesc desc) { |
275 SkAutoTUnref<SkData> data(bm.pixelRef()->refEncodedData()); | 170 SkAutoTUnref<SkData> data(bm.pixelRef()->refEncodedData()); |
276 | 171 |
277 // Is this even encoded data? | 172 // Is this even encoded data? |
278 if (NULL == data) { | 173 if (NULL == data) { |
279 return NULL; | 174 return NULL; |
280 } | 175 } |
281 | 176 |
282 // Is this a valid PKM encoded data? | 177 // Is this a valid PKM encoded data? |
283 const uint8_t *bytes = data->bytes(); | 178 const uint8_t *bytes = data->bytes(); |
(...skipping 24 matching lines...) Expand all Loading... |
308 if (ktx.width() != bm.width() || ktx.height() != bm.height()) { | 203 if (ktx.width() != bm.width() || ktx.height() != bm.height()) { |
309 return NULL; | 204 return NULL; |
310 } | 205 } |
311 | 206 |
312 bytes = ktx.pixelData(); | 207 bytes = ktx.pixelData(); |
313 desc.fConfig = kETC1_GrPixelConfig; | 208 desc.fConfig = kETC1_GrPixelConfig; |
314 } else { | 209 } else { |
315 return NULL; | 210 return NULL; |
316 } | 211 } |
317 | 212 |
318 return sk_gr_allocate_texture(ctx, optionalKey, desc, bytes, 0); | 213 return sk_gr_allocate_texture(ctx, cache, params, bm, desc, bytes, 0); |
319 } | 214 } |
320 #endif // SK_IGNORE_ETC1_SUPPORT | 215 #endif // SK_IGNORE_ETC1_SUPPORT |
321 | 216 |
322 static GrTexture* load_yuv_texture(GrContext* ctx, const GrContentKey& key, | 217 static GrTexture *load_yuv_texture(GrContext* ctx, bool cache, const GrTexturePa
rams* params, |
323 const SkBitmap& bm, const GrSurfaceDesc& desc
) { | 218 const SkBitmap& bm, const GrSurfaceDesc& desc
) { |
324 // Subsets are not supported, the whole pixelRef is loaded when using YUV de
coding | 219 // Subsets are not supported, the whole pixelRef is loaded when using YUV de
coding |
325 SkPixelRef* pixelRef = bm.pixelRef(); | 220 SkPixelRef* pixelRef = bm.pixelRef(); |
326 if ((NULL == pixelRef) || | 221 if ((NULL == pixelRef) || |
327 (pixelRef->info().width() != bm.info().width()) || | 222 (pixelRef->info().width() != bm.info().width()) || |
328 (pixelRef->info().height() != bm.info().height())) { | 223 (pixelRef->info().height() != bm.info().height())) { |
329 return NULL; | 224 return NULL; |
330 } | 225 } |
331 | 226 |
332 SkYUVPlanesCache::Info yuvInfo; | 227 SkYUVPlanesCache::Info yuvInfo; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 yuvDesc.fConfig, planes[i], yuvInfo.fRo
wBytes[i])) { | 275 yuvDesc.fConfig, planes[i], yuvInfo.fRo
wBytes[i])) { |
381 return NULL; | 276 return NULL; |
382 } | 277 } |
383 } | 278 } |
384 | 279 |
385 GrSurfaceDesc rtDesc = desc; | 280 GrSurfaceDesc rtDesc = desc; |
386 rtDesc.fFlags = rtDesc.fFlags | | 281 rtDesc.fFlags = rtDesc.fFlags | |
387 kRenderTarget_GrSurfaceFlag | | 282 kRenderTarget_GrSurfaceFlag | |
388 kNoStencil_GrSurfaceFlag; | 283 kNoStencil_GrSurfaceFlag; |
389 | 284 |
390 GrTexture* result = ctx->createTexture(rtDesc, NULL, 0); | 285 GrTexture* result = sk_gr_allocate_texture(ctx, cache, params, bm, rtDesc, N
ULL, 0); |
391 if (!result) { | 286 |
392 return NULL; | 287 GrRenderTarget* renderTarget = result ? result->asRenderTarget() : NULL; |
| 288 if (renderTarget) { |
| 289 SkAutoTUnref<GrFragmentProcessor> yuvToRgbProcessor(GrYUVtoRGBEffect::Cr
eate( |
| 290 yuvTextures[0], yuvTextures[1], yuvTextures[2], yuvInfo.fColorSp
ace)); |
| 291 GrPaint paint; |
| 292 paint.addColorProcessor(yuvToRgbProcessor); |
| 293 SkRect r = SkRect::MakeWH(SkIntToScalar(yuvInfo.fSize[0].fWidth), |
| 294 SkIntToScalar(yuvInfo.fSize[0].fHeight)); |
| 295 GrContext::AutoRenderTarget autoRT(ctx, renderTarget); |
| 296 GrContext::AutoClip ac(ctx, GrContext::AutoClip::kWideOpen_InitialClip); |
| 297 ctx->drawRect(paint, SkMatrix::I(), r); |
| 298 } else { |
| 299 SkSafeSetNull(result); |
393 } | 300 } |
394 | 301 |
395 GrRenderTarget* renderTarget = result->asRenderTarget(); | |
396 SkASSERT(renderTarget); | |
397 | |
398 SkAutoTUnref<GrFragmentProcessor> | |
399 yuvToRgbProcessor(GrYUVtoRGBEffect::Create(yuvTextures[0], yuvTextures[1
], yuvTextures[2], | |
400 yuvInfo.fColorSpace)); | |
401 GrPaint paint; | |
402 paint.addColorProcessor(yuvToRgbProcessor); | |
403 SkRect r = SkRect::MakeWH(SkIntToScalar(yuvInfo.fSize[0].fWidth), | |
404 SkIntToScalar(yuvInfo.fSize[0].fHeight)); | |
405 GrContext::AutoRenderTarget autoRT(ctx, renderTarget); | |
406 GrContext::AutoClip ac(ctx, GrContext::AutoClip::kWideOpen_InitialClip); | |
407 ctx->drawRect(paint, SkMatrix::I(), r); | |
408 | |
409 return result; | 302 return result; |
410 } | 303 } |
411 | 304 |
412 static GrTexture* create_unstretched_bitmap_texture(GrContext* ctx, | 305 static GrTexture* sk_gr_create_bitmap_texture(GrContext* ctx, |
413 const SkBitmap& origBitmap, | 306 bool cache, |
414 const GrContentKey& optional
Key) { | 307 const GrTextureParams* params, |
| 308 const SkBitmap& origBitmap) { |
415 SkBitmap tmpBitmap; | 309 SkBitmap tmpBitmap; |
416 | 310 |
417 const SkBitmap* bitmap = &origBitmap; | 311 const SkBitmap* bitmap = &origBitmap; |
418 | 312 |
419 GrSurfaceDesc desc; | 313 GrSurfaceDesc desc; |
420 generate_bitmap_texture_desc(*bitmap, &desc); | 314 generate_bitmap_texture_desc(*bitmap, &desc); |
421 | 315 |
422 if (kIndex_8_SkColorType == bitmap->colorType()) { | 316 if (kIndex_8_SkColorType == bitmap->colorType()) { |
423 if (ctx->supportsIndex8PixelConfig()) { | 317 // build_compressed_data doesn't do npot->pot expansion |
| 318 // and paletted textures can't be sub-updated |
| 319 if (cache && ctx->supportsIndex8PixelConfig(params, bitmap->width(), bit
map->height())) { |
424 size_t imageSize = GrCompressedFormatDataSize(kIndex_8_GrPixelConfig
, | 320 size_t imageSize = GrCompressedFormatDataSize(kIndex_8_GrPixelConfig
, |
425 bitmap->width(), bitma
p->height()); | 321 bitmap->width(), bitma
p->height()); |
426 SkAutoMalloc storage(imageSize); | 322 SkAutoMalloc storage(imageSize); |
427 build_index8_data(storage.get(), origBitmap); | 323 build_index8_data(storage.get(), origBitmap); |
428 | 324 |
429 // our compressed data will be trimmed, so pass width() for its | 325 // our compressed data will be trimmed, so pass width() for its |
430 // "rowBytes", since they are the same now. | 326 // "rowBytes", since they are the same now. |
431 return sk_gr_allocate_texture(ctx, optionalKey, desc, storage.get(),
bitmap->width()); | 327 return sk_gr_allocate_texture(ctx, cache, params, origBitmap, |
| 328 desc, storage.get(), bitmap->width()); |
432 } else { | 329 } else { |
433 origBitmap.copyTo(&tmpBitmap, kN32_SkColorType); | 330 origBitmap.copyTo(&tmpBitmap, kN32_SkColorType); |
434 // now bitmap points to our temp, which has been promoted to 32bits | 331 // now bitmap points to our temp, which has been promoted to 32bits |
435 bitmap = &tmpBitmap; | 332 bitmap = &tmpBitmap; |
436 desc.fConfig = SkImageInfo2GrPixelConfig(bitmap->info()); | 333 desc.fConfig = SkImageInfo2GrPixelConfig(bitmap->info()); |
437 } | 334 } |
438 } | 335 } |
439 | 336 |
440 // Is this an ETC1 encoded texture? | 337 // Is this an ETC1 encoded texture? |
441 #ifndef SK_IGNORE_ETC1_SUPPORT | 338 #ifndef SK_IGNORE_ETC1_SUPPORT |
442 else if ( | 339 else if ( |
443 // We do not support scratch ETC1 textures, hence they should all be at
least | 340 // We do not support scratch ETC1 textures, hence they should all be at
least |
444 // trying to go to the cache. | 341 // trying to go to the cache. |
445 optionalKey.isValid() | 342 cache |
446 // Make sure that the underlying device supports ETC1 textures before we
go ahead | 343 // Make sure that the underlying device supports ETC1 textures before we
go ahead |
447 // and check the data. | 344 // and check the data. |
448 && ctx->getGpu()->caps()->isConfigTexturable(kETC1_GrPixelConfig) | 345 && ctx->getGpu()->caps()->isConfigTexturable(kETC1_GrPixelConfig) |
449 // If the bitmap had compressed data and was then uncompressed, it'll st
ill return | 346 // If the bitmap had compressed data and was then uncompressed, it'll st
ill return |
450 // compressed data on 'refEncodedData' and upload it. Probably not good,
since if | 347 // compressed data on 'refEncodedData' and upload it. Probably not good,
since if |
451 // the bitmap has available pixels, then they might not be what the deco
mpressed | 348 // the bitmap has available pixels, then they might not be what the deco
mpressed |
452 // data is. | 349 // data is. |
453 && !(bitmap->readyToDraw())) { | 350 && !(bitmap->readyToDraw())) { |
454 GrTexture *texture = load_etc1_texture(ctx, optionalKey, *bitmap, desc); | 351 GrTexture *texture = load_etc1_texture(ctx, cache, params, *bitmap, desc
); |
455 if (texture) { | 352 if (texture) { |
456 return texture; | 353 return texture; |
457 } | 354 } |
458 } | 355 } |
459 #endif // SK_IGNORE_ETC1_SUPPORT | 356 #endif // SK_IGNORE_ETC1_SUPPORT |
460 | 357 |
461 else { | 358 else { |
462 GrTexture *texture = load_yuv_texture(ctx, optionalKey, *bitmap, desc); | 359 GrTexture *texture = load_yuv_texture(ctx, cache, params, *bitmap, desc)
; |
463 if (texture) { | 360 if (texture) { |
464 return texture; | 361 return texture; |
465 } | 362 } |
466 } | 363 } |
467 SkAutoLockPixels alp(*bitmap); | 364 SkAutoLockPixels alp(*bitmap); |
468 if (!bitmap->readyToDraw()) { | 365 if (!bitmap->readyToDraw()) { |
469 return NULL; | 366 return NULL; |
470 } | 367 } |
471 | 368 |
472 return sk_gr_allocate_texture(ctx, optionalKey, desc, bitmap->getPixels(), b
itmap->rowBytes()); | 369 return sk_gr_allocate_texture(ctx, cache, params, origBitmap, desc, |
473 } | 370 bitmap->getPixels(), bitmap->rowBytes()); |
474 | |
475 static GrTexture* create_bitmap_texture(GrContext* ctx, | |
476 const SkBitmap& bmp, | |
477 Stretch stretch, | |
478 const GrContentKey& unstretchedKey, | |
479 const GrContentKey& stretchedKey) { | |
480 if (kNo_Stretch != stretch) { | |
481 SkAutoTUnref<GrTexture> unstretched; | |
482 // Check if we have the unstretched version in the cache, if not create
it. | |
483 if (unstretchedKey.isValid()) { | |
484 unstretched.reset(ctx->findAndRefCachedTexture(unstretchedKey)); | |
485 } | |
486 if (!unstretched) { | |
487 unstretched.reset(create_unstretched_bitmap_texture(ctx, bmp, unstre
tchedKey)); | |
488 if (!unstretched) { | |
489 return NULL; | |
490 } | |
491 } | |
492 GrTexture* resized = resize_texture(unstretched, stretch, stretchedKey); | |
493 return resized; | |
494 } | |
495 | |
496 return create_unstretched_bitmap_texture(ctx, bmp, unstretchedKey); | |
497 | |
498 } | 371 } |
499 | 372 |
500 static GrTexture* get_texture_backing_bmp(const SkBitmap& bitmap, const GrContex
t* context, | 373 static GrTexture* get_texture_backing_bmp(const SkBitmap& bitmap, const GrContex
t* context, |
501 const GrTextureParams* params) { | 374 const GrTextureParams* params) { |
502 if (GrTexture* texture = bitmap.getTexture()) { | 375 if (GrTexture* texture = bitmap.getTexture()) { |
503 // Our texture-resizing-for-tiling used to upscale NPOT textures for til
ing only works with | 376 // Our texture-resizing-for-tiling used to upscale NPOT textures for til
ing only works with |
504 // content-key cached resources. Rather than invest in that legacy code
path, we'll just | 377 // content-key cached resources. Rather than invest in that legacy code
path, we'll just |
505 // take the horribly slow route of causing a cache miss which will cause
the pixels to be | 378 // take the horribly slow route of causing a cache miss which will cause
the pixels to be |
506 // read and reuploaded to a texture with a content key. | 379 // read and reuploaded to a texture with a content key. |
507 if (params && !context->getGpu()->caps()->npotTextureTileSupport() && | 380 if (params && !context->getGpu()->caps()->npotTextureTileSupport() && |
508 (params->isTiled() || GrTextureParams::kMipMap_FilterMode == params-
>filterMode())) { | 381 (params->isTiled() || GrTextureParams::kMipMap_FilterMode == params-
>filterMode())) { |
509 return NULL; | 382 return NULL; |
510 } | 383 } |
511 return texture; | 384 return texture; |
512 } | 385 } |
513 return NULL; | 386 return NULL; |
514 } | 387 } |
515 | 388 |
516 bool GrIsBitmapInCache(const GrContext* ctx, | 389 bool GrIsBitmapInCache(const GrContext* ctx, |
517 const SkBitmap& bitmap, | 390 const SkBitmap& bitmap, |
518 const GrTextureParams* params) { | 391 const GrTextureParams* params) { |
519 if (get_texture_backing_bmp(bitmap, ctx, params)) { | 392 if (get_texture_backing_bmp(bitmap, ctx, params)) { |
520 return true; | 393 return true; |
521 } | 394 } |
522 | 395 |
523 // We don't cache volatile bitmaps | 396 GrContentKey key; |
524 if (bitmap.isVolatile()) { | 397 generate_bitmap_key(bitmap, &key); |
525 return false; | |
526 } | |
527 | |
528 // If it is inherently texture backed, consider it in the cache | |
529 if (bitmap.getTexture()) { | |
530 return true; | |
531 } | |
532 | |
533 Stretch stretch = get_stretch_type(ctx, bitmap.width(), bitmap.height(), par
ams); | |
534 GrContentKey key, resizedKey; | |
535 generate_bitmap_keys(bitmap, stretch, &key, &resizedKey); | |
536 | 398 |
537 GrSurfaceDesc desc; | 399 GrSurfaceDesc desc; |
538 generate_bitmap_texture_desc(bitmap, &desc); | 400 generate_bitmap_texture_desc(bitmap, &desc); |
539 return ctx->isResourceInCache((kNo_Stretch == stretch) ? key : resizedKey); | 401 return ctx->isTextureInCache(desc, key, params); |
540 } | 402 } |
541 | 403 |
542 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, | 404 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, |
543 const SkBitmap& bitmap, | 405 const SkBitmap& bitmap, |
544 const GrTextureParams* params) { | 406 const GrTextureParams* params) { |
545 GrTexture* result = get_texture_backing_bmp(bitmap, ctx, params); | 407 GrTexture* result = get_texture_backing_bmp(bitmap, ctx, params); |
546 if (result) { | 408 if (result) { |
547 return SkRef(result); | 409 return SkRef(result); |
548 } | 410 } |
549 | 411 |
550 Stretch stretch = get_stretch_type(ctx, bitmap.width(), bitmap.height(), par
ams); | 412 bool cache = !bitmap.isVolatile(); |
551 GrContentKey key, resizedKey; | |
552 | 413 |
553 if (!bitmap.isVolatile()) { | 414 if (cache) { |
554 // If the bitmap isn't changing try to find a cached copy first. | 415 // If the bitmap isn't changing try to find a cached copy first. |
555 generate_bitmap_keys(bitmap, stretch, &key, &resizedKey); | |
556 | 416 |
557 result = ctx->findAndRefCachedTexture(resizedKey.isValid() ? resizedKey
: key); | 417 GrContentKey key; |
558 if (result) { | 418 generate_bitmap_key(bitmap, &key); |
559 return result; | 419 |
560 } | 420 GrSurfaceDesc desc; |
| 421 generate_bitmap_texture_desc(bitmap, &desc); |
| 422 |
| 423 result = ctx->findAndRefTexture(desc, key, params); |
561 } | 424 } |
| 425 if (NULL == result) { |
| 426 result = sk_gr_create_bitmap_texture(ctx, cache, params, bitmap); |
| 427 } |
| 428 if (NULL == result) { |
| 429 SkDebugf("---- failed to create texture for cache [%d %d]\n", |
| 430 bitmap.width(), bitmap.height()); |
| 431 } |
| 432 return result; |
| 433 } |
562 | 434 |
563 result = create_bitmap_texture(ctx, bitmap, stretch, key, resizedKey); | |
564 if (result) { | |
565 return result; | |
566 } | |
567 | |
568 SkDebugf("---- failed to create texture for cache [%d %d]\n", | |
569 bitmap.width(), bitmap.height()); | |
570 | |
571 return NULL; | |
572 } | |
573 /////////////////////////////////////////////////////////////////////////////// | 435 /////////////////////////////////////////////////////////////////////////////// |
574 | 436 |
575 // alphatype is ignore for now, but if GrPixelConfig is expanded to encompass | 437 // alphatype is ignore for now, but if GrPixelConfig is expanded to encompass |
576 // alpha info, that will be considered. | 438 // alpha info, that will be considered. |
577 GrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType, SkColorProf
ileType pt) { | 439 GrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType, SkColorProf
ileType pt) { |
578 switch (ct) { | 440 switch (ct) { |
579 case kUnknown_SkColorType: | 441 case kUnknown_SkColorType: |
580 return kUnknown_GrPixelConfig; | 442 return kUnknown_GrPixelConfig; |
581 case kAlpha_8_SkColorType: | 443 case kAlpha_8_SkColorType: |
582 return kAlpha_8_GrPixelConfig; | 444 return kAlpha_8_GrPixelConfig; |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
722 if (shader->asFragmentProcessor(context, skPaint, viewM, NULL, &paintCol
or, &fp) && fp) { | 584 if (shader->asFragmentProcessor(context, skPaint, viewM, NULL, &paintCol
or, &fp) && fp) { |
723 grPaint->addColorProcessor(fp)->unref(); | 585 grPaint->addColorProcessor(fp)->unref(); |
724 constantColor = false; | 586 constantColor = false; |
725 } | 587 } |
726 } | 588 } |
727 | 589 |
728 // The grcolor is automatically set when calling asFragmentProcessor. | 590 // The grcolor is automatically set when calling asFragmentProcessor. |
729 // If the shader can be seen as an effect it returns true and adds its effec
t to the grpaint. | 591 // If the shader can be seen as an effect it returns true and adds its effec
t to the grpaint. |
730 SkPaint2GrPaintNoShader(context, skPaint, paintColor, constantColor, grPaint
); | 592 SkPaint2GrPaintNoShader(context, skPaint, paintColor, constantColor, grPaint
); |
731 } | 593 } |
OLD | NEW |