diff options
author | 2011-11-02 19:57:21 +0000 | |
---|---|---|
committer | 2011-11-02 19:57:21 +0000 | |
commit | c69809745e6496564639e42ef998ad39adf7dfb8 (patch) | |
tree | 970a42d960ca25434d580932a3926d975a76b9be /tests | |
parent | ace7bd5623354ffabbd224d5b76550bab159c296 (diff) |
Recommit r2584 with gpu pass of the new ReadPixels test disabled in fixed pt (gpu code doesn't work in general in fixed pt).
git-svn-id: http://skia.googlecode.com/svn/trunk@2586 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'tests')
-rw-r--r-- | tests/ReadPixelsTest.cpp | 266 |
1 files changed, 266 insertions, 0 deletions
diff --git a/tests/ReadPixelsTest.cpp b/tests/ReadPixelsTest.cpp new file mode 100644 index 0000000000..c39e03b85d --- /dev/null +++ b/tests/ReadPixelsTest.cpp @@ -0,0 +1,266 @@ + +/* + * 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 "SkRegion.h" +#include "SkGpuDevice.h" + + +static const int DEV_W = 100, DEV_H = 100; +static const SkIRect DEV_RECT = SkIRect::MakeWH(DEV_W, DEV_H); +static const SkRect DEV_RECT_S = SkRect::MakeWH(DEV_W * SK_Scalar1, + DEV_H * SK_Scalar1); + +namespace { +SkPMColor getCanvasColor(int x, int y) { + SkASSERT(x >= 0 && x < DEV_W); + SkASSERT(y >= 0 && y < DEV_H); + return SkPackARGB32(0xff, x, y, 0x0); +} + +SkPMColor getBitmapColor(int x, int y, int w, int h) { + int n = y * w + x; + + U8CPU b = n & 0xff; + U8CPU g = (n >> 8) & 0xff; + U8CPU r = (n >> 16) & 0xff; + return SkPackARGB32(0xff, r, g , b); +} + +void fillCanvas(SkCanvas* canvas) { + static SkBitmap bmp; + if (bmp.isNull()) { + bmp.setConfig(SkBitmap::kARGB_8888_Config, DEV_W, DEV_H); + bool alloc = bmp.allocPixels(); + SkASSERT(alloc); + SkAutoLockPixels alp(bmp); + intptr_t pixels = reinterpret_cast<intptr_t>(bmp.getPixels()); + for (int y = 0; y < DEV_H; ++y) { + for (int x = 0; x < DEV_W; ++x) { + SkPMColor* pixel = reinterpret_cast<SkPMColor*>(pixels + y * bmp.rowBytes() + x * bmp.bytesPerPixel()); + *pixel = getCanvasColor(x, y); + } + } + } + canvas->save(); + canvas->setMatrix(SkMatrix::I()); + canvas->clipRect(DEV_RECT_S, SkRegion::kReplace_Op); + SkPaint paint; + paint.setXfermodeMode(SkXfermode::kSrc_Mode); + canvas->drawBitmap(bmp, 0, 0, &paint); + canvas->restore(); +} + +void fillBitmap(SkBitmap* bitmap) { + SkASSERT(bitmap->lockPixelsAreWritable()); + SkAutoLockPixels alp(*bitmap); + int w = bitmap->width(); + int h = bitmap->height(); + intptr_t pixels = reinterpret_cast<intptr_t>(bitmap->getPixels()); + for (int y = 0; y < h; ++y) { + for (int x = 0; x < w; ++x) { + SkPMColor* pixel = reinterpret_cast<SkPMColor*>(pixels + y * bitmap->rowBytes() + x * bitmap->bytesPerPixel()); + *pixel = getBitmapColor(x, y, w, h); + } + } +} + +// checks the bitmap contains correct pixels after the readPixels +// if the bitmap was prefilled with pixels it checks that these weren't +// overwritten in the area outside the readPixels. +bool checkRead(skiatest::Reporter* reporter, + const SkBitmap& bitmap, + int x, int y, + bool preFilledBmp) { + SkASSERT(SkBitmap::kARGB_8888_Config == bitmap.config()); + SkASSERT(!bitmap.isNull()); + + int bw = bitmap.width(); + int bh = bitmap.height(); + + SkIRect srcRect = SkIRect::MakeXYWH(x, y, bw, bh); + SkIRect clippedSrcRect = DEV_RECT; + if (!clippedSrcRect.intersect(srcRect)) { + clippedSrcRect.setEmpty(); + } + + SkAutoLockPixels alp(bitmap); + intptr_t pixels = reinterpret_cast<intptr_t>(bitmap.getPixels()); + for (int by = 0; by < bh; ++by) { + for (int bx = 0; bx < bw; ++bx) { + int devx = bx + srcRect.fLeft; + int devy = by + srcRect.fTop; + + SkPMColor pixel = *reinterpret_cast<SkPMColor*>(pixels + by * bitmap.rowBytes() + bx * bitmap.bytesPerPixel()); + + if (clippedSrcRect.contains(devx, devy)) { + REPORTER_ASSERT(reporter, getCanvasColor(devx, devy) == pixel); + if (getCanvasColor(devx, devy) != pixel) { + return false; + } + } else if (preFilledBmp) { + REPORTER_ASSERT(reporter, getBitmapColor(bx, by, bw, bh) == pixel); + if (getBitmapColor(bx, by, bw, bh) != pixel) { + return false; + } + } + } + } + return true; +} + +enum BitmapInit { + kFirstBitmapInit = 0, + + kNoPixels_BitmapInit = kFirstBitmapInit, + kTight_BitmapInit, + kRowBytes_BitmapInit, + + kBitmapInitCnt +}; + +BitmapInit nextBMI(BitmapInit bmi) { + int x = bmi; + return static_cast<BitmapInit>(++x); +} + + +void init_bitmap(SkBitmap* bitmap, const SkIRect& rect, BitmapInit init) { + int w = rect.width(); + int h = rect.height(); + int rowBytes = 0; + bool alloc = true; + switch (init) { + case kNoPixels_BitmapInit: + alloc = false; + case kTight_BitmapInit: + break; + case kRowBytes_BitmapInit: + rowBytes = w * sizeof(SkPMColor) + 16 * sizeof(SkPMColor); + break; + default: + SkASSERT(0); + break; + } + bitmap->setConfig(SkBitmap::kARGB_8888_Config, w, h, rowBytes); + if (alloc) { + bitmap->allocPixels(); + } +} + +void ReadPixelsTest(skiatest::Reporter* reporter, GrContext* context) { + SkCanvas canvas; + + const SkIRect testRects[] = { + // entire thing + DEV_RECT, + // larger on all sides + SkIRect::MakeLTRB(-10, -10, DEV_W + 10, DEV_H + 10), + // fully contained + SkIRect::MakeLTRB(DEV_W / 4, DEV_H / 4, 3 * DEV_W / 4, 3 * DEV_H / 4), + // outside top left + SkIRect::MakeLTRB(-10, -10, -1, -1), + // touching top left corner + SkIRect::MakeLTRB(-10, -10, 0, 0), + // overlapping top left corner + SkIRect::MakeLTRB(-10, -10, DEV_W / 4, DEV_H / 4), + // overlapping top left and top right corners + SkIRect::MakeLTRB(-10, -10, DEV_W + 10, DEV_H / 4), + // touching entire top edge + SkIRect::MakeLTRB(-10, -10, DEV_W + 10, 0), + // overlapping top right corner + SkIRect::MakeLTRB(3 * DEV_W / 4, -10, DEV_W + 10, DEV_H / 4), + // contained in x, overlapping top edge + SkIRect::MakeLTRB(DEV_W / 4, -10, 3 * DEV_W / 4, DEV_H / 4), + // outside top right corner + SkIRect::MakeLTRB(DEV_W + 1, -10, DEV_W + 10, -1), + // touching top right corner + SkIRect::MakeLTRB(DEV_W, -10, DEV_W + 10, 0), + // overlapping top left and bottom left corners + SkIRect::MakeLTRB(-10, -10, DEV_W / 4, DEV_H + 10), + // touching entire left edge + SkIRect::MakeLTRB(-10, -10, 0, DEV_H + 10), + // overlapping bottom left corner + SkIRect::MakeLTRB(-10, 3 * DEV_H / 4, DEV_W / 4, DEV_H + 10), + // contained in y, overlapping left edge + SkIRect::MakeLTRB(-10, DEV_H / 4, DEV_W / 4, 3 * DEV_H / 4), + // outside bottom left corner + SkIRect::MakeLTRB(-10, DEV_H + 1, -1, DEV_H + 10), + // touching bottom left corner + SkIRect::MakeLTRB(-10, DEV_H, 0, DEV_H + 10), + // overlapping bottom left and bottom right corners + SkIRect::MakeLTRB(-10, 3 * DEV_H / 4, DEV_W + 10, DEV_H + 10), + // touching entire left edge + SkIRect::MakeLTRB(0, DEV_H, DEV_W, DEV_H + 10), + // overlapping bottom right corner + SkIRect::MakeLTRB(3 * DEV_W / 4, 3 * DEV_H / 4, DEV_W + 10, DEV_H + 10), + // overlapping top right and bottom right corners + SkIRect::MakeLTRB(3 * DEV_W / 4, -10, DEV_W + 10, DEV_H + 10), + }; + + for (int dtype = 0; dtype < 2; ++dtype) { + + if (0 == dtype) { + canvas.setDevice(new SkDevice(SkBitmap::kARGB_8888_Config, DEV_W, DEV_H, 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, DEV_W, DEV_H))->unref(); + } + fillCanvas(&canvas); + + for (int rect = 0; rect < SK_ARRAY_COUNT(testRects); ++rect) { + SkBitmap bmp; + for (BitmapInit bmi = kFirstBitmapInit; bmi < kBitmapInitCnt; bmi = nextBMI(bmi)) { + + const SkIRect& srcRect = testRects[rect]; + + init_bitmap(&bmp, srcRect, bmi); + + // if the bitmap has pixels allocated before the readPixels, note + // that and fill them with pattern + bool startsWithPixels = !bmp.isNull(); + if (startsWithPixels) { + fillBitmap(&bmp); + } + + bool success = canvas.readPixels(&bmp, srcRect.fLeft, srcRect.fTop); + + // determine whether we expected the read to succeed. + REPORTER_ASSERT(reporter, success == SkIRect::Intersects(srcRect, DEV_RECT)); + + if (success || startsWithPixels) { + checkRead(reporter, bmp, srcRect.fLeft, srcRect.fTop, startsWithPixels); + } else { + // if we had no pixels beforehand and the readPixels failed then + // our bitmap should still not have any pixels + REPORTER_ASSERT(reporter, bmp.isNull()); + } + + // check the old webkit version of readPixels that clips the bitmap size + SkBitmap wkbmp; + success = canvas.readPixels(srcRect, &wkbmp); + SkIRect clippedRect = DEV_RECT; + if (clippedRect.intersect(srcRect)) { + REPORTER_ASSERT(reporter, success); + checkRead(reporter, wkbmp, clippedRect.fLeft, clippedRect.fTop, false); + } else { + REPORTER_ASSERT(reporter, !success); + } + } + } + } +} +} + +#include "TestClassDef.h" +DEFINE_GPUTESTCLASS("ReadPixels", ReadPixelsTestClass, ReadPixelsTest) + |