Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

Commit f544d9c

Browse files
author
Fraser J. Gordon
committed
Work around an MSVC bug with templates overloaded on different enum types
1 parent fea054b commit f544d9c

File tree

2 files changed

+108
-25
lines changed

2 files changed

+108
-25
lines changed

engine/src/combiners.cpp

Lines changed: 72 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ static uint32_t g_current_background_colour = 0;
2828
enum BitwiseOperation
2929
{
3030
// Bitwise
31-
OPERATION_CLEAR, // 0
31+
OPERATION_CLEAR,
3232
OPERATION_AND,
3333
OPERATION_AND_REVERSE,
3434
OPERATION_COPY,
@@ -44,25 +44,29 @@ enum BitwiseOperation
4444
OPERATION_OR_INVERTED,
4545
OPERATION_NAND,
4646
OPERATION_SET,
47+
48+
LAST_BITWISE_OPERATION = OPERATION_SET,
4749
};
4850

4951
enum ArithmeticOperation
5052
{
5153
// Arithmetic
52-
OPERATION_BLEND = OPERATION_SET + 1, // 16
54+
OPERATION_BLEND = LAST_BITWISE_OPERATION + 1,
5355
OPERATION_ADD_PIN,
5456
OPERATION_ADD_OVER,
5557
OPERATION_SUB_PIN,
5658
OPERATION_TRANSPARENT,
5759
OPERATION_AD_MAX,
5860
OPERATION_SUB_OVER,
5961
OPERATION_AD_MIN,
62+
63+
LAST_ARITHMETIC_OPERATION = OPERATION_AD_MIN,
6064
};
6165

6266
enum BasicImagingOperation
6367
{
6468
// Basic Imaging Blends
65-
OPERATION_BLEND_CLEAR = OPERATION_AD_MIN + 1, // 24
69+
OPERATION_BLEND_CLEAR = LAST_ARITHMETIC_OPERATION + 1,
6670
OPERATION_BLEND_SRC,
6771
OPERATION_BLEND_DST,
6872
OPERATION_BLEND_SRC_OVER,
@@ -74,15 +78,17 @@ enum BasicImagingOperation
7478
OPERATION_BLEND_SRC_ATOP,
7579
OPERATION_BLEND_DST_ATOP,
7680
OPERATION_BLEND_XOR,
77-
OPERATION_BLEND_PLUS, //36
81+
OPERATION_BLEND_PLUS,
7882
OPERATION_BLEND_MULTIPLY,
7983
OPERATION_BLEND_SCREEN,
84+
85+
LAST_BASIC_IMAGING_OPERATION = OPERATION_BLEND_SCREEN,
8086
};
8187

8288
enum AdvancedImagingOperation
8389
{
8490
// Advanced Imaging Blends
85-
OPERATION_BLEND_OVERLAY = OPERATION_BLEND_SCREEN + 1,
91+
OPERATION_BLEND_OVERLAY = LAST_BASIC_IMAGING_OPERATION + 1,
8692
OPERATION_BLEND_DARKEN,
8793
OPERATION_BLEND_LIGHTEN,
8894
OPERATION_BLEND_DODGE,
@@ -91,6 +97,8 @@ enum AdvancedImagingOperation
9197
OPERATION_BLEND_SOFT_LIGHT,
9298
OPERATION_BLEND_DIFFERENCE,
9399
OPERATION_BLEND_EXCLUSION,
100+
101+
LAST_ADVANCED_IMAGING_OPERATION = OPERATION_BLEND_EXCLUSION,
94102
};
95103

96104
#define OPERATION_SRC_BIC OPERATION_AND_REVERSE
@@ -884,24 +892,46 @@ template<AdvancedImagingOperation x_combiner, bool x_dst_alpha, bool x_src_alpha
884892
return t_red | (t_green << 8) | (t_blue << 16);
885893
}
886894

887-
template<BitwiseOperation x_combiner, bool x_dst_alpha, bool x_src_alpha> INLINE uint32_t pixel_combine(uint32_t dst, uint32_t src)
888-
{
895+
// These are commented out until a particular bug in Visual Studio (described
896+
// below) is fixed.
897+
//
898+
/*template<BitwiseOperation x_combiner, bool x_dst_alpha, bool x_src_alpha> INLINE uint32_t pixel_combine(uint32_t dst, uint32_t src)
899+
{
889900
return bitwise_combiner<x_combiner, x_dst_alpha, x_src_alpha>(dst, src);
890-
}
891-
892-
template<ArithmeticOperation x_combiner, bool x_dst_alpha, bool x_src_alpha> INLINE uint32_t pixel_combine(uint32_t dst, uint32_t src)
893-
{
901+
}
902+
903+
template<ArithmeticOperation x_combiner, bool x_dst_alpha, bool x_src_alpha> INLINE uint32_t pixel_combine(uint32_t dst, uint32_t src)
904+
{
894905
return arithmetic_combiner<x_combiner, x_dst_alpha, x_src_alpha>(dst, src);
895-
}
896-
897-
template<BasicImagingOperation x_combiner, bool x_dst_alpha, bool x_src_alpha> INLINE uint32_t pixel_combine(uint32_t dst, uint32_t src)
898-
{
906+
}
907+
908+
template<BasicImagingOperation x_combiner, bool x_dst_alpha, bool x_src_alpha> INLINE uint32_t pixel_combine(uint32_t dst, uint32_t src)
909+
{
899910
return basic_imaging_combiner<x_combiner, x_dst_alpha, x_src_alpha>(dst, src);
900-
}
911+
}
912+
913+
template<AdvancedImagingOperation x_combiner, bool x_dst_alpha, bool x_src_alpha> INLINE uint32_t pixel_combine(uint32_t dst, uint32_t src)
914+
{
915+
return advanced_imaging_combiner<x_combiner, x_dst_alpha, x_src_alpha>(dst, src);
916+
}*/
901917

902-
template<AdvancedImagingOperation x_combiner, bool x_dst_alpha, bool x_src_alpha> INLINE uint32_t pixel_combine(uint32_t dst, uint32_t src)
918+
// Nasty shim to work around a Visual Studio compiler bug (it doesn't handle
919+
// templates whose parameters are overloaded on enums properly so it always
920+
// tries to use the AdvancedImagingOperation form of the template)
921+
template<int x_combiner, bool x_dst_alpha, bool x_src_alpha> INLINE uint32_t pixel_combine(uint32_t dst, uint32_t src)
903922
{
904-
return advanced_imaging_combiner<x_combiner, x_dst_alpha, x_src_alpha>(dst, src);
923+
// These should get collapsed at compile-time so no need to worry about a
924+
// performance hit (assuming the compiler is half-way sensible...)
925+
if (x_combiner <= LAST_BITWISE_OPERATION)
926+
return bitwise_combiner<BitwiseOperation(x_combiner), x_dst_alpha, x_src_alpha>(dst, src);
927+
else if (x_combiner <= LAST_ARITHMETIC_OPERATION)
928+
return arithmetic_combiner<ArithmeticOperation(x_combiner), x_dst_alpha, x_src_alpha>(dst, src);
929+
else if (x_combiner <= LAST_BASIC_IMAGING_OPERATION)
930+
return basic_imaging_combiner<BasicImagingOperation(x_combiner), x_dst_alpha, x_src_alpha>(dst, src);
931+
else if (x_combiner <= LAST_ADVANCED_IMAGING_OPERATION)
932+
return advanced_imaging_combiner<AdvancedImagingOperation(x_combiner), x_dst_alpha, x_src_alpha>(dst, src);
933+
else
934+
MCUnreachable();
905935
}
906936

907937
template<class T, T x_combiner, bool x_dst_alpha, bool x_src_alpha>
@@ -941,7 +971,10 @@ INLINE void surface_combine(void *p_dst, int32_t p_dst_stride, const void *p_src
941971
}
942972
}
943973

944-
template <BitwiseOperation x_combiner, bool x_dst_alpha, bool x_src_alpha>
974+
// These are commented out until a particular bug in Visual Studio (described
975+
// below) is fixed.
976+
//
977+
/*template <BitwiseOperation x_combiner, bool x_dst_alpha, bool x_src_alpha>
945978
void surface_combine(void *p_dst, int32_t p_dst_stride, const void *p_src, uint32_t p_src_stride, uint32_t p_width, uint32_t p_height, uint8_t p_opacity)
946979
{
947980
return surface_combine<BitwiseOperation, x_combiner, x_dst_alpha, x_src_alpha>(p_dst, p_dst_stride, p_src, p_src_stride, p_width, p_height, p_opacity);
@@ -963,6 +996,26 @@ template <AdvancedImagingOperation x_combiner, bool x_dst_alpha, bool x_src_alph
963996
void surface_combine(void *p_dst, int32_t p_dst_stride, const void *p_src, uint32_t p_src_stride, uint32_t p_width, uint32_t p_height, uint8_t p_opacity)
964997
{
965998
return surface_combine<AdvancedImagingOperation, x_combiner, x_dst_alpha, x_src_alpha>(p_dst, p_dst_stride, p_src, p_src_stride, p_width, p_height, p_opacity);
999+
}*/
1000+
1001+
// Nasty shim to work around a Visual Studio compiler bug (it doesn't handle
1002+
// templates whose parameters are overloaded on enums properly so it always
1003+
// tries to use the AdvancedImagingOperation form of the template)
1004+
template<int x_combiner, bool x_dst_alpha, bool x_src_alpha>
1005+
INLINE void surface_combine(void *p_dst, int32_t p_dst_stride, const void *p_src, uint32_t p_src_stride, uint32_t p_width, uint32_t p_height, uint8_t p_opacity)
1006+
{
1007+
// These should get collapsed at compile-time so no need to worry about a
1008+
// performance hit (assuming the compiler is half-way sensible...)
1009+
if (x_combiner <= LAST_BITWISE_OPERATION)
1010+
return surface_combine<BitwiseOperation, BitwiseOperation(x_combiner), x_dst_alpha, x_src_alpha>(p_dst, p_dst_stride, p_src, p_src_stride, p_width, p_height, p_opacity);
1011+
else if (x_combiner <= LAST_ARITHMETIC_OPERATION)
1012+
return surface_combine<ArithmeticOperation, ArithmeticOperation(x_combiner), x_dst_alpha, x_src_alpha>(p_dst, p_dst_stride, p_src, p_src_stride, p_width, p_height, p_opacity);
1013+
else if (x_combiner <= LAST_BASIC_IMAGING_OPERATION)
1014+
return surface_combine<BasicImagingOperation, BasicImagingOperation(x_combiner), x_dst_alpha, x_src_alpha>(p_dst, p_dst_stride, p_src, p_src_stride, p_width, p_height, p_opacity);
1015+
else if (x_combiner <= LAST_ADVANCED_IMAGING_OPERATION)
1016+
return surface_combine<AdvancedImagingOperation, AdvancedImagingOperation(x_combiner), x_dst_alpha, x_src_alpha>(p_dst, p_dst_stride, p_src, p_src_stride, p_width, p_height, p_opacity);
1017+
else
1018+
MCUnreachable();
9661019
}
9671020

9681021
// MW-2009-02-09: This is the most important combiner so we optimize it.

libgraphics/src/legacyblendmodes.cpp

100644100755
Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
3333
enum BitwiseOperation
3434
{
3535
// Bitwise
36-
OPERATION_CLEAR, // 0
36+
OPERATION_CLEAR,
3737
OPERATION_AND,
3838
OPERATION_AND_REVERSE,
3939
OPERATION_COPY,
@@ -49,25 +49,29 @@ enum BitwiseOperation
4949
OPERATION_OR_INVERTED,
5050
OPERATION_NAND,
5151
OPERATION_SET,
52+
53+
LAST_BITWISE_OPERATION = OPERATION_SET,
5254
};
5355

5456
enum ArithmeticOperation
5557
{
5658
// Arithmetic
57-
OPERATION_BLEND = OPERATION_SET + 1, // 16
59+
OPERATION_BLEND = LAST_BITWISE_OPERATION + 1,
5860
OPERATION_ADD_PIN,
5961
OPERATION_ADD_OVER,
6062
OPERATION_SUB_PIN,
6163
OPERATION_TRANSPARENT,
6264
OPERATION_AD_MAX,
6365
OPERATION_SUB_OVER,
6466
OPERATION_AD_MIN,
67+
68+
LAST_ARITHMETIC_OPERATION = OPERATION_AD_MIN,
6569
};
6670

6771
enum BasicImagingOperation
6872
{
6973
// Basic Imaging Blends
70-
OPERATION_BLEND_CLEAR = OPERATION_AD_MIN + 1, // 24
74+
OPERATION_BLEND_CLEAR = LAST_ARITHMETIC_OPERATION + 1,
7175
OPERATION_BLEND_SRC,
7276
OPERATION_BLEND_DST,
7377
OPERATION_BLEND_SRC_OVER,
@@ -79,15 +83,17 @@ enum BasicImagingOperation
7983
OPERATION_BLEND_SRC_ATOP,
8084
OPERATION_BLEND_DST_ATOP,
8185
OPERATION_BLEND_XOR,
82-
OPERATION_BLEND_PLUS, //36
86+
OPERATION_BLEND_PLUS,
8387
OPERATION_BLEND_MULTIPLY,
8488
OPERATION_BLEND_SCREEN,
89+
90+
LAST_BASIC_IMAGING_OPERATION = OPERATION_BLEND_SCREEN,
8591
};
8692

8793
enum AdvancedImagingOperation
8894
{
8995
// Advanced Imaging Blends
90-
OPERATION_BLEND_OVERLAY = OPERATION_BLEND_SCREEN + 1,
96+
OPERATION_BLEND_OVERLAY = LAST_BASIC_IMAGING_OPERATION + 1,
9197
OPERATION_BLEND_DARKEN,
9298
OPERATION_BLEND_LIGHTEN,
9399
OPERATION_BLEND_DODGE,
@@ -96,6 +102,8 @@ enum AdvancedImagingOperation
96102
OPERATION_BLEND_SOFT_LIGHT,
97103
OPERATION_BLEND_DIFFERENCE,
98104
OPERATION_BLEND_EXCLUSION,
105+
106+
LAST_ADVANCED_IMAGING_OPERATION = OPERATION_BLEND_EXCLUSION,
99107
};
100108

101109
static uint16_t s_sqrt_table[1024] =
@@ -958,7 +966,10 @@ template<AdvancedImagingOperation x_combiner, bool x_dst_alpha, bool x_src_alpha
958966
return t_red | (t_green << 8) | (t_blue << 16);
959967
}
960968

961-
template<BitwiseOperation x_combiner, bool x_dst_alpha, bool x_src_alpha> INLINE uint32_t pixel_combine(uint32_t dst, uint32_t src)
969+
// These are commented out until a particular bug in Visual Studio (described
970+
// below) is fixed.
971+
//
972+
/*template<BitwiseOperation x_combiner, bool x_dst_alpha, bool x_src_alpha> INLINE uint32_t pixel_combine(uint32_t dst, uint32_t src)
962973
{
963974
return bitwise_combiner<x_combiner, x_dst_alpha, x_src_alpha>(dst, src);
964975
}
@@ -976,6 +987,25 @@ template<BasicImagingOperation x_combiner, bool x_dst_alpha, bool x_src_alpha> I
976987
template<AdvancedImagingOperation x_combiner, bool x_dst_alpha, bool x_src_alpha> INLINE uint32_t pixel_combine(uint32_t dst, uint32_t src)
977988
{
978989
return advanced_imaging_combiner<x_combiner, x_dst_alpha, x_src_alpha>(dst, src);
990+
}*/
991+
992+
// Nasty shim to work around a Visual Studio compiler bug (it doesn't handle
993+
// templates whose parameters are overloaded on enums properly so it always
994+
// tries to use the AdvancedImagingOperation form of the template)
995+
template<int x_combiner, bool x_dst_alpha, bool x_src_alpha> INLINE uint32_t pixel_combine(uint32_t dst, uint32_t src)
996+
{
997+
// These should get collapsed at compile-time so no need to worry about a
998+
// performance hit (assuming the compiler is half-way sensible...)
999+
if (x_combiner <= LAST_BITWISE_OPERATION)
1000+
return bitwise_combiner<BitwiseOperation(x_combiner), x_dst_alpha, x_src_alpha>(dst, src);
1001+
else if (x_combiner <= LAST_ARITHMETIC_OPERATION)
1002+
return arithmetic_combiner<ArithmeticOperation(x_combiner), x_dst_alpha, x_src_alpha>(dst, src);
1003+
else if (x_combiner <= LAST_BASIC_IMAGING_OPERATION)
1004+
return basic_imaging_combiner<BasicImagingOperation(x_combiner), x_dst_alpha, x_src_alpha>(dst, src);
1005+
else if (x_combiner <= LAST_ADVANCED_IMAGING_OPERATION)
1006+
return advanced_imaging_combiner<AdvancedImagingOperation(x_combiner), x_dst_alpha, x_src_alpha>(dst, src);
1007+
else
1008+
MCUnreachable();
9791009
}
9801010

9811011
template<int x_combiner, bool x_dst_alpha, bool x_src_alpha> void surface_combine(void *p_dst, int32_t p_dst_stride, const void *p_src, uint32_t p_src_stride, uint32_t p_width, uint32_t p_height, uint8_t p_opacity)

0 commit comments

Comments
 (0)