Add testing for Rectanizer-derived classes
authorcommit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 29 May 2014 18:46:38 +0000 (18:46 +0000)
committercommit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 29 May 2014 18:46:38 +0000 (18:46 +0000)
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

gyp/gpu.gypi
gyp/tests.gypi
src/gpu/GrRectanizer.cpp [deleted file]
src/gpu/GrRectanizer.h
src/gpu/GrRectanizer_pow2.cpp [new file with mode: 0644]
src/gpu/GrRectanizer_pow2.h [new file with mode: 0644]
src/gpu/GrRectanizer_skyline.cpp
src/gpu/GrRectanizer_skyline.h [new file with mode: 0644]
tests/GpuRectanizerTest.cpp [new file with mode: 0644]

index 041068891e4dd0ec60d5501b578a0ab1e366484f..a374ade344891b2c4a802f5e25362a826080c42f 100644 (file)
       '<(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',
index 68c179dfa741ca1ca72beac5b6c51de603f66645..90d7c1f29bd9ccd5cac5c02b5f65de3c2acc6329 100644 (file)
@@ -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.cpp b/src/gpu/GrRectanizer.cpp
deleted file mode 100644 (file)
index 9f0d846..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-
-/*
- * 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 "GrRectanizer.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()) {
-        return false;
-    }
-
-    int32_t area = width * height;
-
-    /*
-        We use bsearch, but there may be more than one row with the same height,
-        so we actually search for height-1, which can only be a pow2 itself if
-        height == 2. Thus we set a minimum height.
-     */
-    height = GrNextPow2(height);
-    if (height < MIN_HEIGHT_POW2) {
-        height = MIN_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 SkNEW_ARGS(GrRectanizerPow2, (width, height));
-//}
index c1ac2c129ecd03ece61b5c0d648cda2ed85fb0e0..2c290e9153ab20fd4cbc2b4d404e3012956dd205 100644 (file)
 
 #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_pow2.cpp b/src/gpu/GrRectanizer_pow2.cpp
new file mode 100644 (file)
index 0000000..d92e80c
--- /dev/null
@@ -0,0 +1,66 @@
+
+/*
+ * 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 "GrRectanizer_pow2.h"
+#include "GrTBSearch.h"
+
+bool GrRectanizerPow2::addRect(int width, int height, GrIPoint16* loc) {
+    if ((unsigned)width > (unsigned)this->width() ||
+        (unsigned)height > (unsigned)this->height()) {
+        return false;
+    }
+
+    int32_t area = width * height;
+
+    /*
+        We use bsearch, but there may be more than one row with the same height,
+        so we actually search for height-1, which can only be a pow2 itself if
+        height == 2. Thus we set a minimum height.
+     */
+    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 SkNEW_ARGS(GrRectanizerPow2, (width, height));
+//}
diff --git a/src/gpu/GrRectanizer_pow2.h b/src/gpu/GrRectanizer_pow2.h
new file mode 100644 (file)
index 0000000..c2e4565
--- /dev/null
@@ -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
index d485ce3ff053e04a5b7ee505019307ccd182cf7a..200fa8327912f229e3956cfe1648761fd07f4b87 100755 (executable)
@@ -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 (file)
index 0000000..d2dfe57
--- /dev/null
@@ -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 (file)
index 0000000..08664b4
--- /dev/null
@@ -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