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 "SkGr.h" | 8 #include "SkGr.h" |
9 | 9 |
10 #include "GrCaps.h" | 10 #include "GrCaps.h" |
11 #include "GrDrawContext.h" | 11 #include "GrDrawContext.h" |
12 #include "GrXferProcessor.h" | 12 #include "GrXferProcessor.h" |
13 #include "SkColorFilter.h" | 13 #include "SkColorFilter.h" |
14 #include "SkConfig8888.h" | 14 #include "SkConfig8888.h" |
| 15 #include "SkCanvas.h" |
15 #include "SkData.h" | 16 #include "SkData.h" |
16 #include "SkErrorInternals.h" | 17 #include "SkErrorInternals.h" |
17 #include "SkGrPixelRef.h" | 18 #include "SkGrPixelRef.h" |
18 #include "SkMessageBus.h" | 19 #include "SkMessageBus.h" |
19 #include "SkPixelRef.h" | 20 #include "SkPixelRef.h" |
20 #include "SkResourceCache.h" | 21 #include "SkResourceCache.h" |
21 #include "SkTextureCompressor.h" | 22 #include "SkTextureCompressor.h" |
22 #include "SkYUVPlanesCache.h" | 23 #include "SkYUVPlanesCache.h" |
23 #include "effects/GrDitherEffect.h" | 24 #include "effects/GrDitherEffect.h" |
24 #include "effects/GrPorterDuffXferProcessor.h" | 25 #include "effects/GrPorterDuffXferProcessor.h" |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 int fHeight; | 99 int fHeight; |
99 }; | 100 }; |
100 | 101 |
101 static void get_stretch(const GrContext* ctx, int width, int height, | 102 static void get_stretch(const GrContext* ctx, int width, int height, |
102 const GrTextureParams* params, Stretch* stretch) { | 103 const GrTextureParams* params, Stretch* stretch) { |
103 stretch->fType = Stretch::kNone_Type; | 104 stretch->fType = Stretch::kNone_Type; |
104 bool doStretch = false; | 105 bool doStretch = false; |
105 if (params && params->isTiled() && !ctx->caps()->npotTextureTileSupport() && | 106 if (params && params->isTiled() && !ctx->caps()->npotTextureTileSupport() && |
106 (!SkIsPow2(width) || !SkIsPow2(height))) { | 107 (!SkIsPow2(width) || !SkIsPow2(height))) { |
107 doStretch = true; | 108 doStretch = true; |
108 stretch->fWidth = GrNextPow2(width); | 109 stretch->fWidth = GrNextPow2(SkTMax(width, ctx->caps()->minTextureSize(
))); |
109 stretch->fHeight = GrNextPow2(height); | 110 stretch->fHeight = GrNextPow2(SkTMax(height, ctx->caps()->minTextureSize
())); |
110 } else if (width < ctx->caps()->minTextureSize() || | 111 } else if (width < ctx->caps()->minTextureSize() || height < ctx->caps()->mi
nTextureSize()) { |
111 height < ctx->caps()->minTextureSize()) { | |
112 // The small texture issues appear to be with tiling. Hence it seems ok
to scale them | 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. | 113 // up using the GPU. If issues persist we may need to CPU-stretch. |
114 doStretch = true; | 114 doStretch = true; |
115 stretch->fWidth = SkTMax(width, ctx->caps()->minTextureSize()); | 115 stretch->fWidth = SkTMax(width, ctx->caps()->minTextureSize()); |
116 stretch->fHeight = SkTMax(height, ctx->caps()->minTextureSize()); | 116 stretch->fHeight = SkTMax(height, ctx->caps()->minTextureSize()); |
117 } | 117 } |
118 if (doStretch) { | 118 if (doStretch) { |
119 if (params) { | 119 if (params) { |
120 switch(params->filterMode()) { | 120 switch(params->filterMode()) { |
121 case GrTextureParams::kNone_FilterMode: | 121 case GrTextureParams::kNone_FilterMode: |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 } | 443 } |
444 | 444 |
445 drawContext->drawRect(renderTarget, GrClip::WideOpen(), paint, SkMatrix::I()
, r); | 445 drawContext->drawRect(renderTarget, GrClip::WideOpen(), paint, SkMatrix::I()
, r); |
446 | 446 |
447 return result; | 447 return result; |
448 } | 448 } |
449 | 449 |
450 static GrTexture* create_unstretched_bitmap_texture(GrContext* ctx, | 450 static GrTexture* create_unstretched_bitmap_texture(GrContext* ctx, |
451 const SkBitmap& origBitmap, | 451 const SkBitmap& origBitmap, |
452 const GrUniqueKey& optionalK
ey) { | 452 const GrUniqueKey& optionalK
ey) { |
| 453 if (origBitmap.width() < ctx->caps()->minTextureSize() || |
| 454 origBitmap.height() < ctx->caps()->minTextureSize()) { |
| 455 return NULL; |
| 456 } |
453 SkBitmap tmpBitmap; | 457 SkBitmap tmpBitmap; |
454 | 458 |
455 const SkBitmap* bitmap = &origBitmap; | 459 const SkBitmap* bitmap = &origBitmap; |
456 | 460 |
457 GrSurfaceDesc desc; | 461 GrSurfaceDesc desc; |
458 generate_bitmap_texture_desc(*bitmap, &desc); | 462 generate_bitmap_texture_desc(*bitmap, &desc); |
459 const GrCaps* caps = ctx->caps(); | 463 const GrCaps* caps = ctx->caps(); |
460 | 464 |
461 if (kIndex_8_SkColorType == bitmap->colorType()) { | 465 if (kIndex_8_SkColorType == bitmap->colorType()) { |
462 if (caps->isConfigTexturable(kIndex_8_GrPixelConfig)) { | 466 if (caps->isConfigTexturable(kIndex_8_GrPixelConfig)) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
501 | 505 |
502 SkAutoLockPixels alp(*bitmap); | 506 SkAutoLockPixels alp(*bitmap); |
503 if (!bitmap->readyToDraw()) { | 507 if (!bitmap->readyToDraw()) { |
504 return NULL; | 508 return NULL; |
505 } | 509 } |
506 | 510 |
507 return create_texture_for_bmp(ctx, optionalKey, desc, origBitmap.pixelRef(), | 511 return create_texture_for_bmp(ctx, optionalKey, desc, origBitmap.pixelRef(), |
508 bitmap->getPixels(), bitmap->rowBytes()); | 512 bitmap->getPixels(), bitmap->rowBytes()); |
509 } | 513 } |
510 | 514 |
| 515 static SkBitmap stretch_on_cpu(const SkBitmap& bmp, const Stretch& stretch) { |
| 516 SkBitmap stretched; |
| 517 stretched.allocN32Pixels(stretch.fWidth, stretch.fHeight); |
| 518 SkCanvas canvas(stretched); |
| 519 SkPaint paint; |
| 520 switch (stretch.fType) { |
| 521 case Stretch::kNearest_Type: |
| 522 paint.setFilterQuality(kNone_SkFilterQuality); |
| 523 break; |
| 524 case Stretch::kBilerp_Type: |
| 525 paint.setFilterQuality(kLow_SkFilterQuality); |
| 526 break; |
| 527 case Stretch::kNone_Type: |
| 528 SkDEBUGFAIL("Shouldn't get here."); |
| 529 break; |
| 530 } |
| 531 SkRect dstRect = SkRect::MakeWH(SkIntToScalar(stretch.fWidth), SkIntToScalar
(stretch.fHeight)); |
| 532 canvas.drawBitmapRectToRect(bmp, NULL, dstRect, &paint); |
| 533 return stretched; |
| 534 } |
| 535 |
511 static GrTexture* create_bitmap_texture(GrContext* ctx, | 536 static GrTexture* create_bitmap_texture(GrContext* ctx, |
512 const SkBitmap& bmp, | 537 const SkBitmap& bmp, |
513 const Stretch& stretch, | 538 const Stretch& stretch, |
514 const GrUniqueKey& unstretchedKey, | 539 const GrUniqueKey& unstretchedKey, |
515 const GrUniqueKey& stretchedKey) { | 540 const GrUniqueKey& stretchedKey) { |
516 if (Stretch::kNone_Type != stretch.fType) { | 541 if (Stretch::kNone_Type != stretch.fType) { |
517 SkAutoTUnref<GrTexture> unstretched; | 542 SkAutoTUnref<GrTexture> unstretched; |
518 // Check if we have the unstretched version in the cache, if not create
it. | 543 // Check if we have the unstretched version in the cache, if not create
it. |
519 if (unstretchedKey.isValid()) { | 544 if (unstretchedKey.isValid()) { |
520 unstretched.reset(ctx->textureProvider()->findAndRefTextureByUniqueK
ey(unstretchedKey)); | 545 unstretched.reset(ctx->textureProvider()->findAndRefTextureByUniqueK
ey(unstretchedKey)); |
521 } | 546 } |
522 if (!unstretched) { | 547 if (!unstretched) { |
523 unstretched.reset(create_unstretched_bitmap_texture(ctx, bmp, unstre
tchedKey)); | 548 unstretched.reset(create_unstretched_bitmap_texture(ctx, bmp, unstre
tchedKey)); |
524 if (!unstretched) { | 549 if (!unstretched) { |
525 return NULL; | 550 // We might not have been able to create a unstrecthed texture b
ecause it is smaller |
| 551 // than the min texture size. In that case do cpu stretching. |
| 552 SkBitmap stretchedBmp = stretch_on_cpu(bmp, stretch); |
| 553 return create_unstretched_bitmap_texture(ctx, stretchedBmp, stre
tchedKey); |
526 } | 554 } |
527 } | 555 } |
528 GrTexture* stretched = stretch_texture(unstretched, stretch, bmp.pixelRe
f(), stretchedKey); | 556 return stretch_texture(unstretched, stretch, bmp.pixelRef(), stretchedKe
y); |
529 return stretched; | |
530 } | 557 } |
531 | |
532 return create_unstretched_bitmap_texture(ctx, bmp, unstretchedKey); | 558 return create_unstretched_bitmap_texture(ctx, bmp, unstretchedKey); |
533 | |
534 } | 559 } |
535 | 560 |
536 bool GrIsBitmapInCache(const GrContext* ctx, | 561 bool GrIsBitmapInCache(const GrContext* ctx, |
537 const SkBitmap& bitmap, | 562 const SkBitmap& bitmap, |
538 const GrTextureParams* params) { | 563 const GrTextureParams* params) { |
539 Stretch stretch; | 564 Stretch stretch; |
540 get_stretch(ctx, bitmap.width(), bitmap.height(), params, &stretch); | 565 get_stretch(ctx, bitmap.width(), bitmap.height(), params, &stretch); |
541 | 566 |
542 // Handle the case where the bitmap is explicitly texture backed. | 567 // Handle the case where the bitmap is explicitly texture backed. |
543 GrTexture* texture = bitmap.getTexture(); | 568 GrTexture* texture = bitmap.getTexture(); |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
801 } | 826 } |
802 return SkImageInfo::Make(w, h, ct, at); | 827 return SkImageInfo::Make(w, h, ct, at); |
803 } | 828 } |
804 | 829 |
805 | 830 |
806 void GrWrapTextureInBitmap(GrTexture* src, int w, int h, bool isOpaque, SkBitmap
* dst) { | 831 void GrWrapTextureInBitmap(GrTexture* src, int w, int h, bool isOpaque, SkBitmap
* dst) { |
807 const SkImageInfo info = GrMakeInfoFromTexture(src, w, h, isOpaque); | 832 const SkImageInfo info = GrMakeInfoFromTexture(src, w, h, isOpaque); |
808 dst->setInfo(info); | 833 dst->setInfo(info); |
809 dst->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, src)))->unref(); | 834 dst->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, src)))->unref(); |
810 } | 835 } |
OLD | NEW |