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 "GrTextureMaker.h" | 8 #include "GrTextureMaker.h" |
| 9 | 9 |
| 10 #include "SkGr.h" | 10 #include "SkGr.h" |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 30 #include "effects/GrDitherEffect.h" | 30 #include "effects/GrDitherEffect.h" |
| 31 #include "effects/GrPorterDuffXferProcessor.h" | 31 #include "effects/GrPorterDuffXferProcessor.h" |
| 32 #include "effects/GrXfermodeFragmentProcessor.h" | 32 #include "effects/GrXfermodeFragmentProcessor.h" |
| 33 #include "effects/GrYUVtoRGBEffect.h" | 33 #include "effects/GrYUVtoRGBEffect.h" |
| 34 | 34 |
| 35 #ifndef SK_IGNORE_ETC1_SUPPORT | 35 #ifndef SK_IGNORE_ETC1_SUPPORT |
| 36 # include "ktx.h" | 36 # include "ktx.h" |
| 37 # include "etc1.h" | 37 # include "etc1.h" |
| 38 #endif | 38 #endif |
| 39 | 39 |
| 40 bool GrTextureUsageSupported(const GrCaps& caps, int width, int height, SkImageU sageType usage) { | |
| 41 if (caps.npotTextureTileSupport()) { | |
| 42 return true; | |
| 43 } | |
|
robertphillips
2015/09/30 19:25:56
isPow2 ?
| |
| 44 const bool is_pow2 = SkIsPow2(width) && SkIsPow2(height); | |
| 45 return is_pow2 || kUntiled_SkImageUsageType == usage; | |
| 46 } | |
| 47 | |
| 48 GrTextureParams GrImageUsageToTextureParams(SkImageUsageType usage) { | |
|
bsalomon
2015/09/30 19:21:12
Maybe it's time to go the other way rather than ex
| |
| 49 // Just need a params that will trigger the correct cache key / etc, since t he usage doesn't | |
| 50 // tell us the specifics about filter level or specific tiling. | |
| 51 | |
|
robertphillips
2015/09/30 19:25:56
Do we need some assert r.e. the number of image us
| |
| 52 const SkShader::TileMode tiles[] = { | |
| 53 SkShader::kClamp_TileMode, // kUntiled_SkImageUsageType | |
| 54 SkShader::kRepeat_TileMode, // kTiled_Unfiltered_SkImageUsageType | |
| 55 SkShader::kRepeat_TileMode, // kTiled_Filtered_SkImageUsageType | |
| 56 }; | |
| 57 | |
| 58 const GrTextureParams::FilterMode filters[] = { | |
| 59 GrTextureParams::kNone_FilterMode, // kUntiled_SkImageUsageType | |
| 60 GrTextureParams::kNone_FilterMode, // kTiled_Unfiltered_SkImageUsag eType | |
| 61 GrTextureParams::kBilerp_FilterMode, // kTiled_Filtered_SkImageUsageT ype | |
| 62 }; | |
| 63 | |
| 64 return GrTextureParams(tiles[usage], filters[usage]); | |
| 65 } | |
| 66 | |
| 40 /* Fill out buffer with the compressed format Ganesh expects from a colortable | 67 /* Fill out buffer with the compressed format Ganesh expects from a colortable |
| 41 based bitmap. [palette (colortable) + indices]. | 68 based bitmap. [palette (colortable) + indices]. |
| 42 | 69 |
| 43 At the moment Ganesh only supports 8bit version. If Ganesh allowed we others | 70 At the moment Ganesh only supports 8bit version. If Ganesh allowed we others |
| 44 we could detect that the colortable.count is <= 16, and then repack the | 71 we could detect that the colortable.count is <= 16, and then repack the |
| 45 indices as nibbles to save RAM, but it would take more time (i.e. a lot | 72 indices as nibbles to save RAM, but it would take more time (i.e. a lot |
| 46 slower than memcpy), so skipping that for now. | 73 slower than memcpy), so skipping that for now. |
| 47 | 74 |
| 48 Ganesh wants a full 256 palette entry, even though Skia's ctable is only as big | 75 Ganesh wants a full 256 palette entry, even though Skia's ctable is only as big |
| 49 as the colortable.count says it is. | 76 as the colortable.count says it is. |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 126 } else { | 153 } else { |
| 127 stretch->fType = SkGrStretch::kBilerp_Type; | 154 stretch->fType = SkGrStretch::kBilerp_Type; |
| 128 } | 155 } |
| 129 } else { | 156 } else { |
| 130 stretch->fWidth = -1; | 157 stretch->fWidth = -1; |
| 131 stretch->fHeight = -1; | 158 stretch->fHeight = -1; |
| 132 stretch->fType = SkGrStretch::kNone_Type; | 159 stretch->fType = SkGrStretch::kNone_Type; |
| 133 } | 160 } |
| 134 } | 161 } |
| 135 | 162 |
| 136 static bool make_stretched_key(const GrUniqueKey& origKey, const SkGrStretch& st retch, | 163 bool GrMakeStretchedKey(const GrUniqueKey& origKey, const SkGrStretch& stretch, |
| 137 GrUniqueKey* stretchedKey) { | 164 GrUniqueKey* stretchedKey) { |
| 138 if (origKey.isValid() && SkGrStretch::kNone_Type != stretch.fType) { | 165 if (origKey.isValid() && SkGrStretch::kNone_Type != stretch.fType) { |
| 139 uint32_t width = SkToU16(stretch.fWidth); | 166 uint32_t width = SkToU16(stretch.fWidth); |
| 140 uint32_t height = SkToU16(stretch.fHeight); | 167 uint32_t height = SkToU16(stretch.fHeight); |
| 141 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain() ; | 168 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain() ; |
| 142 GrUniqueKey::Builder builder(stretchedKey, origKey, kDomain, 2); | 169 GrUniqueKey::Builder builder(stretchedKey, origKey, kDomain, 2); |
| 143 builder[0] = stretch.fType; | 170 builder[0] = stretch.fType; |
| 144 builder[1] = width | (height << 16); | 171 builder[1] = width | (height << 16); |
| 145 builder.finish(); | 172 builder.finish(); |
| 146 return true; | 173 return true; |
| 147 } | 174 } |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 162 } | 189 } |
| 163 | 190 |
| 164 void GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID, const SkIRect& sub set, | 191 void GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID, const SkIRect& sub set, |
| 165 const GrCaps& caps, SkImageUsageType usage) { | 192 const GrCaps& caps, SkImageUsageType usage) { |
| 166 const SkGrStretch::Type stretches[] = { | 193 const SkGrStretch::Type stretches[] = { |
| 167 SkGrStretch::kNone_Type, // kUntiled_SkImageUsageType | 194 SkGrStretch::kNone_Type, // kUntiled_SkImageUsageType |
| 168 SkGrStretch::kNearest_Type, // kTiled_Unfiltered_SkImageUsageType | 195 SkGrStretch::kNearest_Type, // kTiled_Unfiltered_SkImageUsageType |
| 169 SkGrStretch::kBilerp_Type, // kTiled_Filtered_SkImageUsageType | 196 SkGrStretch::kBilerp_Type, // kTiled_Filtered_SkImageUsageType |
| 170 }; | 197 }; |
| 171 | 198 |
| 172 const bool isPow2 = SkIsPow2(subset.width()) && SkIsPow2(subset.height()); | 199 if (!GrTextureUsageSupported(caps, subset.width(), subset.height(), usage)) { |
| 173 const bool needToStretch = !isPow2 && | |
| 174 usage != kUntiled_SkImageUsageType && | |
| 175 !caps.npotTextureTileSupport(); | |
| 176 | |
| 177 if (needToStretch) { | |
| 178 GrUniqueKey tmpKey; | 200 GrUniqueKey tmpKey; |
| 179 make_unstretched_key(&tmpKey, imageID, subset); | 201 make_unstretched_key(&tmpKey, imageID, subset); |
| 180 | 202 |
| 181 SkGrStretch stretch; | 203 SkGrStretch stretch; |
| 182 stretch.fType = stretches[usage]; | 204 stretch.fType = stretches[usage]; |
| 183 stretch.fWidth = SkNextPow2(subset.width()); | 205 stretch.fWidth = SkNextPow2(subset.width()); |
| 184 stretch.fHeight = SkNextPow2(subset.height()); | 206 stretch.fHeight = SkNextPow2(subset.height()); |
| 185 if (!make_stretched_key(tmpKey, stretch, key)) { | 207 if (!GrMakeStretchedKey(tmpKey, stretch, key)) { |
| 186 goto UNSTRETCHED; | 208 goto UNSTRETCHED; |
| 187 } | 209 } |
| 188 } else { | 210 } else { |
| 189 UNSTRETCHED: | 211 UNSTRETCHED: |
| 190 make_unstretched_key(key, imageID, subset); | 212 make_unstretched_key(key, imageID, subset); |
| 191 } | 213 } |
| 192 } | 214 } |
| 193 | 215 |
| 194 static void make_image_keys(uint32_t imageID, const SkIRect& subset, const SkGrS tretch& stretch, | 216 static void make_image_keys(uint32_t imageID, const SkIRect& subset, const SkGrS tretch& stretch, |
| 195 GrUniqueKey* key, GrUniqueKey* stretchedKey) { | 217 GrUniqueKey* key, GrUniqueKey* stretchedKey) { |
| 196 make_unstretched_key(key, imageID, subset); | 218 make_unstretched_key(key, imageID, subset); |
| 197 if (SkGrStretch::kNone_Type != stretch.fType) { | 219 if (SkGrStretch::kNone_Type != stretch.fType) { |
| 198 make_stretched_key(*key, stretch, stretchedKey); | 220 GrMakeStretchedKey(*key, stretch, stretchedKey); |
| 199 } | 221 } |
| 200 } | 222 } |
| 201 | 223 |
| 202 GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo& info) { | 224 GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo& info) { |
| 203 GrSurfaceDesc desc; | 225 GrSurfaceDesc desc; |
| 204 desc.fFlags = kNone_GrSurfaceFlags; | 226 desc.fFlags = kNone_GrSurfaceFlags; |
| 205 desc.fWidth = info.width(); | 227 desc.fWidth = info.width(); |
| 206 desc.fHeight = info.height(); | 228 desc.fHeight = info.height(); |
| 207 desc.fConfig = SkImageInfo2GrPixelConfig(info); | 229 desc.fConfig = SkImageInfo2GrPixelConfig(info); |
| 208 desc.fSampleCnt = 0; | 230 desc.fSampleCnt = 0; |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 503 // Handle the case where the bitmap/image is explicitly texture backed. | 525 // Handle the case where the bitmap/image is explicitly texture backed. |
| 504 if (nativeTexture) { | 526 if (nativeTexture) { |
| 505 if (SkGrStretch::kNone_Type == stretch.fType) { | 527 if (SkGrStretch::kNone_Type == stretch.fType) { |
| 506 return true; | 528 return true; |
| 507 } | 529 } |
| 508 const GrUniqueKey& key = nativeTexture->getUniqueKey(); | 530 const GrUniqueKey& key = nativeTexture->getUniqueKey(); |
| 509 if (!key.isValid()) { | 531 if (!key.isValid()) { |
| 510 return false; | 532 return false; |
| 511 } | 533 } |
| 512 GrUniqueKey stretchedKey; | 534 GrUniqueKey stretchedKey; |
| 513 make_stretched_key(key, stretch, &stretchedKey); | 535 GrMakeStretchedKey(key, stretch, &stretchedKey); |
| 514 return ctx->textureProvider()->existsTextureWithUniqueKey(stretchedKey); | 536 return ctx->textureProvider()->existsTextureWithUniqueKey(stretchedKey); |
| 515 } | 537 } |
| 516 | 538 |
| 517 GrUniqueKey key, stretchedKey; | 539 GrUniqueKey key, stretchedKey; |
| 518 make_image_keys(imageID, subset, stretch, &key, &stretchedKey); | 540 make_image_keys(imageID, subset, stretch, &key, &stretchedKey); |
| 519 return ctx->textureProvider()->existsTextureWithUniqueKey( | 541 return ctx->textureProvider()->existsTextureWithUniqueKey( |
| 520 (SkGrStretch::kNone_Type == stretch.fType) ? key : stretchedKey); | 542 (SkGrStretch::kNone_Type == stretch.fType) ? key : stretchedKey); |
| 521 } | 543 } |
| 522 | 544 |
| 523 class Bitmap_GrTextureMaker : public GrTextureMaker { | 545 class Bitmap_GrTextureMaker : public GrTextureMaker { |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 544 return create_unstretched_bitmap_texture(ctx, fBitmap, unstretchedKey); | 566 return create_unstretched_bitmap_texture(ctx, fBitmap, unstretchedKey); |
| 545 } | 567 } |
| 546 | 568 |
| 547 bool onMakeStretchedKey(const SkGrStretch& stretch, GrUniqueKey* stretchedKe y) override { | 569 bool onMakeStretchedKey(const SkGrStretch& stretch, GrUniqueKey* stretchedKe y) override { |
| 548 if (fBitmap.isVolatile()) { | 570 if (fBitmap.isVolatile()) { |
| 549 return false; | 571 return false; |
| 550 } | 572 } |
| 551 | 573 |
| 552 GrUniqueKey unstretchedKey; | 574 GrUniqueKey unstretchedKey; |
| 553 make_unstretched_key(&unstretchedKey, fBitmap.getGenerationID(), fBitmap .getSubset()); | 575 make_unstretched_key(&unstretchedKey, fBitmap.getGenerationID(), fBitmap .getSubset()); |
| 554 return make_stretched_key(unstretchedKey, stretch, stretchedKey); | 576 return GrMakeStretchedKey(unstretchedKey, stretch, stretchedKey); |
| 555 } | 577 } |
| 556 | 578 |
| 557 void onNotifyStretchCached(const GrUniqueKey& stretchedKey) override { | 579 void onNotifyStretchCached(const GrUniqueKey& stretchedKey) override { |
| 558 fBitmap.pixelRef()->addGenIDChangeListener(new BitmapInvalidator(stretch edKey)); | 580 fBitmap.pixelRef()->addGenIDChangeListener(new BitmapInvalidator(stretch edKey)); |
| 559 } | 581 } |
| 560 | 582 |
| 561 bool onGetROBitmap(SkBitmap* bitmap) override { | 583 bool onGetROBitmap(SkBitmap* bitmap) override { |
| 562 *bitmap = fBitmap; | 584 *bitmap = fBitmap; |
| 563 return true; | 585 return true; |
| 564 } | 586 } |
| 565 | 587 |
| 566 private: | 588 private: |
| 567 const SkBitmap fBitmap; | 589 const SkBitmap fBitmap; |
| 568 | 590 |
| 569 typedef GrTextureMaker INHERITED; | 591 typedef GrTextureMaker INHERITED; |
| 570 }; | 592 }; |
| 571 | 593 |
| 572 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, const SkBitmap& bitmap, | 594 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, const SkBitmap& bitmap, |
| 573 const GrTextureParams* params) { | 595 const GrTextureParams* params) { |
| 574 return Bitmap_GrTextureMaker(bitmap).refCachedTexture(ctx, params); | 596 return Bitmap_GrTextureMaker(bitmap).refCachedTexture(ctx, params); |
| 575 } | 597 } |
| 576 | 598 |
| 577 // TODO: make this be the canonical signature, and turn the version that takes G rTextureParams* | 599 // TODO: make this be the canonical signature, and turn the version that takes G rTextureParams* |
| 578 // into a wrapper that contains the inverse of these tables. | 600 // into a wrapper that contains the inverse of these tables. |
| 579 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, | 601 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, |
| 580 const SkBitmap& bitmap, | 602 const SkBitmap& bitmap, |
| 581 SkImageUsageType usage) { | 603 SkImageUsageType usage) { |
| 582 // Just need a params that will trigger the correct cache key / etc, since t he usage doesn't | 604 GrTextureParams params = GrImageUsageToTextureParams(usage); |
| 583 // tell us the specifics about filter level or specific tiling. | |
| 584 | |
| 585 const SkShader::TileMode tiles[] = { | |
| 586 SkShader::kClamp_TileMode, // kUntiled_SkImageUsageType | |
| 587 SkShader::kRepeat_TileMode, // kTiled_Unfiltered_SkImageUsageType | |
| 588 SkShader::kRepeat_TileMode, // kTiled_Filtered_SkImageUsageType | |
| 589 }; | |
| 590 | |
| 591 const GrTextureParams::FilterMode filters[] = { | |
| 592 GrTextureParams::kNone_FilterMode, // kUntiled_SkImageUsageType | |
| 593 GrTextureParams::kNone_FilterMode, // kTiled_Unfiltered_SkImageUsag eType | |
| 594 GrTextureParams::kBilerp_FilterMode, // kTiled_Filtered_SkImageUsageT ype | |
| 595 }; | |
| 596 | |
| 597 GrTextureParams params(tiles[usage], filters[usage]); | |
| 598 return GrRefCachedBitmapTexture(ctx, bitmap, ¶ms); | 605 return GrRefCachedBitmapTexture(ctx, bitmap, ¶ms); |
| 599 } | 606 } |
| 600 | 607 |
| 601 /////////////////////////////////////////////////////////////////////////////// | 608 /////////////////////////////////////////////////////////////////////////////// |
| 602 | 609 |
| 603 // alphatype is ignore for now, but if GrPixelConfig is expanded to encompass | 610 // alphatype is ignore for now, but if GrPixelConfig is expanded to encompass |
| 604 // alpha info, that will be considered. | 611 // alpha info, that will be considered. |
| 605 GrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType, SkColorProf ileType pt) { | 612 GrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType, SkColorProf ileType pt) { |
| 606 switch (ct) { | 613 switch (ct) { |
| 607 case kUnknown_SkColorType: | 614 case kUnknown_SkColorType: |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 901 "MIPMaps."); | 908 "MIPMaps."); |
| 902 textureFilterMode = GrTextureParams::kMipMap_FilterMode; | 909 textureFilterMode = GrTextureParams::kMipMap_FilterMode; |
| 903 break; | 910 break; |
| 904 | 911 |
| 905 } | 912 } |
| 906 return textureFilterMode; | 913 return textureFilterMode; |
| 907 } | 914 } |
| 908 | 915 |
| 909 //////////////////////////////////////////////////////////////////////////////// //////////////// | 916 //////////////////////////////////////////////////////////////////////////////// //////////////// |
| 910 | 917 |
| 918 GrTexture* GrTextureMaker::refCachedTexture(GrContext* ctx, SkImageUsageType usa ge) { | |
| 919 GrTextureParams params = GrImageUsageToTextureParams(usage); | |
| 920 return this->refCachedTexture(ctx, ¶ms); | |
| 921 } | |
| 922 | |
| 911 GrTexture* GrTextureMaker::refCachedTexture(GrContext* ctx, const GrTextureParam s* params) { | 923 GrTexture* GrTextureMaker::refCachedTexture(GrContext* ctx, const GrTextureParam s* params) { |
| 912 SkGrStretch stretch; | 924 SkGrStretch stretch; |
| 913 get_stretch(ctx, this->width(), this->height(), params, &stretch); | 925 get_stretch(ctx, this->width(), this->height(), params, &stretch); |
| 914 | 926 |
| 915 if (SkGrStretch::kNone_Type == stretch.fType) { | 927 if (SkGrStretch::kNone_Type == stretch.fType) { |
| 916 return this->onRefUnstretchedTexture(ctx); | 928 return this->onRefUnstretchedTexture(ctx); |
| 917 } | 929 } |
| 918 | 930 |
| 919 GrUniqueKey stretchedKey; | 931 GrUniqueKey stretchedKey; |
| 920 if (this->onMakeStretchedKey(stretch, &stretchedKey)) { | 932 if (this->onMakeStretchedKey(stretch, &stretchedKey)) { |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 949 SkBitmap stretchedBmp = stretch_on_cpu(bitmap, stretch); | 961 SkBitmap stretchedBmp = stretch_on_cpu(bitmap, stretch); |
| 950 return create_unstretched_bitmap_texture(ctx, stretchedBmp, GrUniqueKey( )); | 962 return create_unstretched_bitmap_texture(ctx, stretchedBmp, GrUniqueKey( )); |
| 951 } else { | 963 } else { |
| 952 SkAutoTUnref<GrTexture> unstretched(this->onRefUnstretchedTexture(ctx)); | 964 SkAutoTUnref<GrTexture> unstretched(this->onRefUnstretchedTexture(ctx)); |
| 953 if (!unstretched) { | 965 if (!unstretched) { |
| 954 return nullptr; | 966 return nullptr; |
| 955 } | 967 } |
| 956 return stretch_texture(unstretched, stretch, nullptr, GrUniqueKey()); | 968 return stretch_texture(unstretched, stretch, nullptr, GrUniqueKey()); |
| 957 } | 969 } |
| 958 } | 970 } |
| OLD | NEW |