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

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

Issue 1161183002: Stretch small textures up to 16 pixels on PowerVR 54x (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: comments Created 5 years, 6 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/GrCaps.cpp ('k') | src/gpu/gl/GrGLCaps.cpp » ('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 "SkGr.h" 8 #include "SkGr.h"
9 9
10 #include "GrCaps.h" 10 #include "GrCaps.h"
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 for (int y = 0; y < bitmap.height(); y++) { 81 for (int y = 0; y < bitmap.height(); y++) {
82 memcpy(dst, src, width); 82 memcpy(dst, src, width);
83 src += rowBytes; 83 src += rowBytes;
84 dst += width; 84 dst += width;
85 } 85 }
86 } 86 }
87 } 87 }
88 88
89 //////////////////////////////////////////////////////////////////////////////// 89 ////////////////////////////////////////////////////////////////////////////////
90 90
91 enum Stretch { 91 struct Stretch {
92 kNo_Stretch, 92 enum Type {
93 kBilerp_Stretch, 93 kNone_Type,
94 kNearest_Stretch 94 kBilerp_Type,
95 kNearest_Type
96 } fType;
97 int fWidth;
98 int fHeight;
95 }; 99 };
96 100
97 static Stretch get_stretch_type(const GrContext* ctx, int width, int height, 101 static void get_stretch(const GrContext* ctx, int width, int height,
98 const GrTextureParams* params) { 102 const GrTextureParams* params, Stretch* stretch) {
99 if (params && params->isTiled()) { 103 stretch->fType = Stretch::kNone_Type;
100 if (!ctx->caps()->npotTextureTileSupport() && (!SkIsPow2(width) || !SkIs Pow2(height))) { 104 bool doStretch = false;
101 switch(params->filterMode()) { 105 if (params && params->isTiled() && !ctx->caps()->npotTextureTileSupport() &&
102 case GrTextureParams::kNone_FilterMode: 106 (!SkIsPow2(width) || !SkIsPow2(height))) {
103 return kNearest_Stretch; 107 doStretch = true;
104 case GrTextureParams::kBilerp_FilterMode: 108 stretch->fWidth = GrNextPow2(width);
105 case GrTextureParams::kMipMap_FilterMode: 109 stretch->fHeight = GrNextPow2(height);
106 return kBilerp_Stretch; 110 } else if (width < ctx->caps()->minTextureSize() ||
107 } 111 height < ctx->caps()->minTextureSize()) {
112 // The small texture issues appear to be with tiling. Hence it seems ok to scale them
113 // up using the GPU. If issues persist we may need to CPU-stretch.
114 doStretch = true;
115 stretch->fWidth = SkTMax(width, ctx->caps()->minTextureSize());
116 stretch->fHeight = SkTMax(height, ctx->caps()->minTextureSize());
117 }
118 if (doStretch) {
119 switch(params->filterMode()) {
120 case GrTextureParams::kNone_FilterMode:
121 stretch->fType = Stretch::kNearest_Type;
122 break;
123 case GrTextureParams::kBilerp_FilterMode:
124 case GrTextureParams::kMipMap_FilterMode:
125 stretch->fType = Stretch::kBilerp_Type;
126 break;
108 } 127 }
128 } else {
129 stretch->fWidth = -1;
130 stretch->fHeight = -1;
131 stretch->fType = Stretch::kNone_Type;
109 } 132 }
110 return kNo_Stretch;
111 } 133 }
112 134
113 static bool make_stretched_key(const GrUniqueKey& origKey, Stretch stretch, 135 static bool make_stretched_key(const GrUniqueKey& origKey, const Stretch& stretc h,
114 GrUniqueKey* stretchedKey) { 136 GrUniqueKey* stretchedKey) {
115 if (origKey.isValid() && kNo_Stretch != stretch) { 137 if (origKey.isValid() && Stretch::kNone_Type != stretch.fType) {
138 uint32_t width = SkToU16(stretch.fWidth);
139 uint32_t height = SkToU16(stretch.fHeight);
116 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain() ; 140 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain() ;
117 GrUniqueKey::Builder builder(stretchedKey, origKey, kDomain, 1); 141 GrUniqueKey::Builder builder(stretchedKey, origKey, kDomain, 3);
118 builder[0] = stretch; 142 builder[0] = stretch.fType;
143 builder[1] = width | (height << 16);
119 builder.finish(); 144 builder.finish();
120 return true; 145 return true;
121 } 146 }
122 SkASSERT(!stretchedKey->isValid()); 147 SkASSERT(!stretchedKey->isValid());
123 return false; 148 return false;
124 } 149 }
125 150
126 static void make_unstretched_key(const SkBitmap& bitmap, GrUniqueKey* key) { 151 static void make_unstretched_key(const SkBitmap& bitmap, GrUniqueKey* key) {
127 // Our id includes the offset, width, and height so that bitmaps created by extractSubset() 152 // Our id includes the offset, width, and height so that bitmaps created by extractSubset()
128 // are unique. 153 // are unique.
129 uint32_t genID = bitmap.getGenerationID(); 154 uint32_t genID = bitmap.getGenerationID();
130 SkIPoint origin = bitmap.pixelRefOrigin(); 155 SkIPoint origin = bitmap.pixelRefOrigin();
131 uint32_t width = SkToU16(bitmap.width()); 156 uint32_t width = SkToU16(bitmap.width());
132 uint32_t height = SkToU16(bitmap.height()); 157 uint32_t height = SkToU16(bitmap.height());
133 158
134 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); 159 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
135 GrUniqueKey::Builder builder(key, kDomain, 4); 160 GrUniqueKey::Builder builder(key, kDomain, 4);
136 builder[0] = genID; 161 builder[0] = genID;
137 builder[1] = origin.fX; 162 builder[1] = origin.fX;
138 builder[2] = origin.fY; 163 builder[2] = origin.fY;
139 builder[3] = width | (height << 16); 164 builder[3] = width | (height << 16);
140 } 165 }
141 166
142 static void make_bitmap_keys(const SkBitmap& bitmap, 167 static void make_bitmap_keys(const SkBitmap& bitmap,
143 Stretch stretch, 168 const Stretch& stretch,
144 GrUniqueKey* key, 169 GrUniqueKey* key,
145 GrUniqueKey* stretchedKey) { 170 GrUniqueKey* stretchedKey) {
146 make_unstretched_key(bitmap, key); 171 make_unstretched_key(bitmap, key);
147 if (kNo_Stretch != stretch) { 172 if (Stretch::kNone_Type != stretch.fType) {
148 make_stretched_key(*key, stretch, stretchedKey); 173 make_stretched_key(*key, stretch, stretchedKey);
149 } 174 }
150 } 175 }
151 176
152 static void generate_bitmap_texture_desc(const SkBitmap& bitmap, GrSurfaceDesc* desc) { 177 static void generate_bitmap_texture_desc(const SkBitmap& bitmap, GrSurfaceDesc* desc) {
153 desc->fFlags = kNone_GrSurfaceFlags; 178 desc->fFlags = kNone_GrSurfaceFlags;
154 desc->fWidth = bitmap.width(); 179 desc->fWidth = bitmap.width();
155 desc->fHeight = bitmap.height(); 180 desc->fHeight = bitmap.height();
156 desc->fConfig = SkImageInfo2GrPixelConfig(bitmap.info()); 181 desc->fConfig = SkImageInfo2GrPixelConfig(bitmap.info());
157 desc->fSampleCnt = 0; 182 desc->fSampleCnt = 0;
(...skipping 24 matching lines...) Expand all
182 size_t rowBytes) { 207 size_t rowBytes) {
183 GrTexture* result = ctx->textureProvider()->createTexture(desc, true, pixels , rowBytes); 208 GrTexture* result = ctx->textureProvider()->createTexture(desc, true, pixels , rowBytes);
184 if (result && optionalKey.isValid()) { 209 if (result && optionalKey.isValid()) {
185 BitmapInvalidator* listener = SkNEW_ARGS(BitmapInvalidator, (optionalKey )); 210 BitmapInvalidator* listener = SkNEW_ARGS(BitmapInvalidator, (optionalKey ));
186 pixelRefForInvalidationNotification->addGenIDChangeListener(listener); 211 pixelRefForInvalidationNotification->addGenIDChangeListener(listener);
187 ctx->textureProvider()->assignUniqueKeyToTexture(optionalKey, result); 212 ctx->textureProvider()->assignUniqueKeyToTexture(optionalKey, result);
188 } 213 }
189 return result; 214 return result;
190 } 215 }
191 216
192 // creates a new texture that is the input texture scaled up to the next power o f two in 217 // creates a new texture that is the input texture scaled up. If optionalKey is valid it will be
193 // width or height. If optionalKey is valid it will be set on the new texture. s tretch 218 // set on the new texture. stretch controls whether the scaling is done using ne arest or bilerp
194 // controls whether the scaling is done using nearest or bilerp filtering. 219 // filtering and the size to stretch the texture to.
195 GrTexture* stretch_texture_to_next_pot(GrTexture* inputTexture, Stretch stretch, 220 GrTexture* stretch_texture(GrTexture* inputTexture, const Stretch& stretch,
196 SkPixelRef* pixelRef, 221 SkPixelRef* pixelRef,
197 const GrUniqueKey& optionalKey) { 222 const GrUniqueKey& optionalKey) {
198 SkASSERT(kNo_Stretch != stretch); 223 SkASSERT(Stretch::kNone_Type != stretch.fType);
199 224
200 GrContext* context = inputTexture->getContext(); 225 GrContext* context = inputTexture->getContext();
201 SkASSERT(context); 226 SkASSERT(context);
202 const GrCaps* caps = context->caps(); 227 const GrCaps* caps = context->caps();
203 228
204 // Either it's a cache miss or the original wasn't cached to begin with. 229 // Either it's a cache miss or the original wasn't cached to begin with.
205 GrSurfaceDesc rtDesc = inputTexture->desc(); 230 GrSurfaceDesc rtDesc = inputTexture->desc();
206 rtDesc.fFlags = rtDesc.fFlags | kRenderTarget_GrSurfaceFlag; 231 rtDesc.fFlags = rtDesc.fFlags | kRenderTarget_GrSurfaceFlag;
207 rtDesc.fWidth = GrNextPow2(rtDesc.fWidth); 232 rtDesc.fWidth = stretch.fWidth;
208 rtDesc.fHeight = GrNextPow2(rtDesc.fHeight); 233 rtDesc.fHeight = stretch.fHeight;
209 rtDesc.fConfig = GrMakePixelConfigUncompressed(rtDesc.fConfig); 234 rtDesc.fConfig = GrMakePixelConfigUncompressed(rtDesc.fConfig);
210 235
211 // If the config isn't renderable try converting to either A8 or an 32 bit c onfig. Otherwise, 236 // If the config isn't renderable try converting to either A8 or an 32 bit c onfig. Otherwise,
212 // fail. 237 // fail.
213 if (!caps->isConfigRenderable(rtDesc.fConfig, false)) { 238 if (!caps->isConfigRenderable(rtDesc.fConfig, false)) {
214 if (GrPixelConfigIsAlphaOnly(rtDesc.fConfig)) { 239 if (GrPixelConfigIsAlphaOnly(rtDesc.fConfig)) {
215 if (caps->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) { 240 if (caps->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
216 rtDesc.fConfig = kAlpha_8_GrPixelConfig; 241 rtDesc.fConfig = kAlpha_8_GrPixelConfig;
217 } else if (caps->isConfigRenderable(kSkia8888_GrPixelConfig, false)) { 242 } else if (caps->isConfigRenderable(kSkia8888_GrPixelConfig, false)) {
218 rtDesc.fConfig = kSkia8888_GrPixelConfig; 243 rtDesc.fConfig = kSkia8888_GrPixelConfig;
(...skipping 15 matching lines...) Expand all
234 GrTexture* stretched = create_texture_for_bmp(context, optionalKey, rtDesc, pixelRef, NULL, 0); 259 GrTexture* stretched = create_texture_for_bmp(context, optionalKey, rtDesc, pixelRef, NULL, 0);
235 260
236 if (!stretched) { 261 if (!stretched) {
237 return NULL; 262 return NULL;
238 } 263 }
239 GrPaint paint; 264 GrPaint paint;
240 265
241 // If filtering is not desired then we want to ensure all texels in the resa mpled image are 266 // If filtering is not desired then we want to ensure all texels in the resa mpled image are
242 // copies of texels from the original. 267 // copies of texels from the original.
243 GrTextureParams params(SkShader::kClamp_TileMode, 268 GrTextureParams params(SkShader::kClamp_TileMode,
244 kBilerp_Stretch == stretch ? GrTextureParams::kBilerp _FilterMode : 269 Stretch::kBilerp_Type == stretch.fType ?
245 GrTextureParams::kNone_F ilterMode); 270 GrTextureParams::kBilerp_FilterMode :
271 GrTextureParams::kNone_FilterMode);
246 paint.addColorTextureProcessor(inputTexture, SkMatrix::I(), params); 272 paint.addColorTextureProcessor(inputTexture, SkMatrix::I(), params);
247 273
248 SkRect rect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtD esc.fHeight)); 274 SkRect rect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtD esc.fHeight));
249 SkRect localRect = SkRect::MakeWH(1.f, 1.f); 275 SkRect localRect = SkRect::MakeWH(1.f, 1.f);
250 276
251 GrDrawContext* drawContext = context->drawContext(); 277 GrDrawContext* drawContext = context->drawContext();
252 if (!drawContext) { 278 if (!drawContext) {
253 return NULL; 279 return NULL;
254 } 280 }
255 281
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 if (!bitmap->readyToDraw()) { 498 if (!bitmap->readyToDraw()) {
473 return NULL; 499 return NULL;
474 } 500 }
475 501
476 return create_texture_for_bmp(ctx, optionalKey, desc, origBitmap.pixelRef(), 502 return create_texture_for_bmp(ctx, optionalKey, desc, origBitmap.pixelRef(),
477 bitmap->getPixels(), bitmap->rowBytes()); 503 bitmap->getPixels(), bitmap->rowBytes());
478 } 504 }
479 505
480 static GrTexture* create_bitmap_texture(GrContext* ctx, 506 static GrTexture* create_bitmap_texture(GrContext* ctx,
481 const SkBitmap& bmp, 507 const SkBitmap& bmp,
482 Stretch stretch, 508 const Stretch& stretch,
483 const GrUniqueKey& unstretchedKey, 509 const GrUniqueKey& unstretchedKey,
484 const GrUniqueKey& stretchedKey) { 510 const GrUniqueKey& stretchedKey) {
485 if (kNo_Stretch != stretch) { 511 if (Stretch::kNone_Type != stretch.fType) {
486 SkAutoTUnref<GrTexture> unstretched; 512 SkAutoTUnref<GrTexture> unstretched;
487 // Check if we have the unstretched version in the cache, if not create it. 513 // Check if we have the unstretched version in the cache, if not create it.
488 if (unstretchedKey.isValid()) { 514 if (unstretchedKey.isValid()) {
489 unstretched.reset(ctx->textureProvider()->findAndRefTextureByUniqueK ey(unstretchedKey)); 515 unstretched.reset(ctx->textureProvider()->findAndRefTextureByUniqueK ey(unstretchedKey));
490 } 516 }
491 if (!unstretched) { 517 if (!unstretched) {
492 unstretched.reset(create_unstretched_bitmap_texture(ctx, bmp, unstre tchedKey)); 518 unstretched.reset(create_unstretched_bitmap_texture(ctx, bmp, unstre tchedKey));
493 if (!unstretched) { 519 if (!unstretched) {
494 return NULL; 520 return NULL;
495 } 521 }
496 } 522 }
497 GrTexture* stretched = stretch_texture_to_next_pot(unstretched, stretch, bmp.pixelRef(), 523 GrTexture* stretched = stretch_texture(unstretched, stretch, bmp.pixelRe f(), stretchedKey);
498 stretchedKey);
499 return stretched; 524 return stretched;
500 } 525 }
501 526
502 return create_unstretched_bitmap_texture(ctx, bmp, unstretchedKey); 527 return create_unstretched_bitmap_texture(ctx, bmp, unstretchedKey);
503 528
504 } 529 }
505 530
506 bool GrIsBitmapInCache(const GrContext* ctx, 531 bool GrIsBitmapInCache(const GrContext* ctx,
507 const SkBitmap& bitmap, 532 const SkBitmap& bitmap,
508 const GrTextureParams* params) { 533 const GrTextureParams* params) {
509 Stretch stretch = get_stretch_type(ctx, bitmap.width(), bitmap.height(), par ams); 534 Stretch stretch;
535 get_stretch(ctx, bitmap.width(), bitmap.height(), params, &stretch);
510 536
511 // Handle the case where the bitmap is explicitly texture backed. 537 // Handle the case where the bitmap is explicitly texture backed.
512 GrTexture* texture = bitmap.getTexture(); 538 GrTexture* texture = bitmap.getTexture();
513 if (texture) { 539 if (texture) {
514 if (kNo_Stretch == stretch) { 540 if (Stretch::kNone_Type == stretch.fType) {
515 return true; 541 return true;
516 } 542 }
517 // No keys for volatile bitmaps. 543 // No keys for volatile bitmaps.
518 if (bitmap.isVolatile()) { 544 if (bitmap.isVolatile()) {
519 return false; 545 return false;
520 } 546 }
521 const GrUniqueKey& key = texture->getUniqueKey(); 547 const GrUniqueKey& key = texture->getUniqueKey();
522 if (!key.isValid()) { 548 if (!key.isValid()) {
523 return false; 549 return false;
524 } 550 }
525 GrUniqueKey stretchedKey; 551 GrUniqueKey stretchedKey;
526 make_stretched_key(key, stretch, &stretchedKey); 552 make_stretched_key(key, stretch, &stretchedKey);
527 return ctx->textureProvider()->existsTextureWithUniqueKey(stretchedKey); 553 return ctx->textureProvider()->existsTextureWithUniqueKey(stretchedKey);
528 } 554 }
529 555
530 // We don't cache volatile bitmaps 556 // We don't cache volatile bitmaps
531 if (bitmap.isVolatile()) { 557 if (bitmap.isVolatile()) {
532 return false; 558 return false;
533 } 559 }
534 560
535 GrUniqueKey key, stretchedKey; 561 GrUniqueKey key, stretchedKey;
536 make_bitmap_keys(bitmap, stretch, &key, &stretchedKey); 562 make_bitmap_keys(bitmap, stretch, &key, &stretchedKey);
537 return ctx->textureProvider()->existsTextureWithUniqueKey( 563 return ctx->textureProvider()->existsTextureWithUniqueKey(
538 (kNo_Stretch == stretch) ? key : stretchedKey); 564 (Stretch::kNone_Type == stretch.fType) ? key : stretchedKey);
539 } 565 }
540 566
541 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, 567 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx,
542 const SkBitmap& bitmap, 568 const SkBitmap& bitmap,
543 const GrTextureParams* params) { 569 const GrTextureParams* params) {
544 570
545 Stretch stretch = get_stretch_type(ctx, bitmap.width(), bitmap.height(), par ams); 571 Stretch stretch;
572 get_stretch(ctx, bitmap.width(), bitmap.height(), params, &stretch);
546 573
547 GrTexture* result = bitmap.getTexture(); 574 GrTexture* result = bitmap.getTexture();
548 if (result) { 575 if (result) {
549 if (kNo_Stretch == stretch) { 576 if (Stretch::kNone_Type == stretch.fType) {
550 return SkRef(result); 577 return SkRef(result);
551 } 578 }
552 GrUniqueKey stretchedKey; 579 GrUniqueKey stretchedKey;
553 // Don't create a key for the resized version if the bmp is volatile. 580 // Don't create a key for the resized version if the bmp is volatile.
554 if (!bitmap.isVolatile()) { 581 if (!bitmap.isVolatile()) {
555 const GrUniqueKey& key = result->getUniqueKey(); 582 const GrUniqueKey& key = result->getUniqueKey();
556 if (key.isValid()) { 583 if (key.isValid()) {
557 make_stretched_key(key, stretch, &stretchedKey); 584 make_stretched_key(key, stretch, &stretchedKey);
558 GrTexture* stretched = 585 GrTexture* stretched =
559 ctx->textureProvider()->findAndRefTextureByUniqueKey(stretch edKey); 586 ctx->textureProvider()->findAndRefTextureByUniqueKey(stretch edKey);
560 if (stretched) { 587 if (stretched) {
561 return stretched; 588 return stretched;
562 } 589 }
563 } 590 }
564 } 591 }
565 return stretch_texture_to_next_pot(result, stretch, bitmap.pixelRef(), s tretchedKey); 592 return stretch_texture(result, stretch, bitmap.pixelRef(), stretchedKey) ;
566 } 593 }
567 594
568 GrUniqueKey key, resizedKey; 595 GrUniqueKey key, resizedKey;
569 596
570 if (!bitmap.isVolatile()) { 597 if (!bitmap.isVolatile()) {
571 // If the bitmap isn't changing try to find a cached copy first. 598 // If the bitmap isn't changing try to find a cached copy first.
572 make_bitmap_keys(bitmap, stretch, &key, &resizedKey); 599 make_bitmap_keys(bitmap, stretch, &key, &resizedKey);
573 600
574 result = ctx->textureProvider()->findAndRefTextureByUniqueKey( 601 result = ctx->textureProvider()->findAndRefTextureByUniqueKey(
575 resizedKey.isValid() ? resizedKey : key); 602 resizedKey.isValid() ? resizedKey : key);
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 } 794 }
768 return SkImageInfo::Make(w, h, ct, at); 795 return SkImageInfo::Make(w, h, ct, at);
769 } 796 }
770 797
771 798
772 void GrWrapTextureInBitmap(GrTexture* src, int w, int h, bool isOpaque, SkBitmap * dst) { 799 void GrWrapTextureInBitmap(GrTexture* src, int w, int h, bool isOpaque, SkBitmap * dst) {
773 const SkImageInfo info = GrMakeInfoFromTexture(src, w, h, isOpaque); 800 const SkImageInfo info = GrMakeInfoFromTexture(src, w, h, isOpaque);
774 dst->setInfo(info); 801 dst->setInfo(info);
775 dst->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, src)))->unref(); 802 dst->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, src)))->unref();
776 } 803 }
OLDNEW
« no previous file with comments | « src/gpu/GrCaps.cpp ('k') | src/gpu/gl/GrGLCaps.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698