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 #define __STDC_LIMIT_MACROS | 7 #define __STDC_LIMIT_MACROS |
8 | 8 |
9 #include "SkDraw.h" | 9 #include "SkDraw.h" |
10 #include "SkBlitter.h" | 10 #include "SkBlitter.h" |
(...skipping 26 matching lines...) Expand all Loading... |
37 //#define TRACE_BITMAP_DRAWS | 37 //#define TRACE_BITMAP_DRAWS |
38 | 38 |
39 | 39 |
40 /** Helper for allocating small blitters on the stack. | 40 /** Helper for allocating small blitters on the stack. |
41 */ | 41 */ |
42 class SkAutoBlitterChoose : SkNoncopyable { | 42 class SkAutoBlitterChoose : SkNoncopyable { |
43 public: | 43 public: |
44 SkAutoBlitterChoose() { | 44 SkAutoBlitterChoose() { |
45 fBlitter = NULL; | 45 fBlitter = NULL; |
46 } | 46 } |
47 SkAutoBlitterChoose(const SkPixmap& dst, const SkMatrix& matrix, | 47 SkAutoBlitterChoose(const SkBitmap& device, const SkMatrix& matrix, |
48 const SkPaint& paint, bool drawCoverage = false) { | 48 const SkPaint& paint, bool drawCoverage = false) { |
49 fBlitter = SkBlitter::Choose(dst, matrix, paint, &fAllocator, drawCovera
ge); | 49 fBlitter = SkBlitter::Choose(device, matrix, paint, &fAllocator, |
| 50 drawCoverage); |
50 } | 51 } |
51 | 52 |
52 SkBlitter* operator->() { return fBlitter; } | 53 SkBlitter* operator->() { return fBlitter; } |
53 SkBlitter* get() const { return fBlitter; } | 54 SkBlitter* get() const { return fBlitter; } |
54 | 55 |
55 void choose(const SkPixmap& dst, const SkMatrix& matrix, | 56 void choose(const SkBitmap& device, const SkMatrix& matrix, |
56 const SkPaint& paint, bool drawCoverage = false) { | 57 const SkPaint& paint, bool drawCoverage = false) { |
57 SkASSERT(!fBlitter); | 58 SkASSERT(!fBlitter); |
58 fBlitter = SkBlitter::Choose(dst, matrix, paint, &fAllocator, drawCovera
ge); | 59 fBlitter = SkBlitter::Choose(device, matrix, paint, &fAllocator, |
| 60 drawCoverage); |
59 } | 61 } |
60 | 62 |
61 private: | 63 private: |
62 // Owned by fAllocator, which will handle the delete. | 64 // Owned by fAllocator, which will handle the delete. |
63 SkBlitter* fBlitter; | 65 SkBlitter* fBlitter; |
64 SkTBlitterAllocator fAllocator; | 66 SkTBlitterAllocator fAllocator; |
65 }; | 67 }; |
66 #define SkAutoBlitterChoose(...) SK_REQUIRE_LOCAL_VAR(SkAutoBlitterChoose) | 68 #define SkAutoBlitterChoose(...) SK_REQUIRE_LOCAL_VAR(SkAutoBlitterChoose) |
67 | 69 |
68 /** | 70 /** |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 } | 145 } |
144 | 146 |
145 static void D16_Src_BitmapXferProc(void* pixels, size_t bytes, uint32_t data) { | 147 static void D16_Src_BitmapXferProc(void* pixels, size_t bytes, uint32_t data) { |
146 sk_memset16((uint16_t*)pixels, data, SkToInt(bytes >> 1)); | 148 sk_memset16((uint16_t*)pixels, data, SkToInt(bytes >> 1)); |
147 } | 149 } |
148 | 150 |
149 static void DA8_Src_BitmapXferProc(void* pixels, size_t bytes, uint32_t data) { | 151 static void DA8_Src_BitmapXferProc(void* pixels, size_t bytes, uint32_t data) { |
150 memset(pixels, data, bytes); | 152 memset(pixels, data, bytes); |
151 } | 153 } |
152 | 154 |
153 static BitmapXferProc ChooseBitmapXferProc(const SkPixmap& dst, const SkPaint& p
aint, | 155 static BitmapXferProc ChooseBitmapXferProc(const SkBitmap& bitmap, |
| 156 const SkPaint& paint, |
154 uint32_t* data) { | 157 uint32_t* data) { |
155 // todo: we can apply colorfilter up front if no shader, so we wouldn't | 158 // todo: we can apply colorfilter up front if no shader, so we wouldn't |
156 // need to abort this fastpath | 159 // need to abort this fastpath |
157 if (paint.getShader() || paint.getColorFilter()) { | 160 if (paint.getShader() || paint.getColorFilter()) { |
158 return NULL; | 161 return NULL; |
159 } | 162 } |
160 | 163 |
161 SkXfermode::Mode mode; | 164 SkXfermode::Mode mode; |
162 if (!SkXfermode::AsMode(paint.getXfermode(), &mode)) { | 165 if (!SkXfermode::AsMode(paint.getXfermode(), &mode)) { |
163 return NULL; | 166 return NULL; |
(...skipping 16 matching lines...) Expand all Loading... |
180 // SkDebugf("--- D_Clear_BitmapXferProc\n"); | 183 // SkDebugf("--- D_Clear_BitmapXferProc\n"); |
181 return D_Clear_BitmapXferProc; // ignore data | 184 return D_Clear_BitmapXferProc; // ignore data |
182 case SkXfermode::kDst_Mode: | 185 case SkXfermode::kDst_Mode: |
183 // SkDebugf("--- D_Dst_BitmapXferProc\n"); | 186 // SkDebugf("--- D_Dst_BitmapXferProc\n"); |
184 return D_Dst_BitmapXferProc; // ignore data | 187 return D_Dst_BitmapXferProc; // ignore data |
185 case SkXfermode::kSrc_Mode: { | 188 case SkXfermode::kSrc_Mode: { |
186 /* | 189 /* |
187 should I worry about dithering for the lower depths? | 190 should I worry about dithering for the lower depths? |
188 */ | 191 */ |
189 SkPMColor pmc = SkPreMultiplyColor(color); | 192 SkPMColor pmc = SkPreMultiplyColor(color); |
190 switch (dst.colorType()) { | 193 switch (bitmap.colorType()) { |
191 case kN32_SkColorType: | 194 case kN32_SkColorType: |
192 if (data) { | 195 if (data) { |
193 *data = pmc; | 196 *data = pmc; |
194 } | 197 } |
195 // SkDebugf("--- D32_Src_BitmapXferProc\n"); | 198 // SkDebugf("--- D32_Src_BitmapXferProc\n"); |
196 return D32_Src_BitmapXferProc; | 199 return D32_Src_BitmapXferProc; |
197 case kRGB_565_SkColorType: | 200 case kRGB_565_SkColorType: |
198 if (data) { | 201 if (data) { |
199 *data = SkPixel32ToPixel16(pmc); | 202 *data = SkPixel32ToPixel16(pmc); |
200 } | 203 } |
201 // SkDebugf("--- D16_Src_BitmapXferProc\n"); | 204 // SkDebugf("--- D16_Src_BitmapXferProc\n"); |
202 return D16_Src_BitmapXferProc; | 205 return D16_Src_BitmapXferProc; |
203 case kAlpha_8_SkColorType: | 206 case kAlpha_8_SkColorType: |
204 if (data) { | 207 if (data) { |
205 *data = SkGetPackedA32(pmc); | 208 *data = SkGetPackedA32(pmc); |
206 } | 209 } |
207 // SkDebugf("--- DA8_Src_BitmapXferProc\n"); | 210 // SkDebugf("--- DA8_Src_BitmapXferProc\n"); |
208 return DA8_Src_BitmapXferProc; | 211 return DA8_Src_BitmapXferProc; |
209 default: | 212 default: |
210 break; | 213 break; |
211 } | 214 } |
212 break; | 215 break; |
213 } | 216 } |
214 default: | 217 default: |
215 break; | 218 break; |
216 } | 219 } |
217 return NULL; | 220 return NULL; |
218 } | 221 } |
219 | 222 |
220 static void CallBitmapXferProc(const SkPixmap& dst, const SkIRect& rect, BitmapX
ferProc proc, | 223 static void CallBitmapXferProc(const SkBitmap& bitmap, const SkIRect& rect, |
221 uint32_t procData) { | 224 BitmapXferProc proc, uint32_t procData) { |
222 int shiftPerPixel; | 225 int shiftPerPixel; |
223 switch (dst.colorType()) { | 226 switch (bitmap.colorType()) { |
224 case kN32_SkColorType: | 227 case kN32_SkColorType: |
225 shiftPerPixel = 2; | 228 shiftPerPixel = 2; |
226 break; | 229 break; |
227 case kRGB_565_SkColorType: | 230 case kRGB_565_SkColorType: |
228 shiftPerPixel = 1; | 231 shiftPerPixel = 1; |
229 break; | 232 break; |
230 case kAlpha_8_SkColorType: | 233 case kAlpha_8_SkColorType: |
231 shiftPerPixel = 0; | 234 shiftPerPixel = 0; |
232 break; | 235 break; |
233 default: | 236 default: |
234 SkDEBUGFAIL("Can't use xferproc on this config"); | 237 SkDEBUGFAIL("Can't use xferproc on this config"); |
235 return; | 238 return; |
236 } | 239 } |
237 | 240 |
238 uint8_t* pixels = (uint8_t*)dst.writable_addr(); | 241 uint8_t* pixels = (uint8_t*)bitmap.getPixels(); |
239 SkASSERT(pixels); | 242 SkASSERT(pixels); |
240 const size_t rowBytes = dst.rowBytes(); | 243 const size_t rowBytes = bitmap.rowBytes(); |
241 const int widthBytes = rect.width() << shiftPerPixel; | 244 const int widthBytes = rect.width() << shiftPerPixel; |
242 | 245 |
243 // skip down to the first scanline and X position | 246 // skip down to the first scanline and X position |
244 pixels += rect.fTop * rowBytes + (rect.fLeft << shiftPerPixel); | 247 pixels += rect.fTop * rowBytes + (rect.fLeft << shiftPerPixel); |
245 for (int scans = rect.height() - 1; scans >= 0; --scans) { | 248 for (int scans = rect.height() - 1; scans >= 0; --scans) { |
246 proc(pixels, widthBytes, procData); | 249 proc(pixels, widthBytes, procData); |
247 pixels += rowBytes; | 250 pixels += rowBytes; |
248 } | 251 } |
249 } | 252 } |
250 | 253 |
251 void SkDraw::drawPaint(const SkPaint& paint) const { | 254 void SkDraw::drawPaint(const SkPaint& paint) const { |
252 SkDEBUGCODE(this->validate();) | 255 SkDEBUGCODE(this->validate();) |
253 | 256 |
254 if (fRC->isEmpty()) { | 257 if (fRC->isEmpty()) { |
255 return; | 258 return; |
256 } | 259 } |
257 | 260 |
258 SkIRect devRect; | 261 SkIRect devRect; |
259 devRect.set(0, 0, fDst.width(), fDst.height()); | 262 devRect.set(0, 0, fBitmap->width(), fBitmap->height()); |
260 | 263 |
261 if (fRC->isBW()) { | 264 if (fRC->isBW()) { |
262 /* If we don't have a shader (i.e. we're just a solid color) we may | 265 /* If we don't have a shader (i.e. we're just a solid color) we may |
263 be faster to operate directly on the device bitmap, rather than invo
king | 266 be faster to operate directly on the device bitmap, rather than invo
king |
264 a blitter. Esp. true for xfermodes, which require a colorshader to b
e | 267 a blitter. Esp. true for xfermodes, which require a colorshader to b
e |
265 present, which is just redundant work. Since we're drawing everywher
e | 268 present, which is just redundant work. Since we're drawing everywher
e |
266 in the clip, we don't have to worry about antialiasing. | 269 in the clip, we don't have to worry about antialiasing. |
267 */ | 270 */ |
268 uint32_t procData = 0; // to avoid the warning | 271 uint32_t procData = 0; // to avoid the warning |
269 BitmapXferProc proc = ChooseBitmapXferProc(fDst, paint, &procData); | 272 BitmapXferProc proc = ChooseBitmapXferProc(*fBitmap, paint, &procData); |
270 if (proc) { | 273 if (proc) { |
271 if (D_Dst_BitmapXferProc == proc) { // nothing to do | 274 if (D_Dst_BitmapXferProc == proc) { // nothing to do |
272 return; | 275 return; |
273 } | 276 } |
274 | 277 |
275 SkRegion::Iterator iter(fRC->bwRgn()); | 278 SkRegion::Iterator iter(fRC->bwRgn()); |
276 while (!iter.done()) { | 279 while (!iter.done()) { |
277 CallBitmapXferProc(fDst, iter.rect(), proc, procData); | 280 CallBitmapXferProc(*fBitmap, iter.rect(), proc, procData); |
278 iter.next(); | 281 iter.next(); |
279 } | 282 } |
280 return; | 283 return; |
281 } | 284 } |
282 } | 285 } |
283 | 286 |
284 // normal case: use a blitter | 287 // normal case: use a blitter |
285 SkAutoBlitterChoose blitter(fDst, *fMatrix, paint); | 288 SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, paint); |
286 SkScan::FillIRect(devRect, *fRC, blitter.get()); | 289 SkScan::FillIRect(devRect, *fRC, blitter.get()); |
287 } | 290 } |
288 | 291 |
289 /////////////////////////////////////////////////////////////////////////////// | 292 /////////////////////////////////////////////////////////////////////////////// |
290 | 293 |
291 struct PtProcRec { | 294 struct PtProcRec { |
292 SkCanvas::PointMode fMode; | 295 SkCanvas::PointMode fMode; |
293 const SkPaint* fPaint; | 296 const SkPaint* fPaint; |
294 const SkRegion* fClip; | 297 const SkRegion* fClip; |
295 const SkRasterClip* fRC; | 298 const SkRasterClip* fRC; |
(...skipping 25 matching lines...) Expand all Loading... |
321 } | 324 } |
322 } | 325 } |
323 } | 326 } |
324 | 327 |
325 static void bw_pt_rect_16_hair_proc(const PtProcRec& rec, | 328 static void bw_pt_rect_16_hair_proc(const PtProcRec& rec, |
326 const SkPoint devPts[], int count, | 329 const SkPoint devPts[], int count, |
327 SkBlitter* blitter) { | 330 SkBlitter* blitter) { |
328 SkASSERT(rec.fRC->isRect()); | 331 SkASSERT(rec.fRC->isRect()); |
329 const SkIRect& r = rec.fRC->getBounds(); | 332 const SkIRect& r = rec.fRC->getBounds(); |
330 uint32_t value; | 333 uint32_t value; |
331 const SkPixmap* dst = blitter->justAnOpaqueColor(&value); | 334 const SkBitmap* bitmap = blitter->justAnOpaqueColor(&value); |
332 SkASSERT(dst); | 335 SkASSERT(bitmap); |
333 | 336 |
334 uint16_t* addr = dst->writable_addr16(0, 0); | 337 uint16_t* addr = bitmap->getAddr16(0, 0); |
335 size_t rb = dst->rowBytes(); | 338 size_t rb = bitmap->rowBytes(); |
336 | 339 |
337 for (int i = 0; i < count; i++) { | 340 for (int i = 0; i < count; i++) { |
338 int x = SkScalarFloorToInt(devPts[i].fX); | 341 int x = SkScalarFloorToInt(devPts[i].fX); |
339 int y = SkScalarFloorToInt(devPts[i].fY); | 342 int y = SkScalarFloorToInt(devPts[i].fY); |
340 if (r.contains(x, y)) { | 343 if (r.contains(x, y)) { |
341 ((uint16_t*)((char*)addr + y * rb))[x] = SkToU16(value); | 344 ((uint16_t*)((char*)addr + y * rb))[x] = SkToU16(value); |
342 } | 345 } |
343 } | 346 } |
344 } | 347 } |
345 | 348 |
346 static void bw_pt_rect_32_hair_proc(const PtProcRec& rec, | 349 static void bw_pt_rect_32_hair_proc(const PtProcRec& rec, |
347 const SkPoint devPts[], int count, | 350 const SkPoint devPts[], int count, |
348 SkBlitter* blitter) { | 351 SkBlitter* blitter) { |
349 SkASSERT(rec.fRC->isRect()); | 352 SkASSERT(rec.fRC->isRect()); |
350 const SkIRect& r = rec.fRC->getBounds(); | 353 const SkIRect& r = rec.fRC->getBounds(); |
351 uint32_t value; | 354 uint32_t value; |
352 const SkPixmap* dst = blitter->justAnOpaqueColor(&value); | 355 const SkBitmap* bitmap = blitter->justAnOpaqueColor(&value); |
353 SkASSERT(dst); | 356 SkASSERT(bitmap); |
354 | 357 |
355 SkPMColor* addr = dst->writable_addr32(0, 0); | 358 SkPMColor* addr = bitmap->getAddr32(0, 0); |
356 size_t rb = dst->rowBytes(); | 359 size_t rb = bitmap->rowBytes(); |
357 | 360 |
358 for (int i = 0; i < count; i++) { | 361 for (int i = 0; i < count; i++) { |
359 int x = SkScalarFloorToInt(devPts[i].fX); | 362 int x = SkScalarFloorToInt(devPts[i].fX); |
360 int y = SkScalarFloorToInt(devPts[i].fY); | 363 int y = SkScalarFloorToInt(devPts[i].fY); |
361 if (r.contains(x, y)) { | 364 if (r.contains(x, y)) { |
362 ((SkPMColor*)((char*)addr + y * rb))[x] = value; | 365 ((SkPMColor*)((char*)addr + y * rb))[x] = value; |
363 } | 366 } |
364 } | 367 } |
365 } | 368 } |
366 | 369 |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 }; | 505 }; |
503 proc = gAAProcs[fMode]; | 506 proc = gAAProcs[fMode]; |
504 } else if (fPaint->getStrokeCap() != SkPaint::kRound_Cap) { | 507 } else if (fPaint->getStrokeCap() != SkPaint::kRound_Cap) { |
505 SkASSERT(SkCanvas::kPoints_PointMode == fMode); | 508 SkASSERT(SkCanvas::kPoints_PointMode == fMode); |
506 proc = aa_square_proc; | 509 proc = aa_square_proc; |
507 } | 510 } |
508 } else { // BW | 511 } else { // BW |
509 if (fRadius <= SK_FixedHalf) { // small radii and hairline | 512 if (fRadius <= SK_FixedHalf) { // small radii and hairline |
510 if (SkCanvas::kPoints_PointMode == fMode && fClip->isRect()) { | 513 if (SkCanvas::kPoints_PointMode == fMode && fClip->isRect()) { |
511 uint32_t value; | 514 uint32_t value; |
512 const SkPixmap* bm = blitter->justAnOpaqueColor(&value); | 515 const SkBitmap* bm = blitter->justAnOpaqueColor(&value); |
513 if (bm && kRGB_565_SkColorType == bm->colorType()) { | 516 if (bm && kRGB_565_SkColorType == bm->colorType()) { |
514 proc = bw_pt_rect_16_hair_proc; | 517 proc = bw_pt_rect_16_hair_proc; |
515 } else if (bm && kN32_SkColorType == bm->colorType()) { | 518 } else if (bm && kN32_SkColorType == bm->colorType()) { |
516 proc = bw_pt_rect_32_hair_proc; | 519 proc = bw_pt_rect_32_hair_proc; |
517 } else { | 520 } else { |
518 proc = bw_pt_rect_hair_proc; | 521 proc = bw_pt_rect_hair_proc; |
519 } | 522 } |
520 } else { | 523 } else { |
521 static Proc gBWProcs[] = { | 524 static Proc gBWProcs[] = { |
522 bw_pt_hair_proc, bw_line_hair_proc, bw_poly_hair_proc | 525 bw_pt_hair_proc, bw_line_hair_proc, bw_poly_hair_proc |
(...skipping 26 matching lines...) Expand all Loading... |
549 SkASSERT(pts != NULL); | 552 SkASSERT(pts != NULL); |
550 SkDEBUGCODE(this->validate();) | 553 SkDEBUGCODE(this->validate();) |
551 | 554 |
552 // nothing to draw | 555 // nothing to draw |
553 if (fRC->isEmpty()) { | 556 if (fRC->isEmpty()) { |
554 return; | 557 return; |
555 } | 558 } |
556 | 559 |
557 PtProcRec rec; | 560 PtProcRec rec; |
558 if (!forceUseDevice && rec.init(mode, paint, fMatrix, fRC)) { | 561 if (!forceUseDevice && rec.init(mode, paint, fMatrix, fRC)) { |
559 SkAutoBlitterChoose blitter(fDst, *fMatrix, paint); | 562 SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, paint); |
560 | 563 |
561 SkPoint devPts[MAX_DEV_PTS]; | 564 SkPoint devPts[MAX_DEV_PTS]; |
562 const SkMatrix* matrix = fMatrix; | 565 const SkMatrix* matrix = fMatrix; |
563 SkBlitter* bltr = blitter.get(); | 566 SkBlitter* bltr = blitter.get(); |
564 PtProcRec::Proc proc = rec.chooseProc(&bltr); | 567 PtProcRec::Proc proc = rec.chooseProc(&bltr); |
565 // we have to back up subsequent passes if we're in polygon mode | 568 // we have to back up subsequent passes if we're in polygon mode |
566 const size_t backup = (SkCanvas::kPolygon_PointMode == mode); | 569 const size_t backup = (SkCanvas::kPolygon_PointMode == mode); |
567 | 570 |
568 do { | 571 do { |
569 int n = SkToInt(count); | 572 int n = SkToInt(count); |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
843 : compute_stroke_size(paint, *fMatrix); | 846 : compute_stroke_size(paint, *fMatrix); |
844 bbox.outset(SkScalarHalf(ssize.x()), SkScalarHalf(ssize.y())); | 847 bbox.outset(SkScalarHalf(ssize.x()), SkScalarHalf(ssize.y())); |
845 } | 848 } |
846 } | 849 } |
847 | 850 |
848 SkIRect ir = bbox.roundOut(); | 851 SkIRect ir = bbox.roundOut(); |
849 if (fRC->quickReject(ir)) { | 852 if (fRC->quickReject(ir)) { |
850 return; | 853 return; |
851 } | 854 } |
852 | 855 |
853 SkDeviceLooper looper(fDst, *fRC, ir, paint.isAntiAlias()); | 856 SkDeviceLooper looper(*fBitmap, *fRC, ir, paint.isAntiAlias()); |
854 while (looper.next()) { | 857 while (looper.next()) { |
855 SkRect localDevRect; | 858 SkRect localDevRect; |
856 looper.mapRect(&localDevRect, devRect); | 859 looper.mapRect(&localDevRect, devRect); |
857 SkMatrix localMatrix; | 860 SkMatrix localMatrix; |
858 looper.mapMatrix(&localMatrix, *matrix); | 861 looper.mapMatrix(&localMatrix, *matrix); |
859 | 862 |
860 SkAutoBlitterChoose blitterStorage(looper.getPixmap(), localMatrix, pain
t); | 863 SkAutoBlitterChoose blitterStorage(looper.getBitmap(), localMatrix, pain
t); |
861 const SkRasterClip& clip = looper.getRC(); | 864 const SkRasterClip& clip = looper.getRC(); |
862 SkBlitter* blitter = blitterStorage.get(); | 865 SkBlitter* blitter = blitterStorage.get(); |
863 | 866 |
864 // we want to "fill" if we are kFill or kStrokeAndFill, since in the lat
ter | 867 // we want to "fill" if we are kFill or kStrokeAndFill, since in the lat
ter |
865 // case we are also hairline (if we've gotten to here), which devolves t
o | 868 // case we are also hairline (if we've gotten to here), which devolves t
o |
866 // effectively just kFill | 869 // effectively just kFill |
867 switch (rtype) { | 870 switch (rtype) { |
868 case kFill_RectType: | 871 case kFill_RectType: |
869 if (paint.isAntiAlias()) { | 872 if (paint.isAntiAlias()) { |
870 SkScan::AntiFillRect(localDevRect, clip, blitter); | 873 SkScan::AntiFillRect(localDevRect, clip, blitter); |
(...skipping 30 matching lines...) Expand all Loading... |
901 | 904 |
902 SkMask dstM; | 905 SkMask dstM; |
903 if (paint.getMaskFilter() && | 906 if (paint.getMaskFilter() && |
904 paint.getMaskFilter()->filterMask(&dstM, srcM, *fMatrix, NULL)) { | 907 paint.getMaskFilter()->filterMask(&dstM, srcM, *fMatrix, NULL)) { |
905 mask = &dstM; | 908 mask = &dstM; |
906 } else { | 909 } else { |
907 dstM.fImage = NULL; | 910 dstM.fImage = NULL; |
908 } | 911 } |
909 SkAutoMaskFreeImage ami(dstM.fImage); | 912 SkAutoMaskFreeImage ami(dstM.fImage); |
910 | 913 |
911 SkAutoBlitterChoose blitterChooser(fDst, *fMatrix, paint); | 914 SkAutoBlitterChoose blitterChooser(*fBitmap, *fMatrix, paint); |
912 SkBlitter* blitter = blitterChooser.get(); | 915 SkBlitter* blitter = blitterChooser.get(); |
913 | 916 |
914 SkAAClipBlitterWrapper wrapper; | 917 SkAAClipBlitterWrapper wrapper; |
915 const SkRegion* clipRgn; | 918 const SkRegion* clipRgn; |
916 | 919 |
917 if (fRC->isBW()) { | 920 if (fRC->isBW()) { |
918 clipRgn = &fRC->bwRgn(); | 921 clipRgn = &fRC->bwRgn(); |
919 } else { | 922 } else { |
920 wrapper.init(*fRC, blitter); | 923 wrapper.init(*fRC, blitter); |
921 clipRgn = &wrapper.getRgn(); | 924 clipRgn = &wrapper.getRgn(); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
979 | 982 |
980 if (paint.getRasterizer()) { | 983 if (paint.getRasterizer()) { |
981 goto DRAW_PATH; | 984 goto DRAW_PATH; |
982 } | 985 } |
983 } | 986 } |
984 | 987 |
985 if (paint.getMaskFilter()) { | 988 if (paint.getMaskFilter()) { |
986 // Transform the rrect into device space. | 989 // Transform the rrect into device space. |
987 SkRRect devRRect; | 990 SkRRect devRRect; |
988 if (rrect.transform(*fMatrix, &devRRect)) { | 991 if (rrect.transform(*fMatrix, &devRRect)) { |
989 SkAutoBlitterChoose blitter(fDst, *fMatrix, paint); | 992 SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, paint); |
990 if (paint.getMaskFilter()->filterRRect(devRRect, *fMatrix, *fRC, bli
tter.get(), | 993 if (paint.getMaskFilter()->filterRRect(devRRect, *fMatrix, *fRC, bli
tter.get(), |
991 SkPaint::kFill_Style)) { | 994 SkPaint::kFill_Style)) { |
992 return; // filterRRect() called the blitter, so we're done | 995 return; // filterRRect() called the blitter, so we're done |
993 } | 996 } |
994 } | 997 } |
995 } | 998 } |
996 | 999 |
997 DRAW_PATH: | 1000 DRAW_PATH: |
998 // Now fall back to the default case of using a path. | 1001 // Now fall back to the default case of using a path. |
999 SkPath path; | 1002 SkPath path; |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1098 | 1101 |
1099 // avoid possibly allocating a new path in transform if we can | 1102 // avoid possibly allocating a new path in transform if we can |
1100 SkPath* devPathPtr = pathIsMutable ? pathPtr : &tmpPath; | 1103 SkPath* devPathPtr = pathIsMutable ? pathPtr : &tmpPath; |
1101 | 1104 |
1102 // transform the path into device space | 1105 // transform the path into device space |
1103 pathPtr->transform(*matrix, devPathPtr); | 1106 pathPtr->transform(*matrix, devPathPtr); |
1104 | 1107 |
1105 SkBlitter* blitter = NULL; | 1108 SkBlitter* blitter = NULL; |
1106 SkAutoBlitterChoose blitterStorage; | 1109 SkAutoBlitterChoose blitterStorage; |
1107 if (NULL == customBlitter) { | 1110 if (NULL == customBlitter) { |
1108 blitterStorage.choose(fDst, *fMatrix, *paint, drawCoverage); | 1111 blitterStorage.choose(*fBitmap, *fMatrix, *paint, drawCoverage); |
1109 blitter = blitterStorage.get(); | 1112 blitter = blitterStorage.get(); |
1110 } else { | 1113 } else { |
1111 blitter = customBlitter; | 1114 blitter = customBlitter; |
1112 } | 1115 } |
1113 | 1116 |
1114 if (paint->getMaskFilter()) { | 1117 if (paint->getMaskFilter()) { |
1115 SkPaint::Style style = doFill ? SkPaint::kFill_Style : | 1118 SkPaint::Style style = doFill ? SkPaint::kFill_Style : |
1116 SkPaint::kStroke_Style; | 1119 SkPaint::kStroke_Style; |
1117 if (paint->getMaskFilter()->filterPath(*devPathPtr, *fMatrix, *fRC, blit
ter, style)) { | 1120 if (paint->getMaskFilter()->filterPath(*devPathPtr, *fMatrix, *fRC, blit
ter, style)) { |
1118 return; // filterPath() called the blitter, so we're done | 1121 return; // filterPath() called the blitter, so we're done |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1172 | 1175 |
1173 r.set(0, 0, | 1176 r.set(0, 0, |
1174 SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.height())); | 1177 SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.height())); |
1175 fMatrix->mapRect(&r); | 1178 fMatrix->mapRect(&r); |
1176 r.round(&mask.fBounds); | 1179 r.round(&mask.fBounds); |
1177 | 1180 |
1178 // set the mask's bounds to the transformed bitmap-bounds, | 1181 // set the mask's bounds to the transformed bitmap-bounds, |
1179 // clipped to the actual device | 1182 // clipped to the actual device |
1180 { | 1183 { |
1181 SkIRect devBounds; | 1184 SkIRect devBounds; |
1182 devBounds.set(0, 0, fDst.width(), fDst.height()); | 1185 devBounds.set(0, 0, fBitmap->width(), fBitmap->height()); |
1183 // need intersect(l, t, r, b) on irect | 1186 // need intersect(l, t, r, b) on irect |
1184 if (!mask.fBounds.intersect(devBounds)) { | 1187 if (!mask.fBounds.intersect(devBounds)) { |
1185 return; | 1188 return; |
1186 } | 1189 } |
1187 } | 1190 } |
1188 | 1191 |
1189 mask.fFormat = SkMask::kA8_Format; | 1192 mask.fFormat = SkMask::kA8_Format; |
1190 mask.fRowBytes = SkAlign4(mask.fBounds.width()); | 1193 mask.fRowBytes = SkAlign4(mask.fBounds.width()); |
1191 size_t size = mask.computeImageSize(); | 1194 size_t size = mask.computeImageSize(); |
1192 if (0 == size) { | 1195 if (0 == size) { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1270 // (more or less) identity. | 1273 // (more or less) identity. |
1271 // | 1274 // |
1272 SkAutoPixmapUnlock unlocker; | 1275 SkAutoPixmapUnlock unlocker; |
1273 if (!bitmap.requestLock(&unlocker)) { | 1276 if (!bitmap.requestLock(&unlocker)) { |
1274 return; | 1277 return; |
1275 } | 1278 } |
1276 const SkPixmap& pmap = unlocker.pixmap(); | 1279 const SkPixmap& pmap = unlocker.pixmap(); |
1277 int ix = SkScalarRoundToInt(matrix.getTranslateX()); | 1280 int ix = SkScalarRoundToInt(matrix.getTranslateX()); |
1278 int iy = SkScalarRoundToInt(matrix.getTranslateY()); | 1281 int iy = SkScalarRoundToInt(matrix.getTranslateY()); |
1279 if (clipHandlesSprite(*fRC, ix, iy, pmap)) { | 1282 if (clipHandlesSprite(*fRC, ix, iy, pmap)) { |
| 1283 SkPixmap dstPM; |
| 1284 if (!fBitmap->peekPixels(&dstPM)) { |
| 1285 return; |
| 1286 } |
1280 SkTBlitterAllocator allocator; | 1287 SkTBlitterAllocator allocator; |
1281 // blitter will be owned by the allocator. | 1288 // blitter will be owned by the allocator. |
1282 SkBlitter* blitter = SkBlitter::ChooseSprite(fDst, paint, pmap, ix,
iy, &allocator); | 1289 SkBlitter* blitter = SkBlitter::ChooseSprite(dstPM, paint, pmap, ix,
iy, &allocator); |
1283 if (blitter) { | 1290 if (blitter) { |
1284 SkScan::FillIRect(SkIRect::MakeXYWH(ix, iy, pmap.width(), pmap.h
eight()), | 1291 SkScan::FillIRect(SkIRect::MakeXYWH(ix, iy, pmap.width(), pmap.h
eight()), |
1285 *fRC, blitter); | 1292 *fRC, blitter); |
1286 return; | 1293 return; |
1287 } | 1294 } |
1288 // if !blitter, then we fall-through to the slower case | 1295 // if !blitter, then we fall-through to the slower case |
1289 } | 1296 } |
1290 } | 1297 } |
1291 | 1298 |
1292 // now make a temp draw on the stack, and use it | 1299 // now make a temp draw on the stack, and use it |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1327 SkPaint paint(origPaint); | 1334 SkPaint paint(origPaint); |
1328 paint.setStyle(SkPaint::kFill_Style); | 1335 paint.setStyle(SkPaint::kFill_Style); |
1329 | 1336 |
1330 SkAutoPixmapUnlock unlocker; | 1337 SkAutoPixmapUnlock unlocker; |
1331 if (!bitmap.requestLock(&unlocker)) { | 1338 if (!bitmap.requestLock(&unlocker)) { |
1332 return; | 1339 return; |
1333 } | 1340 } |
1334 const SkPixmap& pmap = unlocker.pixmap(); | 1341 const SkPixmap& pmap = unlocker.pixmap(); |
1335 | 1342 |
1336 if (NULL == paint.getColorFilter() && clipHandlesSprite(*fRC, x, y, pmap)) { | 1343 if (NULL == paint.getColorFilter() && clipHandlesSprite(*fRC, x, y, pmap)) { |
| 1344 SkPixmap dstPM; |
| 1345 if (!fBitmap->peekPixels(&dstPM)) { |
| 1346 return; |
| 1347 } |
1337 SkTBlitterAllocator allocator; | 1348 SkTBlitterAllocator allocator; |
1338 // blitter will be owned by the allocator. | 1349 // blitter will be owned by the allocator. |
1339 SkBlitter* blitter = SkBlitter::ChooseSprite(fDst, paint, pmap, x, y, &a
llocator); | 1350 SkBlitter* blitter = SkBlitter::ChooseSprite(dstPM, paint, pmap, x, y, &
allocator); |
1340 if (blitter) { | 1351 if (blitter) { |
1341 SkScan::FillIRect(bounds, *fRC, blitter); | 1352 SkScan::FillIRect(bounds, *fRC, blitter); |
1342 return; | 1353 return; |
1343 } | 1354 } |
1344 } | 1355 } |
1345 | 1356 |
1346 SkMatrix matrix; | 1357 SkMatrix matrix; |
1347 SkRect r; | 1358 SkRect r; |
1348 | 1359 |
1349 // get a scalar version of our rect | 1360 // get a scalar version of our rect |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1628 x -= stopX; | 1639 x -= stopX; |
1629 y -= stopY; | 1640 y -= stopY; |
1630 } | 1641 } |
1631 | 1642 |
1632 const char* stop = text + byteLength; | 1643 const char* stop = text + byteLength; |
1633 | 1644 |
1634 SkAAClipBlitter aaBlitter; | 1645 SkAAClipBlitter aaBlitter; |
1635 SkAutoBlitterChoose blitterChooser; | 1646 SkAutoBlitterChoose blitterChooser; |
1636 SkBlitter* blitter = NULL; | 1647 SkBlitter* blitter = NULL; |
1637 if (needsRasterTextBlit(*this)) { | 1648 if (needsRasterTextBlit(*this)) { |
1638 blitterChooser.choose(fDst, *fMatrix, paint); | 1649 blitterChooser.choose(*fBitmap, *fMatrix, paint); |
1639 blitter = blitterChooser.get(); | 1650 blitter = blitterChooser.get(); |
1640 if (fRC->isAA()) { | 1651 if (fRC->isAA()) { |
1641 aaBlitter.init(blitter, &fRC->aaRgn()); | 1652 aaBlitter.init(blitter, &fRC->aaRgn()); |
1642 blitter = &aaBlitter; | 1653 blitter = &aaBlitter; |
1643 } | 1654 } |
1644 } | 1655 } |
1645 | 1656 |
1646 SkAutoKern autokern; | 1657 SkAutoKern autokern; |
1647 SkDraw1Glyph d1g; | 1658 SkDraw1Glyph d1g; |
1648 SkDraw1Glyph::Proc proc = d1g.init(this, blitter, cache, paint); | 1659 SkDraw1Glyph::Proc proc = d1g.init(this, blitter, cache, paint); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1747 } | 1758 } |
1748 | 1759 |
1749 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); | 1760 SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); |
1750 SkAutoGlyphCache autoCache(paint, &fDevice->getLeakyProperties(), fMatrix
); | 1761 SkAutoGlyphCache autoCache(paint, &fDevice->getLeakyProperties(), fMatrix
); |
1751 SkGlyphCache* cache = autoCache.getCache(); | 1762 SkGlyphCache* cache = autoCache.getCache(); |
1752 | 1763 |
1753 SkAAClipBlitterWrapper wrapper; | 1764 SkAAClipBlitterWrapper wrapper; |
1754 SkAutoBlitterChoose blitterChooser; | 1765 SkAutoBlitterChoose blitterChooser; |
1755 SkBlitter* blitter = NULL; | 1766 SkBlitter* blitter = NULL; |
1756 if (needsRasterTextBlit(*this)) { | 1767 if (needsRasterTextBlit(*this)) { |
1757 blitterChooser.choose(fDst, *fMatrix, paint); | 1768 blitterChooser.choose(*fBitmap, *fMatrix, paint); |
1758 blitter = blitterChooser.get(); | 1769 blitter = blitterChooser.get(); |
1759 if (fRC->isAA()) { | 1770 if (fRC->isAA()) { |
1760 wrapper.init(*fRC, blitter); | 1771 wrapper.init(*fRC, blitter); |
1761 blitter = wrapper.getBlitter(); | 1772 blitter = wrapper.getBlitter(); |
1762 } | 1773 } |
1763 } | 1774 } |
1764 | 1775 |
1765 const char* stop = text + byteLength; | 1776 const char* stop = text + byteLength; |
1766 SkTextAlignProc alignProc(paint.getTextAlign()); | 1777 SkTextAlignProc alignProc(paint.getTextAlign()); |
1767 SkDraw1Glyph d1g; | 1778 SkDraw1Glyph d1g; |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2077 releaseMode = true; | 2088 releaseMode = true; |
2078 } | 2089 } |
2079 composeShader.reset(SkNEW_ARGS(SkComposeShader, (&triShader, shader,
xmode))); | 2090 composeShader.reset(SkNEW_ARGS(SkComposeShader, (&triShader, shader,
xmode))); |
2080 p.setShader(composeShader); | 2091 p.setShader(composeShader); |
2081 if (releaseMode) { | 2092 if (releaseMode) { |
2082 xmode->unref(); | 2093 xmode->unref(); |
2083 } | 2094 } |
2084 } | 2095 } |
2085 } | 2096 } |
2086 | 2097 |
2087 SkAutoBlitterChoose blitter(fDst, *fMatrix, p); | 2098 SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, p); |
2088 // Abort early if we failed to create a shader context. | 2099 // Abort early if we failed to create a shader context. |
2089 if (blitter->isNullBlitter()) { | 2100 if (blitter->isNullBlitter()) { |
2090 return; | 2101 return; |
2091 } | 2102 } |
2092 | 2103 |
2093 // setup our state and function pointer for iterating triangles | 2104 // setup our state and function pointer for iterating triangles |
2094 VertState state(count, indices, indexCount); | 2105 VertState state(count, indices, indexCount); |
2095 VertState::Proc vertProc = state.chooseProc(vmode); | 2106 VertState::Proc vertProc = state.chooseProc(vmode); |
2096 | 2107 |
2097 if (textures || colors) { | 2108 if (textures || colors) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2148 } | 2159 } |
2149 } | 2160 } |
2150 } | 2161 } |
2151 | 2162 |
2152 /////////////////////////////////////////////////////////////////////////////// | 2163 /////////////////////////////////////////////////////////////////////////////// |
2153 /////////////////////////////////////////////////////////////////////////////// | 2164 /////////////////////////////////////////////////////////////////////////////// |
2154 | 2165 |
2155 #ifdef SK_DEBUG | 2166 #ifdef SK_DEBUG |
2156 | 2167 |
2157 void SkDraw::validate() const { | 2168 void SkDraw::validate() const { |
| 2169 SkASSERT(fBitmap != NULL); |
2158 SkASSERT(fMatrix != NULL); | 2170 SkASSERT(fMatrix != NULL); |
2159 SkASSERT(fClip != NULL); | 2171 SkASSERT(fClip != NULL); |
2160 SkASSERT(fRC != NULL); | 2172 SkASSERT(fRC != NULL); |
2161 | 2173 |
2162 const SkIRect& cr = fRC->getBounds(); | 2174 const SkIRect& cr = fRC->getBounds(); |
2163 SkIRect br; | 2175 SkIRect br; |
2164 | 2176 |
2165 br.set(0, 0, fDst.width(), fDst.height()); | 2177 br.set(0, 0, fBitmap->width(), fBitmap->height()); |
2166 SkASSERT(cr.isEmpty() || br.contains(cr)); | 2178 SkASSERT(cr.isEmpty() || br.contains(cr)); |
2167 } | 2179 } |
2168 | 2180 |
2169 #endif | 2181 #endif |
2170 | 2182 |
2171 ////////////////////////////////////////////////////////////////////////////////
//////////////// | 2183 ////////////////////////////////////////////////////////////////////////////////
//////////////// |
2172 | 2184 |
2173 #include "SkPath.h" | 2185 #include "SkPath.h" |
2174 #include "SkDraw.h" | 2186 #include "SkDraw.h" |
2175 #include "SkRegion.h" | 2187 #include "SkRegion.h" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2211 static const int MAX_MARGIN = 128; | 2223 static const int MAX_MARGIN = 128; |
2212 if (!bounds->intersect(clipBounds->makeOutset(SkMin32(margin.fX, MAX_MAR
GIN), | 2224 if (!bounds->intersect(clipBounds->makeOutset(SkMin32(margin.fX, MAX_MAR
GIN), |
2213 SkMin32(margin.fY, MAX_MAR
GIN)))) { | 2225 SkMin32(margin.fY, MAX_MAR
GIN)))) { |
2214 return false; | 2226 return false; |
2215 } | 2227 } |
2216 } | 2228 } |
2217 | 2229 |
2218 return true; | 2230 return true; |
2219 } | 2231 } |
2220 | 2232 |
2221 static void draw_into_mask(const SkMask& mask, const SkPath& devPath, SkPaint::S
tyle style) { | 2233 static void draw_into_mask(const SkMask& mask, const SkPath& devPath, |
2222 SkDraw draw; | 2234 SkPaint::Style style) { |
2223 if (!draw.fDst.reset(mask)) { | 2235 SkBitmap bm; |
2224 return; | 2236 SkDraw draw; |
2225 } | |
2226 | |
2227 SkRasterClip clip; | 2237 SkRasterClip clip; |
2228 SkMatrix matrix; | 2238 SkMatrix matrix; |
2229 SkPaint paint; | 2239 SkPaint paint; |
2230 | 2240 |
| 2241 bm.installPixels(SkImageInfo::MakeA8(mask.fBounds.width(), mask.fBounds.heig
ht()), |
| 2242 mask.fImage, mask.fRowBytes); |
| 2243 |
2231 clip.setRect(SkIRect::MakeWH(mask.fBounds.width(), mask.fBounds.height())); | 2244 clip.setRect(SkIRect::MakeWH(mask.fBounds.width(), mask.fBounds.height())); |
2232 matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft), | 2245 matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft), |
2233 -SkIntToScalar(mask.fBounds.fTop)); | 2246 -SkIntToScalar(mask.fBounds.fTop)); |
2234 | 2247 |
| 2248 draw.fBitmap = &bm; |
2235 draw.fRC = &clip; | 2249 draw.fRC = &clip; |
2236 draw.fClip = &clip.bwRgn(); | 2250 draw.fClip = &clip.bwRgn(); |
2237 draw.fMatrix = &matrix; | 2251 draw.fMatrix = &matrix; |
2238 paint.setAntiAlias(true); | 2252 paint.setAntiAlias(true); |
2239 paint.setStyle(style); | 2253 paint.setStyle(style); |
2240 draw.drawPath(devPath, paint); | 2254 draw.drawPath(devPath, paint); |
2241 } | 2255 } |
2242 | 2256 |
2243 bool SkDraw::DrawToMask(const SkPath& devPath, const SkIRect* clipBounds, | 2257 bool SkDraw::DrawToMask(const SkPath& devPath, const SkIRect* clipBounds, |
2244 const SkMaskFilter* filter, const SkMatrix* filterMatrix
, | 2258 const SkMaskFilter* filter, const SkMatrix* filterMatrix
, |
(...skipping 15 matching lines...) Expand all Loading... |
2260 mask->fImage = SkMask::AllocImage(size); | 2274 mask->fImage = SkMask::AllocImage(size); |
2261 memset(mask->fImage, 0, mask->computeImageSize()); | 2275 memset(mask->fImage, 0, mask->computeImageSize()); |
2262 } | 2276 } |
2263 | 2277 |
2264 if (SkMask::kJustComputeBounds_CreateMode != mode) { | 2278 if (SkMask::kJustComputeBounds_CreateMode != mode) { |
2265 draw_into_mask(*mask, devPath, style); | 2279 draw_into_mask(*mask, devPath, style); |
2266 } | 2280 } |
2267 | 2281 |
2268 return true; | 2282 return true; |
2269 } | 2283 } |
OLD | NEW |