зеркало из https://github.com/mozilla/moz-skia.git
Add testing for Rectanizer-derived classes
This in preparation for expanding the Rectanizer API for removing rects and adding a new derived class R=jvanverth@google.com Author: robertphillips@google.com Review URL: https://codereview.chromium.org/304313002 git-svn-id: http://skia.googlecode.com/svn/trunk@14972 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
d3c6b3f1c8
Коммит
ad854bf9c0
|
@ -102,9 +102,11 @@
|
|||
'<(skia_src_path)/gpu/GrPictureUtils.h',
|
||||
'<(skia_src_path)/gpu/GrPictureUtils.cpp',
|
||||
'<(skia_src_path)/gpu/GrPlotMgr.h',
|
||||
'<(skia_src_path)/gpu/GrRectanizer.cpp',
|
||||
'<(skia_src_path)/gpu/GrRectanizer.h',
|
||||
'<(skia_src_path)/gpu/GrRectanizer_pow2.cpp',
|
||||
'<(skia_src_path)/gpu/GrRectanizer_pow2.h',
|
||||
'<(skia_src_path)/gpu/GrRectanizer_skyline.cpp',
|
||||
'<(skia_src_path)/gpu/GrRectanizer_skyline.h',
|
||||
'<(skia_src_path)/gpu/GrRedBlackTree.h',
|
||||
'<(skia_src_path)/gpu/GrRenderTarget.cpp',
|
||||
'<(skia_src_path)/gpu/GrReducedClip.cpp',
|
||||
|
|
|
@ -87,6 +87,7 @@
|
|||
'../tests/GifTest.cpp',
|
||||
'../tests/GpuColorFilterTest.cpp',
|
||||
'../tests/GpuDrawPathTest.cpp',
|
||||
'../tests/GpuRectanizerTest.cpp',
|
||||
'../tests/GrBinHashKeyTest.cpp',
|
||||
'../tests/GrContextFactoryTest.cpp',
|
||||
'../tests/GrDrawTargetTest.cpp',
|
||||
|
|
|
@ -10,13 +10,6 @@
|
|||
|
||||
#include "GrPoint.h"
|
||||
|
||||
class GrRectanizerPurgeListener {
|
||||
public:
|
||||
virtual ~GrRectanizerPurgeListener() {}
|
||||
|
||||
virtual void notifyPurgeStrip(void*, int yCoord) = 0;
|
||||
};
|
||||
|
||||
class GrRectanizer {
|
||||
public:
|
||||
GrRectanizer(int width, int height) : fWidth(width), fHeight(height) {
|
||||
|
@ -34,12 +27,6 @@ public:
|
|||
virtual bool addRect(int width, int height, GrIPoint16* loc) = 0;
|
||||
virtual float percentFull() const = 0;
|
||||
|
||||
// return the Y-coordinate of a strip that should be purged, given height
|
||||
// i.e. return the oldest such strip, or some other criteria. Return -1
|
||||
// if there is no candidate
|
||||
virtual int stripToPurge(int height) const = 0;
|
||||
virtual void purgeStripAtY(int yCoord) = 0;
|
||||
|
||||
/**
|
||||
* Our factory, which returns the subclass du jour
|
||||
*/
|
||||
|
|
|
@ -6,71 +6,9 @@
|
|||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "GrRectanizer.h"
|
||||
#include "GrRectanizer_pow2.h"
|
||||
#include "GrTBSearch.h"
|
||||
|
||||
#define MIN_HEIGHT_POW2 2
|
||||
|
||||
class GrRectanizerPow2 : public GrRectanizer {
|
||||
public:
|
||||
GrRectanizerPow2(int w, int h) : GrRectanizer(w, h) {
|
||||
fNextStripY = 0;
|
||||
fAreaSoFar = 0;
|
||||
sk_bzero(fRows, sizeof(fRows));
|
||||
}
|
||||
|
||||
virtual ~GrRectanizerPow2() {
|
||||
}
|
||||
|
||||
virtual void reset() {
|
||||
fNextStripY = 0;
|
||||
fAreaSoFar = 0;
|
||||
sk_bzero(fRows, sizeof(fRows));
|
||||
}
|
||||
|
||||
virtual bool addRect(int w, int h, GrIPoint16* loc);
|
||||
|
||||
virtual float percentFull() const {
|
||||
return fAreaSoFar / ((float)this->width() * this->height());
|
||||
}
|
||||
|
||||
virtual int stripToPurge(int height) const { return -1; }
|
||||
virtual void purgeStripAtY(int yCoord) { }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Row {
|
||||
GrIPoint16 fLoc;
|
||||
int fRowHeight;
|
||||
|
||||
bool canAddWidth(int width, int containerWidth) const {
|
||||
return fLoc.fX + width <= containerWidth;
|
||||
}
|
||||
};
|
||||
|
||||
Row fRows[16];
|
||||
|
||||
static int HeightToRowIndex(int height) {
|
||||
SkASSERT(height >= MIN_HEIGHT_POW2);
|
||||
return 32 - SkCLZ(height - 1);
|
||||
}
|
||||
|
||||
int fNextStripY;
|
||||
int32_t fAreaSoFar;
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
bool GrRectanizerPow2::addRect(int width, int height, GrIPoint16* loc) {
|
||||
if ((unsigned)width > (unsigned)this->width() ||
|
||||
(unsigned)height > (unsigned)this->height()) {
|
||||
|
@ -85,8 +23,8 @@ bool GrRectanizerPow2::addRect(int width, int height, GrIPoint16* loc) {
|
|||
height == 2. Thus we set a minimum height.
|
||||
*/
|
||||
height = GrNextPow2(height);
|
||||
if (height < MIN_HEIGHT_POW2) {
|
||||
height = MIN_HEIGHT_POW2;
|
||||
if (height < kMIN_HEIGHT_POW2) {
|
||||
height = kMIN_HEIGHT_POW2;
|
||||
}
|
||||
|
||||
Row* row = &fRows[HeightToRowIndex(height)];
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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 "GrRectanizer.h"
|
||||
|
||||
class GrRectanizerPow2 : public GrRectanizer {
|
||||
public:
|
||||
GrRectanizerPow2(int w, int h) : INHERITED(w, h) {
|
||||
this->reset();
|
||||
}
|
||||
|
||||
virtual ~GrRectanizerPow2() { }
|
||||
|
||||
virtual void reset() SK_OVERRIDE {
|
||||
fNextStripY = 0;
|
||||
fAreaSoFar = 0;
|
||||
sk_bzero(fRows, sizeof(fRows));
|
||||
}
|
||||
|
||||
virtual bool addRect(int w, int h, GrIPoint16* loc) SK_OVERRIDE;
|
||||
|
||||
virtual float percentFull() const SK_OVERRIDE {
|
||||
return fAreaSoFar / ((float)this->width() * this->height());
|
||||
}
|
||||
|
||||
private:
|
||||
static const int kMIN_HEIGHT_POW2 = 2;
|
||||
|
||||
struct Row {
|
||||
GrIPoint16 fLoc;
|
||||
int fRowHeight;
|
||||
|
||||
bool canAddWidth(int width, int containerWidth) const {
|
||||
return fLoc.fX + width <= containerWidth;
|
||||
}
|
||||
};
|
||||
|
||||
Row fRows[16];
|
||||
|
||||
int fNextStripY;
|
||||
int32_t fAreaSoFar;
|
||||
|
||||
static int HeightToRowIndex(int height) {
|
||||
SkASSERT(height >= kMIN_HEIGHT_POW2);
|
||||
return 32 - SkCLZ(height - 1);
|
||||
}
|
||||
|
||||
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
|
|
@ -6,57 +6,7 @@
|
|||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "GrRectanizer.h"
|
||||
#include "SkTDArray.h"
|
||||
|
||||
// Pack rectangles and track the current silhouette
|
||||
// Based in part on Jukka Jylänki's work at http://clb.demon.fi
|
||||
|
||||
class GrRectanizerSkyline : public GrRectanizer {
|
||||
public:
|
||||
GrRectanizerSkyline(int w, int h) : INHERITED(w, h) {
|
||||
this->reset();
|
||||
}
|
||||
|
||||
virtual ~GrRectanizerSkyline() {
|
||||
}
|
||||
|
||||
virtual void reset() SK_OVERRIDE {
|
||||
fAreaSoFar = 0;
|
||||
fSkyline.reset();
|
||||
SkylineSegment* seg = fSkyline.append(1);
|
||||
seg->fX = 0;
|
||||
seg->fY = 0;
|
||||
seg->fWidth = this->width();
|
||||
}
|
||||
|
||||
virtual bool addRect(int w, int h, GrIPoint16* loc) SK_OVERRIDE;
|
||||
|
||||
virtual float percentFull() const SK_OVERRIDE {
|
||||
return fAreaSoFar / ((float)this->width() * this->height());
|
||||
}
|
||||
|
||||
virtual int stripToPurge(int height) const SK_OVERRIDE { return -1; }
|
||||
virtual void purgeStripAtY(int yCoord) SK_OVERRIDE { }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct SkylineSegment {
|
||||
int fX;
|
||||
int fY;
|
||||
int fWidth;
|
||||
};
|
||||
|
||||
SkTDArray<SkylineSegment> fSkyline;
|
||||
|
||||
int32_t fAreaSoFar;
|
||||
|
||||
bool rectangleFits(int skylineIndex, int width, int height, int* y) const;
|
||||
void addSkylineLevel(int skylineIndex, int x, int y, int width, int height);
|
||||
|
||||
private:
|
||||
typedef GrRectanizer INHERITED;
|
||||
};
|
||||
#include "GrRectanizer_skyline.h"
|
||||
|
||||
bool GrRectanizerSkyline::addRect(int width, int height, GrIPoint16* loc) {
|
||||
if ((unsigned)width > (unsigned)this->width() ||
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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_skyline_DEFINED
|
||||
#define GrRectanizer_skyline_DEFINED
|
||||
|
||||
#include "GrRectanizer.h"
|
||||
#include "SkTDArray.h"
|
||||
|
||||
// Pack rectangles and track the current silhouette
|
||||
// Based in part on Jukka Jylänki's work at http://clb.demon.fi
|
||||
class GrRectanizerSkyline : public GrRectanizer {
|
||||
public:
|
||||
GrRectanizerSkyline(int w, int h) : INHERITED(w, h) {
|
||||
this->reset();
|
||||
}
|
||||
|
||||
virtual ~GrRectanizerSkyline() { }
|
||||
|
||||
virtual void reset() SK_OVERRIDE{
|
||||
fAreaSoFar = 0;
|
||||
fSkyline.reset();
|
||||
SkylineSegment* seg = fSkyline.append(1);
|
||||
seg->fX = 0;
|
||||
seg->fY = 0;
|
||||
seg->fWidth = this->width();
|
||||
}
|
||||
|
||||
virtual bool addRect(int w, int h, GrIPoint16* loc) SK_OVERRIDE;
|
||||
|
||||
virtual float percentFull() const SK_OVERRIDE{
|
||||
return fAreaSoFar / ((float)this->width() * this->height());
|
||||
}
|
||||
|
||||
private:
|
||||
struct SkylineSegment {
|
||||
int fX;
|
||||
int fY;
|
||||
int fWidth;
|
||||
};
|
||||
|
||||
SkTDArray<SkylineSegment> fSkyline;
|
||||
|
||||
int32_t fAreaSoFar;
|
||||
|
||||
bool rectangleFits(int skylineIndex, int width, int height, int* y) const;
|
||||
void addSkylineLevel(int skylineIndex, int x, int y, int width, int height);
|
||||
|
||||
typedef GrRectanizer INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
|
||||
#include "GrRectanizer_pow2.h"
|
||||
#include "GrRectanizer_skyline.h"
|
||||
#include "SkRandom.h"
|
||||
#include "SkSize.h"
|
||||
#include "SkTDArray.h"
|
||||
#include "Test.h"
|
||||
|
||||
static const int kWidth = 1000;
|
||||
static const int kHeight = 1000;
|
||||
|
||||
// Basic test of a GrRectanizer-derived class' functionality
|
||||
static void test_rectanizer_basic(skiatest::Reporter* reporter, GrRectanizer* rectanizer) {
|
||||
REPORTER_ASSERT(reporter, kWidth == rectanizer->width());
|
||||
REPORTER_ASSERT(reporter, kHeight == rectanizer->height());
|
||||
|
||||
GrIPoint16 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*,
|
||||
GrRectanizer* rectanizer,
|
||||
const SkTDArray<SkISize>& rects) {
|
||||
int i;
|
||||
for (i = 0; i < rects.count(); ++i) {
|
||||
GrIPoint16 loc;
|
||||
if (!rectanizer->addRect(rects[i].fWidth, rects[i].fHeight, &loc)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//SkDebugf("\n***%d %f\n", i, rectanizer->percentFull());
|
||||
}
|
||||
|
||||
static void test_skyline(skiatest::Reporter* reporter, const SkTDArray<SkISize>& rects) {
|
||||
GrRectanizerSkyline skylineRectanizer(kWidth, kHeight);
|
||||
|
||||
test_rectanizer_basic(reporter, &skylineRectanizer);
|
||||
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> fRects;
|
||||
SkRandom rand;
|
||||
|
||||
for (int i = 0; i < 50; i++) {
|
||||
fRects.push(SkISize::Make(rand.nextRangeU(1, kWidth / 2),
|
||||
rand.nextRangeU(1, kHeight / 2)));
|
||||
}
|
||||
|
||||
test_skyline(reporter, fRects);
|
||||
test_pow2(reporter, fRects);
|
||||
}
|
||||
|
||||
#endif
|
Загрузка…
Ссылка в новой задаче