OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
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 "SkDraw.h" | 8 #include "SkDraw.h" |
9 #include "SkBlitter.h" | 9 #include "SkBlitter.h" |
10 #include "SkBounder.h" | 10 #include "SkBounder.h" |
11 #include "SkCanvas.h" | 11 #include "SkCanvas.h" |
12 #include "SkColorPriv.h" | 12 #include "SkColorPriv.h" |
13 #include "SkDevice.h" | 13 #include "SkDevice.h" |
14 #include "SkDeviceLooper.h" | 14 #include "SkDeviceLooper.h" |
15 #include "SkFixed.h" | 15 #include "SkFixed.h" |
16 #include "SkMaskFilter.h" | 16 #include "SkMaskFilter.h" |
17 #include "SkPaint.h" | 17 #include "SkPaint.h" |
18 #include "SkPathEffect.h" | 18 #include "SkPathEffect.h" |
19 #include "SkRasterClip.h" | 19 #include "SkRasterClip.h" |
20 #include "SkRasterizer.h" | 20 #include "SkRasterizer.h" |
21 #include "SkRRect.h" | 21 #include "SkRRect.h" |
22 #include "SkScan.h" | 22 #include "SkScan.h" |
23 #include "SkShader.h" | 23 #include "SkShader.h" |
| 24 #include "SkSmallAllocator.h" |
24 #include "SkString.h" | 25 #include "SkString.h" |
25 #include "SkStroke.h" | 26 #include "SkStroke.h" |
26 #include "SkTemplatesPriv.h" | |
27 #include "SkTLazy.h" | 27 #include "SkTLazy.h" |
28 #include "SkUtils.h" | 28 #include "SkUtils.h" |
29 | 29 |
30 #include "SkAutoKern.h" | 30 #include "SkAutoKern.h" |
31 #include "SkBitmapProcShader.h" | 31 #include "SkBitmapProcShader.h" |
32 #include "SkDrawProcs.h" | 32 #include "SkDrawProcs.h" |
33 #include "SkMatrixUtils.h" | 33 #include "SkMatrixUtils.h" |
34 | 34 |
| 35 |
35 //#define TRACE_BITMAP_DRAWS | 36 //#define TRACE_BITMAP_DRAWS |
36 | 37 |
37 #define kBlitterStorageLongCount (sizeof(SkBitmapProcShader) >> 2) | |
38 | 38 |
39 /** Helper for allocating small blitters on the stack. | 39 /** Helper for allocating small blitters on the stack. |
40 */ | 40 */ |
41 class SkAutoBlitterChoose : SkNoncopyable { | 41 class SkAutoBlitterChoose : SkNoncopyable { |
42 public: | 42 public: |
43 SkAutoBlitterChoose() { | 43 SkAutoBlitterChoose() { |
44 fBlitter = NULL; | 44 fBlitter = NULL; |
45 } | 45 } |
46 SkAutoBlitterChoose(const SkBitmap& device, const SkMatrix& matrix, | 46 SkAutoBlitterChoose(const SkBitmap& device, const SkMatrix& matrix, |
47 const SkPaint& paint, bool drawCoverage = false) { | 47 const SkPaint& paint, bool drawCoverage = false) { |
48 fBlitter = SkBlitter::Choose(device, matrix, paint, | 48 fBlitter = SkBlitter::Choose(device, matrix, paint, &fAllocator, |
49 fStorage, sizeof(fStorage), drawCoverage); | 49 drawCoverage); |
50 } | |
51 | |
52 ~SkAutoBlitterChoose() { | |
53 if ((void*)fBlitter == (void*)fStorage) { | |
54 fBlitter->~SkBlitter(); | |
55 } else { | |
56 SkDELETE(fBlitter); | |
57 } | |
58 } | 50 } |
59 | 51 |
60 SkBlitter* operator->() { return fBlitter; } | 52 SkBlitter* operator->() { return fBlitter; } |
61 SkBlitter* get() const { return fBlitter; } | 53 SkBlitter* get() const { return fBlitter; } |
62 | 54 |
63 void choose(const SkBitmap& device, const SkMatrix& matrix, | 55 void choose(const SkBitmap& device, const SkMatrix& matrix, |
64 const SkPaint& paint) { | 56 const SkPaint& paint) { |
65 SkASSERT(!fBlitter); | 57 SkASSERT(!fBlitter); |
66 fBlitter = SkBlitter::Choose(device, matrix, paint, | 58 fBlitter = SkBlitter::Choose(device, matrix, paint, &fAllocator); |
67 fStorage, sizeof(fStorage)); | |
68 } | 59 } |
69 | 60 |
70 private: | 61 private: |
71 SkBlitter* fBlitter; | 62 // Owned by fAllocator, which will handle the delete. |
72 uint32_t fStorage[kBlitterStorageLongCount]; | 63 SkBlitter* fBlitter; |
| 64 SkTBlitterAllocator fAllocator; |
73 }; | 65 }; |
74 #define SkAutoBlitterChoose(...) SK_REQUIRE_LOCAL_VAR(SkAutoBlitterChoose) | 66 #define SkAutoBlitterChoose(...) SK_REQUIRE_LOCAL_VAR(SkAutoBlitterChoose) |
75 | 67 |
76 /** | 68 /** |
77 * Since we are providing the storage for the shader (to avoid the perf cost | 69 * Since we are providing the storage for the shader (to avoid the perf cost |
78 * of calling new) we insist that in our destructor we can account for all | 70 * of calling new) we insist that in our destructor we can account for all |
79 * owners of the shader. | 71 * owners of the shader. |
80 */ | 72 */ |
81 class SkAutoBitmapShaderInstall : SkNoncopyable { | 73 class SkAutoBitmapShaderInstall : SkNoncopyable { |
82 public: | 74 public: |
83 SkAutoBitmapShaderInstall(const SkBitmap& src, const SkPaint& paint) | 75 SkAutoBitmapShaderInstall(const SkBitmap& src, const SkPaint& paint) |
84 : fPaint(paint) /* makes a copy of the paint */ { | 76 : fPaint(paint) /* makes a copy of the paint */ { |
85 fPaint.setShader(SkShader::CreateBitmapShader(src, | 77 fPaint.setShader(CreateBitmapShader(src, SkShader::kClamp_TileMode, |
86 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, | 78 SkShader::kClamp_TileMode, |
87 fStorage, sizeof(fStorage))); | 79 &fAllocator)); |
88 // we deliberately left the shader with an owner-count of 2 | 80 // we deliberately left the shader with an owner-count of 2 |
89 SkASSERT(2 == fPaint.getShader()->getRefCnt()); | 81 SkASSERT(2 == fPaint.getShader()->getRefCnt()); |
90 } | 82 } |
91 | 83 |
92 ~SkAutoBitmapShaderInstall() { | 84 ~SkAutoBitmapShaderInstall() { |
93 SkShader* shader = fPaint.getShader(); | 85 // since fAllocator will destroy shader, we insist that owners == 2 |
94 // since we manually destroy shader, we insist that owners == 2 | 86 SkASSERT(2 == fPaint.getShader()->getRefCnt()); |
95 SkASSERT(2 == shader->getRefCnt()); | |
96 | 87 |
97 fPaint.setShader(NULL); // unref the shader by 1 | 88 fPaint.setShader(NULL); // unref the shader by 1 |
98 | 89 |
99 // now destroy to take care of the 2nd owner-count | |
100 if ((void*)shader == (void*)fStorage) { | |
101 shader->~SkShader(); | |
102 } else { | |
103 SkDELETE(shader); | |
104 } | |
105 } | 90 } |
106 | 91 |
107 // return the new paint that has the shader applied | 92 // return the new paint that has the shader applied |
108 const SkPaint& paintWithShader() const { return fPaint; } | 93 const SkPaint& paintWithShader() const { return fPaint; } |
109 | 94 |
110 private: | 95 private: |
111 SkPaint fPaint; // copy of caller's paint (which we then modify) | 96 // copy of caller's paint (which we then modify) |
112 uint32_t fStorage[kBlitterStorageLongCount]; | 97 SkPaint fPaint; |
| 98 // Stores the shader. |
| 99 SkTBlitterAllocator fAllocator; |
113 }; | 100 }; |
114 #define SkAutoBitmapShaderInstall(...) SK_REQUIRE_LOCAL_VAR(SkAutoBitmapShaderIn
stall) | 101 #define SkAutoBitmapShaderInstall(...) SK_REQUIRE_LOCAL_VAR(SkAutoBitmapShaderIn
stall) |
115 | 102 |
116 /////////////////////////////////////////////////////////////////////////////// | 103 /////////////////////////////////////////////////////////////////////////////// |
117 | 104 |
118 SkDraw::SkDraw() { | 105 SkDraw::SkDraw() { |
119 sk_bzero(this, sizeof(*this)); | 106 sk_bzero(this, sizeof(*this)); |
120 } | 107 } |
121 | 108 |
122 SkDraw::SkDraw(const SkDraw& src) { | 109 SkDraw::SkDraw(const SkDraw& src) { |
(...skipping 1193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1316 // It is safe to call lock pixels now, since we know the matrix is | 1303 // It is safe to call lock pixels now, since we know the matrix is |
1317 // (more or less) identity. | 1304 // (more or less) identity. |
1318 // | 1305 // |
1319 SkAutoLockPixels alp(bitmap); | 1306 SkAutoLockPixels alp(bitmap); |
1320 if (!bitmap.readyToDraw()) { | 1307 if (!bitmap.readyToDraw()) { |
1321 return; | 1308 return; |
1322 } | 1309 } |
1323 int ix = SkScalarRoundToInt(matrix.getTranslateX()); | 1310 int ix = SkScalarRoundToInt(matrix.getTranslateX()); |
1324 int iy = SkScalarRoundToInt(matrix.getTranslateY()); | 1311 int iy = SkScalarRoundToInt(matrix.getTranslateY()); |
1325 if (clipHandlesSprite(*fRC, ix, iy, bitmap)) { | 1312 if (clipHandlesSprite(*fRC, ix, iy, bitmap)) { |
1326 uint32_t storage[kBlitterStorageLongCount]; | 1313 SkTBlitterAllocator allocator; |
1327 SkBlitter* blitter = SkBlitter::ChooseSprite(*fBitmap, paint, bitma
p, | 1314 // blitter will be owned by the allocator. |
1328 ix, iy, storage, sizeof(storage)
); | 1315 SkBlitter* blitter = SkBlitter::ChooseSprite(*fBitmap, paint, bitmap
, |
| 1316 ix, iy, &allocator); |
1329 if (blitter) { | 1317 if (blitter) { |
1330 SkAutoTPlacementDelete<SkBlitter> ad(blitter, storage); | |
1331 | |
1332 SkIRect ir; | 1318 SkIRect ir; |
1333 ir.set(ix, iy, ix + bitmap.width(), iy + bitmap.height()); | 1319 ir.set(ix, iy, ix + bitmap.width(), iy + bitmap.height()); |
1334 | 1320 |
1335 SkScan::FillIRect(ir, *fRC, blitter); | 1321 SkScan::FillIRect(ir, *fRC, blitter); |
1336 return; | 1322 return; |
1337 } | 1323 } |
1338 } | 1324 } |
1339 } | 1325 } |
1340 | 1326 |
1341 // now make a temp draw on the stack, and use it | 1327 // now make a temp draw on the stack, and use it |
(...skipping 29 matching lines...) Expand all Loading... |
1371 bounds.set(x, y, x + bitmap.width(), y + bitmap.height()); | 1357 bounds.set(x, y, x + bitmap.width(), y + bitmap.height()); |
1372 | 1358 |
1373 if (fRC->quickReject(bounds)) { | 1359 if (fRC->quickReject(bounds)) { |
1374 return; // nothing to draw | 1360 return; // nothing to draw |
1375 } | 1361 } |
1376 | 1362 |
1377 SkPaint paint(origPaint); | 1363 SkPaint paint(origPaint); |
1378 paint.setStyle(SkPaint::kFill_Style); | 1364 paint.setStyle(SkPaint::kFill_Style); |
1379 | 1365 |
1380 if (NULL == paint.getColorFilter() && clipHandlesSprite(*fRC, x, y, bitmap))
{ | 1366 if (NULL == paint.getColorFilter() && clipHandlesSprite(*fRC, x, y, bitmap))
{ |
1381 uint32_t storage[kBlitterStorageLongCount]; | 1367 SkTBlitterAllocator allocator; |
1382 SkBlitter* blitter = SkBlitter::ChooseSprite(*fBitmap, paint, bitmap, | 1368 // blitter will be owned by the allocator. |
1383 x, y, storage, sizeof(storage)); | 1369 SkBlitter* blitter = SkBlitter::ChooseSprite(*fBitmap, paint, bitmap, |
| 1370 x, y, &allocator); |
1384 | 1371 |
1385 if (blitter) { | 1372 if (blitter) { |
1386 SkAutoTPlacementDelete<SkBlitter> ad(blitter, storage); | |
1387 | |
1388 if (fBounder && !fBounder->doIRect(bounds)) { | 1373 if (fBounder && !fBounder->doIRect(bounds)) { |
1389 return; | 1374 return; |
1390 } | 1375 } |
1391 | 1376 |
1392 SkScan::FillIRect(bounds, *fRC, blitter); | 1377 SkScan::FillIRect(bounds, *fRC, blitter); |
1393 return; | 1378 return; |
1394 } | 1379 } |
1395 } | 1380 } |
1396 | 1381 |
1397 SkAutoBitmapShaderInstall install(bitmap, paint); | 1382 SkAutoBitmapShaderInstall install(bitmap, paint); |
(...skipping 1422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2820 mask->fImage = SkMask::AllocImage(size); | 2805 mask->fImage = SkMask::AllocImage(size); |
2821 memset(mask->fImage, 0, mask->computeImageSize()); | 2806 memset(mask->fImage, 0, mask->computeImageSize()); |
2822 } | 2807 } |
2823 | 2808 |
2824 if (SkMask::kJustComputeBounds_CreateMode != mode) { | 2809 if (SkMask::kJustComputeBounds_CreateMode != mode) { |
2825 draw_into_mask(*mask, devPath, style); | 2810 draw_into_mask(*mask, devPath, style); |
2826 } | 2811 } |
2827 | 2812 |
2828 return true; | 2813 return true; |
2829 } | 2814 } |
OLD | NEW |