1 | /* |
---|---|
2 | * Copyright 2015 Google Inc. |
3 | * |
4 | * Use of this source code is governed by a BSD-style license that can be |
5 | * found in the LICENSE file. |
6 | */ |
7 | |
8 | #ifndef SkPictureCommon_DEFINED |
9 | #define SkPictureCommon_DEFINED |
10 | |
11 | // Some shared code used by both SkBigPicture and SkMiniPicture. |
12 | // SkTextHunter -- SkRecord visitor that returns true when the op draws text. |
13 | // SkPathCounter -- SkRecord visitor that counts paths that draw slowly on the GPU. |
14 | |
15 | #include "include/core/SkPathEffect.h" |
16 | #include "include/core/SkShader.h" |
17 | #include "include/private/SkTLogic.h" |
18 | #include "src/core/SkRecords.h" |
19 | |
20 | // TODO: might be nicer to have operator() return an int (the number of slow paths) ? |
21 | struct SkPathCounter { |
22 | // Some ops have a paint, some have an optional paint. Either way, get back a pointer. |
23 | static const SkPaint* AsPtr(const SkPaint& p) { return &p; } |
24 | static const SkPaint* AsPtr(const SkRecords::Optional<SkPaint>& p) { return p; } |
25 | |
26 | SkPathCounter() : fNumSlowPathsAndDashEffects(0) {} |
27 | |
28 | void checkPaint(const SkPaint* paint) { |
29 | if (paint && paint->getPathEffect()) { |
30 | // Initially assume it's slow. |
31 | fNumSlowPathsAndDashEffects++; |
32 | } |
33 | } |
34 | |
35 | void operator()(const SkRecords::DrawPoints& op) { |
36 | this->checkPaint(&op.paint); |
37 | const SkPathEffect* effect = op.paint.getPathEffect(); |
38 | if (effect) { |
39 | SkPathEffect::DashInfo info; |
40 | SkPathEffect::DashType dashType = effect->asADash(&info); |
41 | if (2 == op.count && SkPaint::kRound_Cap != op.paint.getStrokeCap() && |
42 | SkPathEffect::kDash_DashType == dashType && 2 == info.fCount) { |
43 | fNumSlowPathsAndDashEffects--; |
44 | } |
45 | } |
46 | } |
47 | |
48 | void operator()(const SkRecords::DrawPath& op) { |
49 | this->checkPaint(&op.paint); |
50 | if (op.paint.isAntiAlias() && !op.path.isConvex()) { |
51 | SkPaint::Style paintStyle = op.paint.getStyle(); |
52 | const SkRect& pathBounds = op.path.getBounds(); |
53 | if (SkPaint::kStroke_Style == paintStyle && |
54 | 0 == op.paint.getStrokeWidth()) { |
55 | // AA hairline concave path is not slow. |
56 | } else if (SkPaint::kFill_Style == paintStyle && pathBounds.width() < 64.f && |
57 | pathBounds.height() < 64.f && !op.path.isVolatile()) { |
58 | // AADF eligible concave path is not slow. |
59 | } else { |
60 | fNumSlowPathsAndDashEffects++; |
61 | } |
62 | } |
63 | } |
64 | |
65 | void operator()(const SkRecords::ClipPath& op) { |
66 | // TODO: does the SkRegion op matter? |
67 | if (op.opAA.aa() && !op.path.isConvex()) { |
68 | fNumSlowPathsAndDashEffects++; |
69 | } |
70 | } |
71 | |
72 | void operator()(const SkRecords::SaveLayer& op) { |
73 | this->checkPaint(AsPtr(op.paint)); |
74 | } |
75 | |
76 | template <typename T> |
77 | SK_WHEN(T::kTags & SkRecords::kHasPaint_Tag, void) operator()(const T& op) { |
78 | this->checkPaint(AsPtr(op.paint)); |
79 | } |
80 | |
81 | template <typename T> |
82 | SK_WHEN(!(T::kTags & SkRecords::kHasPaint_Tag), void) |
83 | operator()(const T& op) { /* do nothing */ } |
84 | |
85 | int fNumSlowPathsAndDashEffects; |
86 | }; |
87 | |
88 | sk_sp<SkImage> ImageDeserializer_SkDeserialImageProc(const void*, size_t, void* imagedeserializer); |
89 | |
90 | bool SkPicture_StreamIsSKP(SkStream*, SkPictInfo*); |
91 | |
92 | #endif // SkPictureCommon_DEFINED |
93 |