OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkCanvas.h" | 8 #include "SkCanvas.h" |
9 #include "SkColorPriv.h" | 9 #include "SkColorPriv.h" |
10 #include "SkMathPriv.h" | 10 #include "SkMathPriv.h" |
11 #include "SkRegion.h" | 11 #include "SkRegion.h" |
12 #include "SkSurface.h" | 12 #include "SkSurface.h" |
13 #include "Test.h" | 13 #include "Test.h" |
14 #include "sk_tool_utils.h" | 14 #include "sk_tool_utils.h" |
15 | 15 |
16 #if SK_SUPPORT_GPU | 16 #if SK_SUPPORT_GPU |
17 #include "GrContextFactory.h" | 17 #include "GrContextFactory.h" |
18 #include "SkGpuDevice.h" | 18 #include "SkGpuDevice.h" |
19 #else | 19 #else |
20 class GrContext; | 20 class GrContext; |
21 class GrContextFactory; | 21 class GrContextFactory; |
22 #endif | 22 #endif |
23 | 23 |
24 static const int DEV_W = 100, DEV_H = 100; | 24 static const int DEV_W = 100, DEV_H = 100; |
25 static const SkIRect DEV_RECT = SkIRect::MakeWH(DEV_W, DEV_H); | 25 static const SkIRect DEV_RECT = SkIRect::MakeWH(DEV_W, DEV_H); |
26 static const SkRect DEV_RECT_S = SkRect::MakeWH(DEV_W * SK_Scalar1, | 26 static const SkRect DEV_RECT_S = SkRect::MakeWH(DEV_W * SK_Scalar1, |
27 DEV_H * SK_Scalar1); | 27 DEV_H * SK_Scalar1); |
28 static const U8CPU DEV_PAD = 0xee; | 28 static const U8CPU DEV_PAD = 0xee; |
29 | 29 |
30 static SkPMColor get_canvas_color(int x, int y) { | 30 static SkPMColor getCanvasColor(int x, int y) { |
31 SkASSERT(x >= 0 && x < DEV_W); | 31 SkASSERT(x >= 0 && x < DEV_W); |
32 SkASSERT(y >= 0 && y < DEV_H); | 32 SkASSERT(y >= 0 && y < DEV_H); |
33 | 33 |
34 U8CPU r = x; | 34 U8CPU r = x; |
35 U8CPU g = y; | 35 U8CPU g = y; |
36 U8CPU b = 0xc; | 36 U8CPU b = 0xc; |
37 | 37 |
38 U8CPU a = 0x0; | 38 U8CPU a = 0x0; |
39 switch ((x+y) % 5) { | 39 switch ((x+y) % 5) { |
40 case 0: | 40 case 0: |
41 a = 0xff; | 41 a = 0xff; |
42 break; | 42 break; |
43 case 1: | 43 case 1: |
44 a = 0x80; | 44 a = 0x80; |
45 break; | 45 break; |
46 case 2: | 46 case 2: |
47 a = 0xCC; | 47 a = 0xCC; |
48 break; | 48 break; |
49 case 3: | 49 case 3: |
50 a = 0x00; | 50 a = 0x00; |
51 break; | 51 break; |
52 case 4: | 52 case 4: |
53 a = 0x01; | 53 a = 0x01; |
54 break; | 54 break; |
55 } | 55 } |
56 return SkPremultiplyARGBInline(a, r, g, b); | 56 return SkPremultiplyARGBInline(a, r, g, b); |
57 } | 57 } |
58 | 58 |
59 // assumes any premu/.unpremul has been applied | 59 // assumes any premu/.unpremul has been applied |
60 static uint32_t pack_color_type(SkColorType ct, U8CPU a, U8CPU r, U8CPU g, U8CPU
b) { | 60 static uint32_t packColorType(SkColorType ct, U8CPU a, U8CPU r, U8CPU g, U8CPU b
) { |
61 uint32_t r32; | 61 uint32_t r32; |
62 uint8_t* result = reinterpret_cast<uint8_t*>(&r32); | 62 uint8_t* result = reinterpret_cast<uint8_t*>(&r32); |
63 switch (ct) { | 63 switch (ct) { |
64 case kBGRA_8888_SkColorType: | 64 case kBGRA_8888_SkColorType: |
65 result[0] = b; | 65 result[0] = b; |
66 result[1] = g; | 66 result[1] = g; |
67 result[2] = r; | 67 result[2] = r; |
68 result[3] = a; | 68 result[3] = a; |
69 break; | 69 break; |
70 case kRGBA_8888_SkColorType: | 70 case kRGBA_8888_SkColorType: |
71 result[0] = r; | 71 result[0] = r; |
72 result[1] = g; | 72 result[1] = g; |
73 result[2] = b; | 73 result[2] = b; |
74 result[3] = a; | 74 result[3] = a; |
75 break; | 75 break; |
76 default: | 76 default: |
77 SkASSERT(0); | 77 SkASSERT(0); |
78 return 0; | 78 return 0; |
79 } | 79 } |
80 return r32; | 80 return r32; |
81 } | 81 } |
82 | 82 |
83 static uint32_t get_bitmap_color(int x, int y, int w, SkColorType ct, SkAlphaTyp
e at) { | 83 static uint32_t getBitmapColor(int x, int y, int w, SkColorType ct, SkAlphaType
at) { |
84 int n = y * w + x; | 84 int n = y * w + x; |
85 U8CPU b = n & 0xff; | 85 U8CPU b = n & 0xff; |
86 U8CPU g = (n >> 8) & 0xff; | 86 U8CPU g = (n >> 8) & 0xff; |
87 U8CPU r = (n >> 16) & 0xff; | 87 U8CPU r = (n >> 16) & 0xff; |
88 U8CPU a = 0; | 88 U8CPU a = 0; |
89 switch ((x+y) % 5) { | 89 switch ((x+y) % 5) { |
90 case 4: | 90 case 4: |
91 a = 0xff; | 91 a = 0xff; |
92 break; | 92 break; |
93 case 3: | 93 case 3: |
94 a = 0x80; | 94 a = 0x80; |
95 break; | 95 break; |
96 case 2: | 96 case 2: |
97 a = 0xCC; | 97 a = 0xCC; |
98 break; | 98 break; |
99 case 1: | 99 case 1: |
100 a = 0x01; | 100 a = 0x01; |
101 break; | 101 break; |
102 case 0: | 102 case 0: |
103 a = 0x00; | 103 a = 0x00; |
104 break; | 104 break; |
105 } | 105 } |
106 if (kPremul_SkAlphaType == at) { | 106 if (kPremul_SkAlphaType == at) { |
107 r = SkMulDiv255Ceiling(r, a); | 107 r = SkMulDiv255Ceiling(r, a); |
108 g = SkMulDiv255Ceiling(g, a); | 108 g = SkMulDiv255Ceiling(g, a); |
109 b = SkMulDiv255Ceiling(b, a); | 109 b = SkMulDiv255Ceiling(b, a); |
110 } | 110 } |
111 return pack_color_type(ct, a, r, g , b); | 111 return packColorType(ct, a, r, g , b); |
112 } | 112 } |
113 | 113 |
114 static void fill_canvas(SkCanvas* canvas) { | 114 static void fillCanvas(SkCanvas* canvas) { |
115 SkBitmap bmp; | 115 SkBitmap bmp; |
116 if (bmp.isNull()) { | 116 if (bmp.isNull()) { |
117 bmp.allocN32Pixels(DEV_W, DEV_H); | 117 bmp.allocN32Pixels(DEV_W, DEV_H); |
118 for (int y = 0; y < DEV_H; ++y) { | 118 for (int y = 0; y < DEV_H; ++y) { |
119 for (int x = 0; x < DEV_W; ++x) { | 119 for (int x = 0; x < DEV_W; ++x) { |
120 *bmp.getAddr32(x, y) = get_canvas_color(x, y); | 120 *bmp.getAddr32(x, y) = getCanvasColor(x, y); |
121 } | 121 } |
122 } | 122 } |
123 } | 123 } |
124 canvas->save(); | 124 canvas->save(); |
125 canvas->setMatrix(SkMatrix::I()); | 125 canvas->setMatrix(SkMatrix::I()); |
126 canvas->clipRect(DEV_RECT_S, SkRegion::kReplace_Op); | 126 canvas->clipRect(DEV_RECT_S, SkRegion::kReplace_Op); |
127 SkPaint paint; | 127 SkPaint paint; |
128 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | 128 paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
129 canvas->drawBitmap(bmp, 0, 0, &paint); | 129 canvas->drawBitmap(bmp, 0, 0, &paint); |
130 canvas->restore(); | 130 canvas->restore(); |
(...skipping 26 matching lines...) Expand all Loading... |
157 case kBGRA_8888_SkColorType: | 157 case kBGRA_8888_SkColorType: |
158 color = SkSwizzle_BGRA_to_PMColor(color); | 158 color = SkSwizzle_BGRA_to_PMColor(color); |
159 break; | 159 break; |
160 default: | 160 default: |
161 SkASSERT(0); | 161 SkASSERT(0); |
162 break; | 162 break; |
163 } | 163 } |
164 return color; | 164 return color; |
165 } | 165 } |
166 | 166 |
167 static bool check_pixel(SkPMColor a, SkPMColor b, bool didPremulConversion) { | 167 static bool checkPixel(SkPMColor a, SkPMColor b, bool didPremulConversion) { |
168 if (!didPremulConversion) { | 168 if (!didPremulConversion) { |
169 return a == b; | 169 return a == b; |
170 } | 170 } |
171 int32_t aA = static_cast<int32_t>(SkGetPackedA32(a)); | 171 int32_t aA = static_cast<int32_t>(SkGetPackedA32(a)); |
172 int32_t aR = static_cast<int32_t>(SkGetPackedR32(a)); | 172 int32_t aR = static_cast<int32_t>(SkGetPackedR32(a)); |
173 int32_t aG = static_cast<int32_t>(SkGetPackedG32(a)); | 173 int32_t aG = static_cast<int32_t>(SkGetPackedG32(a)); |
174 int32_t aB = SkGetPackedB32(a); | 174 int32_t aB = SkGetPackedB32(a); |
175 | 175 |
176 int32_t bA = static_cast<int32_t>(SkGetPackedA32(b)); | 176 int32_t bA = static_cast<int32_t>(SkGetPackedA32(b)); |
177 int32_t bR = static_cast<int32_t>(SkGetPackedR32(b)); | 177 int32_t bR = static_cast<int32_t>(SkGetPackedR32(b)); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 | 212 |
213 const SkImageInfo bmInfo = bitmap.info(); | 213 const SkImageInfo bmInfo = bitmap.info(); |
214 | 214 |
215 SkIRect writeRect = SkIRect::MakeXYWH(writeX, writeY, bitmap.width(), bitmap
.height()); | 215 SkIRect writeRect = SkIRect::MakeXYWH(writeX, writeY, bitmap.width(), bitmap
.height()); |
216 for (int cy = 0; cy < DEV_H; ++cy) { | 216 for (int cy = 0; cy < DEV_H; ++cy) { |
217 for (int cx = 0; cx < DEV_W; ++cx) { | 217 for (int cx = 0; cx < DEV_W; ++cx) { |
218 SkPMColor canvasPixel = canvasPixels[cx]; | 218 SkPMColor canvasPixel = canvasPixels[cx]; |
219 if (writeRect.contains(cx, cy)) { | 219 if (writeRect.contains(cx, cy)) { |
220 int bx = cx - writeX; | 220 int bx = cx - writeX; |
221 int by = cy - writeY; | 221 int by = cy - writeY; |
222 uint32_t bmpColor8888 = get_bitmap_color(bx, by, bitmap.width(), | 222 uint32_t bmpColor8888 = getBitmapColor(bx, by, bitmap.width(), |
223 bmInfo.colorType(), bmInf
o.alphaType()); | 223 bmInfo.colorType(), bmInf
o.alphaType()); |
224 bool mul = (kUnpremul_SkAlphaType == bmInfo.alphaType()); | 224 bool mul = (kUnpremul_SkAlphaType == bmInfo.alphaType()); |
225 SkPMColor bmpPMColor = convert_to_PMColor(bmInfo.colorType(), bm
Info.alphaType(), | 225 SkPMColor bmpPMColor = convert_to_PMColor(bmInfo.colorType(), bm
Info.alphaType(), |
226 bmpColor8888); | 226 bmpColor8888); |
227 if (!check_pixel(bmpPMColor, canvasPixel, mul)) { | 227 bool check = checkPixel(bmpPMColor, canvasPixel, mul); |
228 ERRORF(reporter, "Expected canvas pixel at %d, %d to be 0x%0
8x, got 0x%08x. " | 228 REPORTER_ASSERT(reporter, check); |
229 "Write performed premul: %d", cx, cy, bmpPMColor, can
vasPixel, mul); | 229 if (!check) { |
230 return false; | 230 return false; |
231 } | 231 } |
232 } else { | 232 } else { |
233 SkPMColor testColor = get_canvas_color(cx, cy); | 233 bool check; |
234 if (canvasPixel != testColor) { | 234 SkPMColor testColor = getCanvasColor(cx, cy); |
235 ERRORF(reporter, "Canvas pixel outside write rect at %d, %d
changed." | 235 REPORTER_ASSERT(reporter, check = (canvasPixel == testColor)); |
236 " Should be 0x%08x, got 0x%08x. ", cx, cy, testColor,
canvasPixel); | 236 if (!check) { |
237 return false; | 237 return false; |
238 } | 238 } |
239 } | 239 } |
240 } | 240 } |
241 if (cy != DEV_H -1) { | 241 if (cy != DEV_H -1) { |
242 const char* pad = reinterpret_cast<const char*>(canvasPixels + DEV_W
); | 242 const char* pad = reinterpret_cast<const char*>(canvasPixels + DEV_W
); |
243 for (size_t px = 0; px < canvasRowBytes - 4 * DEV_W; ++px) { | 243 for (size_t px = 0; px < canvasRowBytes - 4 * DEV_W; ++px) { |
244 bool check; | 244 bool check; |
245 REPORTER_ASSERT(reporter, check = (pad[px] == static_cast<char>(
DEV_PAD))); | 245 REPORTER_ASSERT(reporter, check = (pad[px] == static_cast<char>(
DEV_PAD))); |
246 if (!check) { | 246 if (!check) { |
(...skipping 28 matching lines...) Expand all Loading... |
275 {kGpu_TopLeft_DevType, true}, // row bytes has no meaning on gpu devices | 275 {kGpu_TopLeft_DevType, true}, // row bytes has no meaning on gpu devices |
276 #endif | 276 #endif |
277 }; | 277 }; |
278 | 278 |
279 #include "SkMallocPixelRef.h" | 279 #include "SkMallocPixelRef.h" |
280 | 280 |
281 // This is a tricky pattern, because we have to setConfig+rowBytes AND specify | 281 // This is a tricky pattern, because we have to setConfig+rowBytes AND specify |
282 // a custom pixelRef (which also has to specify its rowBytes), so we have to be | 282 // a custom pixelRef (which also has to specify its rowBytes), so we have to be |
283 // sure that the two rowBytes match (and the infos match). | 283 // sure that the two rowBytes match (and the infos match). |
284 // | 284 // |
285 static bool alloc_row_bytes(SkBitmap* bm, const SkImageInfo& info, size_t rowByt
es) { | 285 static bool allocRowBytes(SkBitmap* bm, const SkImageInfo& info, size_t rowBytes
) { |
286 if (!bm->setInfo(info, rowBytes)) { | 286 if (!bm->setInfo(info, rowBytes)) { |
287 return false; | 287 return false; |
288 } | 288 } |
289 SkPixelRef* pr = SkMallocPixelRef::NewAllocate(info, rowBytes, NULL); | 289 SkPixelRef* pr = SkMallocPixelRef::NewAllocate(info, rowBytes, NULL); |
290 bm->setPixelRef(pr)->unref(); | 290 bm->setPixelRef(pr)->unref(); |
291 return true; | 291 return true; |
292 } | 292 } |
293 | 293 |
294 static void free_pixels(void* pixels, void* ctx) { | 294 static void free_pixels(void* pixels, void* ctx) { |
295 sk_free(pixels); | 295 sk_free(pixels); |
(...skipping 25 matching lines...) Expand all Loading... |
321 SkAutoTUnref<GrTexture> texture(grCtx->textureProvider()->createText
ure(desc, false)); | 321 SkAutoTUnref<GrTexture> texture(grCtx->textureProvider()->createText
ure(desc, false)); |
322 return SkSurface::NewRenderTargetDirect(texture->asRenderTarget()); | 322 return SkSurface::NewRenderTargetDirect(texture->asRenderTarget()); |
323 #endif | 323 #endif |
324 } | 324 } |
325 return NULL; | 325 return NULL; |
326 } | 326 } |
327 | 327 |
328 static bool setup_bitmap(SkBitmap* bm, SkColorType ct, SkAlphaType at, int w, in
t h, int tightRB) { | 328 static bool setup_bitmap(SkBitmap* bm, SkColorType ct, SkAlphaType at, int w, in
t h, int tightRB) { |
329 size_t rowBytes = tightRB ? 0 : 4 * w + 60; | 329 size_t rowBytes = tightRB ? 0 : 4 * w + 60; |
330 SkImageInfo info = SkImageInfo::Make(w, h, ct, at); | 330 SkImageInfo info = SkImageInfo::Make(w, h, ct, at); |
331 if (!alloc_row_bytes(bm, info, rowBytes)) { | 331 if (!allocRowBytes(bm, info, rowBytes)) { |
332 return false; | 332 return false; |
333 } | 333 } |
334 SkAutoLockPixels alp(*bm); | 334 SkAutoLockPixels alp(*bm); |
335 for (int y = 0; y < h; ++y) { | 335 for (int y = 0; y < h; ++y) { |
336 for (int x = 0; x < w; ++x) { | 336 for (int x = 0; x < w; ++x) { |
337 *bm->getAddr32(x, y) = get_bitmap_color(x, y, w, ct, at); | 337 *bm->getAddr32(x, y) = getBitmapColor(x, y, w, ct, at); |
338 } | 338 } |
339 } | 339 } |
340 return true; | 340 return true; |
341 } | 341 } |
342 | 342 |
343 static void call_writepixels(SkCanvas* canvas) { | 343 static void call_writepixels(SkCanvas* canvas) { |
344 const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1); | 344 const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1); |
345 SkPMColor pixel = 0; | 345 SkPMColor pixel = 0; |
346 canvas->writePixels(info, &pixel, sizeof(SkPMColor), 0, 0); | 346 canvas->writePixels(info, &pixel, sizeof(SkPMColor), 0, 0); |
347 } | 347 } |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
444 { kBGRA_8888_SkColorType, kPremul_SkAlphaType }, | 444 { kBGRA_8888_SkColorType, kPremul_SkAlphaType }, |
445 { kBGRA_8888_SkColorType, kUnpremul_SkAlphaType }, | 445 { kBGRA_8888_SkColorType, kUnpremul_SkAlphaType }, |
446 }; | 446 }; |
447 for (size_t r = 0; r < SK_ARRAY_COUNT(testRects); ++r) { | 447 for (size_t r = 0; r < SK_ARRAY_COUNT(testRects); ++r) { |
448 const SkIRect& rect = testRects[r]; | 448 const SkIRect& rect = testRects[r]; |
449 for (int tightBmp = 0; tightBmp < 2; ++tightBmp) { | 449 for (int tightBmp = 0; tightBmp < 2; ++tightBmp) { |
450 for (size_t c = 0; c < SK_ARRAY_COUNT(gSrcConfigs); ++c) { | 450 for (size_t c = 0; c < SK_ARRAY_COUNT(gSrcConfigs); ++c) { |
451 const SkColorType ct = gSrcConfigs[c].fColorType; | 451 const SkColorType ct = gSrcConfigs[c].fColorType; |
452 const SkAlphaType at = gSrcConfigs[c].fAlphaType; | 452 const SkAlphaType at = gSrcConfigs[c].fAlphaType; |
453 | 453 |
454 fill_canvas(&canvas); | 454 fillCanvas(&canvas); |
455 SkBitmap bmp; | 455 SkBitmap bmp; |
456 REPORTER_ASSERT(reporter, setup_bitmap(&bmp, ct, at, rec
t.width(), | 456 REPORTER_ASSERT(reporter, setup_bitmap(&bmp, ct, at, rec
t.width(), |
457 rect.height(), Sk
ToBool(tightBmp))); | 457 rect.height(), Sk
ToBool(tightBmp))); |
458 uint32_t idBefore = surface->generationID(); | 458 uint32_t idBefore = surface->generationID(); |
459 | 459 |
460 // sk_tool_utils::write_pixels(&canvas, bmp, rect.fLeft,
rect.fTop, ct, at); | 460 // sk_tool_utils::write_pixels(&canvas, bmp, rect.fLeft,
rect.fTop, ct, at); |
461 canvas.writePixels(bmp, rect.fLeft, rect.fTop); | 461 canvas.writePixels(bmp, rect.fLeft, rect.fTop); |
462 | 462 |
463 uint32_t idAfter = surface->generationID(); | 463 uint32_t idAfter = surface->generationID(); |
464 REPORTER_ASSERT(reporter, check_write(reporter, &canvas,
bmp, | 464 REPORTER_ASSERT(reporter, check_write(reporter, &canvas,
bmp, |
465 rect.fLeft, rect.f
Top)); | 465 rect.fLeft, rect.f
Top)); |
466 | 466 |
467 // we should change the genID iff pixels were actually w
ritten. | 467 // we should change the genID iff pixels were actually w
ritten. |
468 SkIRect canvasRect = SkIRect::MakeSize(canvas.getDeviceS
ize()); | 468 SkIRect canvasRect = SkIRect::MakeSize(canvas.getDeviceS
ize()); |
469 SkIRect writeRect = SkIRect::MakeXYWH(rect.fLeft, rect.f
Top, | 469 SkIRect writeRect = SkIRect::MakeXYWH(rect.fLeft, rect.f
Top, |
470 bmp.width(), bmp.h
eight()); | 470 bmp.width(), bmp.h
eight()); |
471 bool intersects = SkIRect::Intersects(canvasRect, writeR
ect) ; | 471 bool intersects = SkIRect::Intersects(canvasRect, writeR
ect) ; |
472 REPORTER_ASSERT(reporter, intersects == (idBefore != idA
fter)); | 472 REPORTER_ASSERT(reporter, intersects == (idBefore != idA
fter)); |
473 } | 473 } |
474 } | 474 } |
475 } | 475 } |
476 } | 476 } |
477 } | 477 } |
478 } | 478 } |
OLD | NEW |