Revert "Specialize SkRectanzier to SkRectanizerSkyline"

This reverts commit 77e1f84a84.

Reason for revert: breaking google3 roll?

Original change's description:
> Specialize SkRectanzier to SkRectanizerSkyline
> 
> It looks like the pow2 rectanizer has never been used. Remove
> the unneeded abstraction for rectanizer everywhere.
> 
> Change-Id: Iba33f1c6faf37201d03928ce8409751c212480a0
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/265983
> Commit-Queue: Herb Derby <herb@google.com>
> Reviewed-by: Mike Klein <mtklein@google.com>

TBR=mtklein@google.com,herb@google.com

Change-Id: I2573534f3ea95c98d089f9c19b027564e77015db
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/266116
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
Mike Reed 2020-01-23 10:13:28 +00:00 committed by Skia Commit-Bot
parent 20d0f92991
commit e4ddb8a7cd
12 changed files with 307 additions and 48 deletions

View File

@ -10,8 +10,8 @@
#include "include/private/SkTDArray.h"
#include "include/utils/SkRandom.h"
#include "src/core/SkMathPriv.h"
#include "src/gpu/GrRectanizerSkyline.h"
#include "src/gpu/GrRectanizer_pow2.h"
#include "src/gpu/GrRectanizer_skyline.h"
/**
* This bench exercises Ganesh' GrRectanizer classes. It exercises the following
@ -29,6 +29,7 @@ public:
static const int kHeight = 1024;
enum RectanizerType {
kPow2_RectanizerType,
kSkyline_RectanizerType,
};
@ -40,9 +41,15 @@ public:
RectanizerBench(RectanizerType rectanizerType, RectType rectType)
: fName("rectanizer_")
, fRectanizerType(rectanizerType)
, fRectType(rectType) {
fName.append("skyline_");
if (kPow2_RectanizerType == fRectanizerType) {
fName.append("pow2_");
} else {
SkASSERT(kSkyline_RectanizerType == fRectanizerType);
fName.append("skyline_");
}
if (kRand_RectType == fRectType) {
fName.append("rand");
@ -66,7 +73,12 @@ protected:
void onDelayedSetup() override {
SkASSERT(nullptr == fRectanizer.get());
fRectanizer.reset(new GrRectanizerSkyline(kWidth, kHeight));
if (kPow2_RectanizerType == fRectanizerType) {
fRectanizer.reset(new GrRectanizerPow2(kWidth, kHeight));
} else {
SkASSERT(kSkyline_RectanizerType == fRectanizerType);
fRectanizer.reset(new GrRectanizerSkyline(kWidth, kHeight));
}
}
void onDraw(int loops, SkCanvas* canvas) override {
@ -99,14 +111,21 @@ protected:
private:
SkString fName;
RectanizerType fRectanizerType;
RectType fRectType;
std::unique_ptr<GrRectanizerSkyline> fRectanizer;
std::unique_ptr<GrRectanizer> fRectanizer;
typedef Benchmark INHERITED;
};
//////////////////////////////////////////////////////////////////////////////
DEF_BENCH(return new RectanizerBench(RectanizerBench::kPow2_RectanizerType,
RectanizerBench::kRand_RectType);)
DEF_BENCH(return new RectanizerBench(RectanizerBench::kPow2_RectanizerType,
RectanizerBench::kRandPow2_RectType);)
DEF_BENCH(return new RectanizerBench(RectanizerBench::kPow2_RectanizerType,
RectanizerBench::kSmallPow2_RectType);)
DEF_BENCH(return new RectanizerBench(RectanizerBench::kSkyline_RectanizerType,
RectanizerBench::kRand_RectType);)
DEF_BENCH(return new RectanizerBench(RectanizerBench::kSkyline_RectanizerType,

View File

@ -147,8 +147,11 @@ skia_gpu_sources = [
"$_src/gpu/GrProxyProvider.h",
"$_src/gpu/GrRecordingContext.cpp",
"$_src/gpu/GrRecordingContextPriv.h",
"$_src/gpu/GrRectanizerSkyline.cpp",
"$_src/gpu/GrRectanizerSkyline.h",
"$_src/gpu/GrRectanizer.h",
"$_src/gpu/GrRectanizer_pow2.cpp",
"$_src/gpu/GrRectanizer_pow2.h",
"$_src/gpu/GrRectanizer_skyline.cpp",
"$_src/gpu/GrRectanizer_skyline.h",
"$_src/gpu/GrRenderTarget.cpp",
"$_src/gpu/GrRenderTarget.h",
"$_src/gpu/GrRenderTargetPriv.h",

View File

@ -10,20 +10,21 @@
#include "include/core/SkPaint.h"
#include "include/utils/SkRandom.h"
#include "samplecode/Sample.h"
#include "src/core/SkMathPriv.h"
#include "src/utils/SkUTF.h"
#if SK_SUPPORT_GPU
#include "src/gpu/GrRectanizerSkyline.h"
#include "src/gpu/GrRectanizer_pow2.h"
#include "src/gpu/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
class RectanizerView : public Sample {
static constexpr int kWidth = 1024;
static constexpr int kHeight = 1024;
public:
RectanizerView()
: fCurRandRect(0)
@ -46,7 +47,10 @@ public:
fCurRects = &fRects[0];
fRectanizers.emplace_back(kWidth, kHeight);
fRectanizers.push_back(
std::unique_ptr<GrRectanizer>(new GrRectanizerPow2(kWidth, kHeight)));
fRectanizers.push_back(
std::unique_ptr<GrRectanizer>(new GrRectanizerSkyline(kWidth, kHeight)));
}
protected:
@ -58,6 +62,9 @@ protected:
// 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;
@ -70,9 +77,9 @@ protected:
void onDrawContent(SkCanvas* canvas) override {
if (fCurRandRect < kNumRandRects) {
if (fRectanizers[fCurRectanizer].addRect((*fCurRects)[fCurRandRect].fWidth,
(*fCurRects)[fCurRandRect].fHeight,
&fRectLocations[fCurRandRect])) {
if (fRectanizers[fCurRectanizer]->addRect((*fCurRects)[fCurRandRect].fWidth,
(*fCurRects)[fCurRandRect].fHeight,
&fRectLocations[fCurRandRect])) {
++fCurRandRect;
}
}
@ -102,34 +109,52 @@ protected:
SkString str;
str.printf("%s-%s: tot Area: %ld (%.2f) numTextures: %d/%d",
str.printf("%s-%s: tot Area: %ld %%full: %.2f (%.2f) numTextures: %d/%d",
this->getRectanizerName(),
this->getRectsName(),
totArea,
100.0f * fRectanizers[fCurRectanizer]->percentFull(),
100.0f * totArea / ((float)kWidth*kHeight),
fCurRandRect,
kNumRandRects);
canvas->drawString(str, 50, kHeight + 50, blackBigFont, SkPaint());
str.printf("Press \'j\' to toggle rectanizer");
canvas->drawString(str, 50, kHeight + 100, blackBigFont, SkPaint());
str.printf("Press \'h\' to toggle rects");
canvas->drawString(str, 50, kHeight + 150, blackBigFont, SkPaint());
}
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;
int fCurRandRect;
SkTDArray<SkISize> fRects[3];
SkTDArray<SkISize>* fCurRects;
SkTDArray<SkIPoint16> fRectLocations;
SkTArray<GrRectanizerSkyline> fRectanizers;
int fCurRectanizer;
int fCurRandRect;
SkTDArray<SkISize> fRects[3];
SkTDArray<SkISize>* fCurRects;
SkTDArray<SkIPoint16> fRectLocations;
SkTArray<std::unique_ptr<GrRectanizer>> fRectanizers;
int fCurRectanizer;
const char* getRectanizerName() const {
return "Skyline";
if (!fCurRectanizer) {
return "Pow2";
} else {
return "Skyline";
}
}
void cycleRectanizer() {
fCurRectanizer = (fCurRectanizer + 1) % fRectanizers.count();
fRectanizers[fCurRectanizer]->reset();
fCurRandRect = 0;
}
const char* getRectsName() const {
@ -151,7 +176,7 @@ private:
fCurRects = &fRects[0];
}
fRectanizers[fCurRectanizer].reset();
fRectanizers[fCurRectanizer]->reset();
fCurRandRect = 0;
}

View File

@ -15,6 +15,7 @@
#include "src/gpu/GrOnFlushResourceProvider.h"
#include "src/gpu/GrOpFlushState.h"
#include "src/gpu/GrProxyProvider.h"
#include "src/gpu/GrRectanizer.h"
#include "src/gpu/GrResourceProvider.h"
#include "src/gpu/GrResourceProviderPriv.h"
#include "src/gpu/GrSurfaceProxyPriv.h"
@ -102,7 +103,7 @@ GrDrawOpAtlas::Plot::Plot(int pageIndex, int plotIndex, uint64_t genID, int offX
, fHeight(height)
, fX(offX)
, fY(offY)
, fRectanizer(width, height)
, fRects(nullptr)
, fOffset(SkIPoint16::Make(fX * fWidth, fY * fHeight))
, fColorType(colorType)
, fBytesPerPixel(GrColorTypeBytesPerPixel(colorType))
@ -119,12 +120,17 @@ GrDrawOpAtlas::Plot::Plot(int pageIndex, int plotIndex, uint64_t genID, int offX
GrDrawOpAtlas::Plot::~Plot() {
sk_free(fData);
delete fRects;
}
bool GrDrawOpAtlas::Plot::addSubImage(int width, int height, const void* image, SkIPoint16* loc) {
SkASSERT(width <= fWidth && height <= fHeight);
if (!fRectanizer.addRect(width, height, loc)) {
if (!fRects) {
fRects = GrRectanizer::Factory(fWidth, fHeight);
}
if (!fRects->addRect(width, height, loc)) {
return false;
}
@ -186,7 +192,9 @@ void GrDrawOpAtlas::Plot::uploadToTexture(GrDeferredTextureUploadWritePixelsFn&
}
void GrDrawOpAtlas::Plot::resetRects() {
fRectanizer.reset();
if (fRects) {
fRects->reset();
}
fGenID++;
fID = CreateId(fPageIndex, fPlotIndex, fGenID);

View File

@ -16,10 +16,10 @@
#include "src/core/SkIPoint16.h"
#include "src/core/SkTInternalLList.h"
#include "src/gpu/GrRectanizerSkyline.h"
#include "src/gpu/ops/GrDrawOp.h"
class GrOnFlushResourceProvider;
class GrRectanizer;
/**
@ -357,7 +357,7 @@ private:
const int fHeight;
const int fX;
const int fY;
GrRectanizerSkyline fRectanizer;
GrRectanizer* fRects;
const SkIPoint16 fOffset; // the offset of the plot in the backing texture
const GrColorType fColorType;
const size_t fBytesPerPixel;

44
src/gpu/GrRectanizer.h Normal file
View File

@ -0,0 +1,44 @@
/*
* Copyright 2010 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrRectanizer_DEFINED
#define GrRectanizer_DEFINED
#include "include/gpu/GrTypes.h"
struct SkIPoint16;
class GrRectanizer {
public:
GrRectanizer(int width, int height) : fWidth(width), fHeight(height) {
SkASSERT(width >= 0);
SkASSERT(height >= 0);
}
virtual ~GrRectanizer() {}
virtual void reset() = 0;
int width() const { return fWidth; }
int height() const { return fHeight; }
// Attempt to add a rect. Return true on success; false on failure. If
// successful the position in the atlas is returned in 'loc'.
virtual bool addRect(int width, int height, SkIPoint16* loc) = 0;
virtual float percentFull() const = 0;
/**
* Our factory, which returns the subclass du jour
*/
static GrRectanizer* Factory(int width, int height);
private:
int fWidth;
int fHeight;
};
#endif

View File

@ -0,0 +1,59 @@
/*
* Copyright 2010 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "src/gpu/GrRectanizer_pow2.h"
bool GrRectanizerPow2::addRect(int width, int height, SkIPoint16* loc) {
if ((unsigned)width > (unsigned)this->width() ||
(unsigned)height > (unsigned)this->height()) {
return false;
}
int32_t area = width * height; // computed here since height will be modified
height = GrNextPow2(height);
if (height < kMIN_HEIGHT_POW2) {
height = kMIN_HEIGHT_POW2;
}
Row* row = &fRows[HeightToRowIndex(height)];
SkASSERT(row->fRowHeight == 0 || row->fRowHeight == height);
if (0 == row->fRowHeight) {
if (!this->canAddStrip(height)) {
return false;
}
this->initRow(row, height);
} else {
if (!row->canAddWidth(width, this->width())) {
if (!this->canAddStrip(height)) {
return false;
}
// that row is now "full", so retarget our Row record for
// another one
this->initRow(row, height);
}
}
SkASSERT(row->fRowHeight == height);
SkASSERT(row->canAddWidth(width, this->width()));
*loc = row->fLoc;
row->fLoc.fX += width;
SkASSERT(row->fLoc.fX <= this->width());
SkASSERT(row->fLoc.fY <= this->height());
SkASSERT(fNextStripY <= this->height());
fAreaSoFar += area;
return true;
}
///////////////////////////////////////////////////////////////////////////////
// factory is now in GrRectanizer_skyline.cpp
//GrRectanizer* GrRectanizer::Factory(int width, int height) {
// return new GrRectanizerPow2 (width, height);
//}

View File

@ -0,0 +1,81 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrRectanizer_pow2_DEFINED
#define GrRectanizer_pow2_DEFINED
#include "include/private/SkMalloc.h"
#include "src/core/SkIPoint16.h"
#include "src/core/SkMathPriv.h"
#include "src/gpu/GrRectanizer.h"
// This Rectanizer quantizes the incoming rects to powers of 2. Each power
// of two can have, at most, one active row/shelf. Once a row/shelf for
// a particular power of two gets full its fRows entry is recycled to point
// to a new row.
// The skyline algorithm almost always provides a better packing.
class GrRectanizerPow2 : public GrRectanizer {
public:
GrRectanizerPow2(int w, int h) : INHERITED(w, h) {
this->reset();
}
~GrRectanizerPow2() override {}
void reset() override {
fNextStripY = 0;
fAreaSoFar = 0;
sk_bzero(fRows, sizeof(fRows));
}
bool addRect(int w, int h, SkIPoint16* loc) override;
float percentFull() const override {
return fAreaSoFar / ((float)this->width() * this->height());
}
private:
static const int kMIN_HEIGHT_POW2 = 2;
static const int kMaxExponent = 16;
struct Row {
SkIPoint16 fLoc;
// fRowHeight is actually known by this struct's position in fRows
// but it is used to signal if there exists an open row of this height
int fRowHeight;
bool canAddWidth(int width, int containerWidth) const {
return fLoc.fX + width <= containerWidth;
}
};
Row fRows[kMaxExponent]; // 0-th entry will be unused
int fNextStripY;
int32_t fAreaSoFar;
static int HeightToRowIndex(int height) {
SkASSERT(height >= kMIN_HEIGHT_POW2);
int index = 32 - SkCLZ(height - 1);
SkASSERT(index < kMaxExponent);
return index;
}
bool canAddStrip(int height) const {
return fNextStripY + height <= this->height();
}
void initRow(Row* row, int rowHeight) {
row->fLoc.set(0, fNextStripY);
row->fRowHeight = rowHeight;
fNextStripY += rowHeight;
}
typedef GrRectanizer INHERITED;
};
#endif

View File

@ -6,7 +6,7 @@
*/
#include "src/core/SkIPoint16.h"
#include "src/gpu/GrRectanizerSkyline.h"
#include "src/gpu/GrRectanizer_skyline.h"
bool GrRectanizerSkyline::addRect(int width, int height, SkIPoint16* loc) {
if ((unsigned)width > (unsigned)this->width() ||
@ -114,3 +114,8 @@ void GrRectanizerSkyline::addSkylineLevel(int skylineIndex, int x, int y, int wi
}
}
///////////////////////////////////////////////////////////////////////////////
GrRectanizer* GrRectanizer::Factory(int width, int height) {
return new GrRectanizerSkyline(width, height);
}

View File

@ -5,21 +5,23 @@
* found in the LICENSE file.
*/
#ifndef GrRectanizerSkyline_DEFINED
#define GrRectanizerSkyline_DEFINED
#ifndef GrRectanizer_skyline_DEFINED
#define GrRectanizer_skyline_DEFINED
#include "include/private/SkTDArray.h"
#include "src/core/SkIPoint16.h"
#include "src/gpu/GrRectanizer.h"
// Pack rectangles and track the current silhouette
// Based, in part, on Jukka Jylanki's work at http://clb.demon.fi
class GrRectanizerSkyline {
class GrRectanizerSkyline : public GrRectanizer {
public:
GrRectanizerSkyline(int w, int h) : fWidth{w}, fHeight{h} {
GrRectanizerSkyline(int w, int h) : INHERITED(w, h) {
this->reset();
}
void reset() {
~GrRectanizerSkyline() override { }
void reset() override {
fAreaSoFar = 0;
fSkyline.reset();
SkylineSegment* seg = fSkyline.append(1);
@ -28,10 +30,11 @@ public:
seg->fWidth = this->width();
}
bool addRect(int w, int h, SkIPoint16* loc);
bool addRect(int w, int h, SkIPoint16* loc) override;
int width() const { return fWidth; }
int height() const { return fHeight; }
float percentFull() const override {
return fAreaSoFar / ((float)this->width() * this->height());
}
private:
struct SkylineSegment {
@ -40,6 +43,10 @@ private:
int fWidth;
};
SkTDArray<SkylineSegment> fSkyline;
int32_t fAreaSoFar;
// Can a width x height rectangle fit in the free space represented by
// the skyline segments >= 'skylineIndex'? If so, return true and fill in
// 'y' with the y-location at which it fits (the x location is pulled from
@ -49,10 +56,7 @@ private:
// at x,y.
void addSkylineLevel(int skylineIndex, int x, int y, int width, int height);
SkTDArray<SkylineSegment> fSkyline;
int32_t fAreaSoFar;
int fWidth;
int fHeight;
typedef GrRectanizer INHERITED;
};
#endif // GrRectanizerSkyline_DEFINED
#endif

View File

@ -13,7 +13,7 @@
#include "src/gpu/GrCaps.h"
#include "src/gpu/GrOnFlushResourceProvider.h"
#include "src/gpu/GrProxyProvider.h"
#include "src/gpu/GrRectanizerSkyline.h"
#include "src/gpu/GrRectanizer_skyline.h"
#include "src/gpu/GrRenderTarget.h"
#include "src/gpu/GrRenderTargetContext.h"
#include "src/gpu/GrTextureProxy.h"

View File

@ -8,25 +8,28 @@
#include "include/core/SkSize.h"
#include "include/private/SkTDArray.h"
#include "include/utils/SkRandom.h"
#include "src/gpu/GrRectanizerSkyline.h"
#include "src/gpu/GrRectanizer_pow2.h"
#include "src/gpu/GrRectanizer_skyline.h"
#include "tests/Test.h"
static const int kWidth = 1024;
static const int kHeight = 1024;
// Basic test of a GrRectanizer-derived class' functionality
static void test_rectanizer_basic(skiatest::Reporter* reporter, GrRectanizerSkyline* rectanizer) {
static void test_rectanizer_basic(skiatest::Reporter* reporter, GrRectanizer* rectanizer) {
REPORTER_ASSERT(reporter, kWidth == rectanizer->width());
REPORTER_ASSERT(reporter, kHeight == rectanizer->height());
SkIPoint16 loc;
REPORTER_ASSERT(reporter, rectanizer->addRect(50, 50, &loc));
REPORTER_ASSERT(reporter, rectanizer->percentFull() > 0.0f);
rectanizer->reset();
REPORTER_ASSERT(reporter, rectanizer->percentFull() == 0.0f);
}
static void test_rectanizer_inserts(skiatest::Reporter*,
GrRectanizerSkyline* rectanizer,
GrRectanizer* rectanizer,
const SkTDArray<SkISize>& rects) {
int i;
for (i = 0; i < rects.count(); ++i) {
@ -46,6 +49,13 @@ static void test_skyline(skiatest::Reporter* reporter, const SkTDArray<SkISize>&
test_rectanizer_inserts(reporter, &skylineRectanizer, rects);
}
static void test_pow2(skiatest::Reporter* reporter, const SkTDArray<SkISize>& rects) {
GrRectanizerPow2 pow2Rectanizer(kWidth, kHeight);
test_rectanizer_basic(reporter, &pow2Rectanizer);
test_rectanizer_inserts(reporter, &pow2Rectanizer, rects);
}
DEF_GPUTEST(GpuRectanizer, reporter, factory) {
SkTDArray<SkISize> rects;
SkRandom rand;
@ -56,4 +66,5 @@ DEF_GPUTEST(GpuRectanizer, reporter, factory) {
}
test_skyline(reporter, rects);
test_pow2(reporter, rects);
}