blob: 41420a9f08a5cef5201845a6a6b1d23bd225cc46 [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"
Herb Derby73c75872020-01-22 18:09:16 -050013#include "src/core/SkMathPriv.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "src/utils/SkUTF.h"
robertphillips901e96d2014-06-02 07:15:18 -070015#if SK_SUPPORT_GPU
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
robertphillips901e96d2014-06-02 07:15:18 -070020// 'h' will cycle through the various rect sets
21// Rand -> random rects from 2-256
22// Pow2Rand -> random power of 2 sized rects from 2-256
23// SmallPow2 -> 128x128 rects
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040024class RectanizerView : public Sample {
Herb Derby73c75872020-01-22 18:09:16 -050025 static constexpr int kWidth = 1024;
26 static constexpr int kHeight = 1024;
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
Herb Derby73c75872020-01-22 18:09:16 -050049 fRectanizers.emplace_back(kWidth, kHeight);
robertphillips901e96d2014-06-02 07:15:18 -070050 }
51
52protected:
Hal Canary8a027312019-07-03 10:55:44 -040053 SkString name() override { return SkString("Rectanizer"); }
54
Hal Canary6cc65e12019-07-03 15:53:04 -040055 bool onChar(SkUnichar uni) override {
Hal Canaryf107a2f2018-07-25 16:52:48 -040056 char utf8[SkUTF::kMaxBytesInUTF8Sequence];
57 size_t size = SkUTF::ToUTF8(uni, utf8);
robertphillips901e96d2014-06-02 07:15:18 -070058 // Only consider events for single char keys
59 if (1 == size) {
60 switch (utf8[0]) {
robertphillips901e96d2014-06-02 07:15:18 -070061 case kCycleRectsKey:
62 this->cycleRects();
63 return true;
64 default:
65 break;
66 }
67 }
Hal Canary6cc65e12019-07-03 15:53:04 -040068 return false;
robertphillips901e96d2014-06-02 07:15:18 -070069 }
70
mtklein36352bf2015-03-25 18:17:31 -070071 void onDrawContent(SkCanvas* canvas) override {
robertphillips901e96d2014-06-02 07:15:18 -070072 if (fCurRandRect < kNumRandRects) {
Herb Derby73c75872020-01-22 18:09:16 -050073 if (fRectanizers[fCurRectanizer].addRect((*fCurRects)[fCurRandRect].fWidth,
74 (*fCurRects)[fCurRandRect].fHeight,
75 &fRectLocations[fCurRandRect])) {
robertphillips901e96d2014-06-02 07:15:18 -070076 ++fCurRandRect;
77 }
78 }
79
Mike Reed89126e42019-01-03 12:59:14 -050080 SkFont blackBigFont;
81 blackBigFont.setSize(20);
robertphillips901e96d2014-06-02 07:15:18 -070082 SkPaint blackStroke;
83 blackStroke.setStyle(SkPaint::kStroke_Style);
84 SkPaint redFill;
85 redFill.setColor(SK_ColorRED);
86
87 SkRect r = SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight));
88
89 canvas->clear(SK_ColorWHITE);
90 canvas->drawRect(r, blackStroke);
91
92 long totArea = 0;
93 for (int i = 0; i < fCurRandRect; ++i) {
halcanary9d524f22016-03-29 09:03:52 -070094 r = SkRect::MakeXYWH(SkIntToScalar(fRectLocations[i].fX),
robertphillips901e96d2014-06-02 07:15:18 -070095 SkIntToScalar(fRectLocations[i].fY),
96 SkIntToScalar((*fCurRects)[i].fWidth),
97 SkIntToScalar((*fCurRects)[i].fHeight));
98 canvas->drawRect(r, redFill);
99 canvas->drawRect(r, blackStroke);
100 totArea += (*fCurRects)[i].fWidth * (*fCurRects)[i].fHeight;
101 }
102
103 SkString str;
104
Herb Derby73c75872020-01-22 18:09:16 -0500105 str.printf("%s-%s: tot Area: %ld (%.2f) numTextures: %d/%d",
robertphillips901e96d2014-06-02 07:15:18 -0700106 this->getRectanizerName(),
107 this->getRectsName(),
108 totArea,
robertphillips901e96d2014-06-02 07:15:18 -0700109 100.0f * totArea / ((float)kWidth*kHeight),
110 fCurRandRect,
111 kNumRandRects);
Hal Canary89a644b2019-01-07 09:36:09 -0500112 canvas->drawString(str, 50, kHeight + 50, blackBigFont, SkPaint());
robertphillips901e96d2014-06-02 07:15:18 -0700113
robertphillips901e96d2014-06-02 07:15:18 -0700114 str.printf("Press \'h\' to toggle rects");
Hal Canary89a644b2019-01-07 09:36:09 -0500115 canvas->drawString(str, 50, kHeight + 150, blackBigFont, SkPaint());
robertphillips901e96d2014-06-02 07:15:18 -0700116 }
117
118private:
robertphillips901e96d2014-06-02 07:15:18 -0700119 static const int kNumRandRects = 200;
robertphillips901e96d2014-06-02 07:15:18 -0700120 static const char kCycleRectsKey = 'h';
121 static const int kMinRectSize = 2;
122 static const int kMaxRectSize = 256;
123
Herb Derby73c75872020-01-22 18:09:16 -0500124 int fCurRandRect;
125 SkTDArray<SkISize> fRects[3];
126 SkTDArray<SkISize>* fCurRects;
127 SkTDArray<SkIPoint16> fRectLocations;
128 SkTArray<GrRectanizerSkyline> fRectanizers;
129 int fCurRectanizer;
robertphillips901e96d2014-06-02 07:15:18 -0700130
131 const char* getRectanizerName() const {
Herb Derby73c75872020-01-22 18:09:16 -0500132 return "Skyline";
robertphillips901e96d2014-06-02 07:15:18 -0700133 }
134
135 const char* getRectsName() const {
136 if (fCurRects == &fRects[0]) {
137 return "Rand";
138 } else if (fCurRects == &fRects[1]) {
139 return "Pow2Rand";
140 } else {
141 return "SmallPow2";
142 }
143 }
144
145 void cycleRects() {
146 if (fCurRects == &fRects[0]) {
147 fCurRects = &fRects[1];
148 } else if (fCurRects == &fRects[1]) {
149 fCurRects = &fRects[2];
150 } else {
151 fCurRects = &fRects[0];
152 }
153
Herb Derby73c75872020-01-22 18:09:16 -0500154 fRectanizers[fCurRectanizer].reset();
robertphillips901e96d2014-06-02 07:15:18 -0700155 fCurRandRect = 0;
156 }
157
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400158 typedef Sample INHERITED;
robertphillips901e96d2014-06-02 07:15:18 -0700159};
160
161//////////////////////////////////////////////////////////////////////////////
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400162
163DEF_SAMPLE( return new RectanizerView(); )
robertphillips901e96d2014-06-02 07:15:18 -0700164
165#endif