| 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 "GrCaps.h" | 10 #include "GrCaps.h" |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 GrUniqueKey::Builder builder(stretchedKey, origKey, kDomain, 2); | 148 GrUniqueKey::Builder builder(stretchedKey, origKey, kDomain, 2); |
| 149 builder[0] = stretch.fType; | 149 builder[0] = stretch.fType; |
| 150 builder[1] = width | (height << 16); | 150 builder[1] = width | (height << 16); |
| 151 builder.finish(); | 151 builder.finish(); |
| 152 return true; | 152 return true; |
| 153 } | 153 } |
| 154 SkASSERT(!stretchedKey->isValid()); | 154 SkASSERT(!stretchedKey->isValid()); |
| 155 return false; | 155 return false; |
| 156 } | 156 } |
| 157 | 157 |
| 158 static void make_unstretched_key(GrUniqueKey* key, uint32_t imageID, | 158 static void make_unstretched_key(GrUniqueKey* key, uint32_t imageID, const SkIRe
ct& subset) { |
| 159 U16CPU width, U16CPU height, SkIPoint origin) { | 159 SkASSERT(SkIsU16(subset.width())); |
| 160 SkASSERT((uint16_t)width == width); | 160 SkASSERT(SkIsU16(subset.height())); |
| 161 SkASSERT((uint16_t)height == height); | |
| 162 | 161 |
| 163 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); | 162 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); |
| 164 GrUniqueKey::Builder builder(key, kDomain, 4); | 163 GrUniqueKey::Builder builder(key, kDomain, 4); |
| 165 builder[0] = imageID; | 164 builder[0] = imageID; |
| 166 builder[1] = origin.fX; | 165 builder[1] = subset.x(); |
| 167 builder[2] = origin.fY; | 166 builder[2] = subset.y(); |
| 168 builder[3] = width | (height << 16); | 167 builder[3] = subset.width() | (subset.height() << 16); |
| 169 } | 168 } |
| 170 | 169 |
| 171 void GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID, | 170 void GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID, const SkIRect& sub
set, |
| 172 U16CPU width, U16CPU height, SkIPoint origin, | |
| 173 const GrCaps& caps, SkImageUsageType usage) { | 171 const GrCaps& caps, SkImageUsageType usage) { |
| 174 const Stretch::Type stretches[] = { | 172 const Stretch::Type stretches[] = { |
| 175 Stretch::kNone_Type, // kUntiled_SkImageUsageType | 173 Stretch::kNone_Type, // kUntiled_SkImageUsageType |
| 176 Stretch::kNearest_Type, // kTiled_Unfiltered_SkImageUsageType | 174 Stretch::kNearest_Type, // kTiled_Unfiltered_SkImageUsageType |
| 177 Stretch::kBilerp_Type, // kTiled_Filtered_SkImageUsageType | 175 Stretch::kBilerp_Type, // kTiled_Filtered_SkImageUsageType |
| 178 }; | 176 }; |
| 179 | 177 |
| 180 const bool isPow2 = SkIsPow2(width) && SkIsPow2(height); | 178 const bool isPow2 = SkIsPow2(subset.width()) && SkIsPow2(subset.height()); |
| 181 const bool needToStretch = !isPow2 && | 179 const bool needToStretch = !isPow2 && |
| 182 usage != kUntiled_SkImageUsageType && | 180 usage != kUntiled_SkImageUsageType && |
| 183 !caps.npotTextureTileSupport(); | 181 !caps.npotTextureTileSupport(); |
| 184 | 182 |
| 185 if (needToStretch) { | 183 if (needToStretch) { |
| 186 GrUniqueKey tmpKey; | 184 GrUniqueKey tmpKey; |
| 187 make_unstretched_key(&tmpKey, imageID, width, height, origin); | 185 make_unstretched_key(&tmpKey, imageID, subset); |
| 188 | 186 |
| 189 Stretch stretch; | 187 Stretch stretch; |
| 190 stretch.fType = stretches[usage]; | 188 stretch.fType = stretches[usage]; |
| 191 stretch.fWidth = SkNextPow2(width); | 189 stretch.fWidth = SkNextPow2(subset.width()); |
| 192 stretch.fHeight = SkNextPow2(height); | 190 stretch.fHeight = SkNextPow2(subset.height()); |
| 193 if (!make_stretched_key(tmpKey, stretch, key)) { | 191 if (!make_stretched_key(tmpKey, stretch, key)) { |
| 194 goto UNSTRETCHED; | 192 goto UNSTRETCHED; |
| 195 } | 193 } |
| 196 } else { | 194 } else { |
| 197 UNSTRETCHED: | 195 UNSTRETCHED: |
| 198 make_unstretched_key(key, imageID, width, height, origin); | 196 make_unstretched_key(key, imageID, subset); |
| 199 } | 197 } |
| 200 } | 198 } |
| 201 | 199 |
| 202 static void make_unstretched_key(const SkBitmap& bitmap, GrUniqueKey* key) { | 200 static void make_image_keys(uint32_t imageID, const SkIRect& subset, const Stret
ch& stretch, |
| 203 make_unstretched_key(key, bitmap.getGenerationID(), bitmap.width(), bitmap.h
eight(), | 201 GrUniqueKey* key, GrUniqueKey* stretchedKey) { |
| 204 bitmap.pixelRefOrigin()); | 202 make_unstretched_key(key, imageID, subset); |
| 205 } | |
| 206 | |
| 207 static void make_bitmap_keys(const SkBitmap& bitmap, | |
| 208 const Stretch& stretch, | |
| 209 GrUniqueKey* key, | |
| 210 GrUniqueKey* stretchedKey) { | |
| 211 make_unstretched_key(bitmap, key); | |
| 212 if (Stretch::kNone_Type != stretch.fType) { | 203 if (Stretch::kNone_Type != stretch.fType) { |
| 213 make_stretched_key(*key, stretch, stretchedKey); | 204 make_stretched_key(*key, stretch, stretchedKey); |
| 214 } | 205 } |
| 215 } | 206 } |
| 216 | 207 |
| 217 static void generate_bitmap_texture_desc(const SkBitmap& bitmap, GrSurfaceDesc*
desc) { | 208 static void generate_bitmap_texture_desc(const SkBitmap& bitmap, GrSurfaceDesc*
desc) { |
| 218 desc->fFlags = kNone_GrSurfaceFlags; | 209 desc->fFlags = kNone_GrSurfaceFlags; |
| 219 desc->fWidth = bitmap.width(); | 210 desc->fWidth = bitmap.width(); |
| 220 desc->fHeight = bitmap.height(); | 211 desc->fHeight = bitmap.height(); |
| 221 desc->fConfig = SkImageInfo2GrPixelConfig(bitmap.info()); | 212 desc->fConfig = SkImageInfo2GrPixelConfig(bitmap.info()); |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 // than the min texture size. In that case do cpu stretching. | 518 // than the min texture size. In that case do cpu stretching. |
| 528 SkBitmap stretchedBmp = stretch_on_cpu(bmp, stretch); | 519 SkBitmap stretchedBmp = stretch_on_cpu(bmp, stretch); |
| 529 return create_unstretched_bitmap_texture(ctx, stretchedBmp, stre
tchedKey); | 520 return create_unstretched_bitmap_texture(ctx, stretchedBmp, stre
tchedKey); |
| 530 } | 521 } |
| 531 } | 522 } |
| 532 return stretch_texture(unstretched, stretch, bmp.pixelRef(), stretchedKe
y); | 523 return stretch_texture(unstretched, stretch, bmp.pixelRef(), stretchedKe
y); |
| 533 } | 524 } |
| 534 return create_unstretched_bitmap_texture(ctx, bmp, unstretchedKey); | 525 return create_unstretched_bitmap_texture(ctx, bmp, unstretchedKey); |
| 535 } | 526 } |
| 536 | 527 |
| 537 bool GrIsBitmapInCache(const GrContext* ctx, | 528 bool GrIsImageInCache(const GrContext* ctx, uint32_t imageID, const SkIRect& sub
set, |
| 538 const SkBitmap& bitmap, | 529 GrTexture* nativeTexture, const GrTextureParams* params) { |
| 539 const GrTextureParams* params) { | |
| 540 Stretch stretch; | 530 Stretch stretch; |
| 541 get_stretch(ctx, bitmap.width(), bitmap.height(), params, &stretch); | 531 get_stretch(ctx, subset.width(), subset.height(), params, &stretch); |
| 542 | 532 |
| 543 // Handle the case where the bitmap is explicitly texture backed. | 533 // Handle the case where the bitmap/image is explicitly texture backed. |
| 544 GrTexture* texture = bitmap.getTexture(); | 534 if (nativeTexture) { |
| 545 if (texture) { | |
| 546 if (Stretch::kNone_Type == stretch.fType) { | 535 if (Stretch::kNone_Type == stretch.fType) { |
| 547 return true; | 536 return true; |
| 548 } | 537 } |
| 549 // No keys for volatile bitmaps. | 538 const GrUniqueKey& key = nativeTexture->getUniqueKey(); |
| 550 if (bitmap.isVolatile()) { | |
| 551 return false; | |
| 552 } | |
| 553 const GrUniqueKey& key = texture->getUniqueKey(); | |
| 554 if (!key.isValid()) { | 539 if (!key.isValid()) { |
| 555 return false; | 540 return false; |
| 556 } | 541 } |
| 557 GrUniqueKey stretchedKey; | 542 GrUniqueKey stretchedKey; |
| 558 make_stretched_key(key, stretch, &stretchedKey); | 543 make_stretched_key(key, stretch, &stretchedKey); |
| 559 return ctx->textureProvider()->existsTextureWithUniqueKey(stretchedKey); | 544 return ctx->textureProvider()->existsTextureWithUniqueKey(stretchedKey); |
| 560 } | 545 } |
| 561 | 546 |
| 562 // We don't cache volatile bitmaps | |
| 563 if (bitmap.isVolatile()) { | |
| 564 return false; | |
| 565 } | |
| 566 | |
| 567 GrUniqueKey key, stretchedKey; | 547 GrUniqueKey key, stretchedKey; |
| 568 make_bitmap_keys(bitmap, stretch, &key, &stretchedKey); | 548 make_image_keys(imageID, subset, stretch, &key, &stretchedKey); |
| 569 return ctx->textureProvider()->existsTextureWithUniqueKey( | 549 return ctx->textureProvider()->existsTextureWithUniqueKey( |
| 570 (Stretch::kNone_Type == stretch.fType) ? key : stretchedKey); | 550 (Stretch::kNone_Type == stretch.fType) ? key : stretchedKey); |
| 571 } | 551 } |
| 572 | 552 |
| 553 bool GrIsBitmapInCache(const GrContext* ctx, const SkBitmap& bitmap, |
| 554 const GrTextureParams* params) { |
| 555 if (bitmap.isVolatile()) { |
| 556 return false; // we don't cache volatile bitmaps. |
| 557 } |
| 558 return GrIsImageInCache(ctx, bitmap.getGenerationID(), bitmap.getSubset(), b
itmap.getTexture(), |
| 559 params); |
| 560 } |
| 561 |
| 573 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, | 562 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, |
| 574 const SkBitmap& bitmap, | 563 const SkBitmap& bitmap, |
| 575 const GrTextureParams* params) { | 564 const GrTextureParams* params) { |
| 576 | 565 |
| 577 Stretch stretch; | 566 Stretch stretch; |
| 578 get_stretch(ctx, bitmap.width(), bitmap.height(), params, &stretch); | 567 get_stretch(ctx, bitmap.width(), bitmap.height(), params, &stretch); |
| 579 | 568 |
| 580 GrTexture* result = bitmap.getTexture(); | 569 GrTexture* result = bitmap.getTexture(); |
| 581 if (result) { | 570 if (result) { |
| 582 if (Stretch::kNone_Type == stretch.fType) { | 571 if (Stretch::kNone_Type == stretch.fType) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 595 } | 584 } |
| 596 } | 585 } |
| 597 } | 586 } |
| 598 return stretch_texture(result, stretch, bitmap.pixelRef(), stretchedKey)
; | 587 return stretch_texture(result, stretch, bitmap.pixelRef(), stretchedKey)
; |
| 599 } | 588 } |
| 600 | 589 |
| 601 GrUniqueKey key, resizedKey; | 590 GrUniqueKey key, resizedKey; |
| 602 | 591 |
| 603 if (!bitmap.isVolatile()) { | 592 if (!bitmap.isVolatile()) { |
| 604 // If the bitmap isn't changing try to find a cached copy first. | 593 // If the bitmap isn't changing try to find a cached copy first. |
| 605 make_bitmap_keys(bitmap, stretch, &key, &resizedKey); | 594 make_image_keys(bitmap.getGenerationID(), bitmap.getSubset(), stretch, &
key, &resizedKey); |
| 606 | 595 |
| 607 result = ctx->textureProvider()->findAndRefTextureByUniqueKey( | 596 result = ctx->textureProvider()->findAndRefTextureByUniqueKey( |
| 608 resizedKey.isValid() ? resizedKey : key); | 597 resizedKey.isValid() ? resizedKey : key); |
| 609 if (result) { | 598 if (result) { |
| 610 return result; | 599 return result; |
| 611 } | 600 } |
| 612 } | 601 } |
| 613 | 602 |
| 614 result = create_bitmap_texture(ctx, bitmap, stretch, key, resizedKey); | 603 result = create_bitmap_texture(ctx, bitmap, stretch, key, resizedKey); |
| 615 if (result) { | 604 if (result) { |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 860 SkErrorInternals::SetError( kInvalidPaint_SkError, | 849 SkErrorInternals::SetError( kInvalidPaint_SkError, |
| 861 "Sorry, I don't understand the filtering
" | 850 "Sorry, I don't understand the filtering
" |
| 862 "mode you asked for. Falling back to " | 851 "mode you asked for. Falling back to " |
| 863 "MIPMaps."); | 852 "MIPMaps."); |
| 864 textureFilterMode = GrTextureParams::kMipMap_FilterMode; | 853 textureFilterMode = GrTextureParams::kMipMap_FilterMode; |
| 865 break; | 854 break; |
| 866 | 855 |
| 867 } | 856 } |
| 868 return textureFilterMode; | 857 return textureFilterMode; |
| 869 } | 858 } |
| OLD | NEW |