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 
get_top_n_float_bits(float f)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 
ComputeKey(const SkPath & path,const SkStrokeRec & stroke,GrUniqueKey * key)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 
ComputeStrokeKey(const SkStrokeRec & stroke)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