OLD | NEW |
| (Empty) |
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 #include "GrStrokeInfo.h" | |
9 #include "GrResourceKey.h" | |
10 #include "SkDashPathPriv.h" | |
11 | |
12 bool all_dash_intervals_zero(const SkScalar* intervals, int count) { | |
13 for (int i = 0 ; i < count; ++i) { | |
14 if (intervals[i] != 0) { | |
15 return false; | |
16 } | |
17 } | |
18 return true; | |
19 } | |
20 | |
21 bool GrStrokeInfo::applyDashToPath(SkPath* dst, GrStrokeInfo* dstStrokeInfo, | |
22 const SkPath& src) const { | |
23 if (this->isDashed()) { | |
24 SkPathEffect::DashInfo info; | |
25 info.fIntervals = fIntervals.get(); | |
26 info.fCount = fIntervals.count(); | |
27 info.fPhase = fDashPhase; | |
28 GrStrokeInfo filteredStroke(*this, false); | |
29 // Handle the case where all intervals are 0 and we simply drop the dash
effect | |
30 if (all_dash_intervals_zero(fIntervals.get(), fIntervals.count())) { | |
31 *dstStrokeInfo = filteredStroke; | |
32 *dst = src; | |
33 return true; | |
34 } | |
35 // See if we can filter the dash into a path on cpu | |
36 if (SkDashPath::FilterDashPath(dst, src, &filteredStroke, nullptr, info)
) { | |
37 *dstStrokeInfo = filteredStroke; | |
38 return true; | |
39 } | |
40 } | |
41 return false; | |
42 } | |
43 | |
44 void GrStrokeInfo::asUniqueKeyFragment(uint32_t* data) const { | |
45 const int kSkScalarData32Cnt = sizeof(SkScalar) / sizeof(uint32_t); | |
46 enum { | |
47 kStyleBits = 2, | |
48 kJoinBits = 2, | |
49 kCapBits = 32 - kStyleBits - kJoinBits, | |
50 | |
51 kJoinShift = kStyleBits, | |
52 kCapShift = kJoinShift + kJoinBits, | |
53 }; | |
54 | |
55 static_assert(SkStrokeRec::kStyleCount <= (1 << kStyleBits), "style_shift_wi
ll_be_wrong"); | |
56 static_assert(SkPaint::kJoinCount <= (1 << kJoinBits), "cap_shift_will_be_wr
ong"); | |
57 static_assert(SkPaint::kCapCount <= (1 << kCapBits), "cap_does_not_fit"); | |
58 uint32_t styleKey = this->getStyle(); | |
59 if (this->needToApply()) { | |
60 styleKey |= this->getJoin() << kJoinShift; | |
61 styleKey |= this->getCap() << kCapShift; | |
62 } | |
63 int i = 0; | |
64 data[i++] = styleKey; | |
65 | |
66 // Memcpy the scalar fields. Does not "reinterpret_cast<SkScalar&>(data[i])
= ..." due to | |
67 // scalars having more strict alignment requirements than what data can guar
antee. The | |
68 // compiler should optimize memcpys to assignments. | |
69 SkScalar scalar; | |
70 scalar = this->getMiter(); | |
71 memcpy(&data[i], &scalar, sizeof(scalar)); | |
72 i += kSkScalarData32Cnt; | |
73 | |
74 scalar = this->getWidth(); | |
75 memcpy(&data[i], &scalar, sizeof(scalar)); | |
76 i += kSkScalarData32Cnt; | |
77 | |
78 if (this->isDashed()) { | |
79 SkScalar phase = this->getDashPhase(); | |
80 memcpy(&data[i], &phase, sizeof(phase)); | |
81 i += kSkScalarData32Cnt; | |
82 | |
83 int32_t count = this->getDashCount() & static_cast<int32_t>(~1); | |
84 SkASSERT(count == this->getDashCount()); | |
85 const SkScalar* intervals = this->getDashIntervals(); | |
86 int intervalByteCnt = count * sizeof(SkScalar); | |
87 memcpy(&data[i], intervals, intervalByteCnt); | |
88 // Enable the line below if fields are added after dashing. | |
89 SkDEBUGCODE(i += kSkScalarData32Cnt * count); | |
90 } | |
91 | |
92 SkASSERT(this->computeUniqueKeyFragmentData32Cnt() == i); | |
93 } | |
OLD | NEW |