diff --git a/src/dec/vp8_dec.c b/src/dec/vp8_dec.c index 6212efd1..c904b529 100644 --- a/src/dec/vp8_dec.c +++ b/src/dec/vp8_dec.c @@ -491,7 +491,7 @@ static int GetCoeffsAlt(VP8BitReader* const br, return 16; } -WEBP_TSAN_IGNORE_FUNCTION static void InitGetCoeffs(void) { +static WEBP_TSAN_IGNORE_FUNCTION void InitGetCoeffs(void) { if (GetCoeffs == NULL) { if (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kSlowSSSE3)) { GetCoeffs = GetCoeffsAlt; diff --git a/src/dsp/alpha_processing.c b/src/dsp/alpha_processing.c index 995b4345..819d1391 100644 --- a/src/dsp/alpha_processing.c +++ b/src/dsp/alpha_processing.c @@ -409,12 +409,7 @@ extern void WebPInitAlphaProcessingSSE2(void); extern void WebPInitAlphaProcessingSSE41(void); extern void WebPInitAlphaProcessingNEON(void); -static volatile VP8CPUInfo alpha_processing_last_cpuinfo_used = - (VP8CPUInfo)&alpha_processing_last_cpuinfo_used; - -WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessing(void) { - if (alpha_processing_last_cpuinfo_used == VP8GetCPUInfo) return; - +WEBP_DSP_INIT_FUNC(WebPInitAlphaProcessing) { WebPMultARGBRow = WebPMultARGBRow_C; WebPMultRow = WebPMultRow_C; WebPApplyAlphaMultiply4444 = ApplyAlphaMultiply_16b_C; @@ -474,6 +469,4 @@ WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessing(void) { assert(WebPPackRGB != NULL); assert(WebPHasAlpha8b != NULL); assert(WebPHasAlpha32b != NULL); - - alpha_processing_last_cpuinfo_used = VP8GetCPUInfo; } diff --git a/src/dsp/cost.c b/src/dsp/cost.c index a732389d..634ccc20 100644 --- a/src/dsp/cost.c +++ b/src/dsp/cost.c @@ -378,12 +378,7 @@ extern void VP8EncDspCostInitMIPS32(void); extern void VP8EncDspCostInitMIPSdspR2(void); extern void VP8EncDspCostInitSSE2(void); -static volatile VP8CPUInfo cost_last_cpuinfo_used = - (VP8CPUInfo)&cost_last_cpuinfo_used; - -WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspCostInit(void) { - if (cost_last_cpuinfo_used == VP8GetCPUInfo) return; - +WEBP_DSP_INIT_FUNC(VP8EncDspCostInit) { VP8GetResidualCost = GetResidualCost_C; VP8SetResidualCoeffs = SetResidualCoeffs_C; @@ -405,8 +400,6 @@ WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspCostInit(void) { } #endif } - - cost_last_cpuinfo_used = VP8GetCPUInfo; } //------------------------------------------------------------------------------ diff --git a/src/dsp/dec.c b/src/dsp/dec.c index 7e824075..1119842d 100644 --- a/src/dsp/dec.c +++ b/src/dsp/dec.c @@ -741,12 +741,7 @@ extern void VP8DspInitMIPS32(void); extern void VP8DspInitMIPSdspR2(void); extern void VP8DspInitMSA(void); -static volatile VP8CPUInfo dec_last_cpuinfo_used = - (VP8CPUInfo)&dec_last_cpuinfo_used; - -WEBP_TSAN_IGNORE_FUNCTION void VP8DspInit(void) { - if (dec_last_cpuinfo_used == VP8GetCPUInfo) return; - +WEBP_DSP_INIT_FUNC(VP8DspInit) { VP8InitClipTables(); #if !WEBP_NEON_OMIT_C_CODE @@ -889,6 +884,4 @@ WEBP_TSAN_IGNORE_FUNCTION void VP8DspInit(void) { assert(VP8PredChroma8[5] != NULL); assert(VP8PredChroma8[6] != NULL); assert(VP8DitherCombine8x8 != NULL); - - dec_last_cpuinfo_used = VP8GetCPUInfo; } diff --git a/src/dsp/dsp.h b/src/dsp/dsp.h index 5146949e..4ab77a51 100644 --- a/src/dsp/dsp.h +++ b/src/dsp/dsp.h @@ -141,6 +141,42 @@ extern "C" { #endif #endif +#if defined(WEBP_USE_THREAD) && !defined(_WIN32) +#include // NOLINT + +#define WEBP_DSP_INIT(func) do { \ + static volatile VP8CPUInfo func ## _last_cpuinfo_used = \ + (VP8CPUInfo)&func ## _last_cpuinfo_used; \ + static pthread_mutex_t func ## _lock = PTHREAD_MUTEX_INITIALIZER; \ + if (pthread_mutex_lock(&func ## _lock)) break; \ + if (func ## _last_cpuinfo_used != VP8GetCPUInfo) func(); \ + func ## _last_cpuinfo_used = VP8GetCPUInfo; \ + (void)pthread_mutex_unlock(&func ## _lock); \ +} while (0) +#else // !(defined(WEBP_USE_THREAD) && !defined(_WIN32)) +#define WEBP_DSP_INIT(func) do { \ + static volatile VP8CPUInfo func ## _last_cpuinfo_used = \ + (VP8CPUInfo)&func ## _last_cpuinfo_used; \ + if (func ## _last_cpuinfo_used == VP8GetCPUInfo) break; \ + func(); \ + func ## _last_cpuinfo_used = VP8GetCPUInfo; \ +} while (0) +#endif // defined(WEBP_USE_THREAD) && !defined(_WIN32) + +// Defines an Init + helper function that control multiple initialization of +// function pointers / tables. +/* Usage: + WEBP_DSP_INIT_FUNC(InitFunc) { + ...function body + } +*/ +#define WEBP_DSP_INIT_FUNC(name) \ + static WEBP_TSAN_IGNORE_FUNCTION void name ## _body(void); \ + WEBP_TSAN_IGNORE_FUNCTION void name(void) { \ + WEBP_DSP_INIT(name ## _body); \ + } \ + static WEBP_TSAN_IGNORE_FUNCTION void name ## _body(void) + #define WEBP_UBSAN_IGNORE_UNDEF #define WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW #if defined(__clang__) && defined(__has_attribute) @@ -196,7 +232,7 @@ WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo; // avoiding a compiler warning. #define WEBP_DSP_INIT_STUB(func) \ extern void func(void); \ - WEBP_TSAN_IGNORE_FUNCTION void func(void) {} + void func(void) {} //------------------------------------------------------------------------------ // Encoding diff --git a/src/dsp/enc.c b/src/dsp/enc.c index 1c807f1d..fa23b40a 100644 --- a/src/dsp/enc.c +++ b/src/dsp/enc.c @@ -740,12 +740,7 @@ extern void VP8EncDspInitMIPS32(void); extern void VP8EncDspInitMIPSdspR2(void); extern void VP8EncDspInitMSA(void); -static volatile VP8CPUInfo enc_last_cpuinfo_used = - (VP8CPUInfo)&enc_last_cpuinfo_used; - -WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspInit(void) { - if (enc_last_cpuinfo_used == VP8GetCPUInfo) return; - +WEBP_DSP_INIT_FUNC(VP8EncDspInit) { VP8DspInit(); // common inverse transforms InitTables(); @@ -838,6 +833,4 @@ WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspInit(void) { assert(VP8EncQuantizeBlockWHT != NULL); assert(VP8Copy4x4 != NULL); assert(VP8Copy16x8 != NULL); - - enc_last_cpuinfo_used = VP8GetCPUInfo; } diff --git a/src/dsp/filters.c b/src/dsp/filters.c index ca5f877d..069a22ea 100644 --- a/src/dsp/filters.c +++ b/src/dsp/filters.c @@ -238,12 +238,7 @@ extern void VP8FiltersInitMSA(void); extern void VP8FiltersInitNEON(void); extern void VP8FiltersInitSSE2(void); -static volatile VP8CPUInfo filters_last_cpuinfo_used = - (VP8CPUInfo)&filters_last_cpuinfo_used; - -WEBP_TSAN_IGNORE_FUNCTION void VP8FiltersInit(void) { - if (filters_last_cpuinfo_used == VP8GetCPUInfo) return; - +WEBP_DSP_INIT_FUNC(VP8FiltersInit) { WebPUnfilters[WEBP_FILTER_NONE] = NULL; #if !WEBP_NEON_OMIT_C_CODE WebPUnfilters[WEBP_FILTER_HORIZONTAL] = HorizontalUnfilter_C; @@ -289,6 +284,4 @@ WEBP_TSAN_IGNORE_FUNCTION void VP8FiltersInit(void) { assert(WebPFilters[WEBP_FILTER_HORIZONTAL] != NULL); assert(WebPFilters[WEBP_FILTER_VERTICAL] != NULL); assert(WebPFilters[WEBP_FILTER_GRADIENT] != NULL); - - filters_last_cpuinfo_used = VP8GetCPUInfo; } diff --git a/src/dsp/lossless.c b/src/dsp/lossless.c index 83f553d9..f9b3c182 100644 --- a/src/dsp/lossless.c +++ b/src/dsp/lossless.c @@ -577,9 +577,6 @@ extern void VP8LDspInitNEON(void); extern void VP8LDspInitMIPSdspR2(void); extern void VP8LDspInitMSA(void); -static volatile VP8CPUInfo lossless_last_cpuinfo_used = - (VP8CPUInfo)&lossless_last_cpuinfo_used; - #define COPY_PREDICTOR_ARRAY(IN, OUT) do { \ (OUT)[0] = IN##0_C; \ (OUT)[1] = IN##1_C; \ @@ -599,9 +596,7 @@ static volatile VP8CPUInfo lossless_last_cpuinfo_used = (OUT)[15] = IN##0_C; \ } while (0); -WEBP_TSAN_IGNORE_FUNCTION void VP8LDspInit(void) { - if (lossless_last_cpuinfo_used == VP8GetCPUInfo) return; - +WEBP_DSP_INIT_FUNC(VP8LDspInit) { COPY_PREDICTOR_ARRAY(Predictor, VP8LPredictors) COPY_PREDICTOR_ARRAY(Predictor, VP8LPredictors_C) COPY_PREDICTOR_ARRAY(PredictorAdd, VP8LPredictorsAdd) @@ -658,8 +653,6 @@ WEBP_TSAN_IGNORE_FUNCTION void VP8LDspInit(void) { assert(VP8LConvertBGRAToRGB565 != NULL); assert(VP8LMapColor32b != NULL); assert(VP8LMapColor8b != NULL); - - lossless_last_cpuinfo_used = VP8GetCPUInfo; } #undef COPY_PREDICTOR_ARRAY diff --git a/src/dsp/lossless_enc.c b/src/dsp/lossless_enc.c index 92ca3c05..d608326f 100644 --- a/src/dsp/lossless_enc.c +++ b/src/dsp/lossless_enc.c @@ -863,12 +863,7 @@ extern void VP8LEncDspInitMIPS32(void); extern void VP8LEncDspInitMIPSdspR2(void); extern void VP8LEncDspInitMSA(void); -static volatile VP8CPUInfo lossless_enc_last_cpuinfo_used = - (VP8CPUInfo)&lossless_enc_last_cpuinfo_used; - -WEBP_TSAN_IGNORE_FUNCTION void VP8LEncDspInit(void) { - if (lossless_enc_last_cpuinfo_used == VP8GetCPUInfo) return; - +WEBP_DSP_INIT_FUNC(VP8LEncDspInit) { VP8LDspInit(); #if !WEBP_NEON_OMIT_C_CODE @@ -1011,8 +1006,6 @@ WEBP_TSAN_IGNORE_FUNCTION void VP8LEncDspInit(void) { assert(VP8LPredictorsSub_C[13] != NULL); assert(VP8LPredictorsSub_C[14] != NULL); assert(VP8LPredictorsSub_C[15] != NULL); - - lossless_enc_last_cpuinfo_used = VP8GetCPUInfo; } //------------------------------------------------------------------------------ diff --git a/src/dsp/rescaler.c b/src/dsp/rescaler.c index 4b6b7834..f307d350 100644 --- a/src/dsp/rescaler.c +++ b/src/dsp/rescaler.c @@ -204,11 +204,7 @@ extern void WebPRescalerDspInitMIPSdspR2(void); extern void WebPRescalerDspInitMSA(void); extern void WebPRescalerDspInitNEON(void); -static volatile VP8CPUInfo rescaler_last_cpuinfo_used = - (VP8CPUInfo)&rescaler_last_cpuinfo_used; - -WEBP_TSAN_IGNORE_FUNCTION void WebPRescalerDspInit(void) { - if (rescaler_last_cpuinfo_used == VP8GetCPUInfo) return; +WEBP_DSP_INIT_FUNC(WebPRescalerDspInit) { #if !defined(WEBP_REDUCE_SIZE) #if !WEBP_NEON_OMIT_C_CODE WebPRescalerExportRowExpand = WebPRescalerExportRowExpand_C; @@ -253,5 +249,4 @@ WEBP_TSAN_IGNORE_FUNCTION void WebPRescalerDspInit(void) { assert(WebPRescalerImportRowExpand != NULL); assert(WebPRescalerImportRowShrink != NULL); #endif // WEBP_REDUCE_SIZE - rescaler_last_cpuinfo_used = VP8GetCPUInfo; } diff --git a/src/dsp/ssim.c b/src/dsp/ssim.c index dc1b518a..989ce825 100644 --- a/src/dsp/ssim.c +++ b/src/dsp/ssim.c @@ -139,12 +139,7 @@ VP8AccumulateSSEFunc VP8AccumulateSSE; extern void VP8SSIMDspInitSSE2(void); -static volatile VP8CPUInfo ssim_last_cpuinfo_used = - (VP8CPUInfo)&ssim_last_cpuinfo_used; - -WEBP_TSAN_IGNORE_FUNCTION void VP8SSIMDspInit(void) { - if (ssim_last_cpuinfo_used == VP8GetCPUInfo) return; - +WEBP_DSP_INIT_FUNC(VP8SSIMDspInit) { #if !defined(WEBP_REDUCE_SIZE) VP8SSIMGetClipped = SSIMGetClipped_C; VP8SSIMGet = SSIMGet_C; @@ -161,6 +156,4 @@ WEBP_TSAN_IGNORE_FUNCTION void VP8SSIMDspInit(void) { } #endif } - - ssim_last_cpuinfo_used = VP8GetCPUInfo; } diff --git a/src/dsp/upsampling.c b/src/dsp/upsampling.c index ddfd1925..9b60da5b 100644 --- a/src/dsp/upsampling.c +++ b/src/dsp/upsampling.c @@ -219,12 +219,7 @@ extern void WebPInitYUV444ConvertersMIPSdspR2(void); extern void WebPInitYUV444ConvertersSSE2(void); extern void WebPInitYUV444ConvertersSSE41(void); -static volatile VP8CPUInfo upsampling_last_cpuinfo_used1 = - (VP8CPUInfo)&upsampling_last_cpuinfo_used1; - -WEBP_TSAN_IGNORE_FUNCTION void WebPInitYUV444Converters(void) { - if (upsampling_last_cpuinfo_used1 == VP8GetCPUInfo) return; - +WEBP_DSP_INIT_FUNC(WebPInitYUV444Converters) { WebPYUV444Converters[MODE_RGBA] = WebPYuv444ToRgba_C; WebPYUV444Converters[MODE_BGRA] = WebPYuv444ToBgra_C; WebPYUV444Converters[MODE_RGB] = WebPYuv444ToRgb_C; @@ -254,7 +249,6 @@ WEBP_TSAN_IGNORE_FUNCTION void WebPInitYUV444Converters(void) { } #endif } - upsampling_last_cpuinfo_used1 = VP8GetCPUInfo; } //------------------------------------------------------------------------------ @@ -266,12 +260,7 @@ extern void WebPInitUpsamplersNEON(void); extern void WebPInitUpsamplersMIPSdspR2(void); extern void WebPInitUpsamplersMSA(void); -static volatile VP8CPUInfo upsampling_last_cpuinfo_used2 = - (VP8CPUInfo)&upsampling_last_cpuinfo_used2; - -WEBP_TSAN_IGNORE_FUNCTION void WebPInitUpsamplers(void) { - if (upsampling_last_cpuinfo_used2 == VP8GetCPUInfo) return; - +WEBP_DSP_INIT_FUNC(WebPInitUpsamplers) { #ifdef FANCY_UPSAMPLING #if !WEBP_NEON_OMIT_C_CODE WebPUpsamplers[MODE_RGBA] = UpsampleRgbaLinePair_C; @@ -333,7 +322,6 @@ WEBP_TSAN_IGNORE_FUNCTION void WebPInitUpsamplers(void) { #endif #endif // FANCY_UPSAMPLING - upsampling_last_cpuinfo_used2 = VP8GetCPUInfo; } //------------------------------------------------------------------------------ diff --git a/src/dsp/yuv.c b/src/dsp/yuv.c index 957d1d66..14e67fc2 100644 --- a/src/dsp/yuv.c +++ b/src/dsp/yuv.c @@ -75,12 +75,7 @@ extern void WebPInitSamplersSSE41(void); extern void WebPInitSamplersMIPS32(void); extern void WebPInitSamplersMIPSdspR2(void); -static volatile VP8CPUInfo yuv_last_cpuinfo_used = - (VP8CPUInfo)&yuv_last_cpuinfo_used; - -WEBP_TSAN_IGNORE_FUNCTION void WebPInitSamplers(void) { - if (yuv_last_cpuinfo_used == VP8GetCPUInfo) return; - +WEBP_DSP_INIT_FUNC(WebPInitSamplers) { WebPSamplers[MODE_RGB] = YuvToRgbRow; WebPSamplers[MODE_RGBA] = YuvToRgbaRow; WebPSamplers[MODE_BGR] = YuvToBgrRow; @@ -116,7 +111,6 @@ WEBP_TSAN_IGNORE_FUNCTION void WebPInitSamplers(void) { } #endif // WEBP_USE_MIPS_DSP_R2 } - yuv_last_cpuinfo_used = VP8GetCPUInfo; } //----------------------------------------------------------------------------- @@ -260,18 +254,13 @@ void (*WebPSharpYUVUpdateRGB)(const int16_t* ref, const int16_t* src, void (*WebPSharpYUVFilterRow)(const int16_t* A, const int16_t* B, int len, const uint16_t* best_y, uint16_t* out); -static volatile VP8CPUInfo rgba_to_yuv_last_cpuinfo_used = - (VP8CPUInfo)&rgba_to_yuv_last_cpuinfo_used; - extern void WebPInitConvertARGBToYUVSSE2(void); extern void WebPInitConvertARGBToYUVSSE41(void); extern void WebPInitConvertARGBToYUVNEON(void); extern void WebPInitSharpYUVSSE2(void); extern void WebPInitSharpYUVNEON(void); -WEBP_TSAN_IGNORE_FUNCTION void WebPInitConvertARGBToYUV(void) { - if (rgba_to_yuv_last_cpuinfo_used == VP8GetCPUInfo) return; - +WEBP_DSP_INIT_FUNC(WebPInitConvertARGBToYUV) { WebPConvertARGBToY = ConvertARGBToY_C; WebPConvertARGBToUV = WebPConvertARGBToUV_C; @@ -316,6 +305,4 @@ WEBP_TSAN_IGNORE_FUNCTION void WebPInitConvertARGBToYUV(void) { assert(WebPSharpYUVUpdateY != NULL); assert(WebPSharpYUVUpdateRGB != NULL); assert(WebPSharpYUVFilterRow != NULL); - - rgba_to_yuv_last_cpuinfo_used = VP8GetCPUInfo; } diff --git a/src/enc/near_lossless_enc.c b/src/enc/near_lossless_enc.c index cadd14c6..5517a7e2 100644 --- a/src/enc/near_lossless_enc.c +++ b/src/enc/near_lossless_enc.c @@ -146,6 +146,6 @@ int VP8ApplyNearLossless(const WebPPicture* const picture, int quality, // Define a stub to suppress compiler warnings. extern void VP8LNearLosslessStub(void); -WEBP_TSAN_IGNORE_FUNCTION void VP8LNearLosslessStub(void) {} +void VP8LNearLosslessStub(void) {} #endif // (WEBP_NEAR_LOSSLESS == 1) diff --git a/src/enc/picture_csp_enc.c b/src/enc/picture_csp_enc.c index d6dbae62..02d9df76 100644 --- a/src/enc/picture_csp_enc.c +++ b/src/enc/picture_csp_enc.c @@ -126,7 +126,7 @@ static WEBP_INLINE int LinearToGamma(uint32_t base_value, int shift) { #else -static WEBP_TSAN_IGNORE_FUNCTION void InitGammaTables(void) {} +static void InitGammaTables(void) {} static WEBP_INLINE uint32_t GammaToLinear(uint8_t v) { return v; } static WEBP_INLINE int LinearToGamma(uint32_t base_value, int shift) { return (int)(base_value << shift); @@ -238,7 +238,7 @@ static WEBP_INLINE uint32_t LinearToGammaS(uint32_t value) { #else -static WEBP_TSAN_IGNORE_FUNCTION void InitGammaTablesS(void) {} +static void InitGammaTablesS(void) {} static WEBP_INLINE uint32_t GammaToLinearS(int v) { return (v << GAMMA_TO_LINEAR_BITS) / MAX_Y_T; }