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