• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 "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/core/SkMathPriv.h"
14 #include "src/utils/SkUTF.h"
15 #if SK_SUPPORT_GPU
16 #include "src/gpu/GrRectanizerSkyline.h"
17 
18 // This slide visualizes the various GrRectanizer-derived classes behavior
19 // for various input sets
20 //  '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
24 class RectanizerView : public Sample {
25     static constexpr int kWidth = 1024;
26     static constexpr int kHeight = 1024;
27 public:
RectanizerView()28     RectanizerView()
29         : fCurRandRect(0)
30         , fCurRectanizer(0) {
31         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);
44             *fRectLocations.append() = SkIPoint16::Make(0, 0);
45         }
46 
47         fCurRects = &fRects[0];
48 
49         fRectanizers.emplace_back(kWidth, kHeight);
50     }
51 
52 protected:
name()53     SkString name() override { return SkString("Rectanizer"); }
54 
onChar(SkUnichar uni)55     bool onChar(SkUnichar uni) override {
56             char utf8[SkUTF::kMaxBytesInUTF8Sequence];
57             size_t size = SkUTF::ToUTF8(uni, utf8);
58             // Only consider events for single char keys
59             if (1 == size) {
60                 switch (utf8[0]) {
61                 case kCycleRectsKey:
62                     this->cycleRects();
63                     return true;
64                 default:
65                     break;
66                 }
67             }
68             return false;
69     }
70 
onDrawContent(SkCanvas * canvas)71     void onDrawContent(SkCanvas* canvas) override {
72         if (fCurRandRect < kNumRandRects) {
73             if (fRectanizers[fCurRectanizer].addRect((*fCurRects)[fCurRandRect].fWidth,
74                                                      (*fCurRects)[fCurRandRect].fHeight,
75                                                      &fRectLocations[fCurRandRect])) {
76                 ++fCurRandRect;
77             }
78         }
79 
80         SkFont blackBigFont;
81         blackBigFont.setSize(20);
82         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) {
94             r = SkRect::MakeXYWH(SkIntToScalar(fRectLocations[i].fX),
95                                  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 
105         str.printf("%s-%s: tot Area: %ld (%.2f) numTextures: %d/%d",
106                    this->getRectanizerName(),
107                    this->getRectsName(),
108                    totArea,
109                    100.0f * totArea / ((float)kWidth*kHeight),
110                    fCurRandRect,
111                    kNumRandRects);
112         canvas->drawString(str, 50, kHeight + 50, blackBigFont, SkPaint());
113 
114         str.printf("Press \'h\' to toggle rects");
115         canvas->drawString(str, 50, kHeight + 150, blackBigFont, SkPaint());
116     }
117 
118 private:
119     static const int kNumRandRects = 200;
120     static const char kCycleRectsKey = 'h';
121     static const int kMinRectSize = 2;
122     static const int kMaxRectSize = 256;
123 
124     int                           fCurRandRect;
125     SkTDArray<SkISize>            fRects[3];
126     SkTDArray<SkISize>*           fCurRects;
127     SkTDArray<SkIPoint16>         fRectLocations;
128     SkTArray<GrRectanizerSkyline> fRectanizers;
129     int                           fCurRectanizer;
130 
getRectanizerName() const131     const char* getRectanizerName() const {
132         return "Skyline";
133     }
134 
getRectsName() const135     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 
cycleRects()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 
154         fRectanizers[fCurRectanizer].reset();
155         fCurRandRect = 0;
156     }
157 
158     typedef Sample INHERITED;
159 };
160 
161 //////////////////////////////////////////////////////////////////////////////
162 
163 DEF_SAMPLE( return new RectanizerView(); )
164 
165 #endif
166