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