blob: 752d5b71365b13a9a945a0fb343a5833b9d315ae [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
8#include "gm.h"
9#include "SampleCode.h"
10#include "SkRandom.h"
11#include "SkUtils.h"
12#if SK_SUPPORT_GPU
13#include "GrRectanizer_pow2.h"
14#include "GrRectanizer_skyline.h"
15
robertphillips901e96d2014-06-02 07:15:18 -070016// This slide visualizes the various GrRectanizer-derived classes behavior
17// for various input sets
18// 'j' will cycle through the various rectanizers
19// Pow2 -> GrRectanizerPow2
20// Skyline -> GrRectanizerSkyline
21// 'h' will cycle through the various rect sets
22// Rand -> random rects from 2-256
23// Pow2Rand -> random power of 2 sized rects from 2-256
24// SmallPow2 -> 128x128 rects
25class RectanizerView : public SampleView {
26public:
27 RectanizerView()
Florin Malitae5ae84b2017-12-24 11:45:38 -050028 : fCurRandRect(0)
29 , fCurRectanizer(0) {
robertphillips901e96d2014-06-02 07:15:18 -070030 for (int i = 0; i < 3; ++i) {
31 fRects[i].setReserve(kNumRandRects);
32 }
33 fRectLocations.setReserve(kNumRandRects);
34
35 SkRandom random;
36 for (int i = 0; i < kNumRandRects; ++i) {
37 *fRects[0].append() = SkISize::Make(random.nextRangeU(kMinRectSize, kMaxRectSize),
38 random.nextRangeU(kMinRectSize, kMaxRectSize));
39 *fRects[1].append() = SkISize::Make(
40 GrNextPow2(random.nextRangeU(kMinRectSize, kMaxRectSize)),
41 GrNextPow2(random.nextRangeU(kMinRectSize, kMaxRectSize)));
42 *fRects[2].append() = SkISize::Make(128, 128);
robertphillipsd5373412014-06-02 10:20:14 -070043 *fRectLocations.append() = SkIPoint16::Make(0, 0);
robertphillips901e96d2014-06-02 07:15:18 -070044 }
45
46 fCurRects = &fRects[0];
47
Florin Malitae5ae84b2017-12-24 11:45:38 -050048 fRectanizers.push_back(
49 std::unique_ptr<GrRectanizer>(new GrRectanizerPow2(kWidth, kHeight)));
50 fRectanizers.push_back(
51 std::unique_ptr<GrRectanizer>(new GrRectanizerSkyline(kWidth, kHeight)));
robertphillips901e96d2014-06-02 07:15:18 -070052 }
53
54protected:
mtklein36352bf2015-03-25 18:17:31 -070055 bool onQuery(SkEvent* evt) override {
robertphillips901e96d2014-06-02 07:15:18 -070056 if (SampleCode::TitleQ(*evt)) {
57 SampleCode::TitleR(evt, "Rectanizer");
58 return true;
59 }
60 SkUnichar uni;
61 if (SampleCode::CharQ(*evt, &uni)) {
62 char utf8[kMaxBytesInUTF8Sequence];
63 size_t size = SkUTF8_FromUnichar(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 }
78 return this->INHERITED::onQuery(evt);
79 }
80
mtklein36352bf2015-03-25 18:17:31 -070081 void onDrawContent(SkCanvas* canvas) override {
robertphillips901e96d2014-06-02 07:15:18 -070082 if (fCurRandRect < kNumRandRects) {
Florin Malitae5ae84b2017-12-24 11:45:38 -050083 if (fRectanizers[fCurRectanizer]->addRect((*fCurRects)[fCurRandRect].fWidth,
84 (*fCurRects)[fCurRandRect].fHeight,
85 &fRectLocations[fCurRandRect])) {
robertphillips901e96d2014-06-02 07:15:18 -070086 ++fCurRandRect;
87 }
88 }
89
90 SkPaint blackBigFont;
91 blackBigFont.setTextSize(20);
92 SkPaint blackStroke;
93 blackStroke.setStyle(SkPaint::kStroke_Style);
94 SkPaint redFill;
95 redFill.setColor(SK_ColorRED);
96
97 SkRect r = SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight));
98
99 canvas->clear(SK_ColorWHITE);
100 canvas->drawRect(r, blackStroke);
101
102 long totArea = 0;
103 for (int i = 0; i < fCurRandRect; ++i) {
halcanary9d524f22016-03-29 09:03:52 -0700104 r = SkRect::MakeXYWH(SkIntToScalar(fRectLocations[i].fX),
robertphillips901e96d2014-06-02 07:15:18 -0700105 SkIntToScalar(fRectLocations[i].fY),
106 SkIntToScalar((*fCurRects)[i].fWidth),
107 SkIntToScalar((*fCurRects)[i].fHeight));
108 canvas->drawRect(r, redFill);
109 canvas->drawRect(r, blackStroke);
110 totArea += (*fCurRects)[i].fWidth * (*fCurRects)[i].fHeight;
111 }
112
113 SkString str;
114
115 str.printf("%s-%s: tot Area: %ld %%full: %.2f (%.2f) numTextures: %d/%d",
116 this->getRectanizerName(),
117 this->getRectsName(),
118 totArea,
Florin Malitae5ae84b2017-12-24 11:45:38 -0500119 100.0f * fRectanizers[fCurRectanizer]->percentFull(),
robertphillips901e96d2014-06-02 07:15:18 -0700120 100.0f * totArea / ((float)kWidth*kHeight),
121 fCurRandRect,
122 kNumRandRects);
Cary Clark2a475ea2017-04-28 15:35:12 -0400123 canvas->drawString(str, 50, kHeight + 50, blackBigFont);
robertphillips901e96d2014-06-02 07:15:18 -0700124
125 str.printf("Press \'j\' to toggle rectanizer");
Cary Clark2a475ea2017-04-28 15:35:12 -0400126 canvas->drawString(str, 50, kHeight + 100, blackBigFont);
robertphillips901e96d2014-06-02 07:15:18 -0700127
128 str.printf("Press \'h\' to toggle rects");
Cary Clark2a475ea2017-04-28 15:35:12 -0400129 canvas->drawString(str, 50, kHeight + 150, blackBigFont);
robertphillips901e96d2014-06-02 07:15:18 -0700130 }
131
132private:
133 static const int kWidth = 1024;
134 static const int kHeight = 1024;
135 static const int kNumRandRects = 200;
136 static const char kCycleRectanizerKey = 'j';
137 static const char kCycleRectsKey = 'h';
138 static const int kMinRectSize = 2;
139 static const int kMaxRectSize = 256;
140
Florin Malitae5ae84b2017-12-24 11:45:38 -0500141 int fCurRandRect;
142 SkTDArray<SkISize> fRects[3];
143 SkTDArray<SkISize>* fCurRects;
144 SkTDArray<SkIPoint16> fRectLocations;
145 SkTArray<std::unique_ptr<GrRectanizer>> fRectanizers;
146 int fCurRectanizer;
robertphillips901e96d2014-06-02 07:15:18 -0700147
148 const char* getRectanizerName() const {
Florin Malitae5ae84b2017-12-24 11:45:38 -0500149 if (!fCurRectanizer) {
robertphillips901e96d2014-06-02 07:15:18 -0700150 return "Pow2";
151 } else {
152 return "Skyline";
153 }
154 }
155
156 void cycleRectanizer() {
Florin Malitae5ae84b2017-12-24 11:45:38 -0500157 fCurRectanizer = (fCurRectanizer + 1) % fRectanizers.count();
robertphillips901e96d2014-06-02 07:15:18 -0700158
Florin Malitae5ae84b2017-12-24 11:45:38 -0500159 fRectanizers[fCurRectanizer]->reset();
robertphillips901e96d2014-06-02 07:15:18 -0700160 fCurRandRect = 0;
161 }
162
163 const char* getRectsName() const {
164 if (fCurRects == &fRects[0]) {
165 return "Rand";
166 } else if (fCurRects == &fRects[1]) {
167 return "Pow2Rand";
168 } else {
169 return "SmallPow2";
170 }
171 }
172
173 void cycleRects() {
174 if (fCurRects == &fRects[0]) {
175 fCurRects = &fRects[1];
176 } else if (fCurRects == &fRects[1]) {
177 fCurRects = &fRects[2];
178 } else {
179 fCurRects = &fRects[0];
180 }
181
Florin Malitae5ae84b2017-12-24 11:45:38 -0500182 fRectanizers[fCurRectanizer]->reset();
robertphillips901e96d2014-06-02 07:15:18 -0700183 fCurRandRect = 0;
184 }
185
186 typedef SampleView INHERITED;
187};
188
189//////////////////////////////////////////////////////////////////////////////
190static SkView* MyFactory() { return new RectanizerView; }
191static SkViewRegister reg(MyFactory);
192
193#endif