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 |