diff options
-rw-r--r-- | gyp/gpu.gypi | 4 | ||||
-rw-r--r-- | gyp/tests.gypi | 1 | ||||
-rw-r--r-- | src/gpu/GrRectanizer.h | 13 | ||||
-rw-r--r-- | src/gpu/GrRectanizer_pow2.cpp (renamed from src/gpu/GrRectanizer.cpp) | 68 | ||||
-rw-r--r-- | src/gpu/GrRectanizer_pow2.h | 68 | ||||
-rwxr-xr-x | src/gpu/GrRectanizer_skyline.cpp | 52 | ||||
-rw-r--r-- | src/gpu/GrRectanizer_skyline.h | 56 | ||||
-rw-r--r-- | tests/GpuRectanizerTest.cpp | 74 |
8 files changed, 206 insertions, 130 deletions
diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi index 041068891e..a374ade344 100644 --- a/gyp/gpu.gypi +++ b/gyp/gpu.gypi @@ -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', diff --git a/gyp/tests.gypi b/gyp/tests.gypi index 68c179dfa7..90d7c1f29b 100644 --- a/gyp/tests.gypi +++ b/gyp/tests.gypi @@ -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', diff --git a/src/gpu/GrRectanizer.h b/src/gpu/GrRectanizer.h index c1ac2c129e..2c290e9153 100644 --- a/src/gpu/GrRectanizer.h +++ b/src/gpu/GrRectanizer.h @@ -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 */ diff --git a/src/gpu/GrRectanizer.cpp b/src/gpu/GrRectanizer_pow2.cpp index 9f0d846e6c..d92e80c2d5 100644 --- a/src/gpu/GrRectanizer.cpp +++ b/src/gpu/GrRectanizer_pow2.cpp @@ -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)]; diff --git a/src/gpu/GrRectanizer_pow2.h b/src/gpu/GrRectanizer_pow2.h new file mode 100644 index 0000000000..c2e45655f1 --- /dev/null +++ b/src/gpu/GrRectanizer_pow2.h @@ -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 diff --git a/src/gpu/GrRectanizer_skyline.cpp b/src/gpu/GrRectanizer_skyline.cpp index d485ce3ff0..200fa83279 100755 --- a/src/gpu/GrRectanizer_skyline.cpp +++ b/src/gpu/GrRectanizer_skyline.cpp @@ -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() || diff --git a/src/gpu/GrRectanizer_skyline.h b/src/gpu/GrRectanizer_skyline.h new file mode 100644 index 0000000000..d2dfe577f1 --- /dev/null +++ b/src/gpu/GrRectanizer_skyline.h @@ -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 diff --git a/tests/GpuRectanizerTest.cpp b/tests/GpuRectanizerTest.cpp new file mode 100644 index 0000000000..08664b4fb1 --- /dev/null +++ b/tests/GpuRectanizerTest.cpp @@ -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 |