blob: 317d24caaa04bdbaec4302b625c889b42d029066 [file] [log] [blame]
robertphillips901e96d2014-06-02 07:15:18 -07001/*
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
Ben Wagnerb2c4ea62018-08-08 11:36:17 -04008#include "Sample.h"
9#include "SkCanvas.h"
robertphillips901e96d2014-06-02 07:15:18 -070010#include "SkRandom.h"
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040011#include "SkPaint.h"
Hal Canaryea60b952018-08-21 11:45:46 -040012#include "SkUTF.h"
robertphillips901e96d2014-06-02 07:15:18 -070013#if SK_SUPPORT_GPU
14#include "GrRectanizer_pow2.h"
15#include "GrRectanizer_skyline.h"
16
robertphillips901e96d2014-06-02 07:15:18 -070017// This slide visualizes the various GrRectanizer-derived classes behavior
18// for various input sets
19// 'j' will cycle through the various rectanizers
20// Pow2 -> GrRectanizerPow2
21// Skyline -> GrRectanizerSkyline
22// 'h' will cycle through the various rect sets
23// Rand -> random rects from 2-256
24// Pow2Rand -> random power of 2 sized rects from 2-256
25// SmallPow2 -> 128x128 rects
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040026class RectanizerView : public Sample {
robertphillips901e96d2014-06-02 07:15:18 -070027public:
28 RectanizerView()
Florin Malitae5ae84b2017-12-24 11:45:38 -050029 : fCurRandRect(0)
30 , fCurRectanizer(0) {
robertphillips901e96d2014-06-02 07:15:18 -070031 for (int i = 0; i < 3; ++i) {
32 fRects[i].setReserve(kNumRandRects);
33 }
34 fRectLocations.setReserve(kNumRandRects);
35
36 SkRandom random;
37 for (int i = 0; i < kNumRandRects; ++i) {
38 *fRects[0].append() = SkISize::Make(random.nextRangeU(kMinRectSize, kMaxRectSize),
39 random.nextRangeU(kMinRectSize, kMaxRectSize));
40 *fRects[1].append() = SkISize::Make(
41 GrNextPow2(random.nextRangeU(kMinRectSize, kMaxRectSize)),
42 GrNextPow2(random.nextRangeU(kMinRectSize, kMaxRectSize)));
43 *fRects[2].append() = SkISize::Make(128, 128);
robertphillipsd5373412014-06-02 10:20:14 -070044 *fRectLocations.append() = SkIPoint16::Make(0, 0);
robertphillips901e96d2014-06-02 07:15:18 -070045 }
46
47 fCurRects = &fRects[0];
48
Florin Malitae5ae84b2017-12-24 11:45:38 -050049 fRectanizers.push_back(
50 std::unique_ptr<GrRectanizer>(new GrRectanizerPow2(kWidth, kHeight)));
51 fRectanizers.push_back(
52 std::unique_ptr<GrRectanizer>(new GrRectanizerSkyline(kWidth, kHeight)));
robertphillips901e96d2014-06-02 07:15:18 -070053 }
54
55protected:
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040056 bool onQuery(Sample::Event* evt) override {
57 if (Sample::TitleQ(*evt)) {
58 Sample::TitleR(evt, "Rectanizer");
robertphillips901e96d2014-06-02 07:15:18 -070059 return true;
60 }
61 SkUnichar uni;
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040062 if (Sample::CharQ(*evt, &uni)) {
Hal Canaryf107a2f2018-07-25 16:52:48 -040063 char utf8[SkUTF::kMaxBytesInUTF8Sequence];
64 size_t size = SkUTF::ToUTF8(uni, utf8);
robertphillips901e96d2014-06-02 07:15:18 -070065 // Only consider events for single char keys
66 if (1 == size) {
67 switch (utf8[0]) {
68 case kCycleRectanizerKey:
69 this->cycleRectanizer();
70 return true;
71 case kCycleRectsKey:
72 this->cycleRects();
73 return true;
74 default:
75 break;
76 }
77 }
78 }
79 return this->INHERITED::onQuery(evt);
80 }
81
mtklein36352bf2015-03-25 18:17:31 -070082 void onDrawContent(SkCanvas* canvas) override {
robertphillips901e96d2014-06-02 07:15:18 -070083 if (fCurRandRect < kNumRandRects) {
Florin Malitae5ae84b2017-12-24 11:45:38 -050084 if (fRectanizers[fCurRectanizer]->addRect((*fCurRects)[fCurRandRect].fWidth,
85 (*fCurRects)[fCurRandRect].fHeight,
86 &fRectLocations[fCurRandRect])) {
robertphillips901e96d2014-06-02 07:15:18 -070087 ++fCurRandRect;
88 }
89 }
90
91 SkPaint blackBigFont;
92 blackBigFont.setTextSize(20);
93 SkPaint blackStroke;
94 blackStroke.setStyle(SkPaint::kStroke_Style);
95 SkPaint redFill;
96 redFill.setColor(SK_ColorRED);
97
98 SkRect r = SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight));
99
100 canvas->clear(SK_ColorWHITE);
101 canvas->drawRect(r, blackStroke);
102
103 long totArea = 0;
104 for (int i = 0; i < fCurRandRect; ++i) {
halcanary9d524f22016-03-29 09:03:52 -0700105 r = SkRect::MakeXYWH(SkIntToScalar(fRectLocations[i].fX),
robertphillips901e96d2014-06-02 07:15:18 -0700106 SkIntToScalar(fRectLocations[i].fY),
107 SkIntToScalar((*fCurRects)[i].fWidth),
108 SkIntToScalar((*fCurRects)[i].fHeight));
109 canvas->drawRect(r, redFill);
110 canvas->drawRect(r, blackStroke);
111 totArea += (*fCurRects)[i].fWidth * (*fCurRects)[i].fHeight;
112 }
113
114 SkString str;
115
116 str.printf("%s-%s: tot Area: %ld %%full: %.2f (%.2f) numTextures: %d/%d",
117 this->getRectanizerName(),
118 this->getRectsName(),
119 totArea,
Florin Malitae5ae84b2017-12-24 11:45:38 -0500120 100.0f * fRectanizers[fCurRectanizer]->percentFull(),
robertphillips901e96d2014-06-02 07:15:18 -0700121 100.0f * totArea / ((float)kWidth*kHeight),
122 fCurRandRect,
123 kNumRandRects);
Cary Clark2a475ea2017-04-28 15:35:12 -0400124 canvas->drawString(str, 50, kHeight + 50, blackBigFont);
robertphillips901e96d2014-06-02 07:15:18 -0700125
126 str.printf("Press \'j\' to toggle rectanizer");
Cary Clark2a475ea2017-04-28 15:35:12 -0400127 canvas->drawString(str, 50, kHeight + 100, blackBigFont);
robertphillips901e96d2014-06-02 07:15:18 -0700128
129 str.printf("Press \'h\' to toggle rects");
Cary Clark2a475ea2017-04-28 15:35:12 -0400130 canvas->drawString(str, 50, kHeight + 150, blackBigFont);
robertphillips901e96d2014-06-02 07:15:18 -0700131 }
132
133private:
134 static const int kWidth = 1024;
135 static const int kHeight = 1024;
136 static const int kNumRandRects = 200;
137 static const char kCycleRectanizerKey = 'j';
138 static const char kCycleRectsKey = 'h';
139 static const int kMinRectSize = 2;
140 static const int kMaxRectSize = 256;
141
Florin Malitae5ae84b2017-12-24 11:45:38 -0500142 int fCurRandRect;
143 SkTDArray<SkISize> fRects[3];
144 SkTDArray<SkISize>* fCurRects;
145 SkTDArray<SkIPoint16> fRectLocations;
146 SkTArray<std::unique_ptr<GrRectanizer>> fRectanizers;
147 int fCurRectanizer;
robertphillips901e96d2014-06-02 07:15:18 -0700148
149 const char* getRectanizerName() const {
Florin Malitae5ae84b2017-12-24 11:45:38 -0500150 if (!fCurRectanizer) {
robertphillips901e96d2014-06-02 07:15:18 -0700151 return "Pow2";
152 } else {
153 return "Skyline";
154 }
155 }
156
157 void cycleRectanizer() {
Florin Malitae5ae84b2017-12-24 11:45:38 -0500158 fCurRectanizer = (fCurRectanizer + 1) % fRectanizers.count();
robertphillips901e96d2014-06-02 07:15:18 -0700159
Florin Malitae5ae84b2017-12-24 11:45:38 -0500160 fRectanizers[fCurRectanizer]->reset();
robertphillips901e96d2014-06-02 07:15:18 -0700161 fCurRandRect = 0;
162 }
163
164 const char* getRectsName() const {
165 if (fCurRects == &fRects[0]) {
166 return "Rand";
167 } else if (fCurRects == &fRects[1]) {
168 return "Pow2Rand";
169 } else {
170 return "SmallPow2";
171 }
172 }
173
174 void cycleRects() {
175 if (fCurRects == &fRects[0]) {
176 fCurRects = &fRects[1];
177 } else if (fCurRects == &fRects[1]) {
178 fCurRects = &fRects[2];
179 } else {
180 fCurRects = &fRects[0];
181 }
182
Florin Malitae5ae84b2017-12-24 11:45:38 -0500183 fRectanizers[fCurRectanizer]->reset();
robertphillips901e96d2014-06-02 07:15:18 -0700184 fCurRandRect = 0;
185 }
186
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400187 typedef Sample INHERITED;
robertphillips901e96d2014-06-02 07:15:18 -0700188};
189
190//////////////////////////////////////////////////////////////////////////////
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400191
192DEF_SAMPLE( return new RectanizerView(); )
robertphillips901e96d2014-06-02 07:15:18 -0700193
194#endif