blob: 2b81079973b4299cadd52e20c1e75cf7908c70da [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
Chris Daltone5a141d2020-05-19 11:57:53 -060015#include "src/gpu/GrRectanizerPow2.h"
Herb Derby73c75872020-01-22 18:09:16 -050016#include "src/gpu/GrRectanizerSkyline.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
Chris Daltone5a141d2020-05-19 11:57:53 -060020// 'j' will cycle through the various rectanizers
21// Pow2 -> GrRectanizerPow2
22// Skyline -> GrRectanizerSkyline
robertphillips901e96d2014-06-02 07:15:18 -070023// '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
Chris Daltone5a141d2020-05-19 11:57:53 -060050 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:
Hal Canary8a027312019-07-03 10:55:44 -040057 SkString name() override { return SkString("Rectanizer"); }
58
Hal Canary6cc65e12019-07-03 15:53:04 -040059 bool onChar(SkUnichar uni) override {
Hal Canaryf107a2f2018-07-25 16:52:48 -040060 char utf8[SkUTF::kMaxBytesInUTF8Sequence];
61 size_t size = SkUTF::ToUTF8(uni, utf8);
robertphillips901e96d2014-06-02 07:15:18 -070062 // Only consider events for single char keys
63 if (1 == size) {
64 switch (utf8[0]) {
Chris Daltone5a141d2020-05-19 11:57:53 -060065 case kCycleRectanizerKey:
66 this->cycleRectanizer();
67 return true;
robertphillips901e96d2014-06-02 07:15:18 -070068 case kCycleRectsKey:
69 this->cycleRects();
70 return true;
71 default:
72 break;
73 }
74 }
Hal Canary6cc65e12019-07-03 15:53:04 -040075 return false;
robertphillips901e96d2014-06-02 07:15:18 -070076 }
77
mtklein36352bf2015-03-25 18:17:31 -070078 void onDrawContent(SkCanvas* canvas) override {
robertphillips901e96d2014-06-02 07:15:18 -070079 if (fCurRandRect < kNumRandRects) {
Chris Daltone5a141d2020-05-19 11:57:53 -060080 if (fRectanizers[fCurRectanizer]->addRect((*fCurRects)[fCurRandRect].fWidth,
81 (*fCurRects)[fCurRandRect].fHeight,
82 &fRectLocations[fCurRandRect])) {
robertphillips901e96d2014-06-02 07:15:18 -070083 ++fCurRandRect;
84 }
85 }
86
Mike Reed89126e42019-01-03 12:59:14 -050087 SkFont blackBigFont;
88 blackBigFont.setSize(20);
robertphillips901e96d2014-06-02 07:15:18 -070089 SkPaint blackStroke;
90 blackStroke.setStyle(SkPaint::kStroke_Style);
91 SkPaint redFill;
92 redFill.setColor(SK_ColorRED);
93
94 SkRect r = SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight));
95
96 canvas->clear(SK_ColorWHITE);
97 canvas->drawRect(r, blackStroke);
98
99 long totArea = 0;
100 for (int i = 0; i < fCurRandRect; ++i) {
halcanary9d524f22016-03-29 09:03:52 -0700101 r = SkRect::MakeXYWH(SkIntToScalar(fRectLocations[i].fX),
robertphillips901e96d2014-06-02 07:15:18 -0700102 SkIntToScalar(fRectLocations[i].fY),
103 SkIntToScalar((*fCurRects)[i].fWidth),
104 SkIntToScalar((*fCurRects)[i].fHeight));
105 canvas->drawRect(r, redFill);
106 canvas->drawRect(r, blackStroke);
107 totArea += (*fCurRects)[i].fWidth * (*fCurRects)[i].fHeight;
108 }
109
110 SkString str;
111
Chris Daltone5a141d2020-05-19 11:57:53 -0600112 str.printf("%s-%s: tot Area: %ld %%full: %.2f (%.2f) numTextures: %d/%d",
robertphillips901e96d2014-06-02 07:15:18 -0700113 this->getRectanizerName(),
114 this->getRectsName(),
115 totArea,
Chris Daltone5a141d2020-05-19 11:57:53 -0600116 100.0f * fRectanizers[fCurRectanizer]->percentFull(),
robertphillips901e96d2014-06-02 07:15:18 -0700117 100.0f * totArea / ((float)kWidth*kHeight),
118 fCurRandRect,
119 kNumRandRects);
Hal Canary89a644b2019-01-07 09:36:09 -0500120 canvas->drawString(str, 50, kHeight + 50, blackBigFont, SkPaint());
robertphillips901e96d2014-06-02 07:15:18 -0700121
Chris Daltone5a141d2020-05-19 11:57:53 -0600122 str.printf("Press \'j\' to toggle rectanizer");
123 canvas->drawString(str, 50, kHeight + 100, blackBigFont, SkPaint());
124
robertphillips901e96d2014-06-02 07:15:18 -0700125 str.printf("Press \'h\' to toggle rects");
Hal Canary89a644b2019-01-07 09:36:09 -0500126 canvas->drawString(str, 50, kHeight + 150, blackBigFont, SkPaint());
robertphillips901e96d2014-06-02 07:15:18 -0700127 }
128
129private:
Chris Daltone5a141d2020-05-19 11:57:53 -0600130 static const int kWidth = 1024;
131 static const int kHeight = 1024;
robertphillips901e96d2014-06-02 07:15:18 -0700132 static const int kNumRandRects = 200;
Chris Daltone5a141d2020-05-19 11:57:53 -0600133 static const char kCycleRectanizerKey = 'j';
robertphillips901e96d2014-06-02 07:15:18 -0700134 static const char kCycleRectsKey = 'h';
135 static const int kMinRectSize = 2;
136 static const int kMaxRectSize = 256;
137
Chris Daltone5a141d2020-05-19 11:57:53 -0600138 int fCurRandRect;
139 SkTDArray<SkISize> fRects[3];
140 SkTDArray<SkISize>* fCurRects;
141 SkTDArray<SkIPoint16> fRectLocations;
142 SkTArray<std::unique_ptr<GrRectanizer>> fRectanizers;
143 int fCurRectanizer;
robertphillips901e96d2014-06-02 07:15:18 -0700144
145 const char* getRectanizerName() const {
Chris Daltone5a141d2020-05-19 11:57:53 -0600146 if (!fCurRectanizer) {
147 return "Pow2";
148 } else {
149 return "Skyline";
150 }
151 }
152
153 void cycleRectanizer() {
154 fCurRectanizer = (fCurRectanizer + 1) % fRectanizers.count();
155
156 fRectanizers[fCurRectanizer]->reset();
157 fCurRandRect = 0;
robertphillips901e96d2014-06-02 07:15:18 -0700158 }
159
160 const char* getRectsName() const {
161 if (fCurRects == &fRects[0]) {
162 return "Rand";
163 } else if (fCurRects == &fRects[1]) {
164 return "Pow2Rand";
165 } else {
166 return "SmallPow2";
167 }
168 }
169
170 void cycleRects() {
171 if (fCurRects == &fRects[0]) {
172 fCurRects = &fRects[1];
173 } else if (fCurRects == &fRects[1]) {
174 fCurRects = &fRects[2];
175 } else {
176 fCurRects = &fRects[0];
177 }
178
Chris Daltone5a141d2020-05-19 11:57:53 -0600179 fRectanizers[fCurRectanizer]->reset();
robertphillips901e96d2014-06-02 07:15:18 -0700180 fCurRandRect = 0;
181 }
182
John Stiles7571f9e2020-09-02 22:42:33 -0400183 using INHERITED = Sample;
robertphillips901e96d2014-06-02 07:15:18 -0700184};
185
186//////////////////////////////////////////////////////////////////////////////
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400187
188DEF_SAMPLE( return new RectanizerView(); )
robertphillips901e96d2014-06-02 07:15:18 -0700189
190#endif