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

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

Powered by Google App Engine
This is Rietveld 408576698