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_will_be_wrong"); 56 static_assert(SkPaint::kJoinCount <= (1 << kJoinBits), "cap_shift_will_be_wrong"); 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 guarantee. 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 } 94 95