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