diff --git a/winrt/lib/effects/CanvasEffect.cpp b/winrt/lib/effects/CanvasEffect.cpp index ce63a5f63..a9c306a85 100644 --- a/winrt/lib/effects/CanvasEffect.cpp +++ b/winrt/lib/effects/CanvasEffect.cpp @@ -205,6 +205,8 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas { na { ThrowIfClosed(); + auto lock = RecursiveLock(m_mutex); + // Check for graph cycles if (m_insideGetImage) ThrowHR(D2DERR_CYCLIC_GRAPH); @@ -212,10 +214,6 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas { na m_insideGetImage = true; auto clearFlagWarden = MakeScopeWarden([&] { m_insideGetImage = false; }); - // Lock after the cycle detection, because m_mutex is not recursive. - // Cycle checks don't need to be threadsafe because that's just a developer error. - auto lock = Lock(m_mutex); - // Process the ReadDpiFromDeviceContext flag. if ((flags & WIN2D_GET_D2D_IMAGE_FLAGS_READ_DPI_FROM_DEVICE_CONTEXT) != WIN2D_GET_D2D_IMAGE_FLAGS_NONE) { @@ -465,7 +463,7 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas { na { CheckInPointer(value); - auto lock = Lock(m_mutex); + auto lock = RecursiveLock(m_mutex); // If we are realized, read the latest value from the underlying D2D resource. if (auto& d2dEffect = MaybeGetResource()) @@ -483,7 +481,7 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas { na return ExceptionBoundary( [&] { - auto lock = Lock(m_mutex); + auto lock = RecursiveLock(m_mutex); m_cacheOutput = value; @@ -503,7 +501,7 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas { na { CheckAndClearOutPointer(value); - auto lock = Lock(m_mutex); + auto lock = RecursiveLock(m_mutex); // If we are realized, read the latest value from the underlying D2D resource. if (auto& d2dEffect = MaybeGetResource()) @@ -529,7 +527,7 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas { na return ExceptionBoundary( [&] { - auto lock = Lock(m_mutex); + auto lock = RecursiveLock(m_mutex); if (value) { @@ -894,7 +892,7 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas { na unsigned int CanvasEffect::GetSourceCount() { - auto lock = Lock(m_mutex); + auto lock = RecursiveLock(m_mutex); auto& d2dEffect = MaybeGetResource(); @@ -915,7 +913,7 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas { na ComPtr CanvasEffect::GetSource(unsigned int index) { - auto lock = Lock(m_mutex); + auto lock = RecursiveLock(m_mutex); auto& d2dEffect = MaybeGetResource(); @@ -946,7 +944,7 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas { na void CanvasEffect::SetSource(unsigned int index, IGraphicsEffectSource* source) { - auto lock = Lock(m_mutex); + auto lock = RecursiveLock(m_mutex); auto& d2dEffect = MaybeGetResource(); @@ -971,7 +969,7 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas { na void CanvasEffect::InsertSource(unsigned int index, IGraphicsEffectSource* source) { - auto lock = Lock(m_mutex); + auto lock = RecursiveLock(m_mutex); auto& d2dEffect = MaybeGetResource(); @@ -1011,7 +1009,7 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas { na void CanvasEffect::RemoveSource(unsigned int index) { - auto lock = Lock(m_mutex); + auto lock = RecursiveLock(m_mutex); auto& d2dEffect = MaybeGetResource(); @@ -1058,7 +1056,7 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas { na void CanvasEffect::AppendSource(IGraphicsEffectSource* source) { - auto lock = Lock(m_mutex); + auto lock = RecursiveLock(m_mutex); auto& d2dEffect = MaybeGetResource(); @@ -1081,7 +1079,7 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas { na void CanvasEffect::ClearSources() { - auto lock = Lock(m_mutex); + auto lock = RecursiveLock(m_mutex); // Effects with variable number of inputs don't allow zero of them, // so we must unrealize before we can clear the collection. @@ -1403,7 +1401,7 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas { na void CanvasEffect::SetProperty(unsigned int index, IPropertyValue* propertyValue) { - auto lock = Lock(m_mutex); + auto lock = RecursiveLock(m_mutex); assert(index < m_properties.size()); @@ -1495,7 +1493,7 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas { na ComPtr CanvasEffect::GetProperty(unsigned int index) { - auto lock = Lock(m_mutex); + auto lock = RecursiveLock(m_mutex); assert(index < m_properties.size()); diff --git a/winrt/lib/effects/CanvasEffect.h b/winrt/lib/effects/CanvasEffect.h index 5485773df..50983587f 100644 --- a/winrt/lib/effects/CanvasEffect.h +++ b/winrt/lib/effects/CanvasEffect.h @@ -138,7 +138,7 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas { na ICanvasDevice* RealizationDevice() { return m_realizationDevice.GetWrapper(); } - std::mutex m_mutex; + std::recursive_mutex m_mutex; public: // Used by ResourceManager (in GetOrCreate and to register effect factories). diff --git a/winrt/lib/effects/shader/PixelShaderEffect.cpp b/winrt/lib/effects/shader/PixelShaderEffect.cpp index 264287717..8d5ee9bdc 100644 --- a/winrt/lib/effects/shader/PixelShaderEffect.cpp +++ b/winrt/lib/effects/shader/PixelShaderEffect.cpp @@ -300,7 +300,7 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas { na void PixelShaderEffect::SetProperty(HSTRING name, IInspectable* boxedValue) { - auto lock = Lock(m_mutex); + auto lock = RecursiveLock(m_mutex); // Store the new property value into our shared state object. m_sharedState->SetProperty(name, boxedValue); @@ -329,7 +329,7 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas { na return ExceptionBoundary([&] { - auto lock = Lock(m_mutex); + auto lock = RecursiveLock(m_mutex); // Store the new value into our shared state object. m_sharedState->CoordinateMapping().Mapping[index] = value; @@ -359,7 +359,7 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas { na return ExceptionBoundary([&] { - auto lock = Lock(m_mutex); + auto lock = RecursiveLock(m_mutex); // Store the new value into our shared state object. m_sharedState->CoordinateMapping().BorderMode[index] = value; @@ -385,7 +385,7 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas { na { return ExceptionBoundary([&] { - auto lock = Lock(m_mutex); + auto lock = RecursiveLock(m_mutex); // Store the new value into our shared state object. m_sharedState->CoordinateMapping().MaxOffset = value; @@ -415,7 +415,7 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas { na return ExceptionBoundary([&] { - auto lock = Lock(m_mutex); + auto lock = RecursiveLock(m_mutex); // Convert the enum from Win2D -> D2D format. auto d2dFilter = ToD2DFilter(value);