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