1d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com/* 2d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com * Copyright 2011 Google Inc. 3d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com * 4d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com * Use of this source code is governed by a BSD-style license that can be 5d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com * found in the LICENSE file. 6d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com */ 7d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com 86323ca5ca5f0bc40fc6fdf421e18b55cceb45fe6robertphillips@google.com#include "SkBitmapDevice.h" 9d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com#include "SkCanvas.h" 10cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#include "SkColorPriv.h" 114b163ed2c22facbe8891616874ae07ba7827d9c9reed@google.com#include "SkMathPriv.h" 12d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com#include "SkRegion.h" 134ee16bfaedb14aff8cf102f1f0722ff2529a9699tfarina@chromium.org#include "Test.h" 144cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org#include "sk_tool_utils.h" 154ee16bfaedb14aff8cf102f1f0722ff2529a9699tfarina@chromium.org 16cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU 1767b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com#include "GrContextFactory.h" 188f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "SkGpuDevice.h" 19cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#else 20cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.comclass GrContext; 2167b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.comclass GrContextFactory; 22cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif 23d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com 24d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.comstatic const int DEV_W = 100, DEV_H = 100; 25d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.comstatic const SkIRect DEV_RECT = SkIRect::MakeWH(DEV_W, DEV_H); 26d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.comstatic const SkRect DEV_RECT_S = SkRect::MakeWH(DEV_W * SK_Scalar1, 27d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com DEV_H * SK_Scalar1); 28d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.comstatic const U8CPU DEV_PAD = 0xee; 29d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com 30ddf94cf108ae430877f009bd67b9070341426947commit-bot@chromium.orgstatic SkPMColor getCanvasColor(int x, int y) { 31d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkASSERT(x >= 0 && x < DEV_W); 32d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkASSERT(y >= 0 && y < DEV_H); 33d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com 34d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com U8CPU r = x; 35d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com U8CPU g = y; 36d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com U8CPU b = 0xc; 37d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com 3831648eb1cfe19257ec077efebb11ab251bfd25f7bsalomon@google.com U8CPU a = 0x0; 39d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com switch ((x+y) % 5) { 40d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com case 0: 41d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com a = 0xff; 42d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com break; 43d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com case 1: 44d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com a = 0x80; 45d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com break; 46d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com case 2: 47d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com a = 0xCC; 48d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com break; 49d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com case 3: 50d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com a = 0x00; 51d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com break; 5231648eb1cfe19257ec077efebb11ab251bfd25f7bsalomon@google.com case 4: 5331648eb1cfe19257ec077efebb11ab251bfd25f7bsalomon@google.com a = 0x01; 5431648eb1cfe19257ec077efebb11ab251bfd25f7bsalomon@google.com break; 55d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 56d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com return SkPremultiplyARGBInline(a, r, g, b); 57d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com} 58d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com 59d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com// assumes any premu/.unpremul has been applied 607111d463cee893a479280c7af41757e709e33ef5reed@google.comstatic uint32_t packColorType(SkColorType ct, U8CPU a, U8CPU r, U8CPU g, U8CPU b) { 61d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com uint32_t r32; 62d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com uint8_t* result = reinterpret_cast<uint8_t*>(&r32); 637111d463cee893a479280c7af41757e709e33ef5reed@google.com switch (ct) { 647111d463cee893a479280c7af41757e709e33ef5reed@google.com case kBGRA_8888_SkColorType: 65d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com result[0] = b; 66d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com result[1] = g; 67d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com result[2] = r; 68d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com result[3] = a; 69d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com break; 707111d463cee893a479280c7af41757e709e33ef5reed@google.com case kRGBA_8888_SkColorType: 71d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com result[0] = r; 72d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com result[1] = g; 73d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com result[2] = b; 74d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com result[3] = a; 75d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com break; 76d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com default: 77d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkASSERT(0); 78d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com return 0; 79d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 80d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com return r32; 81d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com} 82d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com 837111d463cee893a479280c7af41757e709e33ef5reed@google.comstatic uint32_t getBitmapColor(int x, int y, int w, SkColorType ct, SkAlphaType at) { 84d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com int n = y * w + x; 85d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com U8CPU b = n & 0xff; 86d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com U8CPU g = (n >> 8) & 0xff; 87d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com U8CPU r = (n >> 16) & 0xff; 8831648eb1cfe19257ec077efebb11ab251bfd25f7bsalomon@google.com U8CPU a = 0; 89d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com switch ((x+y) % 5) { 90d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com case 4: 91d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com a = 0xff; 92d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com break; 93d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com case 3: 94d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com a = 0x80; 95d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com break; 96d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com case 2: 97d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com a = 0xCC; 98d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com break; 99d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com case 1: 100d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com a = 0x01; 101d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com break; 102d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com case 0: 103d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com a = 0x00; 104d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com break; 105d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 1067111d463cee893a479280c7af41757e709e33ef5reed@google.com if (kPremul_SkAlphaType == at) { 107d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com r = SkMulDiv255Ceiling(r, a); 108d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com g = SkMulDiv255Ceiling(g, a); 109d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com b = SkMulDiv255Ceiling(b, a); 110d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 1117111d463cee893a479280c7af41757e709e33ef5reed@google.com return packColorType(ct, a, r, g , b); 112d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com} 113d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com 114ddf94cf108ae430877f009bd67b9070341426947commit-bot@chromium.orgstatic void fillCanvas(SkCanvas* canvas) { 1154cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkBitmap bmp; 116d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com if (bmp.isNull()) { 117fa9e5fa42a555712fb7a29d08d2ae2bdef0ed68ecommit-bot@chromium.org SkDEBUGCODE(bool alloc = ) bmp.allocN32Pixels(DEV_W, DEV_H); 118d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkASSERT(alloc); 119d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com for (int y = 0; y < DEV_H; ++y) { 120d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com for (int x = 0; x < DEV_W; ++x) { 1214cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org *bmp.getAddr32(x, y) = getCanvasColor(x, y); 122d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 123d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 124d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 125d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com canvas->save(); 126d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com canvas->setMatrix(SkMatrix::I()); 127d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com canvas->clipRect(DEV_RECT_S, SkRegion::kReplace_Op); 128d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkPaint paint; 129d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com paint.setXfermodeMode(SkXfermode::kSrc_Mode); 130d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com canvas->drawBitmap(bmp, 0, 0, &paint); 131d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com canvas->restore(); 132d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com} 133d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com 1347111d463cee893a479280c7af41757e709e33ef5reed@google.com/** 1357111d463cee893a479280c7af41757e709e33ef5reed@google.com * Lucky for us, alpha is always in the same spot (SK_A32_SHIFT), for both RGBA and BGRA. 1367111d463cee893a479280c7af41757e709e33ef5reed@google.com * Thus this routine doesn't need to know the exact colortype 1377111d463cee893a479280c7af41757e709e33ef5reed@google.com */ 1387111d463cee893a479280c7af41757e709e33ef5reed@google.comstatic uint32_t premul(uint32_t color) { 1397111d463cee893a479280c7af41757e709e33ef5reed@google.com unsigned a = SkGetPackedA32(color); 1407111d463cee893a479280c7af41757e709e33ef5reed@google.com // these next three are not necessarily r,g,b in that order, but they are r,g,b in some order. 1417111d463cee893a479280c7af41757e709e33ef5reed@google.com unsigned c0 = SkGetPackedR32(color); 1427111d463cee893a479280c7af41757e709e33ef5reed@google.com unsigned c1 = SkGetPackedG32(color); 1437111d463cee893a479280c7af41757e709e33ef5reed@google.com unsigned c2 = SkGetPackedB32(color); 1447111d463cee893a479280c7af41757e709e33ef5reed@google.com c0 = SkMulDiv255Ceiling(c0, a); 1457111d463cee893a479280c7af41757e709e33ef5reed@google.com c1 = SkMulDiv255Ceiling(c1, a); 1467111d463cee893a479280c7af41757e709e33ef5reed@google.com c2 = SkMulDiv255Ceiling(c2, a); 1477111d463cee893a479280c7af41757e709e33ef5reed@google.com return SkPackARGB32NoCheck(a, c0, c1, c2); 1487111d463cee893a479280c7af41757e709e33ef5reed@google.com} 1497111d463cee893a479280c7af41757e709e33ef5reed@google.com 1507111d463cee893a479280c7af41757e709e33ef5reed@google.comstatic SkPMColor convert_to_PMColor(SkColorType ct, SkAlphaType at, uint32_t color) { 1517111d463cee893a479280c7af41757e709e33ef5reed@google.com if (kUnpremul_SkAlphaType == at) { 1527111d463cee893a479280c7af41757e709e33ef5reed@google.com color = premul(color); 1537111d463cee893a479280c7af41757e709e33ef5reed@google.com } 1547111d463cee893a479280c7af41757e709e33ef5reed@google.com switch (ct) { 1557111d463cee893a479280c7af41757e709e33ef5reed@google.com case kRGBA_8888_SkColorType: 1567111d463cee893a479280c7af41757e709e33ef5reed@google.com color = SkSwizzle_RGBA_to_PMColor(color); 157e14792d99fc7a1a314ef5e2ca5b269239468355acommit-bot@chromium.org break; 1587111d463cee893a479280c7af41757e709e33ef5reed@google.com case kBGRA_8888_SkColorType: 1597111d463cee893a479280c7af41757e709e33ef5reed@google.com color = SkSwizzle_BGRA_to_PMColor(color); 1601121170477302e25ef2a020cf2092aa6b399b3efreed@google.com break; 161231f6b81c22001cac4ea87ea412c4d6fd10ffb8acommit-bot@chromium.org default: 1627111d463cee893a479280c7af41757e709e33ef5reed@google.com SkASSERT(0); 1637111d463cee893a479280c7af41757e709e33ef5reed@google.com break; 164231f6b81c22001cac4ea87ea412c4d6fd10ffb8acommit-bot@chromium.org } 1657111d463cee893a479280c7af41757e709e33ef5reed@google.com return color; 166d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com} 167d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com 168ddf94cf108ae430877f009bd67b9070341426947commit-bot@chromium.orgstatic bool checkPixel(SkPMColor a, SkPMColor b, bool didPremulConversion) { 169d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com if (!didPremulConversion) { 170d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com return a == b; 171d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 172d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com int32_t aA = static_cast<int32_t>(SkGetPackedA32(a)); 173d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com int32_t aR = static_cast<int32_t>(SkGetPackedR32(a)); 174d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com int32_t aG = static_cast<int32_t>(SkGetPackedG32(a)); 175d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com int32_t aB = SkGetPackedB32(a); 176d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com 177d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com int32_t bA = static_cast<int32_t>(SkGetPackedA32(b)); 178d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com int32_t bR = static_cast<int32_t>(SkGetPackedR32(b)); 179d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com int32_t bG = static_cast<int32_t>(SkGetPackedG32(b)); 180d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com int32_t bB = static_cast<int32_t>(SkGetPackedB32(b)); 181d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com 182d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com return aA == bA && 183d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkAbs32(aR - bR) <= 1 && 184d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkAbs32(aG - bG) <= 1 && 185d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkAbs32(aB - bB) <= 1; 186d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com} 187d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com 1887111d463cee893a479280c7af41757e709e33ef5reed@google.comstatic bool checkWrite(skiatest::Reporter* reporter, SkCanvas* canvas, const SkBitmap& bitmap, 1897111d463cee893a479280c7af41757e709e33ef5reed@google.com int writeX, int writeY) { 1907111d463cee893a479280c7af41757e709e33ef5reed@google.com SkImageInfo canvasInfo; 1917111d463cee893a479280c7af41757e709e33ef5reed@google.com size_t canvasRowBytes; 1927111d463cee893a479280c7af41757e709e33ef5reed@google.com const uint32_t* canvasPixels; 1937111d463cee893a479280c7af41757e709e33ef5reed@google.com 1947111d463cee893a479280c7af41757e709e33ef5reed@google.com // Can't use canvas->peekPixels(), as we are trying to look at GPU pixels sometimes as well. 1957111d463cee893a479280c7af41757e709e33ef5reed@google.com // At some point this will be unsupported, as we won't allow accessBitmap() to magically call 1967111d463cee893a479280c7af41757e709e33ef5reed@google.com // readPixels for the client. 1977111d463cee893a479280c7af41757e709e33ef5reed@google.com SkBitmap secretDevBitmap; 1987111d463cee893a479280c7af41757e709e33ef5reed@google.com { 1997111d463cee893a479280c7af41757e709e33ef5reed@google.com SkBaseDevice* dev = canvas->getDevice(); 2007111d463cee893a479280c7af41757e709e33ef5reed@google.com if (!dev) { 2017111d463cee893a479280c7af41757e709e33ef5reed@google.com return false; 2027111d463cee893a479280c7af41757e709e33ef5reed@google.com } 2037111d463cee893a479280c7af41757e709e33ef5reed@google.com secretDevBitmap = dev->accessBitmap(false); 2047111d463cee893a479280c7af41757e709e33ef5reed@google.com } 2057111d463cee893a479280c7af41757e709e33ef5reed@google.com SkAutoLockPixels alp(secretDevBitmap); 2067111d463cee893a479280c7af41757e709e33ef5reed@google.com canvasInfo = secretDevBitmap.info(); 2077111d463cee893a479280c7af41757e709e33ef5reed@google.com canvasRowBytes = secretDevBitmap.rowBytes(); 2087111d463cee893a479280c7af41757e709e33ef5reed@google.com canvasPixels = static_cast<const uint32_t*>(secretDevBitmap.getPixels()); 2097111d463cee893a479280c7af41757e709e33ef5reed@google.com 2107111d463cee893a479280c7af41757e709e33ef5reed@google.com if (NULL == canvasPixels) { 211d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com return false; 212d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 2137111d463cee893a479280c7af41757e709e33ef5reed@google.com 2147111d463cee893a479280c7af41757e709e33ef5reed@google.com if (canvasInfo.width() != DEV_W || 2157111d463cee893a479280c7af41757e709e33ef5reed@google.com canvasInfo.height() != DEV_H || 21628fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org canvasInfo.colorType() != kN32_SkColorType) { 217d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com return false; 218d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 219d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com 2207111d463cee893a479280c7af41757e709e33ef5reed@google.com const SkImageInfo bmInfo = bitmap.info(); 2217111d463cee893a479280c7af41757e709e33ef5reed@google.com 222d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkIRect writeRect = SkIRect::MakeXYWH(writeX, writeY, bitmap.width(), bitmap.height()); 223d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com for (int cy = 0; cy < DEV_H; ++cy) { 224d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com for (int cx = 0; cx < DEV_W; ++cx) { 2257111d463cee893a479280c7af41757e709e33ef5reed@google.com SkPMColor canvasPixel = canvasPixels[cx]; 226d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com if (writeRect.contains(cx, cy)) { 227d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com int bx = cx - writeX; 228d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com int by = cy - writeY; 2297111d463cee893a479280c7af41757e709e33ef5reed@google.com uint32_t bmpColor8888 = getBitmapColor(bx, by, bitmap.width(), 2307111d463cee893a479280c7af41757e709e33ef5reed@google.com bmInfo.colorType(), bmInfo.alphaType()); 2317111d463cee893a479280c7af41757e709e33ef5reed@google.com bool mul = (kUnpremul_SkAlphaType == bmInfo.alphaType()); 2327111d463cee893a479280c7af41757e709e33ef5reed@google.com SkPMColor bmpPMColor = convert_to_PMColor(bmInfo.colorType(), bmInfo.alphaType(), 2337111d463cee893a479280c7af41757e709e33ef5reed@google.com bmpColor8888); 2347111d463cee893a479280c7af41757e709e33ef5reed@google.com bool check = checkPixel(bmpPMColor, canvasPixel, mul); 2357111d463cee893a479280c7af41757e709e33ef5reed@google.com REPORTER_ASSERT(reporter, check); 236d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com if (!check) { 23772f3dca451f4739e20be0b4b198813677339205cbsalomon@google.com return false; 238d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 239d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } else { 240d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com bool check; 241d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkPMColor testColor = getCanvasColor(cx, cy); 242d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com REPORTER_ASSERT(reporter, check = (canvasPixel == testColor)); 243d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com if (!check) { 24472f3dca451f4739e20be0b4b198813677339205cbsalomon@google.com return false; 245d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 246d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 247d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 248d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com if (cy != DEV_H -1) { 2497111d463cee893a479280c7af41757e709e33ef5reed@google.com const char* pad = reinterpret_cast<const char*>(canvasPixels + DEV_W); 250d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com for (size_t px = 0; px < canvasRowBytes - 4 * DEV_W; ++px) { 251d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com bool check; 252d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com REPORTER_ASSERT(reporter, check = (pad[px] == static_cast<char>(DEV_PAD))); 253d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com if (!check) { 25472f3dca451f4739e20be0b4b198813677339205cbsalomon@google.com return false; 255d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 256d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 257d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 2587111d463cee893a479280c7af41757e709e33ef5reed@google.com canvasPixels += canvasRowBytes/4; 259d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 260d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com 26172f3dca451f4739e20be0b4b198813677339205cbsalomon@google.com return true; 262d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com} 263d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com 264d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.comenum DevType { 265d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com kRaster_DevType, 266cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU 2673cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org kGpu_BottomLeft_DevType, 2683cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org kGpu_TopLeft_DevType, 269cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif 270d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com}; 271d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com 272d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.comstruct CanvasConfig { 273d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com DevType fDevType; 274d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com bool fTightRowBytes; 275d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com}; 276d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com 277d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.comstatic const CanvasConfig gCanvasConfigs[] = { 278d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com {kRaster_DevType, true}, 279d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com {kRaster_DevType, false}, 2808f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com#if SK_SUPPORT_GPU 2813cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org {kGpu_BottomLeft_DevType, true}, // row bytes has no meaning on gpu devices 2823cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org {kGpu_TopLeft_DevType, true}, // row bytes has no meaning on gpu devices 283bbce8b29bd0d30ee0b1155ae72023e779cbdce9bbsalomon@google.com#endif 284d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com}; 285d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com 286fa9e5fa42a555712fb7a29d08d2ae2bdef0ed68ecommit-bot@chromium.org#include "SkMallocPixelRef.h" 287fa9e5fa42a555712fb7a29d08d2ae2bdef0ed68ecommit-bot@chromium.org 288fa9e5fa42a555712fb7a29d08d2ae2bdef0ed68ecommit-bot@chromium.org// This is a tricky pattern, because we have to setConfig+rowBytes AND specify 289fa9e5fa42a555712fb7a29d08d2ae2bdef0ed68ecommit-bot@chromium.org// a custom pixelRef (which also has to specify its rowBytes), so we have to be 290fa9e5fa42a555712fb7a29d08d2ae2bdef0ed68ecommit-bot@chromium.org// sure that the two rowBytes match (and the infos match). 291fa9e5fa42a555712fb7a29d08d2ae2bdef0ed68ecommit-bot@chromium.org// 292fa9e5fa42a555712fb7a29d08d2ae2bdef0ed68ecommit-bot@chromium.orgstatic bool allocRowBytes(SkBitmap* bm, const SkImageInfo& info, size_t rowBytes) { 293a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org if (!bm->setInfo(info, rowBytes)) { 294fa9e5fa42a555712fb7a29d08d2ae2bdef0ed68ecommit-bot@chromium.org return false; 295fa9e5fa42a555712fb7a29d08d2ae2bdef0ed68ecommit-bot@chromium.org } 296fa9e5fa42a555712fb7a29d08d2ae2bdef0ed68ecommit-bot@chromium.org SkPixelRef* pr = SkMallocPixelRef::NewAllocate(info, rowBytes, NULL); 297fa9e5fa42a555712fb7a29d08d2ae2bdef0ed68ecommit-bot@chromium.org bm->setPixelRef(pr)->unref(); 298fa9e5fa42a555712fb7a29d08d2ae2bdef0ed68ecommit-bot@chromium.org return true; 299fa9e5fa42a555712fb7a29d08d2ae2bdef0ed68ecommit-bot@chromium.org} 300fa9e5fa42a555712fb7a29d08d2ae2bdef0ed68ecommit-bot@chromium.org 301ddf94cf108ae430877f009bd67b9070341426947commit-bot@chromium.orgstatic SkBaseDevice* createDevice(const CanvasConfig& c, GrContext* grCtx) { 302d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com switch (c.fDevType) { 303d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com case kRaster_DevType: { 304d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkBitmap bmp; 305d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com size_t rowBytes = c.fTightRowBytes ? 0 : 4 * DEV_W + 100; 306fa9e5fa42a555712fb7a29d08d2ae2bdef0ed68ecommit-bot@chromium.org SkImageInfo info = SkImageInfo::MakeN32Premul(DEV_W, DEV_H); 307fa9e5fa42a555712fb7a29d08d2ae2bdef0ed68ecommit-bot@chromium.org if (!allocRowBytes(&bmp, info, rowBytes)) { 30844a42ea8b22a845a419b8ae3b47c4619fdec0215reed@google.com sk_throw(); 30944a42ea8b22a845a419b8ae3b47c4619fdec0215reed@google.com return NULL; 310d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 311d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com // if rowBytes isn't tight then set the padding to a known value 312d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com if (rowBytes) { 313d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkAutoLockPixels alp(bmp); 31461c9b835d13e1d4225f3a04f045658f62c702294commit-bot@chromium.org // We'd just use memset here but GCC 4.8.1 throws up a bogus warning when we do. 31561c9b835d13e1d4225f3a04f045658f62c702294commit-bot@chromium.org for (size_t i = 0; i < bmp.getSafeSize(); i++) { 31661c9b835d13e1d4225f3a04f045658f62c702294commit-bot@chromium.org ((uint8_t*)bmp.getPixels())[i] = DEV_PAD; 31761c9b835d13e1d4225f3a04f045658f62c702294commit-bot@chromium.org } 318d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 3191f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com return new SkBitmapDevice(bmp); 320cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com } 321cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU 3223cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org case kGpu_BottomLeft_DevType: 3233cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org case kGpu_TopLeft_DevType: 3243cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org GrTextureDesc desc; 3253cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org desc.fFlags = kRenderTarget_GrTextureFlagBit; 3263cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org desc.fWidth = DEV_W; 3273cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org desc.fHeight = DEV_H; 328fec0bc3fc13481f5bcb341ab2d2d695911f39bd4bsalomon@google.com desc.fConfig = kSkia8888_GrPixelConfig; 3293cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org desc.fOrigin = kGpu_TopLeft_DevType == c.fDevType ? 3303cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin; 3313cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org GrAutoScratchTexture ast(grCtx, desc, GrContext::kExact_ScratchTexMatch); 3323cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org SkAutoTUnref<GrTexture> tex(ast.detach()); 3333cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org return new SkGpuDevice(grCtx, tex); 334cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif 335d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 33644a42ea8b22a845a419b8ae3b47c4619fdec0215reed@google.com return NULL; 337d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com} 338d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com 3397111d463cee893a479280c7af41757e709e33ef5reed@google.comstatic bool setupBitmap(SkBitmap* bm, SkColorType ct, SkAlphaType at, int w, int h, int tightRB) { 3407111d463cee893a479280c7af41757e709e33ef5reed@google.com size_t rowBytes = tightRB ? 0 : 4 * w + 60; 3417111d463cee893a479280c7af41757e709e33ef5reed@google.com SkImageInfo info = SkImageInfo::Make(w, h, ct, at); 3427111d463cee893a479280c7af41757e709e33ef5reed@google.com if (!allocRowBytes(bm, info, rowBytes)) { 343d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com return false; 344d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 3457111d463cee893a479280c7af41757e709e33ef5reed@google.com SkAutoLockPixels alp(*bm); 346d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com for (int y = 0; y < h; ++y) { 347d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com for (int x = 0; x < w; ++x) { 3487111d463cee893a479280c7af41757e709e33ef5reed@google.com *bm->getAddr32(x, y) = getBitmapColor(x, y, w, ct, at); 349d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 350d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 351d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com return true; 352d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com} 353d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com 3544ee16bfaedb14aff8cf102f1f0722ff2529a9699tfarina@chromium.orgDEF_GPUTEST(WritePixels, reporter, factory) { 355d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkCanvas canvas; 356d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 357d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com const SkIRect testRects[] = { 358d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com // entire thing 359d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com DEV_RECT, 360d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com // larger on all sides 361d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkIRect::MakeLTRB(-10, -10, DEV_W + 10, DEV_H + 10), 362d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com // fully contained 363d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkIRect::MakeLTRB(DEV_W / 4, DEV_H / 4, 3 * DEV_W / 4, 3 * DEV_H / 4), 364d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com // outside top left 365d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkIRect::MakeLTRB(-10, -10, -1, -1), 366d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com // touching top left corner 367d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkIRect::MakeLTRB(-10, -10, 0, 0), 368d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com // overlapping top left corner 369d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkIRect::MakeLTRB(-10, -10, DEV_W / 4, DEV_H / 4), 370d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com // overlapping top left and top right corners 371d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkIRect::MakeLTRB(-10, -10, DEV_W + 10, DEV_H / 4), 372d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com // touching entire top edge 373d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkIRect::MakeLTRB(-10, -10, DEV_W + 10, 0), 374d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com // overlapping top right corner 375d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkIRect::MakeLTRB(3 * DEV_W / 4, -10, DEV_W + 10, DEV_H / 4), 376d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com // contained in x, overlapping top edge 377d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkIRect::MakeLTRB(DEV_W / 4, -10, 3 * DEV_W / 4, DEV_H / 4), 378d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com // outside top right corner 379d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkIRect::MakeLTRB(DEV_W + 1, -10, DEV_W + 10, -1), 380d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com // touching top right corner 381d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkIRect::MakeLTRB(DEV_W, -10, DEV_W + 10, 0), 382d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com // overlapping top left and bottom left corners 383d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkIRect::MakeLTRB(-10, -10, DEV_W / 4, DEV_H + 10), 384d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com // touching entire left edge 385d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkIRect::MakeLTRB(-10, -10, 0, DEV_H + 10), 386d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com // overlapping bottom left corner 387d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkIRect::MakeLTRB(-10, 3 * DEV_H / 4, DEV_W / 4, DEV_H + 10), 388d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com // contained in y, overlapping left edge 389d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkIRect::MakeLTRB(-10, DEV_H / 4, DEV_W / 4, 3 * DEV_H / 4), 390d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com // outside bottom left corner 391d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkIRect::MakeLTRB(-10, DEV_H + 1, -1, DEV_H + 10), 392d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com // touching bottom left corner 393d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkIRect::MakeLTRB(-10, DEV_H, 0, DEV_H + 10), 394d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com // overlapping bottom left and bottom right corners 395d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkIRect::MakeLTRB(-10, 3 * DEV_H / 4, DEV_W + 10, DEV_H + 10), 396d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com // touching entire left edge 397d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkIRect::MakeLTRB(0, DEV_H, DEV_W, DEV_H + 10), 398d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com // overlapping bottom right corner 399d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkIRect::MakeLTRB(3 * DEV_W / 4, 3 * DEV_H / 4, DEV_W + 10, DEV_H + 10), 400d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com // overlapping top right and bottom right corners 401d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com SkIRect::MakeLTRB(3 * DEV_W / 4, -10, DEV_W + 10, DEV_H + 10), 402d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com }; 403d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com 404d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com for (size_t i = 0; i < SK_ARRAY_COUNT(gCanvasConfigs); ++i) { 40567b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com int glCtxTypeCnt = 1; 40667b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com#if SK_SUPPORT_GPU 4073cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org bool isGPUDevice = kGpu_TopLeft_DevType == gCanvasConfigs[i].fDevType || 4083cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org kGpu_BottomLeft_DevType == gCanvasConfigs[i].fDevType; 4093cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org if (isGPUDevice) { 41067b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com glCtxTypeCnt = GrContextFactory::kGLContextTypeCnt; 41167b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com } 41267b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com#endif 41367b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com for (int glCtxType = 0; glCtxType < glCtxTypeCnt; ++glCtxType) { 41467b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com GrContext* context = NULL; 41567b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com#if SK_SUPPORT_GPU 4163cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org if (isGPUDevice) { 41767b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com GrContextFactory::GLContextType type = 41867b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com static_cast<GrContextFactory::GLContextType>(glCtxType); 41967b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com if (!GrContextFactory::IsRenderingGLContext(type)) { 42067b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com continue; 42167b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com } 42267b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com context = factory->get(type); 42367b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com if (NULL == context) { 42467b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com continue; 42567b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com } 42667b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com } 42767b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com#endif 42867b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com 4291f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkAutoTUnref<SkBaseDevice> device(createDevice(gCanvasConfigs[i], context)); 43067b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com SkCanvas canvas(device); 431d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com 4327111d463cee893a479280c7af41757e709e33ef5reed@google.com static const struct { 4337111d463cee893a479280c7af41757e709e33ef5reed@google.com SkColorType fColorType; 4347111d463cee893a479280c7af41757e709e33ef5reed@google.com SkAlphaType fAlphaType; 4357111d463cee893a479280c7af41757e709e33ef5reed@google.com } gSrcConfigs[] = { 4367111d463cee893a479280c7af41757e709e33ef5reed@google.com { kRGBA_8888_SkColorType, kPremul_SkAlphaType }, 4377111d463cee893a479280c7af41757e709e33ef5reed@google.com { kRGBA_8888_SkColorType, kUnpremul_SkAlphaType }, 4387111d463cee893a479280c7af41757e709e33ef5reed@google.com { kBGRA_8888_SkColorType, kPremul_SkAlphaType }, 4397111d463cee893a479280c7af41757e709e33ef5reed@google.com { kBGRA_8888_SkColorType, kUnpremul_SkAlphaType }, 44067b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com }; 44167b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com for (size_t r = 0; r < SK_ARRAY_COUNT(testRects); ++r) { 44267b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com const SkIRect& rect = testRects[r]; 44367b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com for (int tightBmp = 0; tightBmp < 2; ++tightBmp) { 44467b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com for (size_t c = 0; c < SK_ARRAY_COUNT(gSrcConfigs); ++c) { 4457111d463cee893a479280c7af41757e709e33ef5reed@google.com const SkColorType ct = gSrcConfigs[c].fColorType; 4467111d463cee893a479280c7af41757e709e33ef5reed@google.com const SkAlphaType at = gSrcConfigs[c].fAlphaType; 4477111d463cee893a479280c7af41757e709e33ef5reed@google.com 44867b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com fillCanvas(&canvas); 44967b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com SkBitmap bmp; 4507111d463cee893a479280c7af41757e709e33ef5reed@google.com REPORTER_ASSERT(reporter, setupBitmap(&bmp, ct, at, rect.width(), 4517111d463cee893a479280c7af41757e709e33ef5reed@google.com rect.height(), SkToBool(tightBmp))); 45267b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com uint32_t idBefore = canvas.getDevice()->accessBitmap(false).getGenerationID(); 4534cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 4547111d463cee893a479280c7af41757e709e33ef5reed@google.com // sk_tool_utils::write_pixels(&canvas, bmp, rect.fLeft, rect.fTop, ct, at); 4557111d463cee893a479280c7af41757e709e33ef5reed@google.com canvas.writePixels(bmp, rect.fLeft, rect.fTop); 4564cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 45767b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com uint32_t idAfter = canvas.getDevice()->accessBitmap(false).getGenerationID(); 4587111d463cee893a479280c7af41757e709e33ef5reed@google.com REPORTER_ASSERT(reporter, checkWrite(reporter, &canvas, bmp, rect.fLeft, rect.fTop)); 459405d0f43d8fa03874aee23669e5fdb38f21cc3e7bsalomon@google.com 46067b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com // we should change the genID iff pixels were actually written. 46167b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com SkIRect canvasRect = SkIRect::MakeSize(canvas.getDeviceSize()); 46267b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com SkIRect writeRect = SkIRect::MakeXYWH(rect.fLeft, rect.fTop, 46367b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com bmp.width(), bmp.height()); 46467b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com bool intersects = SkIRect::Intersects(canvasRect, writeRect) ; 46567b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com REPORTER_ASSERT(reporter, intersects == (idBefore != idAfter)); 46667b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com } 467d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 468d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 469d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 470d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com } 471d58a1cd00b969a7755c375f55cf80f4d49d3047bbsalomon@google.com} 472