| // Copyright 2021 Google LLC. |
| // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. |
| |
| #ifndef SortKey_DEFINED |
| #define SortKey_DEFINED |
| |
| #include "include/core/SkTypes.h" |
| |
| // These are the material IDs that are stored in the sort key for each class of material |
| constexpr int kInvalidMat = 0; |
| constexpr int kSolidMat = 1; |
| constexpr int kLinearMat = 2; |
| constexpr int kRadialMat = 3; |
| |
| class SortKey { |
| public: |
| // field: | transparent | clipID | depth | material | |
| // bits: | 1 | 8 | 4 | 4 | |
| // Note: the depth and material fields are swapped when the key is opaque and the depth's |
| // order is reversed. This forces all opaque draws with the be sorted by material first |
| // and then front to back. Transparent draws will continue to be sorted back to front. |
| static const uint32_t kMaterialShift = 0; |
| static const uint32_t kNumMaterialBits = 4; |
| static const uint32_t kMaterialMask = (0x1 << kNumMaterialBits) - 1; |
| |
| // The pseudo-Z generated by the draw calls is just a proxy for painter's order. |
| // The "depth" value stored here is a munged version of the pseudo-Z to get the sorting |
| // correct. |
| // For opaque objects the pseudo-Z is reversed so opaque objects are drawn front to back (i.e., |
| // reverse painter's order). |
| // For transparent objects the pseudo-Z is untouched but the transparent bit is set on the |
| // key so transparent object will always be drawn after the opaque objects and in painter's |
| // order. |
| static const uint32_t kDepthShift = kNumMaterialBits; |
| static const uint32_t kNumDepthBits = 4; |
| static const uint32_t kDepthMask = (0x1 << kNumDepthBits) - 1; |
| static const uint32_t kMaxDepth = kDepthMask; |
| |
| static const uint32_t kTransparentShift = kNumMaterialBits + kNumDepthBits; |
| static const uint32_t kNumTransparentBits = 1; |
| static const uint32_t kTransparentMask = (0x1 << kNumTransparentBits) - 1; |
| |
| // TODO: make it clearer that we're initializing the default depth to be 0 here (since the |
| // default key is opaque, its sense is flipped) |
| SortKey() : fKey((kMaxDepth - 1) << kMaterialShift) {} |
| explicit SortKey(bool transparent, uint32_t depth, uint32_t material) { |
| SkASSERT(depth != 0 /* && material != 0*/); |
| SkASSERT(!(depth & ~kDepthMask)); |
| SkASSERT(!(material & ~kMaterialMask)); |
| |
| // TODO: better encapsulate the reversal of the depth & material when the key is opaque |
| if (transparent) { |
| fKey = (0x1 << kTransparentShift) | |
| (depth & kDepthMask) << kDepthShift | |
| (material & kMaterialMask) << kMaterialShift; |
| } else { |
| SkASSERT(kNumDepthBits == kNumMaterialBits); |
| |
| uint32_t munged; |
| // We want the opaque draws to be sorted front to back |
| munged = kMaxDepth - depth - 1; |
| SkASSERT(!(munged & ~kDepthMask)); |
| |
| fKey = (munged & kDepthMask) << kMaterialShift | |
| (material & kMaterialMask) << kDepthShift; |
| } |
| } |
| |
| bool transparent() const { |
| return (fKey >> kTransparentShift) & kTransparentMask; |
| } |
| |
| uint32_t depth() const { |
| if (this->transparent()) { |
| return (fKey >> kDepthShift) & kDepthMask; |
| } |
| |
| // TODO: better encapsulate the reversal of the depth & material when the key is opaque |
| uint32_t tmp = (fKey >> kMaterialShift) & kDepthMask; |
| return (kMaxDepth - tmp) - 1; |
| } |
| |
| uint32_t material() const { |
| // TODO: better encapsulate the reversal of the depth & material when the key is opaque |
| if (this->transparent()) { |
| return (fKey >> kMaterialShift) & kMaterialMask; |
| } else { |
| return (fKey >> kDepthShift) & kMaterialMask; |
| } |
| } |
| |
| void dump() const { |
| SkDebugf("transparent: %d depth: %d mat: %d\n", |
| this->transparent(), |
| this->depth(), |
| this->material()); |
| } |
| |
| bool operator>(const SortKey& other) const { return fKey > other.fKey; } |
| bool operator<(const SortKey& other) const { return fKey < other.fKey; } |
| |
| private: |
| uint64_t fKey; |
| }; |
| |
| #endif // Key_DEFINED |