blob: ecf44c5de0ca35053fe0009dce0bb03bbc62da6e [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#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"
robertphillips901e96d2014-06-02 07:15:18 -070014#if SK_SUPPORT_GPU
Mike Kleinc0bd9f92019-04-23 12:05:21 -050015#include "src/gpu/GrRectanizer_pow2.h"
16#include "src/gpu/GrRectanizer_skyline.h"
robertphillips901e96d2014-06-02 07:15:18 -070017
robertphillips901e96d2014-06-02 07:15:18 -070018// 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
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040027class RectanizerView : public Sample {
robertphillips901e96d2014-06-02 07:15:18 -070028public:
29 RectanizerView()
Florin Malitae5ae84b2017-12-24 11:45:38 -050030 : fCurRandRect(0)
31 , fCurRectanizer(0) {
robertphillips901e96d2014-06-02 07:15:18 -070032 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);
robertphillipsd5373412014-06-02 10:20:14 -070045 *fRectLocations.append() = SkIPoint16::Make(0, 0);
robertphillips901e96d2014-06-02 07:15:18 -070046 }
47
48 fCurRects = &fRects[0];
49
Florin Malitae5ae84b2017-12-24 11:45:38 -050050 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)));
robertphillips901e96d2014-06-02 07:15:18 -070054 }
55
56protected:
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040057 bool onQuery(Sample::Event* evt) override {
58 if (Sample::TitleQ(*evt)) {
59 Sample::TitleR(evt, "Rectanizer");
robertphillips901e96d2014-06-02 07:15:18 -070060 return true;
61 }
62 SkUnichar uni;
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040063 if (Sample::CharQ(*evt, &uni)) {
Hal Canaryf107a2f2018-07-25 16:52:48 -040064 char utf8[SkUTF::kMaxBytesInUTF8Sequence];
65 size_t size = SkUTF::ToUTF8(uni, utf8);
robertphillips901e96d2014-06-02 07:15:18 -070066 // Only consider events for single char keys
67 if (1 == size) {
68 switch (utf8[0]) {
69 case kCycleRectanizerKey:
70 this->cycleRectanizer();
71 return true;
72 case kCycleRectsKey:
73 this->cycleRects();
74 return true;
75 default:
76 break;
77 }
78 }
79 }
80 return this->INHERITED::onQuery(evt);
81 }
82
mtklein36352bf2015-03-25 18:17:31 -070083 void onDrawContent(SkCanvas* canvas) override {
robertphillips901e96d2014-06-02 07:15:18 -070084 if (fCurRandRect < kNumRandRects) {
Florin Malitae5ae84b2017-12-24 11:45:38 -050085 if (fRectanizers[fCurRectanizer]->addRect((*fCurRects)[fCurRandRect].fWidth,
86 (*fCurRects)[fCurRandRect].fHeight,
87 &fRectLocations[fCurRandRect])) {
robertphillips901e96d2014-06-02 07:15:18 -070088 ++fCurRandRect;
89 }
90 }
91
Mike Reed89126e42019-01-03 12:59:14 -050092 SkFont blackBigFont;
93 blackBigFont.setSize(20);
robertphillips901e96d2014-06-02 07:15:18 -070094 SkPaint blackStroke;
95 blackStroke.setStyle(SkPaint::kStroke_Style);
96 SkPaint redFill;
97 redFill.setColor(SK_ColorRED);
98
99 SkRect r = SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight));
100
101 canvas->clear(SK_ColorWHITE);
102 canvas->drawRect(r, blackStroke);
103
104 long totArea = 0;
105 for (int i = 0; i < fCurRandRect; ++i) {
halcanary9d524f22016-03-29 09:03:52 -0700106 r = SkRect::MakeXYWH(SkIntToScalar(fRectLocations[i].fX),
robertphillips901e96d2014-06-02 07:15:18 -0700107 SkIntToScalar(fRectLocations[i].fY),
108 SkIntToScalar((*fCurRects)[i].fWidth),
109 SkIntToScalar((*fCurRects)[i].fHeight));
110 canvas->drawRect(r, redFill);
111 canvas->drawRect(r, blackStroke);
112 totArea += (*fCurRects)[i].fWidth * (*fCurRects)[i].fHeight;
113 }
114
115 SkString str;
116
117 str.printf("%s-%s: tot Area: %ld %%full: %.2f (%.2f) numTextures: %d/%d",
118 this->getRectanizerName(),
119 this->getRectsName(),
120 totArea,
Florin Malitae5ae84b2017-12-24 11:45:38 -0500121 100.0f * fRectanizers[fCurRectanizer]->percentFull(),
robertphillips901e96d2014-06-02 07:15:18 -0700122 100.0f * totArea / ((float)kWidth*kHeight),
123 fCurRandRect,
124 kNumRandRects);
Hal Canary89a644b2019-01-07 09:36:09 -0500125 canvas->drawString(str, 50, kHeight + 50, blackBigFont, SkPaint());
robertphillips901e96d2014-06-02 07:15:18 -0700126
127 str.printf("Press \'j\' to toggle rectanizer");
Hal Canary89a644b2019-01-07 09:36:09 -0500128 canvas->drawString(str, 50, kHeight + 100, blackBigFont, SkPaint());
robertphillips901e96d2014-06-02 07:15:18 -0700129
130 str.printf("Press \'h\' to toggle rects");
Hal Canary89a644b2019-01-07 09:36:09 -0500131 canvas->drawString(str, 50, kHeight + 150, blackBigFont, SkPaint());
robertphillips901e96d2014-06-02 07:15:18 -0700132 }
133
134private:
135 static const int kWidth = 1024;
136 static const int kHeight = 1024;
137 static const int kNumRandRects = 200;
138 static const char kCycleRectanizerKey = 'j';
139 static const char kCycleRectsKey = 'h';
140 static const int kMinRectSize = 2;
141 static const int kMaxRectSize = 256;
142
Florin Malitae5ae84b2017-12-24 11:45:38 -0500143 int fCurRandRect;
144 SkTDArray<SkISize> fRects[3];
145 SkTDArray<SkISize>* fCurRects;
146 SkTDArray<SkIPoint16> fRectLocations;
147 SkTArray<std::unique_ptr<GrRectanizer>> fRectanizers;
148 int fCurRectanizer;
robertphillips901e96d2014-06-02 07:15:18 -0700149
150 const char* getRectanizerName() const {
Florin Malitae5ae84b2017-12-24 11:45:38 -0500151 if (!fCurRectanizer) {
robertphillips901e96d2014-06-02 07:15:18 -0700152 return "Pow2";
153 } else {
154 return "Skyline";
155 }
156 }
157
158 void cycleRectanizer() {
Florin Malitae5ae84b2017-12-24 11:45:38 -0500159 fCurRectanizer = (fCurRectanizer + 1) % fRectanizers.count();
robertphillips901e96d2014-06-02 07:15:18 -0700160
Florin Malitae5ae84b2017-12-24 11:45:38 -0500161 fRectanizers[fCurRectanizer]->reset();
robertphillips901e96d2014-06-02 07:15:18 -0700162 fCurRandRect = 0;
163 }
164
165 const char* getRectsName() const {
166 if (fCurRects == &fRects[0]) {
167 return "Rand";
168 } else if (fCurRects == &fRects[1]) {
169 return "Pow2Rand";
170 } else {
171 return "SmallPow2";
172 }
173 }
174
175 void cycleRects() {
176 if (fCurRects == &fRects[0]) {
177 fCurRects = &fRects[1];
178 } else if (fCurRects == &fRects[1]) {
179 fCurRects = &fRects[2];
180 } else {
181 fCurRects = &fRects[0];
182 }
183
Florin Malitae5ae84b2017-12-24 11:45:38 -0500184 fRectanizers[fCurRectanizer]->reset();
robertphillips901e96d2014-06-02 07:15:18 -0700185 fCurRandRect = 0;
186 }
187
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400188 typedef Sample INHERITED;
robertphillips901e96d2014-06-02 07:15:18 -0700189};
190
191//////////////////////////////////////////////////////////////////////////////
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400192
193DEF_SAMPLE( return new RectanizerView(); )
robertphillips901e96d2014-06-02 07:15:18 -0700194
195#endif