Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(506)

Side by Side Diff: src/core/SkPaint.cpp

Issue 240273004: always store bitfields along with dirty in FlatteningTraits (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: re-compact the dirtybits enum Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/PaintTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2006 The Android Open Source Project 3 * Copyright 2006 The Android Open Source Project
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include "SkPaint.h" 9 #include "SkPaint.h"
10 #include "SkAnnotation.h" 10 #include "SkAnnotation.h"
(...skipping 19 matching lines...) Expand all
30 #include "SkStringUtils.h" 30 #include "SkStringUtils.h"
31 #include "SkStroke.h" 31 #include "SkStroke.h"
32 #include "SkTextFormatParams.h" 32 #include "SkTextFormatParams.h"
33 #include "SkTextToPathIter.h" 33 #include "SkTextToPathIter.h"
34 #include "SkTLazy.h" 34 #include "SkTLazy.h"
35 #include "SkTypeface.h" 35 #include "SkTypeface.h"
36 #include "SkXfermode.h" 36 #include "SkXfermode.h"
37 37
38 enum { 38 enum {
39 kColor_DirtyBit = 1 << 0, 39 kColor_DirtyBit = 1 << 0,
40 kBitfields_DirtyBit = 1 << 1, 40 kTextSize_DirtyBit = 1 << 1,
41 kTextSize_DirtyBit = 1 << 2, 41 kTextScaleX_DirtyBit = 1 << 2,
42 kTextScaleX_DirtyBit = 1 << 3, 42 kTextSkewX_DirtyBit = 1 << 3,
43 kTextSkewX_DirtyBit = 1 << 4, 43 kStrokeWidth_DirtyBit = 1 << 4,
44 kStrokeWidth_DirtyBit = 1 << 5, 44 kStrokeMiter_DirtyBit = 1 << 5,
45 kStrokeMiter_DirtyBit = 1 << 6, 45
46 kPathEffect_DirtyBit = 1 << 7, 46 kPOD_DirtyBitMask = 63,
47 kShader_DirtyBit = 1 << 8, 47
48 kXfermode_DirtyBit = 1 << 9, 48 kPathEffect_DirtyBit = 1 << 6,
49 kMaskFilter_DirtyBit = 1 << 10, 49 kShader_DirtyBit = 1 << 7,
50 kColorFilter_DirtyBit = 1 << 11, 50 kXfermode_DirtyBit = 1 << 8,
51 kRasterizer_DirtyBit = 1 << 12, 51 kMaskFilter_DirtyBit = 1 << 9,
52 kLooper_DirtyBit = 1 << 13, 52 kColorFilter_DirtyBit = 1 << 10,
53 kImageFilter_DirtyBit = 1 << 14, 53 kRasterizer_DirtyBit = 1 << 11,
54 kTypeface_DirtyBit = 1 << 15, 54 kLooper_DirtyBit = 1 << 12,
55 kAnnotation_DirtyBit = 1 << 16, 55 kImageFilter_DirtyBit = 1 << 13,
56 kPaintOptionsAndroid_DirtyBit = 1 << 17, 56 kTypeface_DirtyBit = 1 << 14,
57 kAnnotation_DirtyBit = 1 << 15,
58 kPaintOptionsAndroid_DirtyBit = 1 << 16,
57 }; 59 };
58 60
59 // define this to get a printf for out-of-range parameter in setters 61 // define this to get a printf for out-of-range parameter in setters
60 // e.g. setTextSize(-1) 62 // e.g. setTextSize(-1)
61 //#define SK_REPORT_API_RANGE_CHECK 63 //#define SK_REPORT_API_RANGE_CHECK
62 64
63 #ifdef SK_BUILD_FOR_ANDROID 65 #ifdef SK_BUILD_FOR_ANDROID
64 #define GEN_ID_INC fGenerationID++ 66 #define GEN_ID_INC fGenerationID++
65 #define GEN_ID_INC_EVAL(expression) if (expression) { fGenerationID++; } 67 #define GEN_ID_INC_EVAL(expression) if (expression) { fGenerationID++; }
66 #else 68 #else
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 fPaintOptionsAndroid = options; 249 fPaintOptionsAndroid = options;
248 GEN_ID_INC; 250 GEN_ID_INC;
249 fDirtyBits |= kPaintOptionsAndroid_DirtyBit; 251 fDirtyBits |= kPaintOptionsAndroid_DirtyBit;
250 } 252 }
251 } 253 }
252 #endif 254 #endif
253 255
254 void SkPaint::setFilterLevel(FilterLevel level) { 256 void SkPaint::setFilterLevel(FilterLevel level) {
255 GEN_ID_INC_EVAL((unsigned) level != fFilterLevel); 257 GEN_ID_INC_EVAL((unsigned) level != fFilterLevel);
256 fFilterLevel = level; 258 fFilterLevel = level;
257 fDirtyBits |= kBitfields_DirtyBit;
258 } 259 }
259 260
260 void SkPaint::setHinting(Hinting hintingLevel) { 261 void SkPaint::setHinting(Hinting hintingLevel) {
261 GEN_ID_INC_EVAL((unsigned) hintingLevel != fHinting); 262 GEN_ID_INC_EVAL((unsigned) hintingLevel != fHinting);
262 fHinting = hintingLevel; 263 fHinting = hintingLevel;
263 fDirtyBits |= kBitfields_DirtyBit;
264 } 264 }
265 265
266 void SkPaint::setFlags(uint32_t flags) { 266 void SkPaint::setFlags(uint32_t flags) {
267 GEN_ID_INC_EVAL(fFlags != flags); 267 GEN_ID_INC_EVAL(fFlags != flags);
268 fFlags = flags; 268 fFlags = flags;
269 fDirtyBits |= kBitfields_DirtyBit;
270 } 269 }
271 270
272 void SkPaint::setAntiAlias(bool doAA) { 271 void SkPaint::setAntiAlias(bool doAA) {
273 this->setFlags(SkSetClearMask(fFlags, doAA, kAntiAlias_Flag)); 272 this->setFlags(SkSetClearMask(fFlags, doAA, kAntiAlias_Flag));
274 } 273 }
275 274
276 void SkPaint::setDither(bool doDither) { 275 void SkPaint::setDither(bool doDither) {
277 this->setFlags(SkSetClearMask(fFlags, doDither, kDither_Flag)); 276 this->setFlags(SkSetClearMask(fFlags, doDither, kDither_Flag));
278 } 277 }
279 278
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 } 317 }
319 318
320 void SkPaint::setDistanceFieldTextTEMP(bool doDistanceFieldText) { 319 void SkPaint::setDistanceFieldTextTEMP(bool doDistanceFieldText) {
321 this->setFlags(SkSetClearMask(fFlags, doDistanceFieldText, kDistanceFieldTex tTEMP_Flag)); 320 this->setFlags(SkSetClearMask(fFlags, doDistanceFieldText, kDistanceFieldTex tTEMP_Flag));
322 } 321 }
323 322
324 void SkPaint::setStyle(Style style) { 323 void SkPaint::setStyle(Style style) {
325 if ((unsigned)style < kStyleCount) { 324 if ((unsigned)style < kStyleCount) {
326 GEN_ID_INC_EVAL((unsigned)style != fStyle); 325 GEN_ID_INC_EVAL((unsigned)style != fStyle);
327 fStyle = style; 326 fStyle = style;
328 fDirtyBits |= kBitfields_DirtyBit;
329 } else { 327 } else {
330 #ifdef SK_REPORT_API_RANGE_CHECK 328 #ifdef SK_REPORT_API_RANGE_CHECK
331 SkDebugf("SkPaint::setStyle(%d) out of range\n", style); 329 SkDebugf("SkPaint::setStyle(%d) out of range\n", style);
332 #endif 330 #endif
333 } 331 }
334 } 332 }
335 333
336 void SkPaint::setColor(SkColor color) { 334 void SkPaint::setColor(SkColor color) {
337 GEN_ID_INC_EVAL(color != fColor); 335 GEN_ID_INC_EVAL(color != fColor);
338 fColor = color; 336 fColor = color;
(...skipping 30 matching lines...) Expand all
369 #ifdef SK_REPORT_API_RANGE_CHECK 367 #ifdef SK_REPORT_API_RANGE_CHECK
370 SkDebugf("SkPaint::setStrokeMiter() called with negative value\n"); 368 SkDebugf("SkPaint::setStrokeMiter() called with negative value\n");
371 #endif 369 #endif
372 } 370 }
373 } 371 }
374 372
375 void SkPaint::setStrokeCap(Cap ct) { 373 void SkPaint::setStrokeCap(Cap ct) {
376 if ((unsigned)ct < kCapCount) { 374 if ((unsigned)ct < kCapCount) {
377 GEN_ID_INC_EVAL((unsigned)ct != fCapType); 375 GEN_ID_INC_EVAL((unsigned)ct != fCapType);
378 fCapType = SkToU8(ct); 376 fCapType = SkToU8(ct);
379 fDirtyBits |= kBitfields_DirtyBit;
380 } else { 377 } else {
381 #ifdef SK_REPORT_API_RANGE_CHECK 378 #ifdef SK_REPORT_API_RANGE_CHECK
382 SkDebugf("SkPaint::setStrokeCap(%d) out of range\n", ct); 379 SkDebugf("SkPaint::setStrokeCap(%d) out of range\n", ct);
383 #endif 380 #endif
384 } 381 }
385 } 382 }
386 383
387 void SkPaint::setStrokeJoin(Join jt) { 384 void SkPaint::setStrokeJoin(Join jt) {
388 if ((unsigned)jt < kJoinCount) { 385 if ((unsigned)jt < kJoinCount) {
389 GEN_ID_INC_EVAL((unsigned)jt != fJoinType); 386 GEN_ID_INC_EVAL((unsigned)jt != fJoinType);
390 fJoinType = SkToU8(jt); 387 fJoinType = SkToU8(jt);
391 fDirtyBits |= kBitfields_DirtyBit;
392 } else { 388 } else {
393 #ifdef SK_REPORT_API_RANGE_CHECK 389 #ifdef SK_REPORT_API_RANGE_CHECK
394 SkDebugf("SkPaint::setStrokeJoin(%d) out of range\n", jt); 390 SkDebugf("SkPaint::setStrokeJoin(%d) out of range\n", jt);
395 #endif 391 #endif
396 } 392 }
397 } 393 }
398 394
399 /////////////////////////////////////////////////////////////////////////////// 395 ///////////////////////////////////////////////////////////////////////////////
400 396
401 void SkPaint::setTextAlign(Align align) { 397 void SkPaint::setTextAlign(Align align) {
402 if ((unsigned)align < kAlignCount) { 398 if ((unsigned)align < kAlignCount) {
403 GEN_ID_INC_EVAL((unsigned)align != fTextAlign); 399 GEN_ID_INC_EVAL((unsigned)align != fTextAlign);
404 fTextAlign = SkToU8(align); 400 fTextAlign = SkToU8(align);
405 fDirtyBits |= kBitfields_DirtyBit;
406 } else { 401 } else {
407 #ifdef SK_REPORT_API_RANGE_CHECK 402 #ifdef SK_REPORT_API_RANGE_CHECK
408 SkDebugf("SkPaint::setTextAlign(%d) out of range\n", align); 403 SkDebugf("SkPaint::setTextAlign(%d) out of range\n", align);
409 #endif 404 #endif
410 } 405 }
411 } 406 }
412 407
413 void SkPaint::setTextSize(SkScalar ts) { 408 void SkPaint::setTextSize(SkScalar ts) {
414 if (ts >= 0) { 409 if (ts >= 0) {
415 GEN_ID_INC_EVAL(ts != fTextSize); 410 GEN_ID_INC_EVAL(ts != fTextSize);
(...skipping 15 matching lines...) Expand all
431 void SkPaint::setTextSkewX(SkScalar skewX) { 426 void SkPaint::setTextSkewX(SkScalar skewX) {
432 GEN_ID_INC_EVAL(skewX != fTextSkewX); 427 GEN_ID_INC_EVAL(skewX != fTextSkewX);
433 fTextSkewX = skewX; 428 fTextSkewX = skewX;
434 fDirtyBits |= kTextSkewX_DirtyBit; 429 fDirtyBits |= kTextSkewX_DirtyBit;
435 } 430 }
436 431
437 void SkPaint::setTextEncoding(TextEncoding encoding) { 432 void SkPaint::setTextEncoding(TextEncoding encoding) {
438 if ((unsigned)encoding <= kGlyphID_TextEncoding) { 433 if ((unsigned)encoding <= kGlyphID_TextEncoding) {
439 GEN_ID_INC_EVAL((unsigned)encoding != fTextEncoding); 434 GEN_ID_INC_EVAL((unsigned)encoding != fTextEncoding);
440 fTextEncoding = encoding; 435 fTextEncoding = encoding;
441 fDirtyBits |= kBitfields_DirtyBit;
442 } else { 436 } else {
443 #ifdef SK_REPORT_API_RANGE_CHECK 437 #ifdef SK_REPORT_API_RANGE_CHECK
444 SkDebugf("SkPaint::setTextEncoding(%d) out of range\n", encoding); 438 SkDebugf("SkPaint::setTextEncoding(%d) out of range\n", encoding);
445 #endif 439 #endif
446 } 440 }
447 } 441 }
448 442
449 /////////////////////////////////////////////////////////////////////////////// 443 ///////////////////////////////////////////////////////////////////////////////
450 444
451 // Returns dst with the given bitmask enabled or disabled, depending on value. 445 // Returns dst with the given bitmask enabled or disabled, depending on value.
(...skipping 2191 matching lines...) Expand 10 before | Expand all | Expand 10 after
2643 return true; 2637 return true;
2644 default: 2638 default:
2645 break; 2639 break;
2646 } 2640 }
2647 } 2641 }
2648 return false; 2642 return false;
2649 } 2643 }
2650 2644
2651 void SkPaint::setBitfields(uint32_t bitfields) { 2645 void SkPaint::setBitfields(uint32_t bitfields) {
2652 fBitfields = bitfields; 2646 fBitfields = bitfields;
2653 fDirtyBits |= kBitfields_DirtyBit;
2654 } 2647 }
2655 2648
2656 inline static unsigned popcount(uint8_t x) { 2649 inline static unsigned popcount(uint8_t x) {
2657 // As in Hacker's delight, adapted for just 8 bits. 2650 // As in Hacker's delight, adapted for just 8 bits.
2658 x = (x & 0x55) + ((x >> 1) & 0x55); // a b c d w x y z -> a+b c+d w+x y+z 2651 x = (x & 0x55) + ((x >> 1) & 0x55); // a b c d w x y z -> a+b c+d w+x y+z
2659 x = (x & 0x33) + ((x >> 2) & 0x33); // a+b c+d w+x y+z -> a+b+c+d w+x+y+z 2652 x = (x & 0x33) + ((x >> 2) & 0x33); // a+b c+d w+x y+z -> a+b+c+d w+x+y+z
2660 x = (x & 0x0F) + ((x >> 4) & 0x0F); // a+b+c+d w+x+y+z -> a+b+c+d+w+x+y+z 2653 x = (x & 0x0F) + ((x >> 4) & 0x0F); // a+b+c+d w+x+y+z -> a+b+c+d+w+x+y+z
2661 return x; 2654 return x;
2662 } 2655 }
2663 2656
2664 void SkPaint::FlatteningTraits::Flatten(SkWriteBuffer& buffer, const SkPaint& pa int) { 2657 void SkPaint::FlatteningTraits::Flatten(SkWriteBuffer& buffer, const SkPaint& pa int) {
2665 const uint32_t dirty = paint.fDirtyBits; 2658 const uint32_t dirty = paint.fDirtyBits;
2666 2659
2667 // Each of the low 7 dirty bits corresponds to a 4-byte flat value, plus one for the dirty bits. 2660 // Each of the low 7 dirty bits corresponds to a 4-byte flat value,
2668 const size_t flatBytes = 4 * (popcount(dirty & 127) + 1); 2661 // plus one for the dirty bits and one for the bitfields
2662 const size_t flatBytes = 4 * (popcount(dirty & kPOD_DirtyBitMask) + 2);
2669 SkASSERT(flatBytes <= 32); 2663 SkASSERT(flatBytes <= 32);
2670 uint32_t* u32 = buffer.reserve(flatBytes); 2664 uint32_t* u32 = buffer.reserve(flatBytes);
2671 *u32++ = dirty; 2665 *u32++ = dirty;
2672 if (dirty == 0) { 2666 *u32++ = paint.getBitfields();
2667 if (0 == dirty) {
2673 return; 2668 return;
2674 } 2669 }
2675 2670
2676 #define F(dst, field) if (dirty & k##field##_DirtyBit) *dst++ = paint.get##field () 2671 #define F(dst, field) if (dirty & k##field##_DirtyBit) *dst++ = paint.get##field ()
2677 F(u32, Color); 2672 F(u32, Color);
2678 F(u32, Bitfields);
2679 SkScalar* f32 = reinterpret_cast<SkScalar*>(u32); 2673 SkScalar* f32 = reinterpret_cast<SkScalar*>(u32);
2680 F(f32, TextSize); 2674 F(f32, TextSize);
2681 F(f32, TextScaleX); 2675 F(f32, TextScaleX);
2682 F(f32, TextSkewX); 2676 F(f32, TextSkewX);
2683 F(f32, StrokeWidth); 2677 F(f32, StrokeWidth);
2684 F(f32, StrokeMiter); 2678 F(f32, StrokeMiter);
2685 #undef F 2679 #undef F
2686 #define F(field) if (dirty & k##field##_DirtyBit) buffer.writeFlattenable(paint. get##field()) 2680 #define F(field) if (dirty & k##field##_DirtyBit) buffer.writeFlattenable(paint. get##field())
2687 F(PathEffect); 2681 F(PathEffect);
2688 F(Shader); 2682 F(Shader);
2689 F(Xfermode); 2683 F(Xfermode);
2690 F(MaskFilter); 2684 F(MaskFilter);
2691 F(ColorFilter); 2685 F(ColorFilter);
2692 F(Rasterizer); 2686 F(Rasterizer);
2693 F(Looper); 2687 F(Looper);
2694 F(ImageFilter); 2688 F(ImageFilter);
2695 #undef F 2689 #undef F
2696 if (dirty & kTypeface_DirtyBit) buffer.writeTypeface(paint.getTypeface()); 2690 if (dirty & kTypeface_DirtyBit) buffer.writeTypeface(paint.getTypeface());
2697 if (dirty & kAnnotation_DirtyBit) paint.getAnnotation()->writeToBuffer(buffe r); 2691 if (dirty & kAnnotation_DirtyBit) paint.getAnnotation()->writeToBuffer(buffe r);
2698 #ifdef SK_BUILD_FOR_ANDROID 2692 #ifdef SK_BUILD_FOR_ANDROID
2699 if (dirty & kPaintOptionsAndroid_DirtyBit) paint.getPaintOptionsAndroid().fl atten(buffer); 2693 if (dirty & kPaintOptionsAndroid_DirtyBit) paint.getPaintOptionsAndroid().fl atten(buffer);
2700 #endif 2694 #endif
2701 } 2695 }
2702 2696
2703 void SkPaint::FlatteningTraits::Unflatten(SkReadBuffer& buffer, SkPaint* paint) { 2697 void SkPaint::FlatteningTraits::Unflatten(SkReadBuffer& buffer, SkPaint* paint) {
2704 const uint32_t dirty = buffer.readUInt(); 2698 const uint32_t dirty = buffer.readUInt();
2699 paint->setBitfields(buffer.readUInt());
2705 if (dirty == 0) { 2700 if (dirty == 0) {
2706 return; 2701 return;
2707 } 2702 }
2708 #define F(field, reader) if (dirty & k##field##_DirtyBit) paint->set##field(buff er.reader()) 2703 #define F(field, reader) if (dirty & k##field##_DirtyBit) paint->set##field(buff er.reader())
2709 // Same function, except it unrefs the object newly set on the paint: 2704 // Same function, except it unrefs the object newly set on the paint:
2710 #define F_UNREF(field, reader) \ 2705 #define F_UNREF(field, reader) \
2711 if (dirty & k##field##_DirtyBit) \ 2706 if (dirty & k##field##_DirtyBit) \
2712 paint->set##field(buffer.reader())->unref() 2707 paint->set##field(buffer.reader())->unref()
2713 2708
2714 F(Color, readUInt); 2709 F(Color, readUInt);
2715 F(Bitfields, readUInt);
2716 F(TextSize, readScalar); 2710 F(TextSize, readScalar);
2717 F(TextScaleX, readScalar); 2711 F(TextScaleX, readScalar);
2718 F(TextSkewX, readScalar); 2712 F(TextSkewX, readScalar);
2719 F(StrokeWidth, readScalar); 2713 F(StrokeWidth, readScalar);
2720 F(StrokeMiter, readScalar); 2714 F(StrokeMiter, readScalar);
2721 F_UNREF(PathEffect, readPathEffect); 2715 F_UNREF(PathEffect, readPathEffect);
2722 F_UNREF(Shader, readShader); 2716 F_UNREF(Shader, readShader);
2723 F_UNREF(Xfermode, readXfermode); 2717 F_UNREF(Xfermode, readXfermode);
2724 F_UNREF(MaskFilter, readMaskFilter); 2718 F_UNREF(MaskFilter, readMaskFilter);
2725 F_UNREF(ColorFilter, readColorFilter); 2719 F_UNREF(ColorFilter, readColorFilter);
2726 F_UNREF(Rasterizer, readRasterizer); 2720 F_UNREF(Rasterizer, readRasterizer);
2727 F_UNREF(Looper, readDrawLooper); 2721 F_UNREF(Looper, readDrawLooper);
2728 F_UNREF(ImageFilter, readImageFilter); 2722 F_UNREF(ImageFilter, readImageFilter);
2729 F(Typeface, readTypeface); 2723 F(Typeface, readTypeface);
2730 #undef F 2724 #undef F
2731 #undef F_UNREF 2725 #undef F_UNREF
2732 if (dirty & kAnnotation_DirtyBit) { 2726 if (dirty & kAnnotation_DirtyBit) {
2733 paint->setAnnotation(SkAnnotation::Create(buffer))->unref(); 2727 paint->setAnnotation(SkAnnotation::Create(buffer))->unref();
2734 } 2728 }
2735 #ifdef SK_BUILD_FOR_ANDROID 2729 #ifdef SK_BUILD_FOR_ANDROID
2736 if (dirty & kPaintOptionsAndroid_DirtyBit) { 2730 if (dirty & kPaintOptionsAndroid_DirtyBit) {
2737 SkPaintOptionsAndroid options; 2731 SkPaintOptionsAndroid options;
2738 options.unflatten(buffer); 2732 options.unflatten(buffer);
2739 paint->setPaintOptionsAndroid(options); 2733 paint->setPaintOptionsAndroid(options);
2740 } 2734 }
2741 #endif 2735 #endif
2742 SkASSERT(dirty == paint->fDirtyBits); 2736 SkASSERT(dirty == paint->fDirtyBits);
2743 } 2737 }
OLDNEW
« no previous file with comments | « no previous file | tests/PaintTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698