2014-06-02 14:15:18 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2014 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
2018-08-08 15:36:17 +00:00
|
|
|
#include "Sample.h"
|
|
|
|
#include "SkCanvas.h"
|
2019-01-03 17:59:14 +00:00
|
|
|
#include "SkFont.h"
|
2014-06-02 14:15:18 +00:00
|
|
|
#include "SkRandom.h"
|
2018-08-08 15:36:17 +00:00
|
|
|
#include "SkPaint.h"
|
2018-08-21 15:45:46 +00:00
|
|
|
#include "SkUTF.h"
|
2014-06-02 14:15:18 +00:00
|
|
|
#if SK_SUPPORT_GPU
|
|
|
|
#include "GrRectanizer_pow2.h"
|
|
|
|
#include "GrRectanizer_skyline.h"
|
|
|
|
|
|
|
|
// This slide visualizes the various GrRectanizer-derived classes behavior
|
|
|
|
// for various input sets
|
|
|
|
// 'j' will cycle through the various rectanizers
|
|
|
|
// Pow2 -> GrRectanizerPow2
|
|
|
|
// Skyline -> GrRectanizerSkyline
|
|
|
|
// 'h' will cycle through the various rect sets
|
|
|
|
// Rand -> random rects from 2-256
|
|
|
|
// Pow2Rand -> random power of 2 sized rects from 2-256
|
|
|
|
// SmallPow2 -> 128x128 rects
|
2018-08-08 15:36:17 +00:00
|
|
|
class RectanizerView : public Sample {
|
2014-06-02 14:15:18 +00:00
|
|
|
public:
|
|
|
|
RectanizerView()
|
2017-12-24 16:45:38 +00:00
|
|
|
: fCurRandRect(0)
|
|
|
|
, fCurRectanizer(0) {
|
2014-06-02 14:15:18 +00:00
|
|
|
for (int i = 0; i < 3; ++i) {
|
|
|
|
fRects[i].setReserve(kNumRandRects);
|
|
|
|
}
|
|
|
|
fRectLocations.setReserve(kNumRandRects);
|
|
|
|
|
|
|
|
SkRandom random;
|
|
|
|
for (int i = 0; i < kNumRandRects; ++i) {
|
|
|
|
*fRects[0].append() = SkISize::Make(random.nextRangeU(kMinRectSize, kMaxRectSize),
|
|
|
|
random.nextRangeU(kMinRectSize, kMaxRectSize));
|
|
|
|
*fRects[1].append() = SkISize::Make(
|
|
|
|
GrNextPow2(random.nextRangeU(kMinRectSize, kMaxRectSize)),
|
|
|
|
GrNextPow2(random.nextRangeU(kMinRectSize, kMaxRectSize)));
|
|
|
|
*fRects[2].append() = SkISize::Make(128, 128);
|
2014-06-02 17:20:14 +00:00
|
|
|
*fRectLocations.append() = SkIPoint16::Make(0, 0);
|
2014-06-02 14:15:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fCurRects = &fRects[0];
|
|
|
|
|
2017-12-24 16:45:38 +00:00
|
|
|
fRectanizers.push_back(
|
|
|
|
std::unique_ptr<GrRectanizer>(new GrRectanizerPow2(kWidth, kHeight)));
|
|
|
|
fRectanizers.push_back(
|
|
|
|
std::unique_ptr<GrRectanizer>(new GrRectanizerSkyline(kWidth, kHeight)));
|
2014-06-02 14:15:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
2018-08-08 15:36:17 +00:00
|
|
|
bool onQuery(Sample::Event* evt) override {
|
|
|
|
if (Sample::TitleQ(*evt)) {
|
|
|
|
Sample::TitleR(evt, "Rectanizer");
|
2014-06-02 14:15:18 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
SkUnichar uni;
|
2018-08-08 15:36:17 +00:00
|
|
|
if (Sample::CharQ(*evt, &uni)) {
|
2018-07-25 20:52:48 +00:00
|
|
|
char utf8[SkUTF::kMaxBytesInUTF8Sequence];
|
|
|
|
size_t size = SkUTF::ToUTF8(uni, utf8);
|
2014-06-02 14:15:18 +00:00
|
|
|
// Only consider events for single char keys
|
|
|
|
if (1 == size) {
|
|
|
|
switch (utf8[0]) {
|
|
|
|
case kCycleRectanizerKey:
|
|
|
|
this->cycleRectanizer();
|
|
|
|
return true;
|
|
|
|
case kCycleRectsKey:
|
|
|
|
this->cycleRects();
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return this->INHERITED::onQuery(evt);
|
|
|
|
}
|
|
|
|
|
2015-03-26 01:17:31 +00:00
|
|
|
void onDrawContent(SkCanvas* canvas) override {
|
2014-06-02 14:15:18 +00:00
|
|
|
if (fCurRandRect < kNumRandRects) {
|
2017-12-24 16:45:38 +00:00
|
|
|
if (fRectanizers[fCurRectanizer]->addRect((*fCurRects)[fCurRandRect].fWidth,
|
|
|
|
(*fCurRects)[fCurRandRect].fHeight,
|
|
|
|
&fRectLocations[fCurRandRect])) {
|
2014-06-02 14:15:18 +00:00
|
|
|
++fCurRandRect;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-03 17:59:14 +00:00
|
|
|
SkFont blackBigFont;
|
|
|
|
blackBigFont.setSize(20);
|
2014-06-02 14:15:18 +00:00
|
|
|
SkPaint blackStroke;
|
|
|
|
blackStroke.setStyle(SkPaint::kStroke_Style);
|
|
|
|
SkPaint redFill;
|
|
|
|
redFill.setColor(SK_ColorRED);
|
|
|
|
|
|
|
|
SkRect r = SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight));
|
|
|
|
|
|
|
|
canvas->clear(SK_ColorWHITE);
|
|
|
|
canvas->drawRect(r, blackStroke);
|
|
|
|
|
|
|
|
long totArea = 0;
|
|
|
|
for (int i = 0; i < fCurRandRect; ++i) {
|
2016-03-29 16:03:52 +00:00
|
|
|
r = SkRect::MakeXYWH(SkIntToScalar(fRectLocations[i].fX),
|
2014-06-02 14:15:18 +00:00
|
|
|
SkIntToScalar(fRectLocations[i].fY),
|
|
|
|
SkIntToScalar((*fCurRects)[i].fWidth),
|
|
|
|
SkIntToScalar((*fCurRects)[i].fHeight));
|
|
|
|
canvas->drawRect(r, redFill);
|
|
|
|
canvas->drawRect(r, blackStroke);
|
|
|
|
totArea += (*fCurRects)[i].fWidth * (*fCurRects)[i].fHeight;
|
|
|
|
}
|
|
|
|
|
|
|
|
SkString str;
|
|
|
|
|
|
|
|
str.printf("%s-%s: tot Area: %ld %%full: %.2f (%.2f) numTextures: %d/%d",
|
|
|
|
this->getRectanizerName(),
|
|
|
|
this->getRectsName(),
|
|
|
|
totArea,
|
2017-12-24 16:45:38 +00:00
|
|
|
100.0f * fRectanizers[fCurRectanizer]->percentFull(),
|
2014-06-02 14:15:18 +00:00
|
|
|
100.0f * totArea / ((float)kWidth*kHeight),
|
|
|
|
fCurRandRect,
|
|
|
|
kNumRandRects);
|
2019-01-07 14:36:09 +00:00
|
|
|
canvas->drawString(str, 50, kHeight + 50, blackBigFont, SkPaint());
|
2014-06-02 14:15:18 +00:00
|
|
|
|
|
|
|
str.printf("Press \'j\' to toggle rectanizer");
|
2019-01-07 14:36:09 +00:00
|
|
|
canvas->drawString(str, 50, kHeight + 100, blackBigFont, SkPaint());
|
2014-06-02 14:15:18 +00:00
|
|
|
|
|
|
|
str.printf("Press \'h\' to toggle rects");
|
2019-01-07 14:36:09 +00:00
|
|
|
canvas->drawString(str, 50, kHeight + 150, blackBigFont, SkPaint());
|
2014-06-02 14:15:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
static const int kWidth = 1024;
|
|
|
|
static const int kHeight = 1024;
|
|
|
|
static const int kNumRandRects = 200;
|
|
|
|
static const char kCycleRectanizerKey = 'j';
|
|
|
|
static const char kCycleRectsKey = 'h';
|
|
|
|
static const int kMinRectSize = 2;
|
|
|
|
static const int kMaxRectSize = 256;
|
|
|
|
|
2017-12-24 16:45:38 +00:00
|
|
|
int fCurRandRect;
|
|
|
|
SkTDArray<SkISize> fRects[3];
|
|
|
|
SkTDArray<SkISize>* fCurRects;
|
|
|
|
SkTDArray<SkIPoint16> fRectLocations;
|
|
|
|
SkTArray<std::unique_ptr<GrRectanizer>> fRectanizers;
|
|
|
|
int fCurRectanizer;
|
2014-06-02 14:15:18 +00:00
|
|
|
|
|
|
|
const char* getRectanizerName() const {
|
2017-12-24 16:45:38 +00:00
|
|
|
if (!fCurRectanizer) {
|
2014-06-02 14:15:18 +00:00
|
|
|
return "Pow2";
|
|
|
|
} else {
|
|
|
|
return "Skyline";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void cycleRectanizer() {
|
2017-12-24 16:45:38 +00:00
|
|
|
fCurRectanizer = (fCurRectanizer + 1) % fRectanizers.count();
|
2014-06-02 14:15:18 +00:00
|
|
|
|
2017-12-24 16:45:38 +00:00
|
|
|
fRectanizers[fCurRectanizer]->reset();
|
2014-06-02 14:15:18 +00:00
|
|
|
fCurRandRect = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* getRectsName() const {
|
|
|
|
if (fCurRects == &fRects[0]) {
|
|
|
|
return "Rand";
|
|
|
|
} else if (fCurRects == &fRects[1]) {
|
|
|
|
return "Pow2Rand";
|
|
|
|
} else {
|
|
|
|
return "SmallPow2";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void cycleRects() {
|
|
|
|
if (fCurRects == &fRects[0]) {
|
|
|
|
fCurRects = &fRects[1];
|
|
|
|
} else if (fCurRects == &fRects[1]) {
|
|
|
|
fCurRects = &fRects[2];
|
|
|
|
} else {
|
|
|
|
fCurRects = &fRects[0];
|
|
|
|
}
|
|
|
|
|
2017-12-24 16:45:38 +00:00
|
|
|
fRectanizers[fCurRectanizer]->reset();
|
2014-06-02 14:15:18 +00:00
|
|
|
fCurRandRect = 0;
|
|
|
|
}
|
|
|
|
|
2018-08-08 15:36:17 +00:00
|
|
|
typedef Sample INHERITED;
|
2014-06-02 14:15:18 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
2018-08-08 15:36:17 +00:00
|
|
|
|
|
|
|
DEF_SAMPLE( return new RectanizerView(); )
|
2014-06-02 14:15:18 +00:00
|
|
|
|
|
|
|
#endif
|