Home | History | Annotate | Download | only in samplecode
      1 /*
      2  * Copyright 2014 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 "SampleCode.h"
     10 #include "SkRandom.h"
     11 #include "SkUtils.h"
     12 #if SK_SUPPORT_GPU
     13 #include "GrRectanizer_pow2.h"
     14 #include "GrRectanizer_skyline.h"
     15 
     16 
     17 // This slide visualizes the various GrRectanizer-derived classes behavior
     18 // for various input sets
     19 //  'j' will cycle through the various rectanizers
     20 //          Pow2 -> GrRectanizerPow2
     21 //          Skyline -> GrRectanizerSkyline
     22 //  'h' will cycle through the various rect sets
     23 //          Rand -> random rects from 2-256
     24 //          Pow2Rand -> random power of 2 sized rects from 2-256
     25 //          SmallPow2 -> 128x128 rects
     26 class RectanizerView : public SampleView {
     27 public:
     28     RectanizerView()
     29         : fCurRandRect(0) {
     30         for (int i = 0; i < 3; ++i) {
     31            fRects[i].setReserve(kNumRandRects);
     32         }
     33         fRectLocations.setReserve(kNumRandRects);
     34 
     35         SkRandom random;
     36         for (int i = 0; i < kNumRandRects; ++i) {
     37             *fRects[0].append() = SkISize::Make(random.nextRangeU(kMinRectSize, kMaxRectSize),
     38                                                 random.nextRangeU(kMinRectSize, kMaxRectSize));
     39             *fRects[1].append() = SkISize::Make(
     40                         GrNextPow2(random.nextRangeU(kMinRectSize, kMaxRectSize)),
     41                         GrNextPow2(random.nextRangeU(kMinRectSize, kMaxRectSize)));
     42             *fRects[2].append() = SkISize::Make(128, 128);
     43             *fRectLocations.append() = SkIPoint16::Make(0, 0);
     44         }
     45 
     46         fCurRects = &fRects[0];
     47 
     48         fRectanizers[0] = new GrRectanizerPow2(kWidth, kHeight);
     49         fRectanizers[1] = new GrRectanizerSkyline(kWidth, kHeight);
     50         fCurRectanizer = fRectanizers[0];
     51     }
     52 
     53 protected:
     54     bool onQuery(SkEvent* evt) override {
     55         if (SampleCode::TitleQ(*evt)) {
     56             SampleCode::TitleR(evt, "Rectanizer");
     57             return true;
     58         }
     59         SkUnichar uni;
     60         if (SampleCode::CharQ(*evt, &uni)) {
     61             char utf8[kMaxBytesInUTF8Sequence];
     62             size_t size = SkUTF8_FromUnichar(uni, utf8);
     63             // Only consider events for single char keys
     64             if (1 == size) {
     65                 switch (utf8[0]) {
     66                 case kCycleRectanizerKey:
     67                     this->cycleRectanizer();
     68                     return true;
     69                 case kCycleRectsKey:
     70                     this->cycleRects();
     71                     return true;
     72                 default:
     73                     break;
     74                 }
     75             }
     76         }
     77         return this->INHERITED::onQuery(evt);
     78     }
     79 
     80     void onDrawContent(SkCanvas* canvas) override {
     81         if (fCurRandRect < kNumRandRects) {
     82             if (fCurRectanizer->addRect((*fCurRects)[fCurRandRect].fWidth,
     83                                         (*fCurRects)[fCurRandRect].fHeight,
     84                                         &fRectLocations[fCurRandRect])) {
     85                 ++fCurRandRect;
     86             }
     87         }
     88 
     89         SkPaint blackBigFont;
     90         blackBigFont.setTextSize(20);
     91         SkPaint blackStroke;
     92         blackStroke.setStyle(SkPaint::kStroke_Style);
     93         SkPaint redFill;
     94         redFill.setColor(SK_ColorRED);
     95 
     96         SkRect r = SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight));
     97 
     98         canvas->clear(SK_ColorWHITE);
     99         canvas->drawRect(r, blackStroke);
    100 
    101         long totArea = 0;
    102         for (int i = 0; i < fCurRandRect; ++i) {
    103             r = SkRect::MakeXYWH(SkIntToScalar(fRectLocations[i].fX),
    104                                  SkIntToScalar(fRectLocations[i].fY),
    105                                  SkIntToScalar((*fCurRects)[i].fWidth),
    106                                  SkIntToScalar((*fCurRects)[i].fHeight));
    107             canvas->drawRect(r, redFill);
    108             canvas->drawRect(r, blackStroke);
    109             totArea += (*fCurRects)[i].fWidth * (*fCurRects)[i].fHeight;
    110         }
    111 
    112         SkString str;
    113 
    114         str.printf("%s-%s: tot Area: %ld %%full: %.2f (%.2f) numTextures: %d/%d",
    115                    this->getRectanizerName(),
    116                    this->getRectsName(),
    117                    totArea,
    118                    100.0f * fCurRectanizer->percentFull(),
    119                    100.0f * totArea / ((float)kWidth*kHeight),
    120                    fCurRandRect,
    121                    kNumRandRects);
    122         canvas->drawText(str.c_str(), str.size(), 50, kHeight + 50, blackBigFont);
    123 
    124         str.printf("Press \'j\' to toggle rectanizer");
    125         canvas->drawText(str.c_str(), str.size(), 50, kHeight + 100, blackBigFont);
    126 
    127         str.printf("Press \'h\' to toggle rects");
    128         canvas->drawText(str.c_str(), str.size(), 50, kHeight + 150, blackBigFont);
    129 
    130         this->inval(nullptr);
    131     }
    132 
    133 private:
    134     static const int kWidth = 1024;
    135     static const int kHeight = 1024;
    136     static const int kNumRandRects = 200;
    137     static const char kCycleRectanizerKey = 'j';
    138     static const char kCycleRectsKey = 'h';
    139     static const int kMinRectSize = 2;
    140     static const int kMaxRectSize = 256;
    141 
    142     int                   fCurRandRect;
    143     SkTDArray<SkISize>    fRects[3];
    144     SkTDArray<SkISize>*   fCurRects;
    145     SkTDArray<SkIPoint16> fRectLocations;
    146     GrRectanizer*         fRectanizers[2];
    147     GrRectanizer*         fCurRectanizer;
    148 
    149     const char* getRectanizerName() const {
    150         if (fCurRectanizer == fRectanizers[0]) {
    151             return "Pow2";
    152         } else {
    153             return "Skyline";
    154         }
    155     }
    156 
    157     void cycleRectanizer() {
    158         if (fCurRectanizer == fRectanizers[0]) {
    159             fCurRectanizer = fRectanizers[1];
    160         } else {
    161             fCurRectanizer = fRectanizers[0];
    162         }
    163 
    164         fCurRectanizer->reset();
    165         fCurRandRect = 0;
    166     }
    167 
    168     const char* getRectsName() const {
    169         if (fCurRects == &fRects[0]) {
    170             return "Rand";
    171         } else if (fCurRects == &fRects[1]) {
    172             return "Pow2Rand";
    173         } else {
    174             return "SmallPow2";
    175         }
    176     }
    177 
    178     void cycleRects() {
    179         if (fCurRects == &fRects[0]) {
    180             fCurRects = &fRects[1];
    181         } else if (fCurRects == &fRects[1]) {
    182             fCurRects = &fRects[2];
    183         } else {
    184             fCurRects = &fRects[0];
    185         }
    186 
    187         fCurRectanizer->reset();
    188         fCurRandRect = 0;
    189     }
    190 
    191     typedef SampleView INHERITED;
    192 };
    193 
    194 //////////////////////////////////////////////////////////////////////////////
    195 static SkView* MyFactory() { return new RectanizerView; }
    196 static SkViewRegister reg(MyFactory);
    197 
    198 #endif
    199