1 /* 2 * Copyright 2012 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 "GrPath.h" 9 10 template<int NumBits> static uint64_t get_top_n_float_bits(float f) { 11 char* floatData = reinterpret_cast<char*>(&f); 12 uint32_t floatBits = *reinterpret_cast<uint32_t*>(floatData); 13 return floatBits >> (32 - NumBits); 14 } 15 16 void GrPath::ComputeKey(const SkPath& path, const SkStrokeRec& stroke, GrUniqueKey* key) { 17 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); 18 GrUniqueKey::Builder builder(key, kDomain, 3); 19 *reinterpret_cast<uint64_t*>(&builder[0]) = ComputeStrokeKey(stroke); 20 builder[2] = path.getGenerationID(); 21 } 22 23 uint64_t GrPath::ComputeStrokeKey(const SkStrokeRec& stroke) { 24 enum { 25 kStyleBits = 2, 26 kJoinBits = 2, 27 kCapBits = 2, 28 kWidthBits = 29, 29 kMiterBits = 29, 30 31 kJoinShift = kStyleBits, 32 kCapShift = kJoinShift + kJoinBits, 33 kWidthShift = kCapShift + kCapBits, 34 kMiterShift = kWidthShift + kWidthBits, 35 36 kBitCount = kMiterShift + kMiterBits 37 }; 38 39 SK_COMPILE_ASSERT(SkStrokeRec::kStyleCount <= (1 << kStyleBits), style_shift_will_be_wrong); 40 SK_COMPILE_ASSERT(SkPaint::kJoinCount <= (1 << kJoinBits), cap_shift_will_be_wrong); 41 SK_COMPILE_ASSERT(SkPaint::kCapCount <= (1 << kCapBits), miter_shift_will_be_wrong); 42 SK_COMPILE_ASSERT(kBitCount == 64, wrong_stroke_key_size); 43 44 if (!stroke.needToApply()) { 45 return SkStrokeRec::kFill_Style; 46 } 47 48 uint64_t key = stroke.getStyle(); 49 key |= stroke.getJoin() << kJoinShift; 50 key |= stroke.getCap() << kCapShift; 51 key |= get_top_n_float_bits<kWidthBits>(stroke.getWidth()) << kWidthShift; 52 key |= get_top_n_float_bits<kMiterBits>(stroke.getMiter()) << kMiterShift; 53 54 return key; 55 } 56