• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 Google LLC.
2 // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
3 
4 #ifndef SortKey_DEFINED
5 #define SortKey_DEFINED
6 
7 #include "include/core/SkTypes.h"
8 
9 // These are the material IDs that are stored in the sort key for each class of material
10 constexpr int kInvalidMat = 0;
11 constexpr int kSolidMat   = 1;
12 constexpr int kLinearMat  = 2;
13 constexpr int kRadialMat  = 3;
14 
15 class SortKey {
16 public:
17     // field:  |  transparent  | clipID  | depth   |  material  |
18     // bits:   |      1        |   8     |  4      |     4      |
19     // Note: the depth and material fields are swapped when the key is opaque and the depth's
20     // order is reversed. This forces all opaque draws with the be sorted by material first
21     // and then front to back. Transparent draws will continue to be sorted back to front.
22     static const uint32_t kMaterialShift = 0;
23     static const uint32_t kNumMaterialBits = 4;
24     static const uint32_t kMaterialMask = (0x1 << kNumMaterialBits) - 1;
25 
26     // The pseudo-Z generated by the draw calls is just a proxy for painter's order.
27     // The "depth" value stored here is a munged version of the pseudo-Z to get the sorting
28     // correct.
29     // For opaque objects the pseudo-Z is reversed so opaque objects are drawn front to back (i.e.,
30     // reverse painter's order).
31     // For transparent objects the pseudo-Z is untouched but the transparent bit is set on the
32     // key so transparent object will always be drawn after the opaque objects and in painter's
33     // order.
34     static const uint32_t kDepthShift = kNumMaterialBits;
35     static const uint32_t kNumDepthBits = 4;
36     static const uint32_t kDepthMask = (0x1 << kNumDepthBits) - 1;
37     static const uint32_t kMaxDepth = kDepthMask;
38 
39     static const uint32_t kTransparentShift = kNumMaterialBits + kNumDepthBits;
40     static const uint32_t kNumTransparentBits = 1;
41     static const uint32_t kTransparentMask = (0x1 << kNumTransparentBits) - 1;
42 
43     // TODO: make it clearer that we're initializing the default depth to be 0 here (since the
44     // default key is opaque, its sense is flipped)
SortKey()45     SortKey() : fKey((kMaxDepth - 1) << kMaterialShift) {}
SortKey(bool transparent,uint32_t depth,uint32_t material)46     explicit SortKey(bool transparent, uint32_t depth, uint32_t material) {
47         SkASSERT(depth != 0 /* && material != 0*/);
48         SkASSERT(!(depth & ~kDepthMask));
49         SkASSERT(!(material & ~kMaterialMask));
50 
51         // TODO: better encapsulate the reversal of the depth & material when the key is opaque
52         if (transparent) {
53             fKey = (0x1 << kTransparentShift) |
54                    (depth & kDepthMask) << kDepthShift |
55                    (material & kMaterialMask) << kMaterialShift;
56         } else {
57             SkASSERT(kNumDepthBits == kNumMaterialBits);
58 
59             uint32_t munged;
60             // We want the opaque draws to be sorted front to back
61             munged = kMaxDepth - depth - 1;
62             SkASSERT(!(munged & ~kDepthMask));
63 
64             fKey = (munged & kDepthMask) << kMaterialShift |
65                    (material & kMaterialMask) << kDepthShift;
66         }
67     }
68 
transparent()69     bool transparent() const {
70         return (fKey >> kTransparentShift) & kTransparentMask;
71     }
72 
depth()73     uint32_t depth() const {
74         if (this->transparent()) {
75             return (fKey >> kDepthShift) & kDepthMask;
76         }
77 
78         // TODO: better encapsulate the reversal of the depth & material when the key is opaque
79         uint32_t tmp = (fKey >> kMaterialShift) & kDepthMask;
80         return (kMaxDepth - tmp) - 1;
81     }
82 
material()83     uint32_t material() const {
84         // TODO: better encapsulate the reversal of the depth & material when the key is opaque
85         if (this->transparent()) {
86             return (fKey >> kMaterialShift) & kMaterialMask;
87         } else {
88             return (fKey >> kDepthShift) & kMaterialMask;
89         }
90     }
91 
dump()92     void dump() const {
93         SkDebugf("transparent: %d depth: %d mat: %d\n",
94                  this->transparent(),
95                  this->depth(),
96                  this->material());
97     }
98 
99     bool operator>(const SortKey& other) const { return fKey > other.fKey; }
100     bool operator<(const SortKey& other) const { return fKey < other.fKey; }
101 
102 private:
103     uint64_t fKey;
104 };
105 
106 #endif // Key_DEFINED
107