xref: /aosp_15_r20/external/skia/tools/viewer/RectanizerSlide.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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/private/base/SkTArray.h"
12 #include "src/base/SkRandom.h"
13 #include "src/base/SkUTF.h"
14 #include "tools/viewer/Slide.h"
15 #if defined(SK_GANESH) || defined(SK_GRAPHITE)
16 #include "src/gpu/RectanizerPow2.h"
17 #include "src/gpu/RectanizerSkyline.h"
18 
19 using namespace skia_private;
20 using namespace skgpu;
21 
22 // This slide visualizes the various Rectanizer-derived classes behavior
23 // for various input sets
24 //  'j' will cycle through the various rectanizers
25 //          Pow2 -> RectanizerPow2
26 //          Skyline -> RectanizerSkyline
27 //  'h' will cycle through the various rect sets
28 //          Rand -> random rects from 2-256
29 //          Pow2Rand -> random power of 2 sized rects from 2-256
30 //          SmallPow2 -> 128x128 rects
31 class RectanizerSlide : public Slide {
32 public:
RectanizerSlide()33     RectanizerSlide()
34         : fCurRandRect(0)
35         , fCurRectanizer(0) {
36         for (int i = 0; i < 3; ++i) {
37            fRects[i].reserve(kNumRandRects);
38         }
39         fRectLocations.reserve(kNumRandRects);
40 
41         SkRandom random;
42         for (int i = 0; i < kNumRandRects; ++i) {
43             *fRects[0].append() = SkISize::Make(random.nextRangeU(kMinRectSize, kMaxRectSize),
44                                                 random.nextRangeU(kMinRectSize, kMaxRectSize));
45             *fRects[1].append() = SkISize::Make(
46                         SkNextPow2(random.nextRangeU(kMinRectSize, kMaxRectSize)),
47                         SkNextPow2(random.nextRangeU(kMinRectSize, kMaxRectSize)));
48             *fRects[2].append() = SkISize::Make(128, 128);
49             *fRectLocations.append() = SkIPoint16::Make(0, 0);
50         }
51 
52         fCurRects = &fRects[0];
53 
54         fRectanizers.push_back(
55             std::unique_ptr<Rectanizer>(new RectanizerPow2(kWidth, kHeight)));
56         fRectanizers.push_back(
57             std::unique_ptr<Rectanizer>(new RectanizerSkyline(kWidth, kHeight)));
58         fName = "Rectanizer";
59     }
60 
onChar(SkUnichar uni)61     bool onChar(SkUnichar uni) override {
62             char utf8[SkUTF::kMaxBytesInUTF8Sequence];
63             size_t size = SkUTF::ToUTF8(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             return false;
78     }
79 
draw(SkCanvas * canvas)80     void draw(SkCanvas* canvas) override {
81         if (fCurRandRect < kNumRandRects) {
82             if (fRectanizers[fCurRectanizer]->addRect((*fCurRects)[fCurRandRect].fWidth,
83                                                       (*fCurRects)[fCurRandRect].fHeight,
84                                                       &fRectLocations[fCurRandRect])) {
85                 ++fCurRandRect;
86             }
87         }
88 
89         SkFont blackBigFont;
90         blackBigFont.setSize(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 * fRectanizers[fCurRectanizer]->percentFull(),
119                    100.0f * totArea / ((float)kWidth*kHeight),
120                    fCurRandRect,
121                    kNumRandRects);
122         canvas->drawString(str, 50, kHeight + 50, blackBigFont, SkPaint());
123 
124         str.printf("Press \'j\' to toggle rectanizer");
125         canvas->drawString(str, 50, kHeight + 100, blackBigFont, SkPaint());
126 
127         str.printf("Press \'h\' to toggle rects");
128         canvas->drawString(str, 50, kHeight + 150, blackBigFont, SkPaint());
129     }
130 
131 private:
132     static const int kWidth = 1024;
133     static const int kHeight = 1024;
134     static const int kNumRandRects = 200;
135     static const char kCycleRectanizerKey = 'j';
136     static const char kCycleRectsKey = 'h';
137     static const int kMinRectSize = 2;
138     static const int kMaxRectSize = 256;
139 
140     int                                   fCurRandRect;
141     SkTDArray<SkISize>                    fRects[3];
142     SkTDArray<SkISize>*                   fCurRects;
143     SkTDArray<SkIPoint16>                 fRectLocations;
144     TArray<std::unique_ptr<Rectanizer>> fRectanizers;
145     int                                   fCurRectanizer;
146 
getRectanizerName() const147     const char* getRectanizerName() const {
148         if (!fCurRectanizer) {
149             return "Pow2";
150         } else {
151             return "Skyline";
152         }
153     }
154 
cycleRectanizer()155     void cycleRectanizer() {
156         fCurRectanizer = (fCurRectanizer + 1) % fRectanizers.size();
157 
158         fRectanizers[fCurRectanizer]->reset();
159         fCurRandRect = 0;
160     }
161 
getRectsName() const162     const char* getRectsName() const {
163         if (fCurRects == &fRects[0]) {
164             return "Rand";
165         } else if (fCurRects == &fRects[1]) {
166             return "Pow2Rand";
167         } else {
168             return "SmallPow2";
169         }
170     }
171 
cycleRects()172     void cycleRects() {
173         if (fCurRects == &fRects[0]) {
174             fCurRects = &fRects[1];
175         } else if (fCurRects == &fRects[1]) {
176             fCurRects = &fRects[2];
177         } else {
178             fCurRects = &fRects[0];
179         }
180 
181         fRectanizers[fCurRectanizer]->reset();
182         fCurRandRect = 0;
183     }
184 };
185 
186 //////////////////////////////////////////////////////////////////////////////
187 
188 DEF_SLIDE( return new RectanizerSlide(); )
189 
190 #endif
191