Home | History | Annotate | Download | only in gm
      1 /*
      2  * Copyright 2013 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "gm.h"
      9 #include "SkCanvas.h"
     10 
     11 #if SK_SUPPORT_GPU
     12 #include "GrContext.h"
     13 
     14 namespace skiagm {
     15 extern GrContext* GetGr();
     16 };
     17 
     18 void GrContext::setMaxTextureSizeOverride(int maxTextureSizeOverride) {
     19     fMaxTextureSizeOverride = maxTextureSizeOverride;
     20 }
     21 #endif
     22 
     23 // Create a black&white checked texture with a 1-pixel red ring
     24 // around the outside edge
     25 static void make_red_ringed_bitmap(SkBitmap* result, int width, int height) {
     26     SkASSERT(0 == width % 2 && 0 == width % 2);
     27 
     28     result->setConfig(SkBitmap::kARGB_8888_Config, width, height);
     29     result->allocPixels();
     30     SkAutoLockPixels lock(*result);
     31 
     32     SkPMColor* scanline = result->getAddr32(0, 0);
     33     for (int x = 0; x < width; ++x) {
     34         scanline[x] = SK_ColorRED;
     35     }
     36 
     37     for (int y = 1; y < height/2; ++y) {
     38         scanline = result->getAddr32(0, y);
     39         scanline[0] = SK_ColorRED;
     40         for (int x = 1; x < width/2; ++x) {
     41             scanline[x] = SK_ColorBLACK;
     42         }
     43         for (int x = width/2; x < width-1; ++x) {
     44             scanline[x] = SK_ColorWHITE;
     45         }
     46         scanline[width-1] = SK_ColorRED;
     47     }
     48 
     49     for (int y = height/2; y < height-1; ++y) {
     50         scanline = result->getAddr32(0, y);
     51         scanline[0] = SK_ColorRED;
     52         for (int x = 1; x < width/2; ++x) {
     53             scanline[x] = SK_ColorWHITE;
     54         }
     55         for (int x = width/2; x < width-1; ++x) {
     56             scanline[x] = SK_ColorBLACK;
     57         }
     58         scanline[width-1] = SK_ColorRED;
     59     }
     60 
     61     scanline = result->getAddr32(0, height-1);
     62     for (int x = 0; x < width; ++x) {
     63         scanline[x] = SK_ColorRED;
     64     }
     65     result->setIsOpaque(true);
     66     result->setImmutable();
     67 }
     68 
     69 // This GM exercises the drawBitmapRectToRect "bleed" flag
     70 class BleedGM : public skiagm::GM {
     71 public:
     72     BleedGM() {}
     73 
     74 protected:
     75     virtual SkString onShortName() SK_OVERRIDE {
     76         return SkString("bleed");
     77     }
     78 
     79     virtual SkISize onISize() SK_OVERRIDE {
     80         return SkISize::Make(kWidth, kHeight);
     81     }
     82 
     83     virtual void onOnceBeforeDraw() SK_OVERRIDE {
     84         make_red_ringed_bitmap(&fBitmapSmall, kSmallTextureSize, kSmallTextureSize);
     85 
     86         // To exercise the GPU's tiling path we need a texture
     87         // too big for the GPU to handle in one go
     88         make_red_ringed_bitmap(&fBitmapBig, 2*kMaxTextureSize, 2*kMaxTextureSize);
     89     }
     90 
     91     virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
     92 #if SK_SUPPORT_GPU
     93         GrContext* ctx = skiagm::GetGr();
     94         int oldMaxTextureSize = 0;
     95         if (NULL != ctx) {
     96             // shrink the max texture size so all our textures can be reasonably sized
     97             oldMaxTextureSize = ctx->getMaxTextureSize();
     98             ctx->setMaxTextureSizeOverride(kMaxTextureSize);
     99         }
    100 #endif
    101 
    102         canvas->clear(SK_ColorGRAY);
    103 
    104         SkPaint paint;
    105 
    106         // Bleeding only comes into play when filtering
    107         paint.setFilterBitmap(true);
    108 
    109         // carve out the center of the small bitmap
    110         SkRect src = SkRect::MakeXYWH(1, 1,
    111                                       kSmallTextureSize-2,
    112                                       kSmallTextureSize-2);
    113         SkRect dst = SkRect::MakeXYWH(10, 10, 100, 100);
    114 
    115         // first draw without bleeding
    116         canvas->drawBitmapRectToRect(fBitmapSmall, &src, dst, &paint);
    117 
    118         // then draw with bleeding
    119         dst = SkRect::MakeXYWH(120, 10, 100, 100);
    120         canvas->drawBitmapRectToRect(fBitmapSmall, &src, dst, &paint);
    121 
    122         // Next test out the GPU's tiling of large textures
    123 
    124         // first draw almost the whole thing
    125         src = SkRect::MakeXYWH(1, 1,
    126                                SkIntToScalar(fBitmapBig.width()-2),
    127                                SkIntToScalar(fBitmapBig.height()-2));
    128         dst = SkRect::MakeXYWH(10, 120, 100, 100);
    129 
    130         // first without bleeding
    131         canvas->drawBitmapRectToRect(fBitmapBig, &src, dst, &paint);
    132 
    133         // then with bleeding
    134         dst = SkRect::MakeXYWH(120, 120, 100, 100);
    135         canvas->drawBitmapRectToRect(fBitmapBig, &src, dst, &paint);
    136 
    137         // next draw ~1/4 of the bitmap
    138         src = SkRect::MakeXYWH(1, 1,
    139                                SkIntToScalar(fBitmapBig.width()/2-1),
    140                                SkIntToScalar(fBitmapBig.height()/2-1));
    141         dst = SkRect::MakeXYWH(10, 230, 100, 100);
    142 
    143         // first without bleeding
    144         canvas->drawBitmapRectToRect(fBitmapBig, &src, dst, &paint);
    145 
    146         // then with bleeding
    147         dst = SkRect::MakeXYWH(120, 230, 100, 100);
    148         canvas->drawBitmapRectToRect(fBitmapBig, &src, dst, &paint);
    149 
    150 #if SK_SUPPORT_GPU
    151         if (NULL != ctx) {
    152             ctx->setMaxTextureSizeOverride(oldMaxTextureSize);
    153         }
    154 #endif
    155     }
    156 
    157 private:
    158     static const int kWidth = 230;
    159     static const int kHeight = 340;
    160 
    161     static const int kSmallTextureSize = 4;
    162     static const int kMaxTextureSize = 32;
    163 
    164     SkBitmap fBitmapSmall;
    165     SkBitmap fBitmapBig;
    166 
    167     typedef GM INHERITED;
    168 };
    169 
    170 DEF_GM( return new BleedGM(); )
    171