xref: /aosp_15_r20/external/skia/tools/viewer/RectanizerSlide.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2014 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFont.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTArray.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkRandom.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkUTF.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "tools/viewer/Slide.h"
15*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_GANESH) || defined(SK_GRAPHITE)
16*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/RectanizerPow2.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/RectanizerSkyline.h"
18*c8dee2aaSAndroid Build Coastguard Worker 
19*c8dee2aaSAndroid Build Coastguard Worker using namespace skia_private;
20*c8dee2aaSAndroid Build Coastguard Worker using namespace skgpu;
21*c8dee2aaSAndroid Build Coastguard Worker 
22*c8dee2aaSAndroid Build Coastguard Worker // This slide visualizes the various Rectanizer-derived classes behavior
23*c8dee2aaSAndroid Build Coastguard Worker // for various input sets
24*c8dee2aaSAndroid Build Coastguard Worker //  'j' will cycle through the various rectanizers
25*c8dee2aaSAndroid Build Coastguard Worker //          Pow2 -> RectanizerPow2
26*c8dee2aaSAndroid Build Coastguard Worker //          Skyline -> RectanizerSkyline
27*c8dee2aaSAndroid Build Coastguard Worker //  'h' will cycle through the various rect sets
28*c8dee2aaSAndroid Build Coastguard Worker //          Rand -> random rects from 2-256
29*c8dee2aaSAndroid Build Coastguard Worker //          Pow2Rand -> random power of 2 sized rects from 2-256
30*c8dee2aaSAndroid Build Coastguard Worker //          SmallPow2 -> 128x128 rects
31*c8dee2aaSAndroid Build Coastguard Worker class RectanizerSlide : public Slide {
32*c8dee2aaSAndroid Build Coastguard Worker public:
RectanizerSlide()33*c8dee2aaSAndroid Build Coastguard Worker     RectanizerSlide()
34*c8dee2aaSAndroid Build Coastguard Worker         : fCurRandRect(0)
35*c8dee2aaSAndroid Build Coastguard Worker         , fCurRectanizer(0) {
36*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < 3; ++i) {
37*c8dee2aaSAndroid Build Coastguard Worker            fRects[i].reserve(kNumRandRects);
38*c8dee2aaSAndroid Build Coastguard Worker         }
39*c8dee2aaSAndroid Build Coastguard Worker         fRectLocations.reserve(kNumRandRects);
40*c8dee2aaSAndroid Build Coastguard Worker 
41*c8dee2aaSAndroid Build Coastguard Worker         SkRandom random;
42*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < kNumRandRects; ++i) {
43*c8dee2aaSAndroid Build Coastguard Worker             *fRects[0].append() = SkISize::Make(random.nextRangeU(kMinRectSize, kMaxRectSize),
44*c8dee2aaSAndroid Build Coastguard Worker                                                 random.nextRangeU(kMinRectSize, kMaxRectSize));
45*c8dee2aaSAndroid Build Coastguard Worker             *fRects[1].append() = SkISize::Make(
46*c8dee2aaSAndroid Build Coastguard Worker                         SkNextPow2(random.nextRangeU(kMinRectSize, kMaxRectSize)),
47*c8dee2aaSAndroid Build Coastguard Worker                         SkNextPow2(random.nextRangeU(kMinRectSize, kMaxRectSize)));
48*c8dee2aaSAndroid Build Coastguard Worker             *fRects[2].append() = SkISize::Make(128, 128);
49*c8dee2aaSAndroid Build Coastguard Worker             *fRectLocations.append() = SkIPoint16::Make(0, 0);
50*c8dee2aaSAndroid Build Coastguard Worker         }
51*c8dee2aaSAndroid Build Coastguard Worker 
52*c8dee2aaSAndroid Build Coastguard Worker         fCurRects = &fRects[0];
53*c8dee2aaSAndroid Build Coastguard Worker 
54*c8dee2aaSAndroid Build Coastguard Worker         fRectanizers.push_back(
55*c8dee2aaSAndroid Build Coastguard Worker             std::unique_ptr<Rectanizer>(new RectanizerPow2(kWidth, kHeight)));
56*c8dee2aaSAndroid Build Coastguard Worker         fRectanizers.push_back(
57*c8dee2aaSAndroid Build Coastguard Worker             std::unique_ptr<Rectanizer>(new RectanizerSkyline(kWidth, kHeight)));
58*c8dee2aaSAndroid Build Coastguard Worker         fName = "Rectanizer";
59*c8dee2aaSAndroid Build Coastguard Worker     }
60*c8dee2aaSAndroid Build Coastguard Worker 
onChar(SkUnichar uni)61*c8dee2aaSAndroid Build Coastguard Worker     bool onChar(SkUnichar uni) override {
62*c8dee2aaSAndroid Build Coastguard Worker             char utf8[SkUTF::kMaxBytesInUTF8Sequence];
63*c8dee2aaSAndroid Build Coastguard Worker             size_t size = SkUTF::ToUTF8(uni, utf8);
64*c8dee2aaSAndroid Build Coastguard Worker             // Only consider events for single char keys
65*c8dee2aaSAndroid Build Coastguard Worker             if (1 == size) {
66*c8dee2aaSAndroid Build Coastguard Worker                 switch (utf8[0]) {
67*c8dee2aaSAndroid Build Coastguard Worker                 case kCycleRectanizerKey:
68*c8dee2aaSAndroid Build Coastguard Worker                     this->cycleRectanizer();
69*c8dee2aaSAndroid Build Coastguard Worker                     return true;
70*c8dee2aaSAndroid Build Coastguard Worker                 case kCycleRectsKey:
71*c8dee2aaSAndroid Build Coastguard Worker                     this->cycleRects();
72*c8dee2aaSAndroid Build Coastguard Worker                     return true;
73*c8dee2aaSAndroid Build Coastguard Worker                 default:
74*c8dee2aaSAndroid Build Coastguard Worker                     break;
75*c8dee2aaSAndroid Build Coastguard Worker                 }
76*c8dee2aaSAndroid Build Coastguard Worker             }
77*c8dee2aaSAndroid Build Coastguard Worker             return false;
78*c8dee2aaSAndroid Build Coastguard Worker     }
79*c8dee2aaSAndroid Build Coastguard Worker 
draw(SkCanvas * canvas)80*c8dee2aaSAndroid Build Coastguard Worker     void draw(SkCanvas* canvas) override {
81*c8dee2aaSAndroid Build Coastguard Worker         if (fCurRandRect < kNumRandRects) {
82*c8dee2aaSAndroid Build Coastguard Worker             if (fRectanizers[fCurRectanizer]->addRect((*fCurRects)[fCurRandRect].fWidth,
83*c8dee2aaSAndroid Build Coastguard Worker                                                       (*fCurRects)[fCurRandRect].fHeight,
84*c8dee2aaSAndroid Build Coastguard Worker                                                       &fRectLocations[fCurRandRect])) {
85*c8dee2aaSAndroid Build Coastguard Worker                 ++fCurRandRect;
86*c8dee2aaSAndroid Build Coastguard Worker             }
87*c8dee2aaSAndroid Build Coastguard Worker         }
88*c8dee2aaSAndroid Build Coastguard Worker 
89*c8dee2aaSAndroid Build Coastguard Worker         SkFont blackBigFont;
90*c8dee2aaSAndroid Build Coastguard Worker         blackBigFont.setSize(20);
91*c8dee2aaSAndroid Build Coastguard Worker         SkPaint blackStroke;
92*c8dee2aaSAndroid Build Coastguard Worker         blackStroke.setStyle(SkPaint::kStroke_Style);
93*c8dee2aaSAndroid Build Coastguard Worker         SkPaint redFill;
94*c8dee2aaSAndroid Build Coastguard Worker         redFill.setColor(SK_ColorRED);
95*c8dee2aaSAndroid Build Coastguard Worker 
96*c8dee2aaSAndroid Build Coastguard Worker         SkRect r = SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight));
97*c8dee2aaSAndroid Build Coastguard Worker 
98*c8dee2aaSAndroid Build Coastguard Worker         canvas->clear(SK_ColorWHITE);
99*c8dee2aaSAndroid Build Coastguard Worker         canvas->drawRect(r, blackStroke);
100*c8dee2aaSAndroid Build Coastguard Worker 
101*c8dee2aaSAndroid Build Coastguard Worker         long totArea = 0;
102*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < fCurRandRect; ++i) {
103*c8dee2aaSAndroid Build Coastguard Worker             r = SkRect::MakeXYWH(SkIntToScalar(fRectLocations[i].fX),
104*c8dee2aaSAndroid Build Coastguard Worker                                  SkIntToScalar(fRectLocations[i].fY),
105*c8dee2aaSAndroid Build Coastguard Worker                                  SkIntToScalar((*fCurRects)[i].fWidth),
106*c8dee2aaSAndroid Build Coastguard Worker                                  SkIntToScalar((*fCurRects)[i].fHeight));
107*c8dee2aaSAndroid Build Coastguard Worker             canvas->drawRect(r, redFill);
108*c8dee2aaSAndroid Build Coastguard Worker             canvas->drawRect(r, blackStroke);
109*c8dee2aaSAndroid Build Coastguard Worker             totArea += (*fCurRects)[i].fWidth * (*fCurRects)[i].fHeight;
110*c8dee2aaSAndroid Build Coastguard Worker         }
111*c8dee2aaSAndroid Build Coastguard Worker 
112*c8dee2aaSAndroid Build Coastguard Worker         SkString str;
113*c8dee2aaSAndroid Build Coastguard Worker 
114*c8dee2aaSAndroid Build Coastguard Worker         str.printf("%s-%s: tot Area: %ld %%full: %.2f (%.2f) numTextures: %d/%d",
115*c8dee2aaSAndroid Build Coastguard Worker                    this->getRectanizerName(),
116*c8dee2aaSAndroid Build Coastguard Worker                    this->getRectsName(),
117*c8dee2aaSAndroid Build Coastguard Worker                    totArea,
118*c8dee2aaSAndroid Build Coastguard Worker                    100.0f * fRectanizers[fCurRectanizer]->percentFull(),
119*c8dee2aaSAndroid Build Coastguard Worker                    100.0f * totArea / ((float)kWidth*kHeight),
120*c8dee2aaSAndroid Build Coastguard Worker                    fCurRandRect,
121*c8dee2aaSAndroid Build Coastguard Worker                    kNumRandRects);
122*c8dee2aaSAndroid Build Coastguard Worker         canvas->drawString(str, 50, kHeight + 50, blackBigFont, SkPaint());
123*c8dee2aaSAndroid Build Coastguard Worker 
124*c8dee2aaSAndroid Build Coastguard Worker         str.printf("Press \'j\' to toggle rectanizer");
125*c8dee2aaSAndroid Build Coastguard Worker         canvas->drawString(str, 50, kHeight + 100, blackBigFont, SkPaint());
126*c8dee2aaSAndroid Build Coastguard Worker 
127*c8dee2aaSAndroid Build Coastguard Worker         str.printf("Press \'h\' to toggle rects");
128*c8dee2aaSAndroid Build Coastguard Worker         canvas->drawString(str, 50, kHeight + 150, blackBigFont, SkPaint());
129*c8dee2aaSAndroid Build Coastguard Worker     }
130*c8dee2aaSAndroid Build Coastguard Worker 
131*c8dee2aaSAndroid Build Coastguard Worker private:
132*c8dee2aaSAndroid Build Coastguard Worker     static const int kWidth = 1024;
133*c8dee2aaSAndroid Build Coastguard Worker     static const int kHeight = 1024;
134*c8dee2aaSAndroid Build Coastguard Worker     static const int kNumRandRects = 200;
135*c8dee2aaSAndroid Build Coastguard Worker     static const char kCycleRectanizerKey = 'j';
136*c8dee2aaSAndroid Build Coastguard Worker     static const char kCycleRectsKey = 'h';
137*c8dee2aaSAndroid Build Coastguard Worker     static const int kMinRectSize = 2;
138*c8dee2aaSAndroid Build Coastguard Worker     static const int kMaxRectSize = 256;
139*c8dee2aaSAndroid Build Coastguard Worker 
140*c8dee2aaSAndroid Build Coastguard Worker     int                                   fCurRandRect;
141*c8dee2aaSAndroid Build Coastguard Worker     SkTDArray<SkISize>                    fRects[3];
142*c8dee2aaSAndroid Build Coastguard Worker     SkTDArray<SkISize>*                   fCurRects;
143*c8dee2aaSAndroid Build Coastguard Worker     SkTDArray<SkIPoint16>                 fRectLocations;
144*c8dee2aaSAndroid Build Coastguard Worker     TArray<std::unique_ptr<Rectanizer>> fRectanizers;
145*c8dee2aaSAndroid Build Coastguard Worker     int                                   fCurRectanizer;
146*c8dee2aaSAndroid Build Coastguard Worker 
getRectanizerName() const147*c8dee2aaSAndroid Build Coastguard Worker     const char* getRectanizerName() const {
148*c8dee2aaSAndroid Build Coastguard Worker         if (!fCurRectanizer) {
149*c8dee2aaSAndroid Build Coastguard Worker             return "Pow2";
150*c8dee2aaSAndroid Build Coastguard Worker         } else {
151*c8dee2aaSAndroid Build Coastguard Worker             return "Skyline";
152*c8dee2aaSAndroid Build Coastguard Worker         }
153*c8dee2aaSAndroid Build Coastguard Worker     }
154*c8dee2aaSAndroid Build Coastguard Worker 
cycleRectanizer()155*c8dee2aaSAndroid Build Coastguard Worker     void cycleRectanizer() {
156*c8dee2aaSAndroid Build Coastguard Worker         fCurRectanizer = (fCurRectanizer + 1) % fRectanizers.size();
157*c8dee2aaSAndroid Build Coastguard Worker 
158*c8dee2aaSAndroid Build Coastguard Worker         fRectanizers[fCurRectanizer]->reset();
159*c8dee2aaSAndroid Build Coastguard Worker         fCurRandRect = 0;
160*c8dee2aaSAndroid Build Coastguard Worker     }
161*c8dee2aaSAndroid Build Coastguard Worker 
getRectsName() const162*c8dee2aaSAndroid Build Coastguard Worker     const char* getRectsName() const {
163*c8dee2aaSAndroid Build Coastguard Worker         if (fCurRects == &fRects[0]) {
164*c8dee2aaSAndroid Build Coastguard Worker             return "Rand";
165*c8dee2aaSAndroid Build Coastguard Worker         } else if (fCurRects == &fRects[1]) {
166*c8dee2aaSAndroid Build Coastguard Worker             return "Pow2Rand";
167*c8dee2aaSAndroid Build Coastguard Worker         } else {
168*c8dee2aaSAndroid Build Coastguard Worker             return "SmallPow2";
169*c8dee2aaSAndroid Build Coastguard Worker         }
170*c8dee2aaSAndroid Build Coastguard Worker     }
171*c8dee2aaSAndroid Build Coastguard Worker 
cycleRects()172*c8dee2aaSAndroid Build Coastguard Worker     void cycleRects() {
173*c8dee2aaSAndroid Build Coastguard Worker         if (fCurRects == &fRects[0]) {
174*c8dee2aaSAndroid Build Coastguard Worker             fCurRects = &fRects[1];
175*c8dee2aaSAndroid Build Coastguard Worker         } else if (fCurRects == &fRects[1]) {
176*c8dee2aaSAndroid Build Coastguard Worker             fCurRects = &fRects[2];
177*c8dee2aaSAndroid Build Coastguard Worker         } else {
178*c8dee2aaSAndroid Build Coastguard Worker             fCurRects = &fRects[0];
179*c8dee2aaSAndroid Build Coastguard Worker         }
180*c8dee2aaSAndroid Build Coastguard Worker 
181*c8dee2aaSAndroid Build Coastguard Worker         fRectanizers[fCurRectanizer]->reset();
182*c8dee2aaSAndroid Build Coastguard Worker         fCurRandRect = 0;
183*c8dee2aaSAndroid Build Coastguard Worker     }
184*c8dee2aaSAndroid Build Coastguard Worker };
185*c8dee2aaSAndroid Build Coastguard Worker 
186*c8dee2aaSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////
187*c8dee2aaSAndroid Build Coastguard Worker 
188*c8dee2aaSAndroid Build Coastguard Worker DEF_SLIDE( return new RectanizerSlide(); )
189*c8dee2aaSAndroid Build Coastguard Worker 
190*c8dee2aaSAndroid Build Coastguard Worker #endif
191