| 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" |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 for (int y = 0; y < bitmap.height(); y++) { | 79 for (int y = 0; y < bitmap.height(); y++) { |
| 80 memcpy(dst, src, width); | 80 memcpy(dst, src, width); |
| 81 src += rowBytes; | 81 src += rowBytes; |
| 82 dst += width; | 82 dst += width; |
| 83 } | 83 } |
| 84 } | 84 } |
| 85 } | 85 } |
| 86 | 86 |
| 87 //////////////////////////////////////////////////////////////////////////////// | 87 //////////////////////////////////////////////////////////////////////////////// |
| 88 | 88 |
| 89 static void generate_bitmap_cache_id(const SkBitmap& bitmap, GrCacheID* id) { | 89 static void generate_bitmap_key(const SkBitmap& bitmap, GrContentKey* key) { |
| 90 // 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() |
| 91 // are unique. | 91 // are unique. |
| 92 uint32_t genID = bitmap.getGenerationID(); | 92 uint32_t genID = bitmap.getGenerationID(); |
| 93 SkIPoint origin = bitmap.pixelRefOrigin(); | 93 SkIPoint origin = bitmap.pixelRefOrigin(); |
| 94 int16_t width = SkToS16(bitmap.width()); | 94 uint32_t width = SkToU16(bitmap.width()); |
| 95 int16_t height = SkToS16(bitmap.height()); | 95 uint32_t height = SkToU16(bitmap.height()); |
| 96 | 96 |
| 97 GrCacheID::Key key; | 97 static const GrContentKey::Domain kDomain = GrContentKey::GenerateDomain(); |
| 98 memcpy(key.fData8 + 0, &genID, 4); | 98 GrContentKey::Builder builder(key, kDomain, 4); |
| 99 memcpy(key.fData8 + 4, &origin.fX, 4); | 99 builder[0] = genID; |
| 100 memcpy(key.fData8 + 8, &origin.fY, 4); | 100 builder[1] = origin.fX; |
| 101 memcpy(key.fData8 + 12, &width, 2); | 101 builder[2] = origin.fY; |
| 102 memcpy(key.fData8 + 14, &height, 2); | 102 builder[3] = width | (height << 16); |
| 103 static const size_t kKeyDataSize = 16; | |
| 104 memset(key.fData8 + kKeyDataSize, 0, sizeof(key) - kKeyDataSize); | |
| 105 GR_STATIC_ASSERT(sizeof(key) >= kKeyDataSize); | |
| 106 static const GrCacheID::Domain gBitmapTextureDomain = GrCacheID::GenerateDom
ain(); | |
| 107 id->reset(gBitmapTextureDomain, key); | |
| 108 } | 103 } |
| 109 | 104 |
| 110 static void generate_bitmap_texture_desc(const SkBitmap& bitmap, GrSurfaceDesc*
desc) { | 105 static void generate_bitmap_texture_desc(const SkBitmap& bitmap, GrSurfaceDesc*
desc) { |
| 111 desc->fFlags = kNone_GrSurfaceFlags; | 106 desc->fFlags = kNone_GrSurfaceFlags; |
| 112 desc->fWidth = bitmap.width(); | 107 desc->fWidth = bitmap.width(); |
| 113 desc->fHeight = bitmap.height(); | 108 desc->fHeight = bitmap.height(); |
| 114 desc->fConfig = SkImageInfo2GrPixelConfig(bitmap.info()); | 109 desc->fConfig = SkImageInfo2GrPixelConfig(bitmap.info()); |
| 115 desc->fSampleCnt = 0; | 110 desc->fSampleCnt = 0; |
| 116 } | 111 } |
| 117 | 112 |
| 118 namespace { | 113 namespace { |
| 119 | 114 |
| 120 // 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. |
| 121 class GrResourceInvalidator : public SkPixelRef::GenIDChangeListener { | 116 class GrResourceInvalidator : public SkPixelRef::GenIDChangeListener { |
| 122 public: | 117 public: |
| 123 explicit GrResourceInvalidator(GrResourceKey key) : fKey(key) {} | 118 explicit GrResourceInvalidator(const GrContentKey& key) : fKey(key) {} |
| 124 private: | 119 private: |
| 125 GrResourceKey fKey; | 120 GrContentKey fKey; |
| 126 | 121 |
| 127 void onChange() SK_OVERRIDE { | 122 void onChange() SK_OVERRIDE { |
| 128 const GrResourceInvalidatedMessage message = { fKey }; | 123 const GrResourceInvalidatedMessage message = { fKey }; |
| 129 SkMessageBus<GrResourceInvalidatedMessage>::Post(message); | 124 SkMessageBus<GrResourceInvalidatedMessage>::Post(message); |
| 130 } | 125 } |
| 131 }; | 126 }; |
| 132 | 127 |
| 133 } // namespace | 128 } // namespace |
| 134 | 129 |
| 135 static void add_genID_listener(GrResourceKey key, SkPixelRef* pixelRef) { | 130 static void add_genID_listener(const GrContentKey& key, SkPixelRef* pixelRef) { |
| 136 SkASSERT(pixelRef); | 131 SkASSERT(pixelRef); |
| 137 pixelRef->addGenIDChangeListener(SkNEW_ARGS(GrResourceInvalidator, (key))); | 132 pixelRef->addGenIDChangeListener(SkNEW_ARGS(GrResourceInvalidator, (key))); |
| 138 } | 133 } |
| 139 | 134 |
| 140 static GrTexture* sk_gr_allocate_texture(GrContext* ctx, | 135 static GrTexture* sk_gr_allocate_texture(GrContext* ctx, |
| 141 bool cache, | 136 bool cache, |
| 142 const GrTextureParams* params, | 137 const GrTextureParams* params, |
| 143 const SkBitmap& bm, | 138 const SkBitmap& bm, |
| 144 GrSurfaceDesc desc, | 139 GrSurfaceDesc desc, |
| 145 const void* pixels, | 140 const void* pixels, |
| 146 size_t rowBytes) { | 141 size_t rowBytes) { |
| 147 GrTexture* result; | 142 GrTexture* result; |
| 148 if (cache) { | 143 if (cache) { |
| 149 // This texture is likely to be used again so leave it in the cache | 144 // This texture is likely to be used again so leave it in the cache |
| 150 GrCacheID cacheID; | 145 GrContentKey key; |
| 151 generate_bitmap_cache_id(bm, &cacheID); | 146 generate_bitmap_key(bm, &key); |
| 152 | 147 |
| 153 GrResourceKey key; | 148 result = ctx->createTexture(params, desc, key, pixels, rowBytes, &key); |
| 154 result = ctx->createTexture(params, desc, cacheID, pixels, rowBytes, &ke
y); | |
| 155 if (result) { | 149 if (result) { |
| 156 add_genID_listener(key, bm.pixelRef()); | 150 add_genID_listener(key, bm.pixelRef()); |
| 157 } | 151 } |
| 158 } else { | 152 } else { |
| 159 // This texture is unlikely to be used again (in its present form) so | 153 // This texture is unlikely to be used again (in its present form) so |
| 160 // just use a scratch texture. This will remove the texture from the | 154 // just use a scratch texture. This will remove the texture from the |
| 161 // cache so no one else can find it. Additionally, once unlocked, the | 155 // cache so no one else can find it. Additionally, once unlocked, the |
| 162 // scratch texture will go to the end of the list for purging so will | 156 // scratch texture will go to the end of the list for purging so will |
| 163 // likely be available for this volatile bitmap the next time around. | 157 // likely be available for this volatile bitmap the next time around. |
| 164 result = ctx->refScratchTexture(desc, GrContext::kExact_ScratchTexMatch)
; | 158 result = ctx->refScratchTexture(desc, GrContext::kExact_ScratchTexMatch)
; |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 return NULL; | 386 return NULL; |
| 393 } | 387 } |
| 394 | 388 |
| 395 bool GrIsBitmapInCache(const GrContext* ctx, | 389 bool GrIsBitmapInCache(const GrContext* ctx, |
| 396 const SkBitmap& bitmap, | 390 const SkBitmap& bitmap, |
| 397 const GrTextureParams* params) { | 391 const GrTextureParams* params) { |
| 398 if (get_texture_backing_bmp(bitmap, ctx, params)) { | 392 if (get_texture_backing_bmp(bitmap, ctx, params)) { |
| 399 return true; | 393 return true; |
| 400 } | 394 } |
| 401 | 395 |
| 402 GrCacheID cacheID; | 396 GrContentKey key; |
| 403 generate_bitmap_cache_id(bitmap, &cacheID); | 397 generate_bitmap_key(bitmap, &key); |
| 404 | 398 |
| 405 GrSurfaceDesc desc; | 399 GrSurfaceDesc desc; |
| 406 generate_bitmap_texture_desc(bitmap, &desc); | 400 generate_bitmap_texture_desc(bitmap, &desc); |
| 407 return ctx->isTextureInCache(desc, cacheID, params); | 401 return ctx->isTextureInCache(desc, key, params); |
| 408 } | 402 } |
| 409 | 403 |
| 410 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, | 404 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, |
| 411 const SkBitmap& bitmap, | 405 const SkBitmap& bitmap, |
| 412 const GrTextureParams* params) { | 406 const GrTextureParams* params) { |
| 413 GrTexture* result = get_texture_backing_bmp(bitmap, ctx, params); | 407 GrTexture* result = get_texture_backing_bmp(bitmap, ctx, params); |
| 414 if (result) { | 408 if (result) { |
| 415 return SkRef(result); | 409 return SkRef(result); |
| 416 } | 410 } |
| 417 | 411 |
| 418 bool cache = !bitmap.isVolatile(); | 412 bool cache = !bitmap.isVolatile(); |
| 419 | 413 |
| 420 if (cache) { | 414 if (cache) { |
| 421 // 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. |
| 422 | 416 |
| 423 GrCacheID cacheID; | 417 GrContentKey key; |
| 424 generate_bitmap_cache_id(bitmap, &cacheID); | 418 generate_bitmap_key(bitmap, &key); |
| 425 | 419 |
| 426 GrSurfaceDesc desc; | 420 GrSurfaceDesc desc; |
| 427 generate_bitmap_texture_desc(bitmap, &desc); | 421 generate_bitmap_texture_desc(bitmap, &desc); |
| 428 | 422 |
| 429 result = ctx->findAndRefTexture(desc, cacheID, params); | 423 result = ctx->findAndRefTexture(desc, key, params); |
| 430 } | 424 } |
| 431 if (NULL == result) { | 425 if (NULL == result) { |
| 432 result = sk_gr_create_bitmap_texture(ctx, cache, params, bitmap); | 426 result = sk_gr_create_bitmap_texture(ctx, cache, params, bitmap); |
| 433 } | 427 } |
| 434 if (NULL == result) { | 428 if (NULL == result) { |
| 435 SkDebugf("---- failed to create texture for cache [%d %d]\n", | 429 SkDebugf("---- failed to create texture for cache [%d %d]\n", |
| 436 bitmap.width(), bitmap.height()); | 430 bitmap.width(), bitmap.height()); |
| 437 } | 431 } |
| 438 return result; | 432 return result; |
| 439 } | 433 } |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 590 if (shader->asFragmentProcessor(context, skPaint, viewM, NULL, &paintCol
or, &fp) && fp) { | 584 if (shader->asFragmentProcessor(context, skPaint, viewM, NULL, &paintCol
or, &fp) && fp) { |
| 591 grPaint->addColorProcessor(fp)->unref(); | 585 grPaint->addColorProcessor(fp)->unref(); |
| 592 constantColor = false; | 586 constantColor = false; |
| 593 } | 587 } |
| 594 } | 588 } |
| 595 | 589 |
| 596 // The grcolor is automatically set when calling asFragmentProcessor. | 590 // The grcolor is automatically set when calling asFragmentProcessor. |
| 597 // 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. |
| 598 SkPaint2GrPaintNoShader(context, skPaint, paintColor, constantColor, grPaint
); | 592 SkPaint2GrPaintNoShader(context, skPaint, paintColor, constantColor, grPaint
); |
| 599 } | 593 } |
| OLD | NEW |