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 20 matching lines...) Expand all Loading... |
31 #include "effects/GrDitherEffect.h" | 31 #include "effects/GrDitherEffect.h" |
32 #include "effects/GrPorterDuffXferProcessor.h" | 32 #include "effects/GrPorterDuffXferProcessor.h" |
33 #include "effects/GrXfermodeFragmentProcessor.h" | 33 #include "effects/GrXfermodeFragmentProcessor.h" |
34 #include "effects/GrYUVtoRGBEffect.h" | 34 #include "effects/GrYUVtoRGBEffect.h" |
35 | 35 |
36 #ifndef SK_IGNORE_ETC1_SUPPORT | 36 #ifndef SK_IGNORE_ETC1_SUPPORT |
37 # include "ktx.h" | 37 # include "ktx.h" |
38 # include "etc1.h" | 38 # include "etc1.h" |
39 #endif | 39 #endif |
40 | 40 |
41 bool GrTextureUsageSupported(const GrCaps& caps, int width, int height, SkImageU
sageType usage) { | |
42 if (caps.npotTextureTileSupport()) { | |
43 return true; | |
44 } | |
45 const bool is_pow2 = SkIsPow2(width) && SkIsPow2(height); | |
46 return is_pow2 || kUntiled_SkImageUsageType == usage; | |
47 } | |
48 | |
49 GrTextureParams GrImageUsageToTextureParams(SkImageUsageType usage) { | |
50 // Just need a params that will trigger the correct cache key / etc, since t
he usage doesn't | |
51 // tell us the specifics about filter level or specific tiling. | |
52 | |
53 const SkShader::TileMode tiles[] = { | |
54 SkShader::kClamp_TileMode, // kUntiled_SkImageUsageType | |
55 SkShader::kRepeat_TileMode, // kTiled_Unfiltered_SkImageUsageType | |
56 SkShader::kRepeat_TileMode, // kTiled_Filtered_SkImageUsageType | |
57 }; | |
58 | |
59 const GrTextureParams::FilterMode filters[] = { | |
60 GrTextureParams::kNone_FilterMode, // kUntiled_SkImageUsageType | |
61 GrTextureParams::kNone_FilterMode, // kTiled_Unfiltered_SkImageUsag
eType | |
62 GrTextureParams::kBilerp_FilterMode, // kTiled_Filtered_SkImageUsageT
ype | |
63 }; | |
64 | |
65 return GrTextureParams(tiles[usage], filters[usage]); | |
66 } | |
67 | |
68 /* Fill out buffer with the compressed format Ganesh expects from a colortable | 41 /* Fill out buffer with the compressed format Ganesh expects from a colortable |
69 based bitmap. [palette (colortable) + indices]. | 42 based bitmap. [palette (colortable) + indices]. |
70 | 43 |
71 At the moment Ganesh only supports 8bit version. If Ganesh allowed we others | 44 At the moment Ganesh only supports 8bit version. If Ganesh allowed we others |
72 we could detect that the colortable.count is <= 16, and then repack the | 45 we could detect that the colortable.count is <= 16, and then repack the |
73 indices as nibbles to save RAM, but it would take more time (i.e. a lot | 46 indices as nibbles to save RAM, but it would take more time (i.e. a lot |
74 slower than memcpy), so skipping that for now. | 47 slower than memcpy), so skipping that for now. |
75 | 48 |
76 Ganesh wants a full 256 palette entry, even though Skia's ctable is only as big | 49 Ganesh wants a full 256 palette entry, even though Skia's ctable is only as big |
77 as the colortable.count says it is. | 50 as the colortable.count says it is. |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 for (int y = 0; y < bitmap.height(); y++) { | 90 for (int y = 0; y < bitmap.height(); y++) { |
118 memcpy(dst, src, width); | 91 memcpy(dst, src, width); |
119 src += rowBytes; | 92 src += rowBytes; |
120 dst += width; | 93 dst += width; |
121 } | 94 } |
122 } | 95 } |
123 } | 96 } |
124 | 97 |
125 //////////////////////////////////////////////////////////////////////////////// | 98 //////////////////////////////////////////////////////////////////////////////// |
126 | 99 |
127 static void get_stretch(const GrContext* ctx, int width, int height, | 100 static void get_stretch(const GrCaps& caps, int width, int height, |
128 const GrTextureParams* params, SkGrStretch* stretch) { | 101 const GrTextureParams& params, SkGrStretch* stretch) { |
129 stretch->fType = SkGrStretch::kNone_Type; | 102 stretch->fType = SkGrStretch::kNone_Type; |
130 bool doStretch = false; | 103 bool doStretch = false; |
131 if (params && params->isTiled() && !ctx->caps()->npotTextureTileSupport() && | 104 if (params.isTiled() && !caps.npotTextureTileSupport() && |
132 (!SkIsPow2(width) || !SkIsPow2(height))) { | 105 (!SkIsPow2(width) || !SkIsPow2(height))) { |
133 doStretch = true; | 106 doStretch = true; |
134 stretch->fWidth = GrNextPow2(SkTMax(width, ctx->caps()->minTextureSize(
))); | 107 stretch->fWidth = GrNextPow2(SkTMax(width, caps.minTextureSize())); |
135 stretch->fHeight = GrNextPow2(SkTMax(height, ctx->caps()->minTextureSize
())); | 108 stretch->fHeight = GrNextPow2(SkTMax(height, caps.minTextureSize())); |
136 } else if (width < ctx->caps()->minTextureSize() || height < ctx->caps()->mi
nTextureSize()) { | 109 } else if (width < caps.minTextureSize() || height < caps.minTextureSize())
{ |
137 // The small texture issues appear to be with tiling. Hence it seems ok
to scale them | 110 // The small texture issues appear to be with tiling. Hence it seems ok
to scale them |
138 // up using the GPU. If issues persist we may need to CPU-stretch. | 111 // up using the GPU. If issues persist we may need to CPU-stretch. |
139 doStretch = true; | 112 doStretch = true; |
140 stretch->fWidth = SkTMax(width, ctx->caps()->minTextureSize()); | 113 stretch->fWidth = SkTMax(width, caps.minTextureSize()); |
141 stretch->fHeight = SkTMax(height, ctx->caps()->minTextureSize()); | 114 stretch->fHeight = SkTMax(height, caps.minTextureSize()); |
142 } | 115 } |
143 if (doStretch) { | 116 if (doStretch) { |
144 if (params) { | 117 switch(params.filterMode()) { |
145 switch(params->filterMode()) { | 118 case GrTextureParams::kNone_FilterMode: |
146 case GrTextureParams::kNone_FilterMode: | 119 stretch->fType = SkGrStretch::kNearest_Type; |
147 stretch->fType = SkGrStretch::kNearest_Type; | 120 break; |
148 break; | 121 case GrTextureParams::kBilerp_FilterMode: |
149 case GrTextureParams::kBilerp_FilterMode: | 122 case GrTextureParams::kMipMap_FilterMode: |
150 case GrTextureParams::kMipMap_FilterMode: | 123 stretch->fType = SkGrStretch::kBilerp_Type; |
151 stretch->fType = SkGrStretch::kBilerp_Type; | 124 break; |
152 break; | |
153 } | |
154 } else { | |
155 stretch->fType = SkGrStretch::kBilerp_Type; | |
156 } | 125 } |
157 } else { | 126 } else { |
158 stretch->fWidth = -1; | 127 stretch->fWidth = -1; |
159 stretch->fHeight = -1; | 128 stretch->fHeight = -1; |
160 stretch->fType = SkGrStretch::kNone_Type; | 129 stretch->fType = SkGrStretch::kNone_Type; |
161 } | 130 } |
162 } | 131 } |
163 | 132 |
164 bool GrMakeStretchedKey(const GrUniqueKey& origKey, const SkGrStretch& stretch, | 133 bool GrMakeStretchedKey(const GrUniqueKey& origKey, const SkGrStretch& stretch, |
165 GrUniqueKey* stretchedKey) { | 134 GrUniqueKey* stretchedKey) { |
(...skipping 17 matching lines...) Expand all Loading... |
183 | 152 |
184 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); | 153 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); |
185 GrUniqueKey::Builder builder(key, kDomain, 4); | 154 GrUniqueKey::Builder builder(key, kDomain, 4); |
186 builder[0] = imageID; | 155 builder[0] = imageID; |
187 builder[1] = subset.x(); | 156 builder[1] = subset.x(); |
188 builder[2] = subset.y(); | 157 builder[2] = subset.y(); |
189 builder[3] = subset.width() | (subset.height() << 16); | 158 builder[3] = subset.width() | (subset.height() << 16); |
190 } | 159 } |
191 | 160 |
192 void GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID, const SkIRect& sub
set, | 161 void GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID, const SkIRect& sub
set, |
193 const GrCaps& caps, SkImageUsageType usage) { | 162 const GrCaps& caps, const GrTextureParams& params) { |
194 const SkGrStretch::Type stretches[] = { | 163 SkGrStretch stretch; |
195 SkGrStretch::kNone_Type, // kUntiled_SkImageUsageType | 164 get_stretch(caps, subset.width(), subset.height(), params, &stretch); |
196 SkGrStretch::kNearest_Type, // kTiled_Unfiltered_SkImageUsageType | 165 if (SkGrStretch::kNone_Type != stretch.fType) { |
197 SkGrStretch::kBilerp_Type, // kTiled_Filtered_SkImageUsageType | |
198 }; | |
199 | |
200 if (!GrTextureUsageSupported(caps, subset.width(), subset.height(), usage))
{ | |
201 GrUniqueKey tmpKey; | 166 GrUniqueKey tmpKey; |
202 make_unstretched_key(&tmpKey, imageID, subset); | 167 make_unstretched_key(&tmpKey, imageID, subset); |
203 | |
204 SkGrStretch stretch; | |
205 stretch.fType = stretches[usage]; | |
206 stretch.fWidth = SkNextPow2(subset.width()); | |
207 stretch.fHeight = SkNextPow2(subset.height()); | |
208 if (!GrMakeStretchedKey(tmpKey, stretch, key)) { | 168 if (!GrMakeStretchedKey(tmpKey, stretch, key)) { |
209 goto UNSTRETCHED; | 169 *key = tmpKey; |
210 } | 170 } |
211 } else { | 171 } else { |
212 UNSTRETCHED: | |
213 make_unstretched_key(key, imageID, subset); | 172 make_unstretched_key(key, imageID, subset); |
214 } | 173 } |
215 } | 174 } |
216 | 175 |
217 static void make_image_keys(uint32_t imageID, const SkIRect& subset, const SkGrS
tretch& stretch, | 176 static void make_image_keys(uint32_t imageID, const SkIRect& subset, const SkGrS
tretch& stretch, |
218 GrUniqueKey* key, GrUniqueKey* stretchedKey) { | 177 GrUniqueKey* key, GrUniqueKey* stretchedKey) { |
219 make_unstretched_key(key, imageID, subset); | 178 make_unstretched_key(key, imageID, subset); |
220 if (SkGrStretch::kNone_Type != stretch.fType) { | 179 if (SkGrStretch::kNone_Type != stretch.fType) { |
221 GrMakeStretchedKey(*key, stretch, stretchedKey); | 180 GrMakeStretchedKey(*key, stretch, stretchedKey); |
222 } | 181 } |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 case SkGrStretch::kNone_Type: | 471 case SkGrStretch::kNone_Type: |
513 SkDEBUGFAIL("Shouldn't get here."); | 472 SkDEBUGFAIL("Shouldn't get here."); |
514 break; | 473 break; |
515 } | 474 } |
516 SkRect dstRect = SkRect::MakeWH(SkIntToScalar(stretch.fWidth), SkIntToScalar
(stretch.fHeight)); | 475 SkRect dstRect = SkRect::MakeWH(SkIntToScalar(stretch.fWidth), SkIntToScalar
(stretch.fHeight)); |
517 canvas.drawBitmapRect(bmp, dstRect, &paint); | 476 canvas.drawBitmapRect(bmp, dstRect, &paint); |
518 return stretched; | 477 return stretched; |
519 } | 478 } |
520 | 479 |
521 bool GrIsImageInCache(const GrContext* ctx, uint32_t imageID, const SkIRect& sub
set, | 480 bool GrIsImageInCache(const GrContext* ctx, uint32_t imageID, const SkIRect& sub
set, |
522 GrTexture* nativeTexture, const GrTextureParams* params) { | 481 GrTexture* nativeTexture, const GrTextureParams& params) { |
523 SkGrStretch stretch; | 482 SkGrStretch stretch; |
524 get_stretch(ctx, subset.width(), subset.height(), params, &stretch); | 483 get_stretch(*ctx->caps(), subset.width(), subset.height(), params, &stretch)
; |
525 | 484 |
526 // Handle the case where the bitmap/image is explicitly texture backed. | 485 // Handle the case where the bitmap/image is explicitly texture backed. |
527 if (nativeTexture) { | 486 if (nativeTexture) { |
528 if (SkGrStretch::kNone_Type == stretch.fType) { | 487 if (SkGrStretch::kNone_Type == stretch.fType) { |
529 return true; | 488 return true; |
530 } | 489 } |
531 const GrUniqueKey& key = nativeTexture->getUniqueKey(); | 490 const GrUniqueKey& key = nativeTexture->getUniqueKey(); |
532 if (!key.isValid()) { | 491 if (!key.isValid()) { |
533 return false; | 492 return false; |
534 } | 493 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
586 return true; | 545 return true; |
587 } | 546 } |
588 | 547 |
589 private: | 548 private: |
590 const SkBitmap fBitmap; | 549 const SkBitmap fBitmap; |
591 | 550 |
592 typedef GrTextureMaker INHERITED; | 551 typedef GrTextureMaker INHERITED; |
593 }; | 552 }; |
594 | 553 |
595 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, const SkBitmap& bitmap, | 554 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, const SkBitmap& bitmap, |
596 const GrTextureParams* params) { | 555 const GrTextureParams& params) { |
597 return Bitmap_GrTextureMaker(bitmap).refCachedTexture(ctx, params); | 556 return Bitmap_GrTextureMaker(bitmap).refCachedTexture(ctx, params); |
598 } | 557 } |
599 | 558 |
600 // TODO: make this be the canonical signature, and turn the version that takes G
rTextureParams* | |
601 // into a wrapper that contains the inverse of these tables. | |
602 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, | |
603 const SkBitmap& bitmap, | |
604 SkImageUsageType usage) { | |
605 GrTextureParams params = GrImageUsageToTextureParams(usage); | |
606 return GrRefCachedBitmapTexture(ctx, bitmap, ¶ms); | |
607 } | |
608 | |
609 /////////////////////////////////////////////////////////////////////////////// | 559 /////////////////////////////////////////////////////////////////////////////// |
610 | 560 |
611 // alphatype is ignore for now, but if GrPixelConfig is expanded to encompass | 561 // alphatype is ignore for now, but if GrPixelConfig is expanded to encompass |
612 // alpha info, that will be considered. | 562 // alpha info, that will be considered. |
613 GrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType, SkColorProf
ileType pt) { | 563 GrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType, SkColorProf
ileType pt) { |
614 switch (ct) { | 564 switch (ct) { |
615 case kUnknown_SkColorType: | 565 case kUnknown_SkColorType: |
616 return kUnknown_GrPixelConfig; | 566 return kUnknown_GrPixelConfig; |
617 case kAlpha_8_SkColorType: | 567 case kAlpha_8_SkColorType: |
618 return kAlpha_8_GrPixelConfig; | 568 return kAlpha_8_GrPixelConfig; |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
921 "MIPMaps."); | 871 "MIPMaps."); |
922 textureFilterMode = GrTextureParams::kMipMap_FilterMode; | 872 textureFilterMode = GrTextureParams::kMipMap_FilterMode; |
923 break; | 873 break; |
924 | 874 |
925 } | 875 } |
926 return textureFilterMode; | 876 return textureFilterMode; |
927 } | 877 } |
928 | 878 |
929 ////////////////////////////////////////////////////////////////////////////////
//////////////// | 879 ////////////////////////////////////////////////////////////////////////////////
//////////////// |
930 | 880 |
931 GrTexture* GrTextureMaker::refCachedTexture(GrContext* ctx, SkImageUsageType usa
ge) { | 881 GrTexture* GrTextureMaker::refCachedTexture(GrContext* ctx, const GrTextureParam
s& params) { |
932 GrTextureParams params = GrImageUsageToTextureParams(usage); | |
933 return this->refCachedTexture(ctx, ¶ms); | |
934 } | |
935 | |
936 GrTexture* GrTextureMaker::refCachedTexture(GrContext* ctx, const GrTextureParam
s* params) { | |
937 SkGrStretch stretch; | 882 SkGrStretch stretch; |
938 get_stretch(ctx, this->width(), this->height(), params, &stretch); | 883 get_stretch(*ctx->caps(), this->width(), this->height(), params, &stretch); |
939 | 884 |
940 if (SkGrStretch::kNone_Type == stretch.fType) { | 885 if (SkGrStretch::kNone_Type == stretch.fType) { |
941 return this->onRefUnstretchedTexture(ctx); | 886 return this->onRefUnstretchedTexture(ctx); |
942 } | 887 } |
943 | 888 |
944 GrUniqueKey stretchedKey; | 889 GrUniqueKey stretchedKey; |
945 if (this->onMakeStretchedKey(stretch, &stretchedKey)) { | 890 if (this->onMakeStretchedKey(stretch, &stretchedKey)) { |
946 GrTexture* result = ctx->textureProvider()->findAndRefTextureByUniqueKey
(stretchedKey); | 891 GrTexture* result = ctx->textureProvider()->findAndRefTextureByUniqueKey
(stretchedKey); |
947 if (result) { | 892 if (result) { |
948 return result; | 893 return result; |
(...skipping 25 matching lines...) Expand all Loading... |
974 SkBitmap stretchedBmp = stretch_on_cpu(bitmap, stretch); | 919 SkBitmap stretchedBmp = stretch_on_cpu(bitmap, stretch); |
975 return create_unstretched_bitmap_texture(ctx, stretchedBmp, GrUniqueKey(
)); | 920 return create_unstretched_bitmap_texture(ctx, stretchedBmp, GrUniqueKey(
)); |
976 } else { | 921 } else { |
977 SkAutoTUnref<GrTexture> unstretched(this->onRefUnstretchedTexture(ctx)); | 922 SkAutoTUnref<GrTexture> unstretched(this->onRefUnstretchedTexture(ctx)); |
978 if (!unstretched) { | 923 if (!unstretched) { |
979 return nullptr; | 924 return nullptr; |
980 } | 925 } |
981 return stretch_texture(unstretched, stretch, nullptr, GrUniqueKey()); | 926 return stretch_texture(unstretched, stretch, nullptr, GrUniqueKey()); |
982 } | 927 } |
983 } | 928 } |
OLD | NEW |