ReadPixelsTest.cpp revision 6850eab42ba4c2a7033a99824b02a2846ce0ef2a
1c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 2c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com/* 3c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com * Copyright 2011 Google Inc. 4c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com * 5c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com * Use of this source code is governed by a BSD-style license that can be 6c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com * found in the LICENSE file. 7c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com */ 8c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 9c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com#include "Test.h" 10c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com#include "SkCanvas.h" 11c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com#include "SkRegion.h" 12c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com#include "SkGpuDevice.h" 13c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 14c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 15c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.comstatic const int DEV_W = 100, DEV_H = 100; 16c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.comstatic const SkIRect DEV_RECT = SkIRect::MakeWH(DEV_W, DEV_H); 17c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.comstatic const SkRect DEV_RECT_S = SkRect::MakeWH(DEV_W * SK_Scalar1, 18c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com DEV_H * SK_Scalar1); 19c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 20c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.comnamespace { 21c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.comSkPMColor getCanvasColor(int x, int y) { 22c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkASSERT(x >= 0 && x < DEV_W); 23c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkASSERT(y >= 0 && y < DEV_H); 246850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com 256850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com U8CPU r = x; 266850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com U8CPU g = y; 276850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com U8CPU b = 0xc; 286850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com 296850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com U8CPU a = 0xff; 306850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com switch (x % 5) { 316850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com case 0: 326850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com a = 0xff; 336850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com break; 346850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com case 1: 356850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com a = 0x80; 366850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com break; 376850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com case 2: 386850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com a = 0xCC; 396850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com break; 406850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com case 4: 416850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com a = 0x01; 426850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com break; 436850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com case 3: 446850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com a = 0x00; 456850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com break; 466850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com } 476850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com return SkPremultiplyARGBInline(a, r, g, b); 48c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com} 49c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 50c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.comSkPMColor getBitmapColor(int x, int y, int w, int h) { 51c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com int n = y * w + x; 526850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com 53c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com U8CPU b = n & 0xff; 54c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com U8CPU g = (n >> 8) & 0xff; 55c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com U8CPU r = (n >> 16) & 0xff; 56c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com return SkPackARGB32(0xff, r, g , b); 57c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com} 58c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 596850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.comSkPMColor convertConfig8888ToPMColor(SkCanvas::Config8888 config8888, 606850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com uint32_t color) { 616850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com const uint8_t* c = reinterpret_cast<uint8_t*>(&color); 626850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com U8CPU a,r,g,b; 636850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com bool mul = false; 646850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com switch (config8888) { 656850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com case SkCanvas::kNative_Premul_Config8888: 666850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com return color; 676850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com case SkCanvas::kNative_Unpremul_Config8888: 686850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com mul = true; 696850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com a = SkGetPackedA32(color); 706850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com r = SkGetPackedR32(color); 716850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com g = SkGetPackedG32(color); 726850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com b = SkGetPackedB32(color); 736850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com break; 746850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com case SkCanvas::kBGRA_Unpremul_Config8888: 756850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com mul = true; // fallthru 766850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com case SkCanvas::kBGRA_Premul_Config8888: 776850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com a = static_cast<U8CPU>(c[3]); 786850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com r = static_cast<U8CPU>(c[2]); 796850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com g = static_cast<U8CPU>(c[1]); 806850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com b = static_cast<U8CPU>(c[0]); 816850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com break; 826850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com case SkCanvas::kRGBA_Unpremul_Config8888: 836850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com mul = true; // fallthru 846850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com case SkCanvas::kRGBA_Premul_Config8888: 856850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com a = static_cast<U8CPU>(c[3]); 866850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com r = static_cast<U8CPU>(c[0]); 876850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com g = static_cast<U8CPU>(c[1]); 886850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com b = static_cast<U8CPU>(c[2]); 896850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com break; 906850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com } 916850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com if (mul) { 926850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com r = SkMulDiv255Ceiling(r, a); 936850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com g = SkMulDiv255Ceiling(g, a); 946850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com b = SkMulDiv255Ceiling(b, a); 956850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com } 966850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com return SkPackARGB32(a, r, g, b); 976850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com} 986850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com 99c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.comvoid fillCanvas(SkCanvas* canvas) { 100c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com static SkBitmap bmp; 101c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com if (bmp.isNull()) { 102c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com bmp.setConfig(SkBitmap::kARGB_8888_Config, DEV_W, DEV_H); 103c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com bool alloc = bmp.allocPixels(); 104c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkASSERT(alloc); 105c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkAutoLockPixels alp(bmp); 106c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com intptr_t pixels = reinterpret_cast<intptr_t>(bmp.getPixels()); 107c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com for (int y = 0; y < DEV_H; ++y) { 108c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com for (int x = 0; x < DEV_W; ++x) { 109c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkPMColor* pixel = reinterpret_cast<SkPMColor*>(pixels + y * bmp.rowBytes() + x * bmp.bytesPerPixel()); 110c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com *pixel = getCanvasColor(x, y); 111c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 112c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 113c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 114c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com canvas->save(); 115c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com canvas->setMatrix(SkMatrix::I()); 116c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com canvas->clipRect(DEV_RECT_S, SkRegion::kReplace_Op); 117c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkPaint paint; 118c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com paint.setXfermodeMode(SkXfermode::kSrc_Mode); 119c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com canvas->drawBitmap(bmp, 0, 0, &paint); 120c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com canvas->restore(); 121c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com} 122c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 123c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.comvoid fillBitmap(SkBitmap* bitmap) { 124c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkASSERT(bitmap->lockPixelsAreWritable()); 125c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkAutoLockPixels alp(*bitmap); 126c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com int w = bitmap->width(); 127c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com int h = bitmap->height(); 128c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com intptr_t pixels = reinterpret_cast<intptr_t>(bitmap->getPixels()); 129c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com for (int y = 0; y < h; ++y) { 130c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com for (int x = 0; x < w; ++x) { 131c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkPMColor* pixel = reinterpret_cast<SkPMColor*>(pixels + y * bitmap->rowBytes() + x * bitmap->bytesPerPixel()); 132c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com *pixel = getBitmapColor(x, y, w, h); 133c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 134c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 135c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com} 136c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 137c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com// checks the bitmap contains correct pixels after the readPixels 138c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com// if the bitmap was prefilled with pixels it checks that these weren't 139c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com// overwritten in the area outside the readPixels. 140c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.combool checkRead(skiatest::Reporter* reporter, 141c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com const SkBitmap& bitmap, 142c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com int x, int y, 1436850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com bool checkCanvasPixels, 1446850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com bool checkBitmapPixels, 1456850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com SkCanvas::Config8888 config8888) { 146c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkASSERT(SkBitmap::kARGB_8888_Config == bitmap.config()); 147c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkASSERT(!bitmap.isNull()); 1486850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com SkASSERT(checkCanvasPixels || checkBitmapPixels); 149c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 150c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com int bw = bitmap.width(); 151c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com int bh = bitmap.height(); 152c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 153c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkIRect srcRect = SkIRect::MakeXYWH(x, y, bw, bh); 154c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkIRect clippedSrcRect = DEV_RECT; 155c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com if (!clippedSrcRect.intersect(srcRect)) { 156c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com clippedSrcRect.setEmpty(); 157c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 158c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 159c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkAutoLockPixels alp(bitmap); 160c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com intptr_t pixels = reinterpret_cast<intptr_t>(bitmap.getPixels()); 161c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com for (int by = 0; by < bh; ++by) { 162c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com for (int bx = 0; bx < bw; ++bx) { 163c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com int devx = bx + srcRect.fLeft; 164c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com int devy = by + srcRect.fTop; 165c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 166c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkPMColor pixel = *reinterpret_cast<SkPMColor*>(pixels + by * bitmap.rowBytes() + bx * bitmap.bytesPerPixel()); 167c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 168c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com if (clippedSrcRect.contains(devx, devy)) { 1696850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com if (checkCanvasPixels) { 1706850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com SkPMColor canvasPixel = getCanvasColor(devx, devy); 1716850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com pixel = convertConfig8888ToPMColor(config8888, pixel); 1726850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com REPORTER_ASSERT(reporter, canvasPixel == pixel); 1736850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com if (getCanvasColor(devx, devy) != pixel) { 1746850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com return false; 1756850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com } 176c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 1776850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com } else if (checkBitmapPixels) { 178c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com REPORTER_ASSERT(reporter, getBitmapColor(bx, by, bw, bh) == pixel); 179c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com if (getBitmapColor(bx, by, bw, bh) != pixel) { 180c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com return false; 181c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 182c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 183c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 184c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 185c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com return true; 186c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com} 187c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 188c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.comenum BitmapInit { 189c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com kFirstBitmapInit = 0, 190c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 191c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com kNoPixels_BitmapInit = kFirstBitmapInit, 192c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com kTight_BitmapInit, 193c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com kRowBytes_BitmapInit, 194c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 195c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com kBitmapInitCnt 196c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com}; 197c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 198c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.comBitmapInit nextBMI(BitmapInit bmi) { 199c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com int x = bmi; 200c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com return static_cast<BitmapInit>(++x); 201c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com} 202c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 203c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 204c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.comvoid init_bitmap(SkBitmap* bitmap, const SkIRect& rect, BitmapInit init) { 205c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com int w = rect.width(); 206c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com int h = rect.height(); 207c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com int rowBytes = 0; 208c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com bool alloc = true; 209c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com switch (init) { 210c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com case kNoPixels_BitmapInit: 211c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com alloc = false; 212c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com case kTight_BitmapInit: 213c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com break; 214c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com case kRowBytes_BitmapInit: 215c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com rowBytes = w * sizeof(SkPMColor) + 16 * sizeof(SkPMColor); 216c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com break; 217c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com default: 218c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkASSERT(0); 219c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com break; 220c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 221c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com bitmap->setConfig(SkBitmap::kARGB_8888_Config, w, h, rowBytes); 222c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com if (alloc) { 223c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com bitmap->allocPixels(); 224c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 225c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com} 226c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 227c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.comvoid ReadPixelsTest(skiatest::Reporter* reporter, GrContext* context) { 228c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkCanvas canvas; 229c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 230c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com const SkIRect testRects[] = { 231c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // entire thing 232c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com DEV_RECT, 233c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // larger on all sides 234c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkIRect::MakeLTRB(-10, -10, DEV_W + 10, DEV_H + 10), 235c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // fully contained 236c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkIRect::MakeLTRB(DEV_W / 4, DEV_H / 4, 3 * DEV_W / 4, 3 * DEV_H / 4), 237c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // outside top left 238c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkIRect::MakeLTRB(-10, -10, -1, -1), 239c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // touching top left corner 240c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkIRect::MakeLTRB(-10, -10, 0, 0), 241c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // overlapping top left corner 242c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkIRect::MakeLTRB(-10, -10, DEV_W / 4, DEV_H / 4), 243c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // overlapping top left and top right corners 244c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkIRect::MakeLTRB(-10, -10, DEV_W + 10, DEV_H / 4), 245c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // touching entire top edge 246c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkIRect::MakeLTRB(-10, -10, DEV_W + 10, 0), 247c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // overlapping top right corner 248c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkIRect::MakeLTRB(3 * DEV_W / 4, -10, DEV_W + 10, DEV_H / 4), 249c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // contained in x, overlapping top edge 250c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkIRect::MakeLTRB(DEV_W / 4, -10, 3 * DEV_W / 4, DEV_H / 4), 251c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // outside top right corner 252c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkIRect::MakeLTRB(DEV_W + 1, -10, DEV_W + 10, -1), 253c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // touching top right corner 254c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkIRect::MakeLTRB(DEV_W, -10, DEV_W + 10, 0), 255c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // overlapping top left and bottom left corners 256c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkIRect::MakeLTRB(-10, -10, DEV_W / 4, DEV_H + 10), 257c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // touching entire left edge 258c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkIRect::MakeLTRB(-10, -10, 0, DEV_H + 10), 259c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // overlapping bottom left corner 260c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkIRect::MakeLTRB(-10, 3 * DEV_H / 4, DEV_W / 4, DEV_H + 10), 261c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // contained in y, overlapping left edge 262c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkIRect::MakeLTRB(-10, DEV_H / 4, DEV_W / 4, 3 * DEV_H / 4), 263c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // outside bottom left corner 264c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkIRect::MakeLTRB(-10, DEV_H + 1, -1, DEV_H + 10), 265c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // touching bottom left corner 266c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkIRect::MakeLTRB(-10, DEV_H, 0, DEV_H + 10), 267c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // overlapping bottom left and bottom right corners 268c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkIRect::MakeLTRB(-10, 3 * DEV_H / 4, DEV_W + 10, DEV_H + 10), 269c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // touching entire left edge 270c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkIRect::MakeLTRB(0, DEV_H, DEV_W, DEV_H + 10), 271c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // overlapping bottom right corner 272c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkIRect::MakeLTRB(3 * DEV_W / 4, 3 * DEV_H / 4, DEV_W + 10, DEV_H + 10), 273c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // overlapping top right and bottom right corners 274c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkIRect::MakeLTRB(3 * DEV_W / 4, -10, DEV_W + 10, DEV_H + 10), 275c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com }; 276c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 277c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com for (int dtype = 0; dtype < 2; ++dtype) { 278c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 279c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com if (0 == dtype) { 2806850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com canvas.setDevice(new SkDevice(SkBitmap::kARGB_8888_Config, 2816850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com DEV_W, 2826850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com DEV_H, 2836850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com false))->unref(); 284c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } else { 285c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com#if SK_SCALAR_IS_FIXED 286c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com // GPU device known not to work in the fixed pt build. 287c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com continue; 288c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com#endif 2896850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com canvas.setDevice(new SkGpuDevice(context, 2906850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com SkBitmap::kARGB_8888_Config, 2916850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com DEV_W, 2926850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com DEV_H))->unref(); 293c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 294c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com fillCanvas(&canvas); 295c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 2966850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com static const SkCanvas::Config8888 gReadConfigs[] = { 2976850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com SkCanvas::kNative_Premul_Config8888, 2986850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com SkCanvas::kNative_Unpremul_Config8888, 2996850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com SkCanvas::kBGRA_Premul_Config8888, 3006850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com SkCanvas::kBGRA_Unpremul_Config8888, 3016850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com SkCanvas::kRGBA_Premul_Config8888, 3026850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com SkCanvas::kRGBA_Unpremul_Config8888, 3036850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com }; 304c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com for (int rect = 0; rect < SK_ARRAY_COUNT(testRects); ++rect) { 3056850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com const SkIRect& srcRect = testRects[rect]; 3066850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com for (BitmapInit bmi = kFirstBitmapInit; 3076850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com bmi < kBitmapInitCnt; 3086850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com bmi = nextBMI(bmi)) { 3096850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com for (int c = 0; c < SK_ARRAY_COUNT(gReadConfigs); ++c) { 3106850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com SkCanvas::Config8888 config8888 = gReadConfigs[c]; 3116850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com SkBitmap bmp; 3126850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com init_bitmap(&bmp, srcRect, bmi); 313c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 3146850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com // if the bitmap has pixels allocated before the readPixels, 3156850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com // note that and fill them with pattern 3166850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com bool startsWithPixels = !bmp.isNull(); 3176850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com if (startsWithPixels) { 3186850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com fillBitmap(&bmp); 3196850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com } 320c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 3216850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com bool success = 3226850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com canvas.readPixels(&bmp, srcRect.fLeft, 3236850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com srcRect.fTop, config8888); 324c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 3256850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com // non-native not implemented on GPU yet 3266850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com bool expectSuccess = 3276850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com SkIRect::Intersects(srcRect, DEV_RECT) && 3286850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com !(1 == dtype && 3296850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com config8888 != SkCanvas::kNative_Premul_Config8888); 330c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 3316850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com // determine whether we expected the read to succeed. 3326850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com REPORTER_ASSERT(reporter, success == expectSuccess); 333c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 3346850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com if (success || startsWithPixels) { 3356850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com checkRead(reporter, bmp, srcRect.fLeft, srcRect.fTop, 3366850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com success, startsWithPixels, config8888); 3376850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com } else { 3386850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com // if we had no pixels beforehand and the readPixels 3396850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com // failed then our bitmap should still not have pixels 3406850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com REPORTER_ASSERT(reporter, bmp.isNull()); 3416850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com } 3426850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com } 3436850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com // check the old webkit version of readPixels that clips the 3446850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com // bitmap size 345c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkBitmap wkbmp; 3466850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com bool success = canvas.readPixels(srcRect, &wkbmp); 347c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com SkIRect clippedRect = DEV_RECT; 348c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com if (clippedRect.intersect(srcRect)) { 349c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com REPORTER_ASSERT(reporter, success); 3506850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com checkRead(reporter, wkbmp, clippedRect.fLeft, 3516850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com clippedRect.fTop, true, false, 3526850eab42ba4c2a7033a99824b02a2846ce0ef2absalomon@google.com SkCanvas::kNative_Premul_Config8888); 353c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } else { 354c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com REPORTER_ASSERT(reporter, !success); 355c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 356c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 357c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 358c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 359c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com} 360c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com} 361c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 362c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com#include "TestClassDef.h" 363c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.comDEFINE_GPUTESTCLASS("ReadPixels", ReadPixelsTestClass, ReadPixelsTest) 364c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 365