@@ -28,7 +28,7 @@ static uint32_t g_current_background_colour = 0;
2828enum 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
4951enum 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
6266enum 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
8288enum 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
907937template <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>
945978void 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
963996void 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.
0 commit comments