• 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 "include/core/SkCanvas.h"
9 #include "include/core/SkFont.h"
10 #include "include/core/SkPaint.h"
11 #include "include/utils/SkRandom.h"
12 #include "samplecode/Sample.h"
13 #include "src/utils/SkUTF.h"
14 #if SK_SUPPORT_GPU
15 #include "src/gpu/GrRectanizer_pow2.h"
16 #include "src/gpu/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:
name()57     SkString name() override { return SkString("Rectanizer"); }
58 
onChar(SkUnichar uni)59     bool onChar(SkUnichar uni) override {
60             char utf8[SkUTF::kMaxBytesInUTF8Sequence];
61             size_t size = SkUTF::ToUTF8(uni, utf8);
62             // Only consider events for single char keys
63             if (1 == size) {
64                 switch (utf8[0]) {
65                 case kCycleRectanizerKey:
66                     this->cycleRectanizer();
67                     return true;
68                 case kCycleRectsKey:
69                     this->cycleRects();
70                     return true;
71                 default:
72                     break;
73                 }
74             }
75             return false;
76     }
77 
onDrawContent(SkCanvas * canvas)78     void onDrawContent(SkCanvas* canvas) override {
79         if (fCurRandRect < kNumRandRects) {
80             if (fRectanizers[fCurRectanizer]->addRect((*fCurRects)[fCurRandRect].fWidth,
81                                                       (*fCurRects)[fCurRandRect].fHeight,
82                                                       &fRectLocations[fCurRandRect])) {
83                 ++fCurRandRect;
84             }
85         }
86 
87         SkFont blackBigFont;
88         blackBigFont.setSize(20);
89         SkPaint blackStroke;
90         blackStroke.setStyle(SkPaint::kStroke_Style);
91         SkPaint redFill;
92         redFill.setColor(SK_ColorRED);
93 
94         SkRect r = SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight));
95 
96         canvas->clear(SK_ColorWHITE);
97         canvas->drawRect(r, blackStroke);
98 
99         long totArea = 0;
100         for (int i = 0; i < fCurRandRect; ++i) {
101             r = SkRect::MakeXYWH(SkIntToScalar(fRectLocations[i].fX),
102                                  SkIntToScalar(fRectLocations[i].fY),
103                                  SkIntToScalar((*fCurRects)[i].fWidth),
104                                  SkIntToScalar((*fCurRects)[i].fHeight));
105             canvas->drawRect(r, redFill);
106             canvas->drawRect(r, blackStroke);
107             totArea += (*fCurRects)[i].fWidth * (*fCurRects)[i].fHeight;
108         }
109 
110         SkString str;
111 
112         str.printf("%s-%s: tot Area: %ld %%full: %.2f (%.2f) numTextures: %d/%d",
113                    this->getRectanizerName(),
114                    this->getRectsName(),
115                    totArea,
116                    100.0f * fRectanizers[fCurRectanizer]->percentFull(),
117                    100.0f * totArea / ((float)kWidth*kHeight),
118                    fCurRandRect,
119                    kNumRandRects);
120         canvas->drawString(str, 50, kHeight + 50, blackBigFont, SkPaint());
121 
122         str.printf("Press \'j\' to toggle rectanizer");
123         canvas->drawString(str, 50, kHeight + 100, blackBigFont, SkPaint());
124 
125         str.printf("Press \'h\' to toggle rects");
126         canvas->drawString(str, 50, kHeight + 150, blackBigFont, SkPaint());
127     }
128 
129 private:
130     static const int kWidth = 1024;
131     static const int kHeight = 1024;
132     static const int kNumRandRects = 200;
133     static const char kCycleRectanizerKey = 'j';
134     static const char kCycleRectsKey = 'h';
135     static const int kMinRectSize = 2;
136     static const int kMaxRectSize = 256;
137 
138     int                                     fCurRandRect;
139     SkTDArray<SkISize>                      fRects[3];
140     SkTDArray<SkISize>*                     fCurRects;
141     SkTDArray<SkIPoint16>                   fRectLocations;
142     SkTArray<std::unique_ptr<GrRectanizer>> fRectanizers;
143     int                                     fCurRectanizer;
144 
getRectanizerName() const145     const char* getRectanizerName() const {
146         if (!fCurRectanizer) {
147             return "Pow2";
148         } else {
149             return "Skyline";
150         }
151     }
152 
cycleRectanizer()153     void cycleRectanizer() {
154         fCurRectanizer = (fCurRectanizer + 1) % fRectanizers.count();
155 
156         fRectanizers[fCurRectanizer]->reset();
157         fCurRandRect = 0;
158     }
159 
getRectsName() const160     const char* getRectsName() const {
161         if (fCurRects == &fRects[0]) {
162             return "Rand";
163         } else if (fCurRects == &fRects[1]) {
164             return "Pow2Rand";
165         } else {
166             return "SmallPow2";
167         }
168     }
169 
cycleRects()170     void cycleRects() {
171         if (fCurRects == &fRects[0]) {
172             fCurRects = &fRects[1];
173         } else if (fCurRects == &fRects[1]) {
174             fCurRects = &fRects[2];
175         } else {
176             fCurRects = &fRects[0];
177         }
178 
179         fRectanizers[fCurRectanizer]->reset();
180         fCurRandRect = 0;
181     }
182 
183     typedef Sample INHERITED;
184 };
185 
186 //////////////////////////////////////////////////////////////////////////////
187 
188 DEF_SAMPLE( return new RectanizerView(); )
189 
190 #endif
191