1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2014 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include "include/core/SkCanvas.h"
9cb93a386Sopenharmony_ci#include "include/core/SkFont.h"
10cb93a386Sopenharmony_ci#include "include/core/SkPaint.h"
11cb93a386Sopenharmony_ci#include "include/utils/SkRandom.h"
12cb93a386Sopenharmony_ci#include "samplecode/Sample.h"
13cb93a386Sopenharmony_ci#include "src/utils/SkUTF.h"
14cb93a386Sopenharmony_ci#if SK_SUPPORT_GPU
15cb93a386Sopenharmony_ci#include "src/gpu/GrRectanizerPow2.h"
16cb93a386Sopenharmony_ci#include "src/gpu/GrRectanizerSkyline.h"
17cb93a386Sopenharmony_ci
18cb93a386Sopenharmony_ci// This slide visualizes the various GrRectanizer-derived classes behavior
19cb93a386Sopenharmony_ci// for various input sets
20cb93a386Sopenharmony_ci//  'j' will cycle through the various rectanizers
21cb93a386Sopenharmony_ci//          Pow2 -> GrRectanizerPow2
22cb93a386Sopenharmony_ci//          Skyline -> GrRectanizerSkyline
23cb93a386Sopenharmony_ci//  'h' will cycle through the various rect sets
24cb93a386Sopenharmony_ci//          Rand -> random rects from 2-256
25cb93a386Sopenharmony_ci//          Pow2Rand -> random power of 2 sized rects from 2-256
26cb93a386Sopenharmony_ci//          SmallPow2 -> 128x128 rects
27cb93a386Sopenharmony_ciclass RectanizerView : public Sample {
28cb93a386Sopenharmony_cipublic:
29cb93a386Sopenharmony_ci    RectanizerView()
30cb93a386Sopenharmony_ci        : fCurRandRect(0)
31cb93a386Sopenharmony_ci        , fCurRectanizer(0) {
32cb93a386Sopenharmony_ci        for (int i = 0; i < 3; ++i) {
33cb93a386Sopenharmony_ci           fRects[i].setReserve(kNumRandRects);
34cb93a386Sopenharmony_ci        }
35cb93a386Sopenharmony_ci        fRectLocations.setReserve(kNumRandRects);
36cb93a386Sopenharmony_ci
37cb93a386Sopenharmony_ci        SkRandom random;
38cb93a386Sopenharmony_ci        for (int i = 0; i < kNumRandRects; ++i) {
39cb93a386Sopenharmony_ci            *fRects[0].append() = SkISize::Make(random.nextRangeU(kMinRectSize, kMaxRectSize),
40cb93a386Sopenharmony_ci                                                random.nextRangeU(kMinRectSize, kMaxRectSize));
41cb93a386Sopenharmony_ci            *fRects[1].append() = SkISize::Make(
42cb93a386Sopenharmony_ci                        GrNextPow2(random.nextRangeU(kMinRectSize, kMaxRectSize)),
43cb93a386Sopenharmony_ci                        GrNextPow2(random.nextRangeU(kMinRectSize, kMaxRectSize)));
44cb93a386Sopenharmony_ci            *fRects[2].append() = SkISize::Make(128, 128);
45cb93a386Sopenharmony_ci            *fRectLocations.append() = SkIPoint16::Make(0, 0);
46cb93a386Sopenharmony_ci        }
47cb93a386Sopenharmony_ci
48cb93a386Sopenharmony_ci        fCurRects = &fRects[0];
49cb93a386Sopenharmony_ci
50cb93a386Sopenharmony_ci        fRectanizers.push_back(
51cb93a386Sopenharmony_ci            std::unique_ptr<GrRectanizer>(new GrRectanizerPow2(kWidth, kHeight)));
52cb93a386Sopenharmony_ci        fRectanizers.push_back(
53cb93a386Sopenharmony_ci            std::unique_ptr<GrRectanizer>(new GrRectanizerSkyline(kWidth, kHeight)));
54cb93a386Sopenharmony_ci    }
55cb93a386Sopenharmony_ci
56cb93a386Sopenharmony_ciprotected:
57cb93a386Sopenharmony_ci    SkString name() override { return SkString("Rectanizer"); }
58cb93a386Sopenharmony_ci
59cb93a386Sopenharmony_ci    bool onChar(SkUnichar uni) override {
60cb93a386Sopenharmony_ci            char utf8[SkUTF::kMaxBytesInUTF8Sequence];
61cb93a386Sopenharmony_ci            size_t size = SkUTF::ToUTF8(uni, utf8);
62cb93a386Sopenharmony_ci            // Only consider events for single char keys
63cb93a386Sopenharmony_ci            if (1 == size) {
64cb93a386Sopenharmony_ci                switch (utf8[0]) {
65cb93a386Sopenharmony_ci                case kCycleRectanizerKey:
66cb93a386Sopenharmony_ci                    this->cycleRectanizer();
67cb93a386Sopenharmony_ci                    return true;
68cb93a386Sopenharmony_ci                case kCycleRectsKey:
69cb93a386Sopenharmony_ci                    this->cycleRects();
70cb93a386Sopenharmony_ci                    return true;
71cb93a386Sopenharmony_ci                default:
72cb93a386Sopenharmony_ci                    break;
73cb93a386Sopenharmony_ci                }
74cb93a386Sopenharmony_ci            }
75cb93a386Sopenharmony_ci            return false;
76cb93a386Sopenharmony_ci    }
77cb93a386Sopenharmony_ci
78cb93a386Sopenharmony_ci    void onDrawContent(SkCanvas* canvas) override {
79cb93a386Sopenharmony_ci        if (fCurRandRect < kNumRandRects) {
80cb93a386Sopenharmony_ci            if (fRectanizers[fCurRectanizer]->addRect((*fCurRects)[fCurRandRect].fWidth,
81cb93a386Sopenharmony_ci                                                      (*fCurRects)[fCurRandRect].fHeight,
82cb93a386Sopenharmony_ci                                                      &fRectLocations[fCurRandRect])) {
83cb93a386Sopenharmony_ci                ++fCurRandRect;
84cb93a386Sopenharmony_ci            }
85cb93a386Sopenharmony_ci        }
86cb93a386Sopenharmony_ci
87cb93a386Sopenharmony_ci        SkFont blackBigFont;
88cb93a386Sopenharmony_ci        blackBigFont.setSize(20);
89cb93a386Sopenharmony_ci        SkPaint blackStroke;
90cb93a386Sopenharmony_ci        blackStroke.setStyle(SkPaint::kStroke_Style);
91cb93a386Sopenharmony_ci        SkPaint redFill;
92cb93a386Sopenharmony_ci        redFill.setColor(SK_ColorRED);
93cb93a386Sopenharmony_ci
94cb93a386Sopenharmony_ci        SkRect r = SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight));
95cb93a386Sopenharmony_ci
96cb93a386Sopenharmony_ci        canvas->clear(SK_ColorWHITE);
97cb93a386Sopenharmony_ci        canvas->drawRect(r, blackStroke);
98cb93a386Sopenharmony_ci
99cb93a386Sopenharmony_ci        long totArea = 0;
100cb93a386Sopenharmony_ci        for (int i = 0; i < fCurRandRect; ++i) {
101cb93a386Sopenharmony_ci            r = SkRect::MakeXYWH(SkIntToScalar(fRectLocations[i].fX),
102cb93a386Sopenharmony_ci                                 SkIntToScalar(fRectLocations[i].fY),
103cb93a386Sopenharmony_ci                                 SkIntToScalar((*fCurRects)[i].fWidth),
104cb93a386Sopenharmony_ci                                 SkIntToScalar((*fCurRects)[i].fHeight));
105cb93a386Sopenharmony_ci            canvas->drawRect(r, redFill);
106cb93a386Sopenharmony_ci            canvas->drawRect(r, blackStroke);
107cb93a386Sopenharmony_ci            totArea += (*fCurRects)[i].fWidth * (*fCurRects)[i].fHeight;
108cb93a386Sopenharmony_ci        }
109cb93a386Sopenharmony_ci
110cb93a386Sopenharmony_ci        SkString str;
111cb93a386Sopenharmony_ci
112cb93a386Sopenharmony_ci        str.printf("%s-%s: tot Area: %ld %%full: %.2f (%.2f) numTextures: %d/%d",
113cb93a386Sopenharmony_ci                   this->getRectanizerName(),
114cb93a386Sopenharmony_ci                   this->getRectsName(),
115cb93a386Sopenharmony_ci                   totArea,
116cb93a386Sopenharmony_ci                   100.0f * fRectanizers[fCurRectanizer]->percentFull(),
117cb93a386Sopenharmony_ci                   100.0f * totArea / ((float)kWidth*kHeight),
118cb93a386Sopenharmony_ci                   fCurRandRect,
119cb93a386Sopenharmony_ci                   kNumRandRects);
120cb93a386Sopenharmony_ci        canvas->drawString(str, 50, kHeight + 50, blackBigFont, SkPaint());
121cb93a386Sopenharmony_ci
122cb93a386Sopenharmony_ci        str.printf("Press \'j\' to toggle rectanizer");
123cb93a386Sopenharmony_ci        canvas->drawString(str, 50, kHeight + 100, blackBigFont, SkPaint());
124cb93a386Sopenharmony_ci
125cb93a386Sopenharmony_ci        str.printf("Press \'h\' to toggle rects");
126cb93a386Sopenharmony_ci        canvas->drawString(str, 50, kHeight + 150, blackBigFont, SkPaint());
127cb93a386Sopenharmony_ci    }
128cb93a386Sopenharmony_ci
129cb93a386Sopenharmony_ciprivate:
130cb93a386Sopenharmony_ci    static const int kWidth = 1024;
131cb93a386Sopenharmony_ci    static const int kHeight = 1024;
132cb93a386Sopenharmony_ci    static const int kNumRandRects = 200;
133cb93a386Sopenharmony_ci    static const char kCycleRectanizerKey = 'j';
134cb93a386Sopenharmony_ci    static const char kCycleRectsKey = 'h';
135cb93a386Sopenharmony_ci    static const int kMinRectSize = 2;
136cb93a386Sopenharmony_ci    static const int kMaxRectSize = 256;
137cb93a386Sopenharmony_ci
138cb93a386Sopenharmony_ci    int                                     fCurRandRect;
139cb93a386Sopenharmony_ci    SkTDArray<SkISize>                      fRects[3];
140cb93a386Sopenharmony_ci    SkTDArray<SkISize>*                     fCurRects;
141cb93a386Sopenharmony_ci    SkTDArray<SkIPoint16>                   fRectLocations;
142cb93a386Sopenharmony_ci    SkTArray<std::unique_ptr<GrRectanizer>> fRectanizers;
143cb93a386Sopenharmony_ci    int                                     fCurRectanizer;
144cb93a386Sopenharmony_ci
145cb93a386Sopenharmony_ci    const char* getRectanizerName() const {
146cb93a386Sopenharmony_ci        if (!fCurRectanizer) {
147cb93a386Sopenharmony_ci            return "Pow2";
148cb93a386Sopenharmony_ci        } else {
149cb93a386Sopenharmony_ci            return "Skyline";
150cb93a386Sopenharmony_ci        }
151cb93a386Sopenharmony_ci    }
152cb93a386Sopenharmony_ci
153cb93a386Sopenharmony_ci    void cycleRectanizer() {
154cb93a386Sopenharmony_ci        fCurRectanizer = (fCurRectanizer + 1) % fRectanizers.count();
155cb93a386Sopenharmony_ci
156cb93a386Sopenharmony_ci        fRectanizers[fCurRectanizer]->reset();
157cb93a386Sopenharmony_ci        fCurRandRect = 0;
158cb93a386Sopenharmony_ci    }
159cb93a386Sopenharmony_ci
160cb93a386Sopenharmony_ci    const char* getRectsName() const {
161cb93a386Sopenharmony_ci        if (fCurRects == &fRects[0]) {
162cb93a386Sopenharmony_ci            return "Rand";
163cb93a386Sopenharmony_ci        } else if (fCurRects == &fRects[1]) {
164cb93a386Sopenharmony_ci            return "Pow2Rand";
165cb93a386Sopenharmony_ci        } else {
166cb93a386Sopenharmony_ci            return "SmallPow2";
167cb93a386Sopenharmony_ci        }
168cb93a386Sopenharmony_ci    }
169cb93a386Sopenharmony_ci
170cb93a386Sopenharmony_ci    void cycleRects() {
171cb93a386Sopenharmony_ci        if (fCurRects == &fRects[0]) {
172cb93a386Sopenharmony_ci            fCurRects = &fRects[1];
173cb93a386Sopenharmony_ci        } else if (fCurRects == &fRects[1]) {
174cb93a386Sopenharmony_ci            fCurRects = &fRects[2];
175cb93a386Sopenharmony_ci        } else {
176cb93a386Sopenharmony_ci            fCurRects = &fRects[0];
177cb93a386Sopenharmony_ci        }
178cb93a386Sopenharmony_ci
179cb93a386Sopenharmony_ci        fRectanizers[fCurRectanizer]->reset();
180cb93a386Sopenharmony_ci        fCurRandRect = 0;
181cb93a386Sopenharmony_ci    }
182cb93a386Sopenharmony_ci
183cb93a386Sopenharmony_ci    using INHERITED = Sample;
184cb93a386Sopenharmony_ci};
185cb93a386Sopenharmony_ci
186cb93a386Sopenharmony_ci//////////////////////////////////////////////////////////////////////////////
187cb93a386Sopenharmony_ci
188cb93a386Sopenharmony_ciDEF_SAMPLE( return new RectanizerView(); )
189cb93a386Sopenharmony_ci
190cb93a386Sopenharmony_ci#endif
191