Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Side by Side Diff: src/gpu/SkGr.cpp

Issue 1376603002: try texture-maker to generalize stretching for npot and min-tex-size (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/GrTextureMaker.h ('k') | src/gpu/SkGrPriv.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
9
8 #include "SkGr.h" 10 #include "SkGr.h"
9 11
10 #include "GrCaps.h" 12 #include "GrCaps.h"
11 #include "GrDrawContext.h" 13 #include "GrDrawContext.h"
12 #include "GrXferProcessor.h" 14 #include "GrXferProcessor.h"
13 #include "GrYUVProvider.h" 15 #include "GrYUVProvider.h"
14 16
15 #include "SkColorFilter.h" 17 #include "SkColorFilter.h"
16 #include "SkConfig8888.h" 18 #include "SkConfig8888.h"
17 #include "SkCanvas.h" 19 #include "SkCanvas.h"
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 for (int y = 0; y < bitmap.height(); y++) { 89 for (int y = 0; y < bitmap.height(); y++) {
88 memcpy(dst, src, width); 90 memcpy(dst, src, width);
89 src += rowBytes; 91 src += rowBytes;
90 dst += width; 92 dst += width;
91 } 93 }
92 } 94 }
93 } 95 }
94 96
95 //////////////////////////////////////////////////////////////////////////////// 97 ////////////////////////////////////////////////////////////////////////////////
96 98
97 struct Stretch {
98 enum Type {
99 kNone_Type,
100 kBilerp_Type,
101 kNearest_Type
102 } fType;
103 int fWidth;
104 int fHeight;
105 };
106
107 static void get_stretch(const GrContext* ctx, int width, int height, 99 static void get_stretch(const GrContext* ctx, int width, int height,
108 const GrTextureParams* params, Stretch* stretch) { 100 const GrTextureParams* params, SkGrStretch* stretch) {
109 stretch->fType = Stretch::kNone_Type; 101 stretch->fType = SkGrStretch::kNone_Type;
110 bool doStretch = false; 102 bool doStretch = false;
111 if (params && params->isTiled() && !ctx->caps()->npotTextureTileSupport() && 103 if (params && params->isTiled() && !ctx->caps()->npotTextureTileSupport() &&
112 (!SkIsPow2(width) || !SkIsPow2(height))) { 104 (!SkIsPow2(width) || !SkIsPow2(height))) {
113 doStretch = true; 105 doStretch = true;
114 stretch->fWidth = GrNextPow2(SkTMax(width, ctx->caps()->minTextureSize( ))); 106 stretch->fWidth = GrNextPow2(SkTMax(width, ctx->caps()->minTextureSize( )));
115 stretch->fHeight = GrNextPow2(SkTMax(height, ctx->caps()->minTextureSize ())); 107 stretch->fHeight = GrNextPow2(SkTMax(height, ctx->caps()->minTextureSize ()));
116 } else if (width < ctx->caps()->minTextureSize() || height < ctx->caps()->mi nTextureSize()) { 108 } else if (width < ctx->caps()->minTextureSize() || height < ctx->caps()->mi nTextureSize()) {
117 // The small texture issues appear to be with tiling. Hence it seems ok to scale them 109 // The small texture issues appear to be with tiling. Hence it seems ok to scale them
118 // up using the GPU. If issues persist we may need to CPU-stretch. 110 // up using the GPU. If issues persist we may need to CPU-stretch.
119 doStretch = true; 111 doStretch = true;
120 stretch->fWidth = SkTMax(width, ctx->caps()->minTextureSize()); 112 stretch->fWidth = SkTMax(width, ctx->caps()->minTextureSize());
121 stretch->fHeight = SkTMax(height, ctx->caps()->minTextureSize()); 113 stretch->fHeight = SkTMax(height, ctx->caps()->minTextureSize());
122 } 114 }
123 if (doStretch) { 115 if (doStretch) {
124 if (params) { 116 if (params) {
125 switch(params->filterMode()) { 117 switch(params->filterMode()) {
126 case GrTextureParams::kNone_FilterMode: 118 case GrTextureParams::kNone_FilterMode:
127 stretch->fType = Stretch::kNearest_Type; 119 stretch->fType = SkGrStretch::kNearest_Type;
128 break; 120 break;
129 case GrTextureParams::kBilerp_FilterMode: 121 case GrTextureParams::kBilerp_FilterMode:
130 case GrTextureParams::kMipMap_FilterMode: 122 case GrTextureParams::kMipMap_FilterMode:
131 stretch->fType = Stretch::kBilerp_Type; 123 stretch->fType = SkGrStretch::kBilerp_Type;
132 break; 124 break;
133 } 125 }
134 } else { 126 } else {
135 stretch->fType = Stretch::kBilerp_Type; 127 stretch->fType = SkGrStretch::kBilerp_Type;
136 } 128 }
137 } else { 129 } else {
138 stretch->fWidth = -1; 130 stretch->fWidth = -1;
139 stretch->fHeight = -1; 131 stretch->fHeight = -1;
140 stretch->fType = Stretch::kNone_Type; 132 stretch->fType = SkGrStretch::kNone_Type;
141 } 133 }
142 } 134 }
143 135
144 static bool make_stretched_key(const GrUniqueKey& origKey, const Stretch& stretc h, 136 static bool make_stretched_key(const GrUniqueKey& origKey, const SkGrStretch& st retch,
145 GrUniqueKey* stretchedKey) { 137 GrUniqueKey* stretchedKey) {
146 if (origKey.isValid() && Stretch::kNone_Type != stretch.fType) { 138 if (origKey.isValid() && SkGrStretch::kNone_Type != stretch.fType) {
147 uint32_t width = SkToU16(stretch.fWidth); 139 uint32_t width = SkToU16(stretch.fWidth);
148 uint32_t height = SkToU16(stretch.fHeight); 140 uint32_t height = SkToU16(stretch.fHeight);
149 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain() ; 141 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain() ;
150 GrUniqueKey::Builder builder(stretchedKey, origKey, kDomain, 2); 142 GrUniqueKey::Builder builder(stretchedKey, origKey, kDomain, 2);
151 builder[0] = stretch.fType; 143 builder[0] = stretch.fType;
152 builder[1] = width | (height << 16); 144 builder[1] = width | (height << 16);
153 builder.finish(); 145 builder.finish();
154 return true; 146 return true;
155 } 147 }
156 SkASSERT(!stretchedKey->isValid()); 148 SkASSERT(!stretchedKey->isValid());
157 return false; 149 return false;
158 } 150 }
159 151
160 static void make_unstretched_key(GrUniqueKey* key, uint32_t imageID, const SkIRe ct& subset) { 152 static void make_unstretched_key(GrUniqueKey* key, uint32_t imageID, const SkIRe ct& subset) {
161 SkASSERT(SkIsU16(subset.width())); 153 SkASSERT(SkIsU16(subset.width()));
162 SkASSERT(SkIsU16(subset.height())); 154 SkASSERT(SkIsU16(subset.height()));
163 155
164 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); 156 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
165 GrUniqueKey::Builder builder(key, kDomain, 4); 157 GrUniqueKey::Builder builder(key, kDomain, 4);
166 builder[0] = imageID; 158 builder[0] = imageID;
167 builder[1] = subset.x(); 159 builder[1] = subset.x();
168 builder[2] = subset.y(); 160 builder[2] = subset.y();
169 builder[3] = subset.width() | (subset.height() << 16); 161 builder[3] = subset.width() | (subset.height() << 16);
170 } 162 }
171 163
172 void GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID, const SkIRect& sub set, 164 void GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID, const SkIRect& sub set,
173 const GrCaps& caps, SkImageUsageType usage) { 165 const GrCaps& caps, SkImageUsageType usage) {
174 const Stretch::Type stretches[] = { 166 const SkGrStretch::Type stretches[] = {
175 Stretch::kNone_Type, // kUntiled_SkImageUsageType 167 SkGrStretch::kNone_Type, // kUntiled_SkImageUsageType
176 Stretch::kNearest_Type, // kTiled_Unfiltered_SkImageUsageType 168 SkGrStretch::kNearest_Type, // kTiled_Unfiltered_SkImageUsageType
177 Stretch::kBilerp_Type, // kTiled_Filtered_SkImageUsageType 169 SkGrStretch::kBilerp_Type, // kTiled_Filtered_SkImageUsageType
178 }; 170 };
179 171
180 const bool isPow2 = SkIsPow2(subset.width()) && SkIsPow2(subset.height()); 172 const bool isPow2 = SkIsPow2(subset.width()) && SkIsPow2(subset.height());
181 const bool needToStretch = !isPow2 && 173 const bool needToStretch = !isPow2 &&
182 usage != kUntiled_SkImageUsageType && 174 usage != kUntiled_SkImageUsageType &&
183 !caps.npotTextureTileSupport(); 175 !caps.npotTextureTileSupport();
184 176
185 if (needToStretch) { 177 if (needToStretch) {
186 GrUniqueKey tmpKey; 178 GrUniqueKey tmpKey;
187 make_unstretched_key(&tmpKey, imageID, subset); 179 make_unstretched_key(&tmpKey, imageID, subset);
188 180
189 Stretch stretch; 181 SkGrStretch stretch;
190 stretch.fType = stretches[usage]; 182 stretch.fType = stretches[usage];
191 stretch.fWidth = SkNextPow2(subset.width()); 183 stretch.fWidth = SkNextPow2(subset.width());
192 stretch.fHeight = SkNextPow2(subset.height()); 184 stretch.fHeight = SkNextPow2(subset.height());
193 if (!make_stretched_key(tmpKey, stretch, key)) { 185 if (!make_stretched_key(tmpKey, stretch, key)) {
194 goto UNSTRETCHED; 186 goto UNSTRETCHED;
195 } 187 }
196 } else { 188 } else {
197 UNSTRETCHED: 189 UNSTRETCHED:
198 make_unstretched_key(key, imageID, subset); 190 make_unstretched_key(key, imageID, subset);
199 } 191 }
200 } 192 }
201 193
202 static void make_image_keys(uint32_t imageID, const SkIRect& subset, const Stret ch& stretch, 194 static void make_image_keys(uint32_t imageID, const SkIRect& subset, const SkGrS tretch& stretch,
203 GrUniqueKey* key, GrUniqueKey* stretchedKey) { 195 GrUniqueKey* key, GrUniqueKey* stretchedKey) {
204 make_unstretched_key(key, imageID, subset); 196 make_unstretched_key(key, imageID, subset);
205 if (Stretch::kNone_Type != stretch.fType) { 197 if (SkGrStretch::kNone_Type != stretch.fType) {
206 make_stretched_key(*key, stretch, stretchedKey); 198 make_stretched_key(*key, stretch, stretchedKey);
207 } 199 }
208 } 200 }
209 201
210 GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo& info) { 202 GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo& info) {
211 GrSurfaceDesc desc; 203 GrSurfaceDesc desc;
212 desc.fFlags = kNone_GrSurfaceFlags; 204 desc.fFlags = kNone_GrSurfaceFlags;
213 desc.fWidth = info.width(); 205 desc.fWidth = info.width();
214 desc.fHeight = info.height(); 206 desc.fHeight = info.height();
215 desc.fConfig = SkImageInfo2GrPixelConfig(info); 207 desc.fConfig = SkImageInfo2GrPixelConfig(info);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 pixelRefForInvalidationNotification->addGenIDChangeListener(listener ); 239 pixelRefForInvalidationNotification->addGenIDChangeListener(listener );
248 } 240 }
249 ctx->textureProvider()->assignUniqueKeyToTexture(optionalKey, result); 241 ctx->textureProvider()->assignUniqueKeyToTexture(optionalKey, result);
250 } 242 }
251 return result; 243 return result;
252 } 244 }
253 245
254 // creates a new texture that is the input texture scaled up. If optionalKey is valid it will be 246 // creates a new texture that is the input texture scaled up. If optionalKey is valid it will be
255 // set on the new texture. stretch controls whether the scaling is done using ne arest or bilerp 247 // set on the new texture. stretch controls whether the scaling is done using ne arest or bilerp
256 // filtering and the size to stretch the texture to. 248 // filtering and the size to stretch the texture to.
257 GrTexture* stretch_texture(GrTexture* inputTexture, const Stretch& stretch, 249 GrTexture* stretch_texture(GrTexture* inputTexture, const SkGrStretch& stretch,
258 SkPixelRef* pixelRef, 250 SkPixelRef* pixelRef,
259 const GrUniqueKey& optionalKey) { 251 const GrUniqueKey& optionalKey) {
260 SkASSERT(Stretch::kNone_Type != stretch.fType); 252 SkASSERT(SkGrStretch::kNone_Type != stretch.fType);
261 253
262 GrContext* context = inputTexture->getContext(); 254 GrContext* context = inputTexture->getContext();
263 SkASSERT(context); 255 SkASSERT(context);
264 const GrCaps* caps = context->caps(); 256 const GrCaps* caps = context->caps();
265 257
266 // Either it's a cache miss or the original wasn't cached to begin with. 258 // Either it's a cache miss or the original wasn't cached to begin with.
267 GrSurfaceDesc rtDesc = inputTexture->desc(); 259 GrSurfaceDesc rtDesc = inputTexture->desc();
268 rtDesc.fFlags = rtDesc.fFlags | kRenderTarget_GrSurfaceFlag; 260 rtDesc.fFlags = rtDesc.fFlags | kRenderTarget_GrSurfaceFlag;
269 rtDesc.fWidth = stretch.fWidth; 261 rtDesc.fWidth = stretch.fWidth;
270 rtDesc.fHeight = stretch.fHeight; 262 rtDesc.fHeight = stretch.fHeight;
(...skipping 25 matching lines...) Expand all
296 SkAutoTUnref<GrTexture> stretched(GrCreateTextureForPixels(context, optional Key, rtDesc, 288 SkAutoTUnref<GrTexture> stretched(GrCreateTextureForPixels(context, optional Key, rtDesc,
297 pixelRef, nullptr ,0)); 289 pixelRef, nullptr ,0));
298 if (!stretched) { 290 if (!stretched) {
299 return nullptr; 291 return nullptr;
300 } 292 }
301 GrPaint paint; 293 GrPaint paint;
302 294
303 // If filtering is not desired then we want to ensure all texels in the resa mpled image are 295 // If filtering is not desired then we want to ensure all texels in the resa mpled image are
304 // copies of texels from the original. 296 // copies of texels from the original.
305 GrTextureParams params(SkShader::kClamp_TileMode, 297 GrTextureParams params(SkShader::kClamp_TileMode,
306 Stretch::kBilerp_Type == stretch.fType ? 298 SkGrStretch::kBilerp_Type == stretch.fType ?
307 GrTextureParams::kBilerp_FilterMode : 299 GrTextureParams::kBilerp_FilterMode :
308 GrTextureParams::kNone_FilterMode); 300 GrTextureParams::kNone_FilterMode);
309 paint.addColorTextureProcessor(inputTexture, SkMatrix::I(), params); 301 paint.addColorTextureProcessor(inputTexture, SkMatrix::I(), params);
310 302
311 SkRect rect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtD esc.fHeight)); 303 SkRect rect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtD esc.fHeight));
312 SkRect localRect = SkRect::MakeWH(1.f, 1.f); 304 SkRect localRect = SkRect::MakeWH(1.f, 1.f);
313 305
314 SkAutoTUnref<GrDrawContext> drawContext(context->drawContext()); 306 SkAutoTUnref<GrDrawContext> drawContext(context->drawContext());
315 if (!drawContext) { 307 if (!drawContext) {
316 return nullptr; 308 return nullptr;
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 467
476 SkAutoLockPixels alp(*bitmap); 468 SkAutoLockPixels alp(*bitmap);
477 if (!bitmap->readyToDraw()) { 469 if (!bitmap->readyToDraw()) {
478 return nullptr; 470 return nullptr;
479 } 471 }
480 472
481 return GrCreateTextureForPixels(ctx, optionalKey, desc, origBitmap.pixelRef( ), 473 return GrCreateTextureForPixels(ctx, optionalKey, desc, origBitmap.pixelRef( ),
482 bitmap->getPixels(), bitmap->rowBytes()); 474 bitmap->getPixels(), bitmap->rowBytes());
483 } 475 }
484 476
485 static SkBitmap stretch_on_cpu(const SkBitmap& bmp, const Stretch& stretch) { 477 static SkBitmap stretch_on_cpu(const SkBitmap& bmp, const SkGrStretch& stretch) {
486 SkBitmap stretched; 478 SkBitmap stretched;
487 stretched.allocN32Pixels(stretch.fWidth, stretch.fHeight); 479 stretched.allocN32Pixels(stretch.fWidth, stretch.fHeight);
488 SkCanvas canvas(stretched); 480 SkCanvas canvas(stretched);
489 SkPaint paint; 481 SkPaint paint;
490 switch (stretch.fType) { 482 switch (stretch.fType) {
491 case Stretch::kNearest_Type: 483 case SkGrStretch::kNearest_Type:
492 paint.setFilterQuality(kNone_SkFilterQuality); 484 paint.setFilterQuality(kNone_SkFilterQuality);
493 break; 485 break;
494 case Stretch::kBilerp_Type: 486 case SkGrStretch::kBilerp_Type:
495 paint.setFilterQuality(kLow_SkFilterQuality); 487 paint.setFilterQuality(kLow_SkFilterQuality);
496 break; 488 break;
497 case Stretch::kNone_Type: 489 case SkGrStretch::kNone_Type:
498 SkDEBUGFAIL("Shouldn't get here."); 490 SkDEBUGFAIL("Shouldn't get here.");
499 break; 491 break;
500 } 492 }
501 SkRect dstRect = SkRect::MakeWH(SkIntToScalar(stretch.fWidth), SkIntToScalar (stretch.fHeight)); 493 SkRect dstRect = SkRect::MakeWH(SkIntToScalar(stretch.fWidth), SkIntToScalar (stretch.fHeight));
502 canvas.drawBitmapRect(bmp, dstRect, &paint); 494 canvas.drawBitmapRect(bmp, dstRect, &paint);
503 return stretched; 495 return stretched;
504 } 496 }
505 497
506 static GrTexture* create_bitmap_texture(GrContext* ctx,
507 const SkBitmap& bmp,
508 const Stretch& stretch,
509 const GrUniqueKey& unstretchedKey,
510 const GrUniqueKey& stretchedKey) {
511 if (Stretch::kNone_Type != stretch.fType) {
512 SkAutoTUnref<GrTexture> unstretched;
513 // Check if we have the unstretched version in the cache, if not create it.
514 if (unstretchedKey.isValid()) {
515 unstretched.reset(ctx->textureProvider()->findAndRefTextureByUniqueK ey(unstretchedKey));
516 }
517 if (!unstretched) {
518 unstretched.reset(create_unstretched_bitmap_texture(ctx, bmp, unstre tchedKey));
519 if (!unstretched) {
520 // We might not have been able to create a unstrecthed texture b ecause it is smaller
521 // than the min texture size. In that case do cpu stretching.
522 SkBitmap stretchedBmp = stretch_on_cpu(bmp, stretch);
523 return create_unstretched_bitmap_texture(ctx, stretchedBmp, stre tchedKey);
524 }
525 }
526 return stretch_texture(unstretched, stretch, bmp.pixelRef(), stretchedKe y);
527 }
528 return create_unstretched_bitmap_texture(ctx, bmp, unstretchedKey);
529 }
530
531 bool GrIsImageInCache(const GrContext* ctx, uint32_t imageID, const SkIRect& sub set, 498 bool GrIsImageInCache(const GrContext* ctx, uint32_t imageID, const SkIRect& sub set,
532 GrTexture* nativeTexture, const GrTextureParams* params) { 499 GrTexture* nativeTexture, const GrTextureParams* params) {
533 Stretch stretch; 500 SkGrStretch stretch;
534 get_stretch(ctx, subset.width(), subset.height(), params, &stretch); 501 get_stretch(ctx, subset.width(), subset.height(), params, &stretch);
535 502
536 // Handle the case where the bitmap/image is explicitly texture backed. 503 // Handle the case where the bitmap/image is explicitly texture backed.
537 if (nativeTexture) { 504 if (nativeTexture) {
538 if (Stretch::kNone_Type == stretch.fType) { 505 if (SkGrStretch::kNone_Type == stretch.fType) {
539 return true; 506 return true;
540 } 507 }
541 const GrUniqueKey& key = nativeTexture->getUniqueKey(); 508 const GrUniqueKey& key = nativeTexture->getUniqueKey();
542 if (!key.isValid()) { 509 if (!key.isValid()) {
543 return false; 510 return false;
544 } 511 }
545 GrUniqueKey stretchedKey; 512 GrUniqueKey stretchedKey;
546 make_stretched_key(key, stretch, &stretchedKey); 513 make_stretched_key(key, stretch, &stretchedKey);
547 return ctx->textureProvider()->existsTextureWithUniqueKey(stretchedKey); 514 return ctx->textureProvider()->existsTextureWithUniqueKey(stretchedKey);
548 } 515 }
549 516
550 GrUniqueKey key, stretchedKey; 517 GrUniqueKey key, stretchedKey;
551 make_image_keys(imageID, subset, stretch, &key, &stretchedKey); 518 make_image_keys(imageID, subset, stretch, &key, &stretchedKey);
552 return ctx->textureProvider()->existsTextureWithUniqueKey( 519 return ctx->textureProvider()->existsTextureWithUniqueKey(
553 (Stretch::kNone_Type == stretch.fType) ? key : stretchedKey); 520 (SkGrStretch::kNone_Type == stretch.fType) ? key : stretchedKey);
554 } 521 }
555 522
556 bool GrIsBitmapInCache(const GrContext* ctx, const SkBitmap& bitmap, 523 bool GrIsBitmapInCache(const GrContext* ctx, const SkBitmap& bitmap,
557 const GrTextureParams* params) { 524 const GrTextureParams* params) {
558 if (bitmap.isVolatile()) { 525 if (bitmap.isVolatile()) {
559 return false; // we don't cache volatile bitmaps. 526 return false; // we don't cache volatile bitmaps.
560 } 527 }
561 return GrIsImageInCache(ctx, bitmap.getGenerationID(), bitmap.getSubset(), b itmap.getTexture(), 528 return GrIsImageInCache(ctx, bitmap.getGenerationID(), bitmap.getSubset(), b itmap.getTexture(),
562 params); 529 params);
563 } 530 }
564 531
565 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, 532 class Bitmap_GrTextureMaker : public GrTextureMaker {
566 const SkBitmap& bitmap, 533 public:
567 const GrTextureParams* params) { 534 Bitmap_GrTextureMaker(const SkBitmap& bitmap)
535 : INHERITED(bitmap.width(), bitmap.height())
536 , fBitmap(bitmap)
537 {}
568 538
569 Stretch stretch; 539 protected:
570 get_stretch(ctx, bitmap.width(), bitmap.height(), params, &stretch); 540 GrTexture* onRefUnstretchedTexture(GrContext* ctx) override {
541 GrTexture* tex = fBitmap.getTexture();
542 if (tex) {
543 return SkRef(tex);
544 }
571 545
572 GrTexture* result = bitmap.getTexture(); 546 GrUniqueKey unstretchedKey;
573 if (result) { 547 make_unstretched_key(&unstretchedKey, fBitmap.getGenerationID(), fBitmap .getSubset());
574 if (Stretch::kNone_Type == stretch.fType) {
575 return SkRef(result);
576 }
577 GrUniqueKey stretchedKey;
578 // Don't create a key for the resized version if the bmp is volatile.
579 if (!bitmap.isVolatile()) {
580 const GrUniqueKey& key = result->getUniqueKey();
581 if (key.isValid()) {
582 make_stretched_key(key, stretch, &stretchedKey);
583 GrTexture* stretched =
584 ctx->textureProvider()->findAndRefTextureByUniqueKey(stretch edKey);
585 if (stretched) {
586 return stretched;
587 }
588 }
589 }
590 return stretch_texture(result, stretch, bitmap.pixelRef(), stretchedKey) ;
591 }
592 548
593 GrUniqueKey key, resizedKey; 549 GrTexture* result = ctx->textureProvider()->findAndRefTextureByUniqueKey (unstretchedKey);
594
595 if (!bitmap.isVolatile()) {
596 // If the bitmap isn't changing try to find a cached copy first.
597 make_image_keys(bitmap.getGenerationID(), bitmap.getSubset(), stretch, & key, &resizedKey);
598
599 result = ctx->textureProvider()->findAndRefTextureByUniqueKey(
600 resizedKey.isValid() ? resizedKey : key);
601 if (result) { 550 if (result) {
602 return result; 551 return result;
603 } 552 }
553 return create_unstretched_bitmap_texture(ctx, fBitmap, unstretchedKey);
604 } 554 }
605 555
606 result = create_bitmap_texture(ctx, bitmap, stretch, key, resizedKey); 556 bool onMakeStretchedKey(const SkGrStretch& stretch, GrUniqueKey* stretchedKe y) override {
607 if (result) { 557 if (fBitmap.isVolatile()) {
608 return result; 558 return false;
559 }
560
561 GrUniqueKey unstretchedKey;
562 make_unstretched_key(&unstretchedKey, fBitmap.getGenerationID(), fBitmap .getSubset());
563 return make_stretched_key(unstretchedKey, stretch, stretchedKey);
609 } 564 }
610 565
611 SkErrorInternals::SetError( kInternalError_SkError, 566 void onNotifyStretchCached(const GrUniqueKey& stretchedKey) override {
612 "---- failed to create texture for cache [%d %d] \n", 567 fBitmap.pixelRef()->addGenIDChangeListener(new BitmapInvalidator(stretch edKey));
613 bitmap.width(), bitmap.height()); 568 }
614 569
615 return nullptr; 570 bool onGetROBitmap(SkBitmap* bitmap) override {
571 *bitmap = fBitmap;
572 return true;
573 }
574
575 private:
576 const SkBitmap fBitmap;
577
578 typedef GrTextureMaker INHERITED;
579 };
580
581 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, const SkBitmap& bitmap,
582 const GrTextureParams* params) {
583 return Bitmap_GrTextureMaker(bitmap).refCachedTexture(ctx, params);
616 } 584 }
617 585
618 // TODO: make this be the canonical signature, and turn the version that takes G rTextureParams* 586 // TODO: make this be the canonical signature, and turn the version that takes G rTextureParams*
619 // into a wrapper that contains the inverse of these tables. 587 // into a wrapper that contains the inverse of these tables.
620 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, 588 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx,
621 const SkBitmap& bitmap, 589 const SkBitmap& bitmap,
622 SkImageUsageType usage) { 590 SkImageUsageType usage) {
623 // Just need a params that will trigger the correct cache key / etc, since t he usage doesn't 591 // Just need a params that will trigger the correct cache key / etc, since t he usage doesn't
624 // tell us the specifics about filter level or specific tiling. 592 // tell us the specifics about filter level or specific tiling.
625 593
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
941 SkErrorInternals::SetError( kInvalidPaint_SkError, 909 SkErrorInternals::SetError( kInvalidPaint_SkError,
942 "Sorry, I don't understand the filtering " 910 "Sorry, I don't understand the filtering "
943 "mode you asked for. Falling back to " 911 "mode you asked for. Falling back to "
944 "MIPMaps."); 912 "MIPMaps.");
945 textureFilterMode = GrTextureParams::kMipMap_FilterMode; 913 textureFilterMode = GrTextureParams::kMipMap_FilterMode;
946 break; 914 break;
947 915
948 } 916 }
949 return textureFilterMode; 917 return textureFilterMode;
950 } 918 }
919
920 //////////////////////////////////////////////////////////////////////////////// ////////////////
921
922 GrTexture* GrTextureMaker::refCachedTexture(GrContext* ctx, const GrTextureParam s* params) {
923 SkGrStretch stretch;
924 get_stretch(ctx, this->width(), this->height(), params, &stretch);
925
926 if (SkGrStretch::kNone_Type == stretch.fType) {
927 return this->onRefUnstretchedTexture(ctx);
928 }
929
930 GrUniqueKey stretchedKey;
931 if (this->onMakeStretchedKey(stretch, &stretchedKey)) {
932 GrTexture* result = ctx->textureProvider()->findAndRefTextureByUniqueKey (stretchedKey);
933 if (result) {
934 return result;
935 }
936 }
937
938 GrTexture* result = this->onGenerateStretchedTexture(ctx, stretch);
939 if (!result) {
940 return nullptr;
941 }
942
943 if (stretchedKey.isValid()) {
944 ctx->textureProvider()->assignUniqueKeyToTexture(stretchedKey, result);
945 this->onNotifyStretchCached(stretchedKey);
946 }
947 return result;
948 }
949
950 GrTexture* GrTextureMaker::onGenerateStretchedTexture(GrContext* ctx, const SkGr Stretch& stretch) {
951 if (this->width() < ctx->caps()->minTextureSize() ||
952 this->height() < ctx->caps()->minTextureSize())
953 {
954 // we can't trust our ability to use HW to perform the stretch, so we re quest
955 // a raster instead, and perform the stretch on the CPU.
956 SkBitmap bitmap;
957 if (!this->onGetROBitmap(&bitmap)) {
958 return nullptr;
959 }
960 SkBitmap stretchedBmp = stretch_on_cpu(bitmap, stretch);
961 return create_unstretched_bitmap_texture(ctx, stretchedBmp, GrUniqueKey( ));
962 } else {
963 SkAutoTUnref<GrTexture> unstretched(this->onRefUnstretchedTexture(ctx));
964 if (!unstretched) {
965 return nullptr;
966 }
967 return stretch_texture(unstretched, stretch, nullptr, GrUniqueKey());
968 }
969 }
OLDNEW
« no previous file with comments | « src/gpu/GrTextureMaker.h ('k') | src/gpu/SkGrPriv.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698