aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorDerek Sollenberger <djsollen@google.com>2012-03-06 09:06:43 -0500
committerDerek Sollenberger <derek@android.com>2012-03-06 09:44:47 -0500
commit4f1dae40e24d57d647db01443b8bf2410514b8b5 (patch)
tree594df3f3fc6c1d90a76691a75763ae1beacfdf98 /tests
parent1cab2921ab279367f8206cdadc9259d12e603548 (diff)
downloadexternal_skia-4f1dae40e24d57d647db01443b8bf2410514b8b5.zip
external_skia-4f1dae40e24d57d647db01443b8bf2410514b8b5.tar.gz
external_skia-4f1dae40e24d57d647db01443b8bf2410514b8b5.tar.bz2
Skia Merge (revision 3312)
This CL also includes changes made to Android's copy of Skia in their J release branch. Change-Id: Ib2baecf48004951a3ad4a1574cdc38790c814cbc
Diffstat (limited to 'tests')
-rw-r--r--tests/AAClipTest.cpp53
-rw-r--r--tests/Android.mk4
-rw-r--r--tests/BitmapCopyTest.cpp11
-rw-r--r--tests/CanvasTest.cpp781
-rw-r--r--tests/ClipCubicTest.cpp20
-rw-r--r--tests/ColorTest.cpp42
-rw-r--r--tests/DeferredCanvasTest.cpp187
-rw-r--r--tests/DrawPathTest.cpp46
-rw-r--r--tests/DrawTextTest.cpp115
-rw-r--r--tests/FontHostTest.cpp95
-rwxr-xr-xtests/GLInterfaceValidation.cpp12
-rw-r--r--tests/GLProgramsTest.cpp2
-rw-r--r--tests/GeometryTest.cpp21
-rw-r--r--tests/PathMeasureTest.cpp85
-rw-r--r--tests/PathTest.cpp55
-rw-r--r--tests/PremulAlphaRoundTripTest.cpp106
-rw-r--r--tests/ReadPixelsTest.cpp2
-rw-r--r--tests/Test.cpp2
-rw-r--r--tests/Test.h11
-rw-r--r--tests/WArrayTest.cpp6
-rw-r--r--tests/WritePixelsTest.cpp9
21 files changed, 1600 insertions, 65 deletions
diff --git a/tests/AAClipTest.cpp b/tests/AAClipTest.cpp
index b3051fd..4f3f759 100644
--- a/tests/AAClipTest.cpp
+++ b/tests/AAClipTest.cpp
@@ -272,15 +272,68 @@ static void test_irect(skiatest::Reporter* reporter) {
}
REPORTER_ASSERT(reporter, nonEmptyAA == nonEmptyBW);
REPORTER_ASSERT(reporter, clip2.getBounds() == rgn2.getBounds());
+
+ SkMask maskBW, maskAA;
+ copyToMask(rgn2, &maskBW);
+ clip2.copyToMask(&maskAA);
+ REPORTER_ASSERT(reporter, maskBW == maskAA);
}
}
}
+static void test_path_with_hole(skiatest::Reporter* reporter) {
+ static const uint8_t gExpectedImage[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ };
+ SkMask expected;
+ expected.fBounds.set(0, 0, 4, 6);
+ expected.fRowBytes = 4;
+ expected.fFormat = SkMask::kA8_Format;
+ expected.fImage = (uint8_t*)gExpectedImage;
+
+ SkPath path;
+ path.addRect(SkRect::MakeXYWH(0, 0,
+ SkIntToScalar(4), SkIntToScalar(2)));
+ path.addRect(SkRect::MakeXYWH(0, SkIntToScalar(4),
+ SkIntToScalar(4), SkIntToScalar(2)));
+
+ for (int i = 0; i < 2; ++i) {
+ SkAAClip clip;
+ clip.setPath(path, NULL, 1 == i);
+
+ SkMask mask;
+ clip.copyToMask(&mask);
+
+ REPORTER_ASSERT(reporter, expected == mask);
+ }
+}
+
+static void test_regressions(skiatest::Reporter* reporter) {
+ // these should not assert in the debug build
+ // bug was introduced in rev. 3209
+ {
+ SkAAClip clip;
+ SkRect r;
+ r.fLeft = SkFloatToScalar(129.892181);
+ r.fTop = SkFloatToScalar(10.3999996);
+ r.fRight = SkFloatToScalar(130.892181);
+ r.fBottom = SkFloatToScalar(20.3999996);
+ clip.setRect(r, true);
+ }
+}
+
static void TestAAClip(skiatest::Reporter* reporter) {
test_empty(reporter);
test_path_bounds(reporter);
test_irect(reporter);
test_rgn(reporter);
+ test_path_with_hole(reporter);
+ test_regressions(reporter);
}
#include "TestClassDef.h"
diff --git a/tests/Android.mk b/tests/Android.mk
index 14d23f8..8487699 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -16,11 +16,14 @@ LOCAL_SRC_FILES:= \
ColorFilterTest.cpp \
ColorTest.cpp \
DataRefTest.cpp \
+ DeferredCanvasTest.cpp \
DequeTest.cpp \
DrawBitmapRectTest.cpp \
+ DrawTextTest.cpp \
EmptyPathTest.cpp \
FillPathTest.cpp \
FlateTest.cpp \
+ FontHostTest.cpp \
GeometryTest.cpp \
GLInterfaceValidation.cpp \
GLProgramsTest.cpp \
@@ -37,6 +40,7 @@ LOCAL_SRC_FILES:= \
PathMeasureTest.cpp \
PathTest.cpp \
PointTest.cpp \
+ PremulAlphaRoundTripTest.cpp \
QuickRejectTest.cpp \
Reader32Test.cpp \
ReadPixelsTest.cpp \
diff --git a/tests/BitmapCopyTest.cpp b/tests/BitmapCopyTest.cpp
index b8d16bf..d5fd7df 100644
--- a/tests/BitmapCopyTest.cpp
+++ b/tests/BitmapCopyTest.cpp
@@ -308,12 +308,16 @@ static void TestBitmapCopy(skiatest::Reporter* reporter) {
}
// test extractSubset
{
+ SkBitmap bitmap(src);
SkBitmap subset;
SkIRect r;
r.set(1, 1, 2, 2);
- if (src.extractSubset(&subset, r)) {
+ bitmap.setIsVolatile(true);
+ if (bitmap.extractSubset(&subset, r)) {
REPORTER_ASSERT(reporter, subset.width() == 1);
REPORTER_ASSERT(reporter, subset.height() == 1);
+ REPORTER_ASSERT(reporter,
+ subset.isVolatile() == true);
SkBitmap copy;
REPORTER_ASSERT(reporter,
@@ -329,6 +333,11 @@ static void TestBitmapCopy(skiatest::Reporter* reporter) {
REPORTER_ASSERT(reporter,
(copy.getColorTable() != NULL) == hasCT);
}
+ bitmap.setIsVolatile(false);
+ if (bitmap.extractSubset(&subset, r)) {
+ REPORTER_ASSERT(reporter,
+ subset.isVolatile() == false);
+ }
}
} else {
// dst should be unchanged from its initial state
diff --git a/tests/CanvasTest.cpp b/tests/CanvasTest.cpp
index da1fafd..7cafda2 100644
--- a/tests/CanvasTest.cpp
+++ b/tests/CanvasTest.cpp
@@ -1,66 +1,759 @@
/*
- * Copyright 2011 Google Inc.
+ * Copyright 2012 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
-#include "Test.h"
+
+/* Description:
+ * This test defines a series of elementatry test steps that perform
+ * a single or a small group of canvas API calls. Each test step is
+ * used in several test cases that verify that different types of SkCanvas
+ * flavors and derivatives pass it and yield consistent behavior. The
+ * test cases analyse results that are queryable through the API. They do
+ * not look at rendering results.
+ *
+ * Adding test stepss:
+ * The general pattern for creating a new test step is to write a test
+ * function of the form:
+ *
+ * static void MyTestStepFunction(SkCanvas* canvas,
+ * skiatest::Reporter* reporter,
+ * CanvasTestStep* testStep)
+ * {
+ * canvas->someCanvasAPImethod();
+ * (...)
+ * REPORTER_ASSERT_MESSAGE(reporter, (...), \
+ * testStep->assertMessage());
+ * }
+ *
+ * The definition of the test step function should be followed by an
+ * invocation of the TEST_STEP macro, which generates a class and
+ * instance for the test step:
+ *
+ * TEST_STEP(MyTestStep, MyTestStepFunction)
+ *
+ * There are also short hand macros for defining simple test steps
+ * in a single line of code. A simple test step is a one that is made
+ * of a single canvas API call.
+ *
+ * SIMPLE_TEST_STEP(MytestStep, someCanvasAPIMethod());
+ *
+ * There is another macro called SIMPLE_TEST_STEP_WITH_ASSERT that
+ * works the same way as SIMPLE_TEST_STEP, and additionally verifies
+ * that the invoked method returns a non-zero value.
+ */
#include "SkBitmap.h"
#include "SkCanvas.h"
+#include "SkDeferredCanvas.h"
+#include "SkDevice.h"
+#include "SkMatrix.h"
+#include "SkNWayCanvas.h"
+#include "SkPaint.h"
+#include "SkPath.h"
+#include "SkPicture.h"
+#include "SkPictureRecord.h"
+#include "SkProxyCanvas.h"
+#include "SkRect.h"
+#include "SkRegion.h"
+#include "SkShader.h"
+#include "SkStream.h"
+#include "SkTDArray.h"
+#include "Test.h"
-static void test_isDrawingToLayer(skiatest::Reporter* reporter) {
- SkBitmap bm;
- bm.setConfig(SkBitmap::kARGB_8888_Config, 256, 256);
- bm.allocPixels();
-
- SkCanvas canvas(bm);
+static const int kWidth = 2;
+static const int kHeight = 2;
+// Maximum stream length for picture serialization
+static const size_t kMaxPictureBufferSize = 1024;
+
+// Format strings that describe the test context. The %s token is where
+// the name of the test step is inserted. The context is required for
+// disambiguating the error in the case of failures that are reported in
+// functions that are called multiple times in different contexts (test
+// cases and test steps).
+static const char* const kDefaultAssertMessageFormat = "%s";
+static const char* const kCanvasDrawAssertMessageFormat =
+ "Drawing test step %s with SkCanvas";
+static const char* const kPictureDrawAssertMessageFormat =
+ "Drawing test step %s with SkPicture";
+static const char* const kPictureSecondDrawAssertMessageFormat =
+ "Duplicate draw of test step %s with SkPicture";
+static const char* const kPictureReDrawAssertMessageFormat =
+ "Playing back test step %s from an SkPicture to another SkPicture";
+static const char* const kDeferredDrawAssertMessageFormat =
+ "Drawing test step %s with SkDeferredCanvas";
+static const char* const kProxyDrawAssertMessageFormat =
+ "Drawing test step %s with SkProxyCanvas";
+static const char* const kNWayDrawAssertMessageFormat =
+ "Drawing test step %s with SkNWayCanvas";
+static const char* const kRoundTripAssertMessageFormat =
+ "test step %s, SkPicture consistency after round trip";
+static const char* const kPictureRecoringAssertMessageFormat =
+ "test step %s, SkPicture state consistency after recording";
+static const char* const kPicturePlaybackAssertMessageFormat =
+ "test step %s, SkPicture state consistency in playback canvas";
+static const char* const kDeferredPreFlushAssertMessageFormat =
+ "test step %s, SkDeferredCanvas state consistency before flush";
+static const char* const kDeferredPostFlushAssertMessageFormat =
+ "test step %s, SkDeferredCanvas state consistency after flush";
+static const char* const kPictureResourceReuseMessageFormat =
+ "test step %s, SkPicture duplicate flattened object test";
+static const char* const kProxyStateAssertMessageFormat =
+ "test step %s, SkProxyCanvas state consistency";
+static const char* const kProxyIndirectStateAssertMessageFormat =
+ "test step %s, SkProxyCanvas indirect canvas state consistency";
+static const char* const kNWayStateAssertMessageFormat =
+ "test step %s, SkNWayCanvas state consistency";
+static const char* const kNWayIndirect1StateAssertMessageFormat =
+ "test step %s, SkNWayCanvas indirect canvas 1 state consistency";
+static const char* const kNWayIndirect2StateAssertMessageFormat =
+ "test step %s, SkNWayCanvas indirect canvas 2 state consistency";
+
+static void createBitmap(SkBitmap* bm, SkBitmap::Config config, SkColor color) {
+ bm->setConfig(config, kWidth, kHeight);
+ bm->allocPixels();
+ bm->eraseColor(color);
+}
+
+class CanvasTestStep;
+static SkTDArray<CanvasTestStep*>& testStepArray() {
+ static SkTDArray<CanvasTestStep*> theTests;
+ return theTests;
+}
+
+class CanvasTestStep {
+public:
+ CanvasTestStep() {
+ *testStepArray().append() = this;
+ fAssertMessageFormat = kDefaultAssertMessageFormat;
+ }
+ virtual ~CanvasTestStep() { }
+
+ virtual void draw(SkCanvas*, skiatest::Reporter*) = 0;
+ virtual const char* name() const = 0;
+
+ const char* assertMessage() {
+ fAssertMessage.printf(fAssertMessageFormat, name());
+ return fAssertMessage.c_str();
+ }
+
+ void setAssertMessageFormat(const char* format) {
+ fAssertMessageFormat = format;
+ }
+
+private:
+ SkString fAssertMessage;
+ const char* fAssertMessageFormat;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Constants used by test steps
+
+const SkRect kTestRect =
+ SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(0),
+ SkIntToScalar(2), SkIntToScalar(1));
+static SkMatrix testMatrix() {
+ SkMatrix matrix;
+ matrix.reset();
+ matrix.setScale(SkIntToScalar(2), SkIntToScalar(3));
+ return matrix;
+}
+const SkMatrix kTestMatrix = testMatrix();
+static SkPath testPath() {
+ SkPath path;
+ path.addRect(SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(0),
+ SkIntToScalar(2), SkIntToScalar(1)));
+ return path;
+}
+const SkPath kTestPath = testPath();
+static SkRegion testRegion() {
+ SkRegion region;
+ SkIRect rect = SkIRect::MakeXYWH(0, 0, 2, 1);
+ region.setRect(rect);
+ return region;
+}
+const SkIRect kTestIRect = SkIRect::MakeXYWH(0, 0, 2, 1);
+const SkRegion kTestRegion = testRegion();
+const SkColor kTestColor = 0x01020304;
+const SkPaint kTestPaint;
+const SkPoint kTestPoints[3] = {
+ {SkIntToScalar(0), SkIntToScalar(0)},
+ {SkIntToScalar(2), SkIntToScalar(1)},
+ {SkIntToScalar(0), SkIntToScalar(2)}
+};
+const size_t kTestPointCount = 3;
+static SkBitmap testBitmap() {
+ SkBitmap bitmap;
+ createBitmap(&bitmap, SkBitmap::kARGB_8888_Config, 0x05060708);
+ return bitmap;
+}
+SkBitmap kTestBitmap; // cannot be created during static init
+SkString kTestText("Hello World");
+SkPoint kTestPoint = SkPoint::Make(SkIntToScalar(0), SkIntToScalar(1));
+
+///////////////////////////////////////////////////////////////////////////////
+// Macros for defining test steps
+
+#define TEST_STEP(NAME, FUNCTION) \
+class NAME##_TestStep : public CanvasTestStep{ \
+public: \
+ virtual void draw(SkCanvas* canvas, skiatest::Reporter* reporter) { \
+ FUNCTION (canvas, reporter, this); \
+ } \
+ virtual const char* name() const {return #NAME ;} \
+}; \
+static NAME##_TestStep NAME##_TestStepInstance;
+
+#define SIMPLE_TEST_STEP(NAME, CALL) \
+static void NAME##TestStep(SkCanvas* canvas, skiatest::Reporter*, \
+ CanvasTestStep*) { \
+ canvas-> CALL ; \
+} \
+TEST_STEP(NAME, NAME##TestStep )
+
+#define SIMPLE_TEST_STEP_WITH_ASSERT(NAME, CALL) \
+static void NAME##TestStep(SkCanvas* canvas, skiatest::Reporter* reporter, \
+ CanvasTestStep* testStep) { \
+ REPORTER_ASSERT_MESSAGE(reporter, canvas-> CALL , \
+ testStep->assertMessage()); \
+} \
+TEST_STEP(NAME, NAME##TestStep )
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Basic test steps for most virtual methods in SkCanvas that draw or affect
+// the state of the canvas.
+
+SIMPLE_TEST_STEP(SaveMatrix, save(SkCanvas::kMatrix_SaveFlag));
+SIMPLE_TEST_STEP(SaveClip, save(SkCanvas::kClip_SaveFlag));
+SIMPLE_TEST_STEP(SaveMatrixClip, save(SkCanvas::kMatrixClip_SaveFlag));
+SIMPLE_TEST_STEP(SaveLayer, saveLayer(NULL, NULL));
+SIMPLE_TEST_STEP(BoundedSaveLayer, saveLayer(&kTestRect, NULL));
+SIMPLE_TEST_STEP(PaintSaveLayer, saveLayer(NULL, &kTestPaint));
+SIMPLE_TEST_STEP_WITH_ASSERT(Translate,
+ translate(SkIntToScalar(1), SkIntToScalar(2)));
+SIMPLE_TEST_STEP_WITH_ASSERT(Scale,
+ scale(SkIntToScalar(1), SkIntToScalar(2)));
+SIMPLE_TEST_STEP_WITH_ASSERT(Rotate, rotate(SkIntToScalar(1)));
+SIMPLE_TEST_STEP_WITH_ASSERT(Skew,
+ skew(SkIntToScalar(1), SkIntToScalar(2)));
+SIMPLE_TEST_STEP_WITH_ASSERT(Concat, concat(kTestMatrix));
+SIMPLE_TEST_STEP(SetMatrix, setMatrix(kTestMatrix));
+SIMPLE_TEST_STEP_WITH_ASSERT(ClipRect, clipRect(kTestRect));
+SIMPLE_TEST_STEP_WITH_ASSERT(ClipPath, clipPath(kTestPath));
+SIMPLE_TEST_STEP_WITH_ASSERT(ClipRegion,
+ clipRegion(kTestRegion, SkRegion::kReplace_Op));
+SIMPLE_TEST_STEP(Clear, clear(kTestColor));
+SIMPLE_TEST_STEP(DrawPaint, drawPaint(kTestPaint));
+SIMPLE_TEST_STEP(DrawPointsPoints, drawPoints(SkCanvas::kPoints_PointMode,
+ kTestPointCount, kTestPoints, kTestPaint));
+SIMPLE_TEST_STEP(DrawPointsLiness, drawPoints(SkCanvas::kLines_PointMode,
+ kTestPointCount, kTestPoints, kTestPaint));
+SIMPLE_TEST_STEP(DrawPointsPolygon, drawPoints(SkCanvas::kPolygon_PointMode,
+ kTestPointCount, kTestPoints, kTestPaint));
+SIMPLE_TEST_STEP(DrawRect, drawRect(kTestRect, kTestPaint));
+SIMPLE_TEST_STEP(DrawPath, drawPath(kTestPath, kTestPaint));
+SIMPLE_TEST_STEP(DrawBitmap, drawBitmap(kTestBitmap, 0, 0));
+SIMPLE_TEST_STEP(DrawBitmapPaint, drawBitmap(kTestBitmap, 0, 0, &kTestPaint));
+SIMPLE_TEST_STEP(DrawBitmapRect, drawBitmapRect(kTestBitmap, NULL, kTestRect,
+ NULL));
+SIMPLE_TEST_STEP(DrawBitmapRectSrcRect, drawBitmapRect(kTestBitmap,
+ &kTestIRect, kTestRect, NULL));
+SIMPLE_TEST_STEP(DrawBitmapRectPaint, drawBitmapRect(kTestBitmap, NULL,
+ kTestRect, &kTestPaint));
+SIMPLE_TEST_STEP(DrawBitmapMatrix, drawBitmapMatrix(kTestBitmap, kTestMatrix,
+ NULL));
+SIMPLE_TEST_STEP(DrawBitmapMatrixPaint, drawBitmapMatrix(kTestBitmap,
+ kTestMatrix, &kTestPaint));
+SIMPLE_TEST_STEP(DrawBitmapNine, drawBitmapNine(kTestBitmap, kTestIRect,
+ kTestRect, NULL));
+SIMPLE_TEST_STEP(DrawBitmapNinePaint, drawBitmapNine(kTestBitmap, kTestIRect,
+ kTestRect, &kTestPaint));
+SIMPLE_TEST_STEP(DrawSprite, drawSprite(kTestBitmap, 0, 0, NULL));
+SIMPLE_TEST_STEP(DrawSpritePaint, drawSprite(kTestBitmap, 0, 0, &kTestPaint));
+SIMPLE_TEST_STEP(DrawText, drawText(kTestText.c_str(), kTestText.size(),
+ 0, 1, kTestPaint));
+SIMPLE_TEST_STEP(DrawPosText, drawPosText(kTestText.c_str(),
+ kTestText.size(), &kTestPoint, kTestPaint));
+SIMPLE_TEST_STEP(DrawTextOnPath, drawTextOnPath(kTestText.c_str(),
+ kTestText.size(), kTestPath, NULL, kTestPaint));
+SIMPLE_TEST_STEP(DrawTextOnPathMatrix, drawTextOnPath(kTestText.c_str(),
+ kTestText.size(), kTestPath, &kTestMatrix, kTestPaint));
+SIMPLE_TEST_STEP(SetExternalMatrix, setExternalMatrix(&kTestMatrix));
+SIMPLE_TEST_STEP(DrawData, drawData(kTestText.c_str(), kTestText.size()));
+
+///////////////////////////////////////////////////////////////////////////////
+// Complex test steps
+
+static void DrawVerticesShaderTestStep(SkCanvas* canvas,
+ skiatest::Reporter* reporter,
+ CanvasTestStep* testStep) {
+ SkPoint pts[4];
+ pts[0].set(0, 0);
+ pts[1].set(SkIntToScalar(kWidth), 0);
+ pts[2].set(SkIntToScalar(kWidth), SkIntToScalar(kHeight));
+ pts[3].set(0, SkIntToScalar(kHeight));
+ SkPaint paint;
+ SkShader* shader = SkShader::CreateBitmapShader(kTestBitmap,
+ SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
+ paint.setShader(shader)->unref();
+ canvas->drawVertices(SkCanvas::kTriangleFan_VertexMode, 4, pts, pts,
+ NULL, NULL, NULL, 0, paint);
+}
+TEST_STEP(DrawVerticesShader, DrawVerticesShaderTestStep);
+
+static void DrawPictureTestStep(SkCanvas* canvas,
+ skiatest::Reporter* reporter,
+ CanvasTestStep* testStep) {
+ SkPicture* testPicture = SkNEW_ARGS(SkPicture, ());
+ SkAutoUnref aup(testPicture);
+ SkCanvas* testCanvas = testPicture->beginRecording(kWidth, kHeight);
+ testCanvas->scale(SkIntToScalar(2), SkIntToScalar(1));
+ testCanvas->clipRect(kTestRect);
+ testCanvas->drawRect(kTestRect, kTestPaint);
+ canvas->drawPicture(*testPicture);
+}
+TEST_STEP(DrawPicture, DrawPictureTestStep);
+
+static void SaveRestoreTestStep(SkCanvas* canvas,
+ skiatest::Reporter* reporter,
+ CanvasTestStep* testStep) {
+ REPORTER_ASSERT_MESSAGE(reporter, 1 == canvas->getSaveCount(),
+ testStep->assertMessage());
+ size_t n = canvas->save();
+ REPORTER_ASSERT_MESSAGE(reporter, 1 == n, testStep->assertMessage());
+ REPORTER_ASSERT_MESSAGE(reporter, 2 == canvas->getSaveCount(),
+ testStep->assertMessage());
+ canvas->save();
+ canvas->save();
+ REPORTER_ASSERT_MESSAGE(reporter, 4 == canvas->getSaveCount(),
+ testStep->assertMessage());
+ canvas->restoreToCount(2);
+ REPORTER_ASSERT_MESSAGE(reporter, 2 == canvas->getSaveCount(),
+ testStep->assertMessage());
+
+ // should this pin to 1, or be a no-op, or crash?
+ canvas->restoreToCount(0);
+ REPORTER_ASSERT_MESSAGE(reporter, 1 == canvas->getSaveCount(),
+ testStep->assertMessage());
+}
+TEST_STEP(SaveRestore, SaveRestoreTestStep);
- REPORTER_ASSERT(reporter, !canvas.isDrawingToLayer());
- canvas.save();
- REPORTER_ASSERT(reporter, !canvas.isDrawingToLayer());
+static void DrawLayerTestStep(SkCanvas* canvas,
+ skiatest::Reporter* reporter,
+ CanvasTestStep* testStep) {
+ REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(),
+ testStep->assertMessage());
+ canvas->save();
+ REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(),
+ testStep->assertMessage());
const SkRect* bounds = NULL; // null means include entire bounds
const SkPaint* paint = NULL;
- canvas.saveLayer(bounds, paint);
- REPORTER_ASSERT(reporter, canvas.isDrawingToLayer());
- canvas.restore();
- REPORTER_ASSERT(reporter, !canvas.isDrawingToLayer());
-
- canvas.saveLayer(bounds, paint);
- canvas.saveLayer(bounds, paint);
- REPORTER_ASSERT(reporter, canvas.isDrawingToLayer());
- canvas.restore();
- REPORTER_ASSERT(reporter, canvas.isDrawingToLayer());
- canvas.restore();
+ canvas->saveLayer(bounds, paint);
+ REPORTER_ASSERT_MESSAGE(reporter, canvas->isDrawingToLayer(),
+ testStep->assertMessage());
+ canvas->restore();
+ REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(),
+ testStep->assertMessage());
+
+ canvas->saveLayer(bounds, paint);
+ canvas->saveLayer(bounds, paint);
+ REPORTER_ASSERT_MESSAGE(reporter, canvas->isDrawingToLayer(),
+ testStep->assertMessage());
+ canvas->restore();
+ REPORTER_ASSERT_MESSAGE(reporter, canvas->isDrawingToLayer(),
+ testStep->assertMessage());
+ canvas->restore();
// now layer count should be 0
- REPORTER_ASSERT(reporter, !canvas.isDrawingToLayer());
+ REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(),
+ testStep->assertMessage());
}
+TEST_STEP(DrawLayer, DrawLayerTestStep);
-static void TestCanvas(skiatest::Reporter* reporter) {
- SkBitmap bm;
- bm.setConfig(SkBitmap::kARGB_8888_Config, 256, 256);
- bm.allocPixels();
-
- SkCanvas canvas(bm);
- int n;
-
- REPORTER_ASSERT(reporter, 1 == canvas.getSaveCount());
- n = canvas.save();
- REPORTER_ASSERT(reporter, 1 == n);
- REPORTER_ASSERT(reporter, 2 == canvas.getSaveCount());
- canvas.save();
- canvas.save();
- REPORTER_ASSERT(reporter, 4 == canvas.getSaveCount());
- canvas.restoreToCount(2);
- REPORTER_ASSERT(reporter, 2 == canvas.getSaveCount());
+static void AssertCanvasStatesEqual(skiatest::Reporter* reporter,
+ const SkCanvas* canvas1,
+ const SkCanvas* canvas2,
+ CanvasTestStep* testStep) {
+ REPORTER_ASSERT_MESSAGE(reporter, canvas1->getDeviceSize() ==
+ canvas2->getDeviceSize(), testStep->assertMessage());
+ REPORTER_ASSERT_MESSAGE(reporter, canvas1->getSaveCount() ==
+ canvas2->getSaveCount(), testStep->assertMessage());
+ REPORTER_ASSERT_MESSAGE(reporter, canvas1->isDrawingToLayer() ==
+ canvas2->isDrawingToLayer(), testStep->assertMessage());
+ SkRect bounds1, bounds2;
+ REPORTER_ASSERT_MESSAGE(reporter,
+ canvas1->getClipBounds(&bounds1, SkCanvas::kAA_EdgeType) ==
+ canvas2->getClipBounds(&bounds2, SkCanvas::kAA_EdgeType),
+ testStep->assertMessage());
+ REPORTER_ASSERT_MESSAGE(reporter, bounds1 == bounds2,
+ testStep->assertMessage());
+ REPORTER_ASSERT_MESSAGE(reporter,
+ canvas1->getClipBounds(&bounds1, SkCanvas::kBW_EdgeType) ==
+ canvas2->getClipBounds(&bounds2, SkCanvas::kBW_EdgeType),
+ testStep->assertMessage());
+ REPORTER_ASSERT_MESSAGE(reporter, bounds1 == bounds2,
+ testStep->assertMessage());
+ REPORTER_ASSERT_MESSAGE(reporter, canvas1->getDrawFilter() ==
+ canvas2->getDrawFilter(), testStep->assertMessage());
+ SkIRect deviceBounds1, deviceBounds2;
+ REPORTER_ASSERT_MESSAGE(reporter,
+ canvas1->getClipDeviceBounds(&deviceBounds1) ==
+ canvas2->getClipDeviceBounds(&deviceBounds2),
+ testStep->assertMessage());
+ REPORTER_ASSERT_MESSAGE(reporter, deviceBounds1 == deviceBounds2,
+ testStep->assertMessage());
+ REPORTER_ASSERT_MESSAGE(reporter, canvas1->getBounder() ==
+ canvas2->getBounder(), testStep->assertMessage());
+ REPORTER_ASSERT_MESSAGE(reporter, canvas1->getTotalMatrix() ==
+ canvas2->getTotalMatrix(), testStep->assertMessage());
+ REPORTER_ASSERT_MESSAGE(reporter, canvas1->getClipType() ==
+ canvas2->getClipType(), testStep->assertMessage());
+ REPORTER_ASSERT_MESSAGE(reporter, canvas1->getTotalClip() ==
+ canvas2->getTotalClip(), testStep->assertMessage());
+ REPORTER_ASSERT_MESSAGE(reporter, canvas1->getTotalClipStack() ==
+ canvas2->getTotalClipStack(), testStep->assertMessage());
- // should this pin to 1, or be a no-op, or crash?
- canvas.restoreToCount(0);
- REPORTER_ASSERT(reporter, 1 == canvas.getSaveCount());
+ // The following test code is commented out because the test fails when
+ // the canvas is an SkPictureRecord or SkDeferredCanvas
+ // Issue: http://code.google.com/p/skia/issues/detail?id=498
+ // Also, creating a LayerIter on an SkProxyCanvas crashes
+ // Issue: http://code.google.com/p/skia/issues/detail?id=499
+ /*
+ SkCanvas::LayerIter layerIter1(const_cast<SkCanvas*>(canvas1), false);
+ SkCanvas::LayerIter layerIter2(const_cast<SkCanvas*>(canvas2), false);
+ while (!layerIter1.done() && !layerIter2.done()) {
+ REPORTER_ASSERT_MESSAGE(reporter, layerIter1.matrix() ==
+ layerIter2.matrix(), testStep->assertMessage());
+ REPORTER_ASSERT_MESSAGE(reporter, layerIter1.clip() ==
+ layerIter2.clip(), testStep->assertMessage());
+ REPORTER_ASSERT_MESSAGE(reporter, layerIter1.paint() ==
+ layerIter2.paint(), testStep->assertMessage());
+ REPORTER_ASSERT_MESSAGE(reporter, layerIter1.x() ==
+ layerIter2.x(), testStep->assertMessage());
+ REPORTER_ASSERT_MESSAGE(reporter, layerIter1.y() ==
+ layerIter2.y(), testStep->assertMessage());
+ layerIter1.next();
+ layerIter2.next();
+ }
+ REPORTER_ASSERT_MESSAGE(reporter, layerIter1.done(),
+ testStep->assertMessage());
+ REPORTER_ASSERT_MESSAGE(reporter, layerIter2.done(),
+ testStep->assertMessage());
+ */
+}
+
+// The following class groups static functions that need to access
+// the privates members of SkPictureRecord
+class SkPictureTester {
+private:
+ static void AssertFlattenedObjectsEqual(
+ SkPictureRecord* referenceRecord,
+ SkPictureRecord* testRecord,
+ skiatest::Reporter* reporter,
+ CanvasTestStep* testStep) {
+
+ REPORTER_ASSERT_MESSAGE(reporter,
+ referenceRecord->fBitmaps.count() ==
+ testRecord->fBitmaps.count(), testStep->assertMessage());
+ for (int i = 0; i < referenceRecord->fBitmaps.count(); ++i) {
+ REPORTER_ASSERT_MESSAGE(reporter,
+ SkFlatData::Compare(referenceRecord->fBitmaps[i],
+ testRecord->fBitmaps[i]) == 0, testStep->assertMessage());
+ }
+ REPORTER_ASSERT_MESSAGE(reporter,
+ referenceRecord->fMatrices.count() ==
+ testRecord->fMatrices.count(), testStep->assertMessage());
+ for (int i = 0; i < referenceRecord->fMatrices.count(); ++i) {
+ REPORTER_ASSERT_MESSAGE(reporter,
+ SkFlatData::Compare(referenceRecord->fMatrices[i],
+ testRecord->fMatrices[i]) == 0,
+ testStep->assertMessage());
+ }
+ REPORTER_ASSERT_MESSAGE(reporter,
+ referenceRecord->fPaints.count() ==
+ testRecord->fPaints.count(), testStep->assertMessage());
+ for (int i = 0; i < referenceRecord->fPaints.count(); ++i) {
+ REPORTER_ASSERT_MESSAGE(reporter,
+ SkFlatData::Compare(referenceRecord->fPaints[i],
+ testRecord->fPaints[i]) == 0, testStep->assertMessage());
+ }
+ REPORTER_ASSERT_MESSAGE(reporter,
+ referenceRecord->fRegions.count() ==
+ testRecord->fRegions.count(), testStep->assertMessage());
+ for (int i = 0; i < referenceRecord->fRegions.count(); ++i) {
+ REPORTER_ASSERT_MESSAGE(reporter,
+ SkFlatData::Compare(referenceRecord->fRegions[i],
+ testRecord->fRegions[i]) == 0, testStep->assertMessage());
+ }
+ REPORTER_ASSERT_MESSAGE(reporter,
+ !referenceRecord->fPathHeap ==
+ !testRecord->fPathHeap,
+ testStep->assertMessage());
+ // The following tests are commented out because they currently
+ // fail. Issue: http://code.google.com/p/skia/issues/detail?id=507
+ /*
+ if (referenceRecord->fPathHeap) {
+ REPORTER_ASSERT_MESSAGE(reporter,
+ referenceRecord->fPathHeap->count() ==
+ testRecord->fPathHeap->count(),
+ testStep->assertMessage());
+ for (int i = 0; i < referenceRecord->fPathHeap->count(); ++i) {
+ REPORTER_ASSERT_MESSAGE(reporter,
+ (*referenceRecord->fPathHeap)[i] ==
+ (*testRecord->fPathHeap)[i], testStep->assertMessage());
+ }
+ }
+ */
+
+ }
+
+public:
+
+ static void TestPictureSerializationRoundTrip(skiatest::Reporter* reporter,
+ CanvasTestStep* testStep) {
+ testStep->setAssertMessageFormat(kPictureDrawAssertMessageFormat);
+ SkPicture referencePicture;
+ testStep->draw(referencePicture.beginRecording(kWidth, kHeight),
+ reporter);
+ SkPicture initialPicture;
+ testStep->draw(initialPicture.beginRecording(kWidth, kHeight),
+ reporter);
+ testStep->setAssertMessageFormat(kPictureReDrawAssertMessageFormat);
+ SkPicture roundTripPicture;
+ initialPicture.draw(roundTripPicture.beginRecording(kWidth, kHeight));
+
+ SkPictureRecord* referenceRecord = static_cast<SkPictureRecord*>(
+ referencePicture.getRecordingCanvas());
+ SkPictureRecord* roundTripRecord = static_cast<SkPictureRecord*>(
+ roundTripPicture.getRecordingCanvas());
+
+ testStep->setAssertMessageFormat(kPictureReDrawAssertMessageFormat);
+
+ // Verify that deserialization-serialization round trip conserves all
+ // data by comparing referenceRecord to roundTripRecord
+ REPORTER_ASSERT_MESSAGE(reporter, referenceRecord->fBitmapIndex ==
+ roundTripRecord->fBitmapIndex, testStep->assertMessage());
+ REPORTER_ASSERT_MESSAGE(reporter, referenceRecord->fMatrixIndex ==
+ roundTripRecord->fMatrixIndex, testStep->assertMessage());
+ REPORTER_ASSERT_MESSAGE(reporter, referenceRecord->fPaintIndex ==
+ roundTripRecord->fPaintIndex, testStep->assertMessage());
+ REPORTER_ASSERT_MESSAGE(reporter, referenceRecord->fRegionIndex ==
+ roundTripRecord->fRegionIndex, testStep->assertMessage());
+ char referenceBuffer[kMaxPictureBufferSize];
+ SkMemoryWStream referenceStream(referenceBuffer,
+ kMaxPictureBufferSize);
+ referenceRecord->fWriter.writeToStream(&referenceStream);
+ char roundTripBuffer[kMaxPictureBufferSize];
+ SkMemoryWStream roundTripStream(roundTripBuffer,
+ kMaxPictureBufferSize);
+ roundTripRecord->fWriter.writeToStream(&roundTripStream);
+ REPORTER_ASSERT_MESSAGE(reporter,
+ roundTripStream.bytesWritten() == referenceStream.bytesWritten(),
+ testStep->assertMessage());
+ REPORTER_ASSERT_MESSAGE(reporter, 0 == memcmp(referenceBuffer,
+ roundTripBuffer, roundTripStream.bytesWritten()),
+ testStep->assertMessage());
+ REPORTER_ASSERT_MESSAGE(reporter, referenceRecord->fRecordFlags ==
+ roundTripRecord->fRecordFlags, testStep->assertMessage());
+ REPORTER_ASSERT_MESSAGE(reporter,
+ referenceRecord->fRestoreOffsetStack ==
+ roundTripRecord->fRestoreOffsetStack,
+ testStep->assertMessage());
+ AssertFlattenedObjectsEqual(referenceRecord, roundTripRecord,
+ reporter, testStep);
+ AssertCanvasStatesEqual(reporter, referenceRecord, roundTripRecord,
+ testStep);
+ }
+
+ static void TestPictureFlattenedObjectReuse(skiatest::Reporter* reporter,
+ CanvasTestStep* testStep) {
+ // Verify that when a test step is executed twice, no extra resources
+ // are flattened during the second execution
+ testStep->setAssertMessageFormat(kPictureDrawAssertMessageFormat);
+ SkPicture referencePicture;
+ SkCanvas* referenceCanvas = referencePicture.beginRecording(kWidth,
+ kHeight);
+ testStep->draw(referenceCanvas, reporter);
+ SkPicture testPicture;
+ SkCanvas* testCanvas = testPicture.beginRecording(kWidth,
+ kHeight);
+ testStep->draw(testCanvas, reporter);
+ testStep->setAssertMessageFormat(kPictureSecondDrawAssertMessageFormat);
+ testStep->draw(testCanvas, reporter);
+
+ SkPictureRecord* referenceRecord = static_cast<SkPictureRecord*>(
+ referenceCanvas);
+ SkPictureRecord* testRecord = static_cast<SkPictureRecord*>(
+ testCanvas);
+ testStep->setAssertMessageFormat(kPictureResourceReuseMessageFormat);
+ AssertFlattenedObjectsEqual(referenceRecord, testRecord,
+ reporter, testStep);
+ }
+};
+
+static void TestPictureStateConsistency(skiatest::Reporter* reporter,
+ CanvasTestStep* testStep,
+ const SkCanvas& referenceCanvas) {
+ // Verify that the recording canvas's state is consistent
+ // with that of a regular canvas
+ SkPicture testPicture;
+ SkCanvas* pictureCanvas = testPicture.beginRecording(kWidth, kHeight);
+ testStep->setAssertMessageFormat(kPictureDrawAssertMessageFormat);
+ testStep->draw(pictureCanvas, reporter);
+ testStep->setAssertMessageFormat(kPictureRecoringAssertMessageFormat);
+ AssertCanvasStatesEqual(reporter, pictureCanvas, &referenceCanvas,
+ testStep);
+
+ SkBitmap playbackStore;
+ createBitmap(&playbackStore, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
+ SkDevice playbackDevice(playbackStore);
+ SkCanvas playbackCanvas(&playbackDevice);
+ testPicture.draw(&playbackCanvas);
+ testStep->setAssertMessageFormat(kPicturePlaybackAssertMessageFormat);
+ AssertCanvasStatesEqual(reporter, &playbackCanvas, &referenceCanvas,
+ testStep);
+
+ // The following test code is commented out because SkPicture is not
+ // currently expected to preserve state when restarting recording.
+ /*
+ SkCanvas* pictureCanvas = testPicture.beginRecording(kWidth, kHeight);
+ testStep->setAssertMessageFormat(kPictureResumeAssertMessageFormat);
+ AssertCanvasStatesEqual(reporter, pictureCanvas, &referenceCanvas,
+ testStep);
+ */
+}
+
+static void TestDeferredCanvasStateConsistency(
+ skiatest::Reporter* reporter,
+ CanvasTestStep* testStep,
+ const SkCanvas& referenceCanvas) {
+
+ SkBitmap deferredStore;
+ createBitmap(&deferredStore, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
+ SkDevice deferredDevice(deferredStore);
+ SkDeferredCanvas deferredCanvas(&deferredDevice);
+ testStep->setAssertMessageFormat(kDeferredDrawAssertMessageFormat);
+ testStep->draw(&deferredCanvas, reporter);
+ testStep->setAssertMessageFormat(kDeferredPreFlushAssertMessageFormat);
+ AssertCanvasStatesEqual(reporter, &deferredCanvas, &referenceCanvas,
+ testStep);
+
+ // Verified that deferred canvas state is not affected by flushing
+ // pending draw operations
+
+ // The following test code is commented out because it currently fails.
+ // Issue: http://code.google.com/p/skia/issues/detail?id=496
+ /*
+ deferredCanvas.flush();
+ testStep->setAssertMessageFormat(kDeferredPostFlushAssertMessageFormat);
+ AssertCanvasStatesEqual(reporter, &deferredCanvas, &referenceCanvas,
+ testStep);
+ */
+}
+
+static void TestProxyCanvasStateConsistency(
+ skiatest::Reporter* reporter,
+ CanvasTestStep* testStep,
+ const SkCanvas& referenceCanvas) {
+
+ SkBitmap indirectStore;
+ createBitmap(&indirectStore, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
+ SkDevice indirectDevice(indirectStore);
+ SkCanvas indirectCanvas(&indirectDevice);
+ SkProxyCanvas proxyCanvas(&indirectCanvas);
+ testStep->setAssertMessageFormat(kProxyDrawAssertMessageFormat);
+ testStep->draw(&proxyCanvas, reporter);
+ // Verify that the SkProxyCanvas reports consitent state
+ testStep->setAssertMessageFormat(kProxyStateAssertMessageFormat);
+ AssertCanvasStatesEqual(reporter, &proxyCanvas, &referenceCanvas,
+ testStep);
+ // Verify that the indirect canvas reports consitent state
+ testStep->setAssertMessageFormat(kProxyIndirectStateAssertMessageFormat);
+ AssertCanvasStatesEqual(reporter, &indirectCanvas, &referenceCanvas,
+ testStep);
+}
+
+static void TestNWayCanvasStateConsistency(
+ skiatest::Reporter* reporter,
+ CanvasTestStep* testStep,
+ const SkCanvas& referenceCanvas) {
+
+ SkBitmap indirectStore1;
+ createBitmap(&indirectStore1, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
+ SkDevice indirectDevice1(indirectStore1);
+ SkCanvas indirectCanvas1(&indirectDevice1);
+
+ SkBitmap indirectStore2;
+ createBitmap(&indirectStore2, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
+ SkDevice indirectDevice2(indirectStore2);
+ SkCanvas indirectCanvas2(&indirectDevice2);
+
+ SkNWayCanvas nWayCanvas;
+ nWayCanvas.addCanvas(&indirectCanvas1);
+ nWayCanvas.addCanvas(&indirectCanvas2);
+
+ testStep->setAssertMessageFormat(kNWayDrawAssertMessageFormat);
+ testStep->draw(&nWayCanvas, reporter);
+ // Verify that the SkProxyCanvas reports consitent state
+ testStep->setAssertMessageFormat(kNWayStateAssertMessageFormat);
+ AssertCanvasStatesEqual(reporter, &nWayCanvas, &referenceCanvas,
+ testStep);
+ // Verify that the indirect canvases report consitent state
+ testStep->setAssertMessageFormat(kNWayIndirect1StateAssertMessageFormat);
+ AssertCanvasStatesEqual(reporter, &indirectCanvas1, &referenceCanvas,
+ testStep);
+ testStep->setAssertMessageFormat(kNWayIndirect2StateAssertMessageFormat);
+ AssertCanvasStatesEqual(reporter, &indirectCanvas2, &referenceCanvas,
+ testStep);
+}
+
+/*
+ * This sub-test verifies that the test step passes when executed
+ * with SkCanvas and with classes derrived from SkCanvas. It also verifies
+ * that the all canvas derivatives report the same state as an SkCanvas
+ * after having executed the test step.
+ */
+static void TestOverrideStateConsistency(skiatest::Reporter* reporter,
+ CanvasTestStep* testStep) {
+ SkBitmap referenceStore;
+ createBitmap(&referenceStore, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
+ SkDevice referenceDevice(referenceStore);
+ SkCanvas referenceCanvas(&referenceDevice);
+ testStep->setAssertMessageFormat(kCanvasDrawAssertMessageFormat);
+ testStep->draw(&referenceCanvas, reporter);
+
+ TestPictureStateConsistency(reporter, testStep, referenceCanvas);
+ TestDeferredCanvasStateConsistency(reporter, testStep, referenceCanvas);
+
+ // The following test code is commented out because SkProxyCanvas is
+ // missing a lot of virtual overrides on get* methods, which are used
+ // to verify canvas state.
+ // Issue: http://code.google.com/p/skia/issues/detail?id=500
+
+ //TestProxyCanvasStateConsistency(reporter, testStep, referenceCanvas);
+
+ // The following test code is commented out because SkNWayCanvas does not
+ // report correct clipping and device bounds information
+ // Issue: http://code.google.com/p/skia/issues/detail?id=501
+
+ //TestNWayCanvasStateConsistency(reporter, testStep, referenceCanvas);
+}
+
+static void TestCanvas(skiatest::Reporter* reporter) {
+ // Init global here because bitmap pixels cannot be alocated during
+ // static initialization
+ kTestBitmap = testBitmap();
- test_isDrawingToLayer(reporter);
+ for (int testStep = 0; testStep < testStepArray().count(); testStep++) {
+ TestOverrideStateConsistency(reporter, testStepArray()[testStep]);
+ SkPictureTester::TestPictureSerializationRoundTrip(reporter,
+ testStepArray()[testStep]);
+ SkPictureTester::TestPictureFlattenedObjectReuse(reporter,
+ testStepArray()[testStep]);
+ }
}
#include "TestClassDef.h"
diff --git a/tests/ClipCubicTest.cpp b/tests/ClipCubicTest.cpp
index 931b61e..491d0e5 100644
--- a/tests/ClipCubicTest.cpp
+++ b/tests/ClipCubicTest.cpp
@@ -7,9 +7,27 @@
*/
#include "Test.h"
+#include "SkCanvas.h"
+#include "SkPaint.h"
#include "SkCubicClipper.h"
#include "SkGeometry.h"
+// Currently the supersampler blitter uses int16_t for its index into an array
+// the width of the clip. Test that we don't crash/assert if we try to draw
+// with a device/clip that is larger.
+static void test_giantClip() {
+ SkBitmap bm;
+ bm.setConfig(SkBitmap::kARGB_8888_Config, 64919, 1);
+ bm.allocPixels();
+ SkCanvas canvas(bm);
+ canvas.clear(0);
+
+ SkPath path;
+ path.moveTo(0, 0); path.lineTo(1, 0); path.lineTo(33, 1);
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ canvas.drawPath(path, paint);
+}
static void PrintCurve(const char *name, const SkPoint crv[4]) {
printf("%s: %.10g, %.10g, %.10g, %.10g, %.10g, %.10g, %.10g, %.10g\n",
@@ -142,6 +160,8 @@ static void TestCubicClipping(skiatest::Reporter* reporter) {
1.297736168, 7.059780121,
2.505550385, 10,
shouldbe), tol));
+
+ test_giantClip();
}
diff --git a/tests/ColorTest.cpp b/tests/ColorTest.cpp
index 0efb892..83e2e3f 100644
--- a/tests/ColorTest.cpp
+++ b/tests/ColorTest.cpp
@@ -7,7 +7,9 @@
*/
#include "Test.h"
#include "SkColor.h"
+#include "SkColorPriv.h"
#include "SkMath.h"
+#include "SkRandom.h"
#include "SkUnPreMultiply.h"
static void test_premul(skiatest::Reporter* reporter) {
@@ -31,9 +33,49 @@ static void test_premul(skiatest::Reporter* reporter) {
}
}
+/**
+ This test fails: SkFourByteInterp does *not* preserve opaque destinations.
+ SkAlpha255To256 implemented as (alpha + 1) is faster than
+ (alpha + (alpha >> 7)), but inaccurate, and Skia intends to phase it out.
+*/
+/*
+static void test_interp(skiatest::Reporter* reporter) {
+ SkRandom r;
+
+ U8CPU a0 = 0;
+ U8CPU a255 = 255;
+ for (int i = 0; i < 200; i++) {
+ SkColor colorSrc = r.nextU();
+ SkColor colorDst = r.nextU();
+ SkPMColor src = SkPreMultiplyColor(colorSrc);
+ SkPMColor dst = SkPreMultiplyColor(colorDst);
+
+ REPORTER_ASSERT(reporter, SkFourByteInterp(src, dst, a0) == dst);
+ REPORTER_ASSERT(reporter, SkFourByteInterp(src, dst, a255) == src);
+ }
+}
+*/
+
+static void test_fast_interp(skiatest::Reporter* reporter) {
+ SkRandom r;
+
+ U8CPU a0 = 0;
+ U8CPU a255 = 255;
+ for (int i = 0; i < 200; i++) {
+ SkColor colorSrc = r.nextU();
+ SkColor colorDst = r.nextU();
+ SkPMColor src = SkPreMultiplyColor(colorSrc);
+ SkPMColor dst = SkPreMultiplyColor(colorDst);
+
+ REPORTER_ASSERT(reporter, SkFastFourByteInterp(src, dst, a0) == dst);
+ REPORTER_ASSERT(reporter, SkFastFourByteInterp(src, dst, a255) == src);
+ }
+}
static void TestColor(skiatest::Reporter* reporter) {
test_premul(reporter);
+ //test_interp(reporter);
+ test_fast_interp(reporter);
}
#include "TestClassDef.h"
diff --git a/tests/DeferredCanvasTest.cpp b/tests/DeferredCanvasTest.cpp
new file mode 100644
index 0000000..17adb52
--- /dev/null
+++ b/tests/DeferredCanvasTest.cpp
@@ -0,0 +1,187 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "Test.h"
+#include "SkBitmap.h"
+#include "SkDeferredCanvas.h"
+#include "SkShader.h"
+
+
+static const int gWidth = 2;
+static const int gHeight = 2;
+
+static void create(SkBitmap* bm, SkBitmap::Config config, SkColor color) {
+ bm->setConfig(config, gWidth, gHeight);
+ bm->allocPixels();
+ bm->eraseColor(color);
+}
+
+static void TestDeferredCanvasBitmapAccess(skiatest::Reporter* reporter) {
+ SkBitmap store;
+
+ create(&store, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
+ SkDevice device(store);
+ SkDeferredCanvas canvas(&device);
+
+ canvas.clear(0x00000000);
+
+ SkAutoLockPixels alp(store);
+ REPORTER_ASSERT(reporter, store.getColor(0,0) == 0xFFFFFFFF); //verify that clear was deferred
+ SkBitmap accessed = canvas.getDevice()->accessBitmap(false);
+ REPORTER_ASSERT(reporter, store.getColor(0,0) == 0x00000000); //verify that clear was executed
+ REPORTER_ASSERT(reporter, accessed.pixelRef() == store.pixelRef());
+}
+
+static void TestDeferredCanvasFlush(skiatest::Reporter* reporter) {
+ SkBitmap store;
+
+ create(&store, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
+ SkDevice device(store);
+ SkDeferredCanvas canvas(&device);
+
+ canvas.clear(0x00000000);
+
+ SkAutoLockPixels alp(store);
+ REPORTER_ASSERT(reporter, store.getColor(0,0) == 0xFFFFFFFF); //verify that clear was deferred
+ canvas.flush();
+ REPORTER_ASSERT(reporter, store.getColor(0,0) == 0x00000000); //verify that clear was executed
+}
+
+static void TestDeferredCanvasFreshFrame(skiatest::Reporter* reporter) {
+ SkBitmap store;
+ SkRect fullRect;
+ fullRect.setXYWH(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(gWidth),
+ SkIntToScalar(gHeight));
+ SkRect partialRect;
+ partialRect.setXYWH(SkIntToScalar(0), SkIntToScalar(0),
+ SkIntToScalar(1), SkIntToScalar(1));
+ create(&store, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
+ SkDevice device(store);
+ SkDeferredCanvas canvas(&device);
+
+ // verify that frame is intially fresh
+ REPORTER_ASSERT(reporter, canvas.getDeferredDevice()->isFreshFrame());
+ // no clearing op since last call to isFreshFrame -> not fresh
+ REPORTER_ASSERT(reporter, !canvas.getDeferredDevice()->isFreshFrame());
+
+ // Verify that clear triggers a fresh frame
+ canvas.clear(0x00000000);
+ REPORTER_ASSERT(reporter, canvas.getDeferredDevice()->isFreshFrame());
+
+ // Verify that clear with saved state triggers a fresh frame
+ canvas.save(SkCanvas::kMatrixClip_SaveFlag);
+ canvas.clear(0x00000000);
+ canvas.restore();
+ REPORTER_ASSERT(reporter, canvas.getDeferredDevice()->isFreshFrame());
+
+ // Verify that clear within a layer does NOT trigger a fresh frame
+ canvas.saveLayer(NULL, NULL, SkCanvas::kARGB_ClipLayer_SaveFlag);
+ canvas.clear(0x00000000);
+ canvas.restore();
+ REPORTER_ASSERT(reporter, !canvas.getDeferredDevice()->isFreshFrame());
+
+ // Verify that a clear with clipping triggers a fresh frame
+ // (clear is not affected by clipping)
+ canvas.save(SkCanvas::kMatrixClip_SaveFlag);
+ canvas.clipRect(partialRect, SkRegion::kIntersect_Op, false);
+ canvas.clear(0x00000000);
+ canvas.restore();
+ REPORTER_ASSERT(reporter, canvas.getDeferredDevice()->isFreshFrame());
+
+ // Verify that full frame rects with different forms of opaque paint
+ // trigger frames to be marked as fresh
+ {
+ SkPaint paint;
+ paint.setStyle( SkPaint::kFill_Style );
+ paint.setAlpha( 255 );
+ canvas.drawRect(fullRect, paint);
+ REPORTER_ASSERT(reporter, canvas.getDeferredDevice()->isFreshFrame());
+ }
+ {
+ SkPaint paint;
+ paint.setStyle( SkPaint::kFill_Style );
+ SkBitmap bmp;
+ create(&bmp, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
+ bmp.setIsOpaque(true);
+ SkShader* shader = SkShader::CreateBitmapShader(bmp,
+ SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
+ paint.setShader(shader)->unref();
+ canvas.drawRect(fullRect, paint);
+ REPORTER_ASSERT(reporter, canvas.getDeferredDevice()->isFreshFrame());
+ }
+
+ // Verify that full frame rects with different forms of non-opaque paint
+ // do not trigger frames to be marked as fresh
+ {
+ SkPaint paint;
+ paint.setStyle( SkPaint::kFill_Style );
+ paint.setAlpha( 254 );
+ canvas.drawRect(fullRect, paint);
+ REPORTER_ASSERT(reporter, !canvas.getDeferredDevice()->isFreshFrame());
+ }
+ {
+ SkPaint paint;
+ paint.setStyle( SkPaint::kFill_Style );
+ SkBitmap bmp;
+ create(&bmp, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
+ bmp.setIsOpaque(false);
+ SkShader* shader = SkShader::CreateBitmapShader(bmp,
+ SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
+ paint.setShader(shader)->unref();
+ canvas.drawRect(fullRect, paint);
+ REPORTER_ASSERT(reporter, !canvas.getDeferredDevice()->isFreshFrame());
+ }
+
+ // Verify that incomplete coverage does not trigger a fresh frame
+ {
+ SkPaint paint;
+ paint.setStyle(SkPaint::kFill_Style);
+ paint.setAlpha(255);
+ canvas.drawRect(partialRect, paint);
+ REPORTER_ASSERT(reporter, !canvas.getDeferredDevice()->isFreshFrame());
+ }
+
+ // Verify that incomplete coverage due to clipping does not trigger a fresh
+ // frame
+ {
+ canvas.save(SkCanvas::kMatrixClip_SaveFlag);
+ canvas.clipRect(partialRect, SkRegion::kIntersect_Op, false);
+ SkPaint paint;
+ paint.setStyle(SkPaint::kFill_Style);
+ paint.setAlpha(255);
+ canvas.drawRect(fullRect, paint);
+ REPORTER_ASSERT(reporter, !canvas.getDeferredDevice()->isFreshFrame());
+ }
+
+ // Verify that stroked rect does not trigger a fresh frame
+ {
+ SkPaint paint;
+ paint.setStyle( SkPaint::kStroke_Style );
+ paint.setAlpha( 255 );
+ canvas.drawRect(fullRect, paint);
+ REPORTER_ASSERT(reporter, !canvas.getDeferredDevice()->isFreshFrame());
+ }
+
+ // Verify kSrcMode triggers a fresh frame even with transparent color
+ {
+ SkPaint paint;
+ paint.setStyle( SkPaint::kFill_Style );
+ paint.setAlpha( 100 );
+ paint.setXfermodeMode(SkXfermode::kSrc_Mode);
+ canvas.drawRect(fullRect, paint);
+ REPORTER_ASSERT(reporter, !canvas.getDeferredDevice()->isFreshFrame());
+ }
+}
+
+static void TestDeferredCanvas(skiatest::Reporter* reporter) {
+ TestDeferredCanvasBitmapAccess(reporter);
+ TestDeferredCanvasFlush(reporter);
+ TestDeferredCanvasFreshFrame(reporter);
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("DeferredCanvas", TestDeferredCanvasClass, TestDeferredCanvas)
diff --git a/tests/DrawPathTest.cpp b/tests/DrawPathTest.cpp
new file mode 100644
index 0000000..ae0068b
--- /dev/null
+++ b/tests/DrawPathTest.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "Test.h"
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+
+static SkCanvas* create(SkBitmap::Config config, int w, int h, int rb,
+ void* addr = NULL) {
+ SkBitmap bm;
+ bm.setConfig(config, w, h, rb);
+ if (addr) {
+ bm.setPixels(addr);
+ } else {
+ bm.allocPixels();
+ }
+ return new SkCanvas(bm);
+}
+
+// we used to assert if the bounds of the device (clip) was larger than 32K
+// even when the path itself was smaller. We just draw and hope in the debug
+// version to not assert.
+static void test_giantaa(skiatest::Reporter* reporter) {
+ const int W = 400;
+ const int H = 400;
+ SkCanvas* canvas = create(SkBitmap::kARGB_8888_Config, 33000, 10, 0, NULL);
+ canvas->clear(0);
+
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ SkPath path;
+ path.addOval(SkRect::MakeXYWH(-10, -10, 20 + W, 20 + H));
+ canvas->drawPath(path, paint);
+ canvas->unref();
+}
+
+static void TestDrawPath(skiatest::Reporter* reporter) {
+ test_giantaa(reporter);
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("DrawPath", TestDrawPathClass, TestDrawPath)
diff --git a/tests/DrawTextTest.cpp b/tests/DrawTextTest.cpp
new file mode 100644
index 0000000..aefe2f9
--- /dev/null
+++ b/tests/DrawTextTest.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkTypes.h"
+
+#include "Test.h"
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkColor.h"
+#include "SkPaint.h"
+#include "SkPoint.h"
+#include "SkRect.h"
+
+///////////////////////////////////////////////////////////////////////////////
+
+static const SkColor bgColor = SK_ColorWHITE;
+
+static void create(SkBitmap* bm, SkIRect bound, SkBitmap::Config config) {
+ bm->setConfig(config, bound.width(), bound.height());
+ bm->allocPixels();
+}
+
+static void drawBG(SkCanvas* canvas) {
+ canvas->drawColor(bgColor);
+}
+
+/** Assumes that the ref draw was completely inside ref canvas --
+ implies that everything outside is "bgColor".
+ Checks that all overlap is the same and that all non-overlap on the
+ ref is "bgColor".
+ */
+static bool compare(const SkBitmap& ref, const SkIRect& iref,
+ const SkBitmap& test, const SkIRect& itest)
+{
+ const int xOff = itest.fLeft - iref.fLeft;
+ const int yOff = itest.fTop - iref.fTop;
+
+ SkAutoLockPixels alpRef(ref);
+ SkAutoLockPixels alpTest(test);
+
+ for (int y = 0; y < test.height(); ++y) {
+ for (int x = 0; x < test.width(); ++x) {
+ SkColor testColor = test.getColor(x, y);
+ int refX = x + xOff;
+ int refY = y + yOff;
+ SkColor refColor;
+ if (refX >= 0 && refX < ref.width() &&
+ refY >= 0 && refY < ref.height())
+ {
+ refColor = ref.getColor(refX, refY);
+ } else {
+ refColor = bgColor;
+ }
+ if (refColor != testColor) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+static void test_drawText(skiatest::Reporter* reporter) {
+
+ SkPaint paint;
+ paint.setColor(SK_ColorGRAY);
+ paint.setTextSize(SkIntToScalar(20));
+
+ SkIRect drawTextRect = SkIRect::MakeWH(64, 64);
+ SkBitmap drawTextBitmap;
+ create(&drawTextBitmap, drawTextRect, SkBitmap::kARGB_8888_Config);
+ SkCanvas drawTextCanvas(drawTextBitmap);
+
+ SkIRect drawPosTextRect = SkIRect::MakeWH(64, 64);
+ SkBitmap drawPosTextBitmap;
+ create(&drawPosTextBitmap, drawPosTextRect, SkBitmap::kARGB_8888_Config);
+ SkCanvas drawPosTextCanvas(drawPosTextBitmap);
+
+ for (float offsetY = 0.0f; offsetY < 1.0f; offsetY += (1.0f / 16.0f)) {
+ for (float offsetX = 0.0f; offsetX < 1.0f; offsetX += (1.0f / 16.0f)) {
+ SkPoint point = SkPoint::Make(SkFloatToScalar(25.0f + offsetX),
+ SkFloatToScalar(25.0f + offsetY));
+
+ for (int align = 0; align < SkPaint::kAlignCount; ++align) {
+ paint.setTextAlign(static_cast<SkPaint::Align>(align));
+
+ for (unsigned int flags = 0; flags < (1 << 3); ++flags) {
+ static const unsigned int antiAliasFlag = 1;
+ static const unsigned int subpixelFlag = 1 << 1;
+ static const unsigned int lcdFlag = 1 << 2;
+
+ paint.setAntiAlias(SkToBool(flags & antiAliasFlag));
+ paint.setSubpixelText(SkToBool(flags & subpixelFlag));
+ paint.setLCDRenderText(SkToBool(flags & lcdFlag));
+
+ // Test: drawText and drawPosText draw the same.
+ drawBG(&drawTextCanvas);
+ drawTextCanvas.drawText("A", 1, point.fX, point.fY, paint);
+
+ drawBG(&drawPosTextCanvas);
+ drawPosTextCanvas.drawPosText("A", 1, &point, paint);
+
+ REPORTER_ASSERT(reporter,
+ compare(drawTextBitmap, drawTextRect,
+ drawPosTextBitmap, drawPosTextRect));
+ }
+ }
+ }
+ }
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("DrawText_DrawPosText", DrawTextTestClass, test_drawText)
diff --git a/tests/FontHostTest.cpp b/tests/FontHostTest.cpp
new file mode 100644
index 0000000..8ab7ad3
--- /dev/null
+++ b/tests/FontHostTest.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "Test.h"
+#include "SkTypeface.h"
+#include "SkFontHost.h"
+
+//#define DUMP_TABLES
+
+#define kFontTableTag_head SkSetFourByteTag('h', 'e', 'a', 'd')
+#define kFontTableTag_hhea SkSetFourByteTag('h', 'h', 'e', 'a')
+#define kFontTableTag_maxp SkSetFourByteTag('m', 'a', 'x', 'p')
+
+static const struct TagSize {
+ SkFontTableTag fTag;
+ size_t fSize;
+} gKnownTableSizes[] = {
+ { kFontTableTag_head, 54 },
+ { kFontTableTag_hhea, 36 },
+ { kFontTableTag_maxp, 32 },
+};
+
+static void test_tables(skiatest::Reporter* reporter, SkTypeface* face) {
+ SkFontID fontID = face->uniqueID();
+
+ int count = SkFontHost::CountTables(fontID);
+
+ SkAutoTMalloc<SkFontTableTag> storage(count);
+ SkFontTableTag* tags = storage.get();
+
+ int count2 = SkFontHost::GetTableTags(fontID, tags);
+ REPORTER_ASSERT(reporter, count2 == count);
+
+ for (int i = 0; i < count; ++i) {
+ size_t size = SkFontHost::GetTableSize(fontID, tags[i]);
+ REPORTER_ASSERT(reporter, size > 0);
+
+#ifdef DUMP_TABLES
+ char name[5];
+ name[0] = (tags[i] >> 24) & 0xFF;
+ name[1] = (tags[i] >> 16) & 0xFF;
+ name[2] = (tags[i] >> 8) & 0xFF;
+ name[3] = (tags[i] >> 0) & 0xFF;
+ name[4] = 0;
+ SkDebugf("%s %d\n", name, size);
+#endif
+
+ for (size_t j = 0; j < SK_ARRAY_COUNT(gKnownTableSizes); ++j) {
+ if (gKnownTableSizes[j].fTag == tags[i]) {
+ REPORTER_ASSERT(reporter, gKnownTableSizes[j].fSize == size);
+ }
+ }
+
+ // do we get the same size from GetTableData and GetTableSize
+ {
+ SkAutoMalloc data(size);
+ size_t size2 = SkFontHost::GetTableData(fontID, tags[i], 0, size,
+ data.get());
+ REPORTER_ASSERT(reporter, size2 == size);
+ }
+ }
+}
+
+static void test_tables(skiatest::Reporter* reporter) {
+ static const char* const gNames[] = {
+ NULL, // default font
+ "Arial", "Times", "Times New Roman", "Helvetica", "Courier",
+ "Courier New",
+ };
+
+ for (size_t i = 0; i < SK_ARRAY_COUNT(gNames); ++i) {
+ SkTypeface* face = SkTypeface::CreateFromName(gNames[i],
+ SkTypeface::kNormal);
+ if (face) {
+#ifdef DUMP_TABLES
+ SkDebugf("%s\n", gNames[i]);
+#endif
+ test_tables(reporter, face);
+ face->unref();
+ }
+ }
+}
+
+static void TestFontHost(skiatest::Reporter* reporter) {
+ test_tables(reporter);
+}
+
+// need tests for SkStrSearch
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("FontHost", FontHostTestClass, TestFontHost)
diff --git a/tests/GLInterfaceValidation.cpp b/tests/GLInterfaceValidation.cpp
index 2be13f0..5cee0e4 100755
--- a/tests/GLInterfaceValidation.cpp
+++ b/tests/GLInterfaceValidation.cpp
@@ -7,8 +7,8 @@
*/
#include "Test.h"
-#include "SkNativeGLContext.h"
-#include "SkMesaGLContext.h"
+#include "gl/SkNativeGLContext.h"
+#include "gl/SkMesaGLContext.h"
static void GLInterfaceValidationTest(skiatest::Reporter* reporter) {
typedef const GrGLInterface* (*interfaceFactory)();
@@ -51,7 +51,13 @@ static void GLInterfaceValidationTest(skiatest::Reporter* reporter) {
iface.reset(interfaceFactories[i].fFactory());
REPORTER_ASSERT(reporter, NULL != iface.get());
if (iface.get()) {
- REPORTER_ASSERT(reporter, iface.get()->validate());
+ for (GrGLBinding binding = kFirstGrGLBinding;
+ binding <= kLastGrGLBinding;
+ binding = static_cast<GrGLBinding>(binding << 1)) {
+ if (iface.get()->fBindingsExported & binding) {
+ REPORTER_ASSERT(reporter, iface.get()->validate(binding));
+ }
+ }
}
}
}
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index 5cacade..583b802 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -8,7 +8,7 @@
#include "Test.h"
#include "GrContext.h"
-#include "GrGpuGLShaders.h"
+#include "gl/GrGpuGLShaders.h"
static void GLProgramsTest(skiatest::Reporter* reporter, GrContext* context) {
GrGpuGLShaders* shadersGpu = (GrGpuGLShaders*) context->getGpu();
diff --git a/tests/GeometryTest.cpp b/tests/GeometryTest.cpp
index 6158a20..9a0f78f 100644
--- a/tests/GeometryTest.cpp
+++ b/tests/GeometryTest.cpp
@@ -12,6 +12,25 @@ static bool nearly_equal(const SkPoint& a, const SkPoint& b) {
return SkScalarNearlyEqual(a.fX, b.fX) && SkScalarNearlyEqual(a.fY, b.fY);
}
+static void testChopCubic(skiatest::Reporter* reporter) {
+ /*
+ Inspired by this test, which used to assert that the tValues had dups
+
+ <path stroke="#202020" d="M0,0 C0,0 1,1 2190,5130 C2190,5070 2220,5010 2205,4980" />
+ */
+ const SkPoint src[] = {
+ { SkIntToScalar(2190), SkIntToScalar(5130) },
+ { SkIntToScalar(2190), SkIntToScalar(5070) },
+ { SkIntToScalar(2220), SkIntToScalar(5010) },
+ { SkIntToScalar(2205), SkIntToScalar(4980) },
+ };
+ SkPoint dst[13];
+ SkScalar tValues[3];
+ // make sure we don't assert internally
+ int count = SkChopCubicAtMaxCurvature(src, dst, tValues);
+}
+
+
static void TestGeometry(skiatest::Reporter* reporter) {
SkPoint pts[3], dst[5];
@@ -35,6 +54,8 @@ static void TestGeometry(skiatest::Reporter* reporter) {
for (int i = 0; i < 4; ++i) {
REPORTER_ASSERT(reporter, nearly_equal(cubic[i], dst[i]));
}
+
+ testChopCubic(reporter);
}
#include "TestClassDef.h"
diff --git a/tests/PathMeasureTest.cpp b/tests/PathMeasureTest.cpp
index d454e37..2ff9f3a 100644
--- a/tests/PathMeasureTest.cpp
+++ b/tests/PathMeasureTest.cpp
@@ -43,6 +43,91 @@ static void TestPathMeasure(skiatest::Reporter* reporter) {
d, p.fX, p.fY, v.fX, v.fY);
#endif
}
+
+ // Test the behavior following a close not followed by a move.
+ path.reset();
+ path.lineTo(SK_Scalar1, 0);
+ path.lineTo(SK_Scalar1, SK_Scalar1);
+ path.lineTo(0, SK_Scalar1);
+ path.close();
+ path.lineTo(-SK_Scalar1, 0);
+ meas.setPath(&path, false);
+ length = meas.getLength();
+ REPORTER_ASSERT(reporter, length == SK_Scalar1 * 4);
+ meas.nextContour();
+ length = meas.getLength();
+ REPORTER_ASSERT(reporter, length == SK_Scalar1);
+ SkPoint position;
+ SkVector tangent;
+ REPORTER_ASSERT(reporter, meas.getPosTan(SK_ScalarHalf, &position, &tangent));
+ REPORTER_ASSERT(reporter,
+ SkScalarNearlyEqual(position.fX, -SK_ScalarHalf, SK_Scalar1 * 0.0001));
+ REPORTER_ASSERT(reporter, position.fY == 0);
+ REPORTER_ASSERT(reporter, tangent.fX == -SK_Scalar1);
+ REPORTER_ASSERT(reporter, tangent.fY == 0);
+
+ // Test degenerate paths
+ path.reset();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(SK_Scalar1, 0);
+ path.quadTo(SK_Scalar1, 0, SK_Scalar1, 0);
+ path.quadTo(SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1 * 2);
+ path.cubicTo(SK_Scalar1, SK_Scalar1 * 2,
+ SK_Scalar1, SK_Scalar1 * 2,
+ SK_Scalar1, SK_Scalar1 * 2);
+ path.cubicTo(SK_Scalar1*2, SK_Scalar1 * 2,
+ SK_Scalar1*3, SK_Scalar1 * 2,
+ SK_Scalar1*4, SK_Scalar1 * 2);
+ meas.setPath(&path, false);
+ length = meas.getLength();
+ REPORTER_ASSERT(reporter, length == SK_Scalar1 * 6);
+ REPORTER_ASSERT(reporter, meas.getPosTan(SK_ScalarHalf, &position, &tangent));
+ REPORTER_ASSERT(reporter,
+ SkScalarNearlyEqual(position.fX, SK_ScalarHalf, SK_Scalar1 * 0.0001));
+ REPORTER_ASSERT(reporter, position.fY == 0);
+ REPORTER_ASSERT(reporter, tangent.fX == SK_Scalar1);
+ REPORTER_ASSERT(reporter, tangent.fY == 0);
+ REPORTER_ASSERT(reporter, meas.getPosTan(SK_Scalar1 * 2.5f, &position, &tangent));
+ REPORTER_ASSERT(reporter,
+ SkScalarNearlyEqual(position.fX, SK_Scalar1, SK_Scalar1 * 0.0001));
+ REPORTER_ASSERT(reporter,
+ SkScalarNearlyEqual(position.fY, SK_Scalar1 * 1.5f));
+ REPORTER_ASSERT(reporter, tangent.fX == 0);
+ REPORTER_ASSERT(reporter, tangent.fY == SK_Scalar1);
+ REPORTER_ASSERT(reporter, meas.getPosTan(SK_Scalar1 * 4.5f, &position, &tangent));
+ REPORTER_ASSERT(reporter,
+ SkScalarNearlyEqual(position.fX, SK_Scalar1 * 2.5f, SK_Scalar1 * 0.0001));
+ REPORTER_ASSERT(reporter,
+ SkScalarNearlyEqual(position.fY, SK_Scalar1 * 2.0f, SK_Scalar1 * 0.0001));
+ REPORTER_ASSERT(reporter, tangent.fX == SK_Scalar1);
+ REPORTER_ASSERT(reporter, tangent.fY == 0);
+
+ path.reset();
+ path.moveTo(0, 0);
+ path.lineTo(SK_Scalar1, 0);
+ path.moveTo(SK_Scalar1, SK_Scalar1);
+ path.moveTo(SK_Scalar1 * 2, SK_Scalar1 * 2);
+ path.lineTo(SK_Scalar1, SK_Scalar1 * 2);
+ meas.setPath(&path, false);
+ length = meas.getLength();
+ REPORTER_ASSERT(reporter, length == SK_Scalar1);
+ REPORTER_ASSERT(reporter, meas.getPosTan(SK_ScalarHalf, &position, &tangent));
+ REPORTER_ASSERT(reporter,
+ SkScalarNearlyEqual(position.fX, SK_ScalarHalf, SK_Scalar1 * 0.0001));
+ REPORTER_ASSERT(reporter, position.fY == 0);
+ REPORTER_ASSERT(reporter, tangent.fX == SK_Scalar1);
+ REPORTER_ASSERT(reporter, tangent.fY == 0);
+ meas.nextContour();
+ length = meas.getLength();
+ REPORTER_ASSERT(reporter, length == SK_Scalar1);
+ REPORTER_ASSERT(reporter, meas.getPosTan(SK_ScalarHalf, &position, &tangent));
+ REPORTER_ASSERT(reporter,
+ SkScalarNearlyEqual(position.fX, SK_Scalar1 * 1.5f, SK_Scalar1 * 0.0001));
+ REPORTER_ASSERT(reporter,
+ SkScalarNearlyEqual(position.fY, SK_Scalar1 * 2.0f, SK_Scalar1 * 0.0001));
+ REPORTER_ASSERT(reporter, tangent.fX == -SK_Scalar1);
+ REPORTER_ASSERT(reporter, tangent.fY == 0);
}
#include "TestClassDef.h"
diff --git a/tests/PathTest.cpp b/tests/PathTest.cpp
index fadb0d9..868ce31 100644
--- a/tests/PathTest.cpp
+++ b/tests/PathTest.cpp
@@ -15,6 +15,21 @@
#include "SkSize.h"
#include "SkWriter32.h"
+/**
+ * cheapIsDirection can take a shortcut when a path is marked convex.
+ * This function ensures that we always test cheapIsDirection when the path
+ * is flagged with unknown convexity status.
+ */
+static void check_direction(SkPath* path,
+ SkPath::Direction expectedDir,
+ skiatest::Reporter* reporter) {
+ if (SkPath::kConvex_Convexity == path->getConvexity()) {
+ REPORTER_ASSERT(reporter, path->cheapIsDirection(expectedDir));
+ path->setConvexity(SkPath::kUnknown_Convexity);
+ }
+ REPORTER_ASSERT(reporter, path->cheapIsDirection(expectedDir));
+}
+
static void test_direction(skiatest::Reporter* reporter) {
size_t i;
SkPath path;
@@ -40,24 +55,48 @@ static void test_direction(skiatest::Reporter* reporter) {
static const char* gCW[] = {
"M 10 10 L 10 10 Q 20 10 20 20",
"M 10 10 C 20 10 20 20 20 20",
+ "M 20 10 Q 20 20 30 20 L 10 20", // test double-back at y-max
};
for (i = 0; i < SK_ARRAY_COUNT(gCW); ++i) {
path.reset();
bool valid = SkParsePath::FromSVGString(gCW[i], &path);
REPORTER_ASSERT(reporter, valid);
- REPORTER_ASSERT(reporter, path.cheapIsDirection(SkPath::kCW_Direction));
+ check_direction(&path, SkPath::kCW_Direction, reporter);
}
static const char* gCCW[] = {
"M 10 10 L 10 10 Q 20 10 20 -20",
"M 10 10 C 20 10 20 -20 20 -20",
+ "M 20 10 Q 20 20 10 20 L 30 20", // test double-back at y-max
};
for (i = 0; i < SK_ARRAY_COUNT(gCCW); ++i) {
path.reset();
bool valid = SkParsePath::FromSVGString(gCCW[i], &path);
REPORTER_ASSERT(reporter, valid);
- REPORTER_ASSERT(reporter, path.cheapIsDirection(SkPath::kCCW_Direction));
+ check_direction(&path, SkPath::kCCW_Direction, reporter);
}
+
+ // Test two donuts, each wound a different direction. Only the outer contour
+ // determines the cheap direction
+ path.reset();
+ path.addCircle(0, 0, SkIntToScalar(2), SkPath::kCW_Direction);
+ path.addCircle(0, 0, SkIntToScalar(1), SkPath::kCCW_Direction);
+ check_direction(&path, SkPath::kCW_Direction, reporter);
+
+ path.reset();
+ path.addCircle(0, 0, SkIntToScalar(1), SkPath::kCW_Direction);
+ path.addCircle(0, 0, SkIntToScalar(2), SkPath::kCCW_Direction);
+ check_direction(&path, SkPath::kCCW_Direction, reporter);
+
+#ifdef SK_SCALAR_IS_FLOAT
+ // triangle with one point really far from the origin.
+ path.reset();
+ // the first point is roughly 1.05e10, 1.05e10
+ path.moveTo(SkFloatToScalar(SkBits2Float(0x501c7652)), SkFloatToScalar(SkBits2Float(0x501c7652)));
+ path.lineTo(110 * SK_Scalar1, -10 * SK_Scalar1);
+ path.lineTo(-10 * SK_Scalar1, 60 * SK_Scalar1);
+ check_direction(&path, SkPath::kCCW_Direction, reporter);
+#endif
}
static void add_rect(SkPath* path, const SkRect& r) {
@@ -889,12 +928,14 @@ static void test_raw_iter(skiatest::Reporter* reporter) {
// Max of 10 segments, max 3 points per segment
SkRandom rand(9876543);
SkPoint expectedPts[31]; // May have leading moveTo
- SkPath::Verb expectedVerbs[11]; // May have leading moveTo
+ SkPath::Verb expectedVerbs[22]; // May have leading moveTo
SkPath::Verb nextVerb;
+
for (int i = 0; i < 500; ++i) {
p.reset();
bool lastWasClose = true;
bool haveMoveTo = false;
+ SkPoint lastMoveToPt = { 0, 0 };
int numPoints = 0;
int numVerbs = (rand.nextU() >> 16) % 10;
int numIterVerbs = 0;
@@ -907,13 +948,14 @@ static void test_raw_iter(skiatest::Reporter* reporter) {
case SkPath::kMove_Verb:
expectedPts[numPoints] = randomPts[(rand.nextU() >> 16) % 25];
p.moveTo(expectedPts[numPoints]);
+ lastMoveToPt = expectedPts[numPoints];
numPoints += 1;
lastWasClose = false;
haveMoveTo = true;
break;
case SkPath::kLine_Verb:
if (!haveMoveTo) {
- expectedPts[numPoints++].set(0, 0);
+ expectedPts[numPoints++] = lastMoveToPt;
expectedVerbs[numIterVerbs++] = SkPath::kMove_Verb;
haveMoveTo = true;
}
@@ -924,7 +966,7 @@ static void test_raw_iter(skiatest::Reporter* reporter) {
break;
case SkPath::kQuad_Verb:
if (!haveMoveTo) {
- expectedPts[numPoints++].set(0, 0);
+ expectedPts[numPoints++] = lastMoveToPt;
expectedVerbs[numIterVerbs++] = SkPath::kMove_Verb;
haveMoveTo = true;
}
@@ -936,7 +978,7 @@ static void test_raw_iter(skiatest::Reporter* reporter) {
break;
case SkPath::kCubic_Verb:
if (!haveMoveTo) {
- expectedPts[numPoints++].set(0, 0);
+ expectedPts[numPoints++] = lastMoveToPt;
expectedVerbs[numIterVerbs++] = SkPath::kMove_Verb;
haveMoveTo = true;
}
@@ -950,6 +992,7 @@ static void test_raw_iter(skiatest::Reporter* reporter) {
break;
case SkPath::kClose_Verb:
p.close();
+ haveMoveTo = false;
lastWasClose = true;
break;
default:;
diff --git a/tests/PremulAlphaRoundTripTest.cpp b/tests/PremulAlphaRoundTripTest.cpp
new file mode 100644
index 0000000..c4ec6ab
--- /dev/null
+++ b/tests/PremulAlphaRoundTripTest.cpp
@@ -0,0 +1,106 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "Test.h"
+#include "SkCanvas.h"
+#include "SkConfig8888.h"
+#include "SkGpuDevice.h"
+
+
+namespace {
+
+void fillCanvas(SkCanvas* canvas, SkCanvas::Config8888 unpremulConfig) {
+ SkBitmap bmp;
+ bmp.setConfig(SkBitmap::kARGB_8888_Config, 256, 256);
+ bmp.allocPixels();
+ SkAutoLockPixels alp(bmp);
+ uint32_t* pixels = reinterpret_cast<uint32_t*>(bmp.getPixels());
+
+ for (int a = 0; a < 256; ++a) {
+ for (int r = 0; r < 256; ++r) {
+ pixels[a * 256 + r] = SkPackConfig8888(unpremulConfig, a, r, 0, 0);
+ }
+ }
+ canvas->writePixels(bmp, 0, 0, unpremulConfig);
+}
+
+static const SkCanvas::Config8888 gUnpremulConfigs[] = {
+ SkCanvas::kNative_Unpremul_Config8888,
+/**
+ * There is a bug in Ganesh (http://code.google.com/p/skia/issues/detail?id=438)
+ * that causes the readback of pixels from BGRA canvas to an RGBA bitmap to
+ * fail. This should be removed as soon as the issue above is resolved.
+ */
+#if !defined(SK_BUILD_FOR_ANDROID)
+ SkCanvas::kBGRA_Unpremul_Config8888,
+#endif
+ SkCanvas::kRGBA_Unpremul_Config8888,
+};
+
+void PremulAlphaRoundTripTest(skiatest::Reporter* reporter,
+ GrContext* context) {
+ SkCanvas canvas;
+ for (int dtype = 0; dtype < 2; ++dtype) {
+ if (0 == dtype) {
+ canvas.setDevice(new SkDevice(SkBitmap::kARGB_8888_Config,
+ 256,
+ 256,
+ false))->unref();
+ } else {
+#if SK_SCALAR_IS_FIXED
+ // GPU device known not to work in the fixed pt build.
+ continue;
+#endif
+ canvas.setDevice(new SkGpuDevice(context,
+ SkBitmap::kARGB_8888_Config,
+ 256,
+ 256))->unref();
+ }
+
+ SkBitmap readBmp1;
+ readBmp1.setConfig(SkBitmap::kARGB_8888_Config, 256, 256);
+ readBmp1.allocPixels();
+ SkBitmap readBmp2;
+ readBmp2.setConfig(SkBitmap::kARGB_8888_Config, 256, 256);
+ readBmp2.allocPixels();
+
+ for (size_t upmaIdx = 0;
+ upmaIdx < SK_ARRAY_COUNT(gUnpremulConfigs);
+ ++upmaIdx) {
+ fillCanvas(&canvas, gUnpremulConfigs[upmaIdx]);
+ {
+ SkAutoLockPixels alp1(readBmp1);
+ SkAutoLockPixels alp2(readBmp2);
+ sk_bzero(readBmp1.getPixels(), readBmp1.getSafeSize());
+ sk_bzero(readBmp2.getPixels(), readBmp2.getSafeSize());
+ }
+
+ canvas.readPixels(&readBmp1, 0, 0, gUnpremulConfigs[upmaIdx]);
+ canvas.writePixels(readBmp1, 0, 0, gUnpremulConfigs[upmaIdx]);
+ canvas.readPixels(&readBmp2, 0, 0, gUnpremulConfigs[upmaIdx]);
+
+ SkAutoLockPixels alp1(readBmp1);
+ SkAutoLockPixels alp2(readBmp2);
+ uint32_t* pixels1 =
+ reinterpret_cast<uint32_t*>(readBmp1.getPixels());
+ uint32_t* pixels2 =
+ reinterpret_cast<uint32_t*>(readBmp2.getPixels());
+ for (int y = 0; y < 256; ++y) {
+ for (int x = 0; x < 256; ++x) {
+ int i = y * 256 + x;
+ REPORTER_ASSERT(reporter, pixels1[i] == pixels2[i]);
+ }
+ }
+ }
+ }
+}
+}
+
+#include "TestClassDef.h"
+DEFINE_GPUTESTCLASS("PremulAlphaRoundTripTest", PremulAlphaRoundTripTestClass, PremulAlphaRoundTripTest)
+
diff --git a/tests/ReadPixelsTest.cpp b/tests/ReadPixelsTest.cpp
index b531e92..4e0fcc6 100644
--- a/tests/ReadPixelsTest.cpp
+++ b/tests/ReadPixelsTest.cpp
@@ -297,7 +297,7 @@ void ReadPixelsTest(skiatest::Reporter* reporter, GrContext* context) {
SkIRect::MakeLTRB(3 * DEV_W / 4, -10, DEV_W + 10, DEV_H + 10),
};
- for (int dtype = 1; dtype < 2; ++dtype) {
+ for (int dtype = 0; dtype < 2; ++dtype) {
if (0 == dtype) {
canvas.setDevice(new SkDevice(SkBitmap::kARGB_8888_Config,
diff --git a/tests/Test.cpp b/tests/Test.cpp
index 1c3b691..62df731 100644
--- a/tests/Test.cpp
+++ b/tests/Test.cpp
@@ -8,7 +8,7 @@
#include "Test.h"
#include "GrContext.h"
-#include "SkNativeGLContext.h"
+#include "gl/SkNativeGLContext.h"
#include "SkTLazy.h"
using namespace skiatest;
diff --git a/tests/Test.h b/tests/Test.h
index 8728040..4ca1971 100644
--- a/tests/Test.h
+++ b/tests/Test.h
@@ -115,10 +115,19 @@ namespace skiatest {
do { \
if (!(cond)) { \
SkString desc; \
- desc.printf("%s:%d: %s", __FILE__, __LINE__, #cond); \
+ desc.printf("%s:%d: %s", __FILE__, __LINE__, #cond); \
r->reportFailed(desc); \
} \
} while(0)
+#define REPORTER_ASSERT_MESSAGE(r, cond, message) \
+ do { \
+ if (!(cond)) { \
+ SkString desc; \
+ desc.printf("%s %s:%d: %s", message, __FILE__, __LINE__, #cond); \
+ r->reportFailed(desc); \
+ } \
+ } while(0)
+
#endif
diff --git a/tests/WArrayTest.cpp b/tests/WArrayTest.cpp
index 428ca5f..daab543 100644
--- a/tests/WArrayTest.cpp
+++ b/tests/WArrayTest.cpp
@@ -108,7 +108,7 @@ static SkString stringify_advance_data(
bool leadingSpace = false;
while (data != NULL) {
if (leadingSpace) {
- result.appendf(" ");
+ result.append(" ");
} else {
leadingSpace = true;
}
@@ -121,11 +121,11 @@ static SkString stringify_advance_data(
result.appendf("%d[", data->fStartId);
for (int i = 0; i < data->fAdvance.count(); ++i) {
if (i > 0) {
- result.appendf(" ");
+ result.append(" ");
}
result.appendf("%d", data->fAdvance[i]);
}
- result.appendf("]");
+ result.append("]");
break;
case SkAdvancedTypefaceMetrics::AdvanceMetric<int16_t>::kDefault:
result.appendf("<Default=%d>", data->fAdvance[0]);
diff --git a/tests/WritePixelsTest.cpp b/tests/WritePixelsTest.cpp
index 0c5b7b9..403ab84 100644
--- a/tests/WritePixelsTest.cpp
+++ b/tests/WritePixelsTest.cpp
@@ -233,6 +233,7 @@ bool checkWrite(skiatest::Reporter* reporter,
intptr_t canvasPixels = reinterpret_cast<intptr_t>(devBmp.getPixels());
size_t canvasRowBytes = devBmp.rowBytes();
SkIRect writeRect = SkIRect::MakeXYWH(writeX, writeY, bitmap.width(), bitmap.height());
+ bool success = true;
for (int cy = 0; cy < DEV_H; ++cy) {
const SkPMColor* canvasRow = reinterpret_cast<const SkPMColor*>(canvasPixels);
for (int cx = 0; cx < DEV_W; ++cx) {
@@ -246,14 +247,14 @@ bool checkWrite(skiatest::Reporter* reporter,
bool check;
REPORTER_ASSERT(reporter, check = checkPixel(bmpPMColor, canvasPixel, mul));
if (!check) {
- return false;
+ success = false;
}
} else {
bool check;
SkPMColor testColor = getCanvasColor(cx, cy);
REPORTER_ASSERT(reporter, check = (canvasPixel == testColor));
if (!check) {
- return false;
+ success = false;
}
}
}
@@ -263,14 +264,14 @@ bool checkWrite(skiatest::Reporter* reporter,
bool check;
REPORTER_ASSERT(reporter, check = (pad[px] == static_cast<char>(DEV_PAD)));
if (!check) {
- return false;
+ success = false;
}
}
}
canvasPixels += canvasRowBytes;
}
- return true;
+ return success;
}
enum DevType {