compopinfo.cpp (6754B)
1 // This file is part of Blend2D project <https://blend2d.com> 2 // 3 // See blend2d.h or LICENSE.md for license and copyright information 4 // SPDX-License-Identifier: Zlib 5 6 #include "api-build_p.h" 7 #include "compopinfo_p.h" 8 #include "compopsimplifyimpl_p.h" 9 10 namespace bl { 11 12 struct CompOpInfoGen { 13 #define F(VALUE) CompOpFlags::VALUE 14 15 static constexpr CompOpInfo value(size_t op) noexcept { 16 return CompOpInfo { uint16_t( 17 op == size_t(CompOpExt::kSrcOver) ? F(kTypeA) | F(kDc) | F(kDa) | F(kSc) | F(kSa) | F(kNone) | F(kNopIfSaEq0) : 18 op == size_t(CompOpExt::kSrcCopy) ? F(kTypeB) | F(kNone) | F(kNone) | F(kSc) | F(kSa) | F(kNone) | F(kNone) : 19 op == size_t(CompOpExt::kSrcIn) ? F(kTypeB) | F(kNone) | F(kDa) | F(kSc) | F(kSa) | F(kNopIfDaEq0) | F(kNone) : 20 op == size_t(CompOpExt::kSrcOut) ? F(kTypeB) | F(kNone) | F(kDa) | F(kSc) | F(kSa) | F(kNone) | F(kNone) : 21 op == size_t(CompOpExt::kSrcAtop) ? F(kTypeA) | F(kDc) | F(kDa) | F(kSc) | F(kSa) | F(kNopIfDaEq0) | F(kNopIfSaEq0) : 22 op == size_t(CompOpExt::kDstOver) ? F(kTypeA) | F(kDc) | F(kDa) | F(kSc) | F(kSa) | F(kNopIfDaEq1) | F(kNopIfSaEq0) : 23 op == size_t(CompOpExt::kDstCopy) ? F(kTypeC) | F(kDc) | F(kDa) | F(kNone) | F(kNone) | F(kNop) | F(kNop) : 24 op == size_t(CompOpExt::kDstIn) ? F(kTypeB) | F(kDc) | F(kDa) | F(kNone) | F(kSa) | F(kNone) | F(kNopIfSaEq1) : 25 op == size_t(CompOpExt::kDstOut) ? F(kTypeA) | F(kDc) | F(kDa) | F(kNone) | F(kSa) | F(kNone) | F(kNopIfSaEq0) : 26 op == size_t(CompOpExt::kDstAtop) ? F(kTypeB) | F(kDc) | F(kDa) | F(kSc) | F(kSa) | F(kNone) | F(kNone) : 27 op == size_t(CompOpExt::kXor) ? F(kTypeA) | F(kDc) | F(kDa) | F(kSc) | F(kSa) | F(kNone) | F(kNopIfSaEq0) : 28 op == size_t(CompOpExt::kClear) ? F(kTypeC) | F(kNone) | F(kNone) | F(kNone) | F(kNone) | F(kNopIfDaEq0) | F(kNone) : 29 30 op == size_t(CompOpExt::kPlus) ? F(kTypeA) | F(kDc) | F(kDa) | F(kSc) | F(kSa) | F(kNone) | F(kNopIfSaEq0) : 31 op == size_t(CompOpExt::kMinus) ? F(kTypeC) | F(kDc) | F(kDa) | F(kSc) | F(kSa) | F(kNone) | F(kNopIfSaEq0) : 32 op == size_t(CompOpExt::kModulate) ? F(kTypeB) | F(kDc) | F(kDa) | F(kSc) | F(kSa) | F(kNopIfDaEq0) | F(kNone) : 33 op == size_t(CompOpExt::kMultiply) ? F(kTypeA) | F(kDc) | F(kDa) | F(kSc) | F(kSa) | F(kNopIfDaEq0) | F(kNopIfSaEq0) : 34 op == size_t(CompOpExt::kScreen) ? F(kTypeA) | F(kDc) | F(kDa) | F(kSc) | F(kSa) | F(kNone) | F(kNopIfSaEq0) : 35 op == size_t(CompOpExt::kOverlay) ? F(kTypeA) | F(kDc) | F(kDa) | F(kSc) | F(kSa) | F(kNone) | F(kNopIfSaEq0) : 36 op == size_t(CompOpExt::kDarken) ? F(kTypeA) | F(kDc) | F(kDa) | F(kSc) | F(kSa) | F(kNone) | F(kNopIfSaEq0) : 37 op == size_t(CompOpExt::kLighten) ? F(kTypeA) | F(kDc) | F(kDa) | F(kSc) | F(kSa) | F(kNone) | F(kNopIfSaEq0) : 38 op == size_t(CompOpExt::kColorDodge) ? F(kTypeA) | F(kDc) | F(kDa) | F(kSc) | F(kSa) | F(kNone) | F(kNopIfSaEq0) : 39 op == size_t(CompOpExt::kColorBurn) ? F(kTypeA) | F(kDc) | F(kDa) | F(kSc) | F(kSa) | F(kNone) | F(kNopIfSaEq0) : 40 op == size_t(CompOpExt::kLinearBurn) ? F(kTypeA) | F(kDc) | F(kDa) | F(kSc) | F(kSa) | F(kNone) | F(kNopIfSaEq0) : 41 op == size_t(CompOpExt::kLinearLight) ? F(kTypeA) | F(kDc) | F(kDa) | F(kSc) | F(kSa) | F(kNone) | F(kNopIfSaEq0) : 42 op == size_t(CompOpExt::kPinLight) ? F(kTypeC) | F(kDc) | F(kDa) | F(kSc) | F(kSa) | F(kNone) | F(kNopIfSaEq0) : 43 op == size_t(CompOpExt::kHardLight) ? F(kTypeA) | F(kDc) | F(kDa) | F(kSc) | F(kSa) | F(kNone) | F(kNopIfSaEq0) : 44 op == size_t(CompOpExt::kSoftLight) ? F(kTypeA) | F(kDc) | F(kDa) | F(kSc) | F(kSa) | F(kNone) | F(kNopIfSaEq0) : 45 op == size_t(CompOpExt::kDifference) ? F(kTypeA) | F(kDc) | F(kDa) | F(kSc) | F(kSa) | F(kNone) | F(kNopIfSaEq0) : 46 op == size_t(CompOpExt::kExclusion) ? F(kTypeA) | F(kDc) | F(kDa) | F(kSc) | F(kSa) | F(kNone) | F(kNopIfSaEq0) : 47 48 op == size_t(CompOpExt::kAlphaInv) ? F(kTypeC) | F(kNone) | F(kDa) | F(kNone) | F(kNone) | F(kNone) | F(kNone) : F(kNone) 49 ) }; 50 } 51 52 #undef F 53 }; 54 55 const LookupTable<CompOpInfo, uint32_t(CompOpExt::kMaxValue) + 1> comp_op_info_table = 56 make_lookup_table<CompOpInfo, uint32_t(CompOpExt::kMaxValue) + 1, CompOpInfoGen>(); 57 58 struct CompOpSimplifyInfoGen { 59 // Function called by the table generator, decomposes the parameters and passes them to the simplifier. 60 static constexpr CompOpSimplifyInfo value(size_t index) noexcept { 61 return CompOpSimplifyInfoImpl::simplify( 62 CompOpExt(uint32_t((index / kFormatExtCount)) % kCompOpExtCount), 63 FormatExt(index / (kCompOpExtCount * kFormatExtCount)), 64 FormatExt(index % kFormatExtCount)); 65 } 66 }; 67 68 template<bl::FormatExt Dst> 69 struct CompOpSimplifyInfoRecordSetGen { 70 // Function called by the table generator, decomposes the parameters and passes them to the simplifier. 71 static constexpr CompOpSimplifyInfo value(size_t index) noexcept { 72 return CompOpSimplifyInfoImpl::simplify(CompOpExt(index / kFormatExtCount), Dst, FormatExt(index % kFormatExtCount)); 73 } 74 }; 75 76 static_assert(BL_FORMAT_MAX_VALUE == 3u, "Don't forget to add new formats to comp_op_simplify_info_table"); 77 78 // HACK: MSVC doesn't honor constexpr functions and sometimes outputs initialization 79 // code even when the expression can be calculated at compile time. To fix this 80 // we go through an additional constexpr to force the compiler to always generate 81 // our lookup tables at compile time. 82 // 83 // Additionally, if there is a mistake leading to recursion the compiler would catch it 84 // at compile-time instead of hitting it at runtime during initialization. 85 static constexpr const CompOpSimplifyInfoTable comp_op_simplify_info_table_ = {{ 86 make_lookup_table<CompOpSimplifyInfo, kCompOpSimplifyRecordSize, CompOpSimplifyInfoRecordSetGen<FormatExt(0)>>(), 87 make_lookup_table<CompOpSimplifyInfo, kCompOpSimplifyRecordSize, CompOpSimplifyInfoRecordSetGen<FormatExt(1)>>(), 88 make_lookup_table<CompOpSimplifyInfo, kCompOpSimplifyRecordSize, CompOpSimplifyInfoRecordSetGen<FormatExt(2)>>(), 89 make_lookup_table<CompOpSimplifyInfo, kCompOpSimplifyRecordSize, CompOpSimplifyInfoRecordSetGen<FormatExt(3)>>() 90 }}; 91 const CompOpSimplifyInfoTable comp_op_simplify_info_table = comp_op_simplify_info_table_; 92 93 } // {bl}