ComPtr CanvasEffect::GetD2DProperty()

in winrt/lib/effects/CanvasEffect.cpp [1232:1309]


    ComPtr<IPropertyValue> CanvasEffect::GetD2DProperty(ID2D1Effect* d2dEffect, unsigned int index)
    {
        switch (d2dEffect->GetType(index))
        {
        case D2D1_PROPERTY_TYPE_BOOL:
            {
                BOOL value = d2dEffect->GetValue<BOOL>(index);
                return CreateProperty(m_propertyValueFactory.Get(), static_cast<boolean>(value));
            }
            break;

        case D2D1_PROPERTY_TYPE_INT32:
        case D2D1_PROPERTY_TYPE_UINT32:     // Not a mistake: unsigned DImage properties are exposed in WinRT as signed.
            {
                INT32 value = d2dEffect->GetValue<INT32>(index);
                return CreateProperty(m_propertyValueFactory.Get(), value);
            }
            break;

        case D2D1_PROPERTY_TYPE_ENUM:
            {
                UINT32 value = d2dEffect->GetValue<UINT32>(index);
                return CreateProperty(m_propertyValueFactory.Get(), value);
            }
            break;

        case D2D1_PROPERTY_TYPE_FLOAT:
            {
                float value = d2dEffect->GetValue<float>(index);
                return CreateProperty(m_propertyValueFactory.Get(), value);
            }
            break;

        case D2D1_PROPERTY_TYPE_VECTOR2:
        case D2D1_PROPERTY_TYPE_VECTOR3:
        case D2D1_PROPERTY_TYPE_VECTOR4:
        case D2D1_PROPERTY_TYPE_MATRIX_3X2:
        case D2D1_PROPERTY_TYPE_MATRIX_4X4:
        case D2D1_PROPERTY_TYPE_MATRIX_5X4:
        case D2D1_PROPERTY_TYPE_BLOB:
            {
                unsigned sizeInBytes = d2dEffect->GetValueSize(index);
                unsigned sizeInFloats = sizeInBytes / sizeof(float);

                std::vector<BYTE> value(sizeInBytes);
                ThrowIfFailed(d2dEffect->GetValue(index, value.data(), sizeInBytes));

                return CreateProperty(m_propertyValueFactory.Get(), sizeInFloats, reinterpret_cast<float*>(value.data()));
            }
            break;

        case D2D1_PROPERTY_TYPE_IUNKNOWN:
        case D2D1_PROPERTY_TYPE_COLOR_CONTEXT:
            {
                ComPtr<IUnknown> d2dResource;

                if (IsEqualGUID(m_effectId, CLSID_D2D1ColorManagement) && index == D2D1_COLORMANAGEMENT_PROP_DESTINATION_COLOR_CONTEXT)
                {
                    // Windows has a bug that prevents reading back DESTINATION_COLOR_CONTEXT from a CLSID_D2D1ColorManagement effect.
                    // As a partial workaround, we cache this property value in the Win2D wrapper and return that instead.
                    // This is correct as long as the Win2D wrapper is kept alive, and the property is not changed via D2D interop.
                    d2dResource = m_workaround6146411;
                }
                else
                {
                    d2dResource.Attach(d2dEffect->GetValue<IUnknown*>(index));
                }

                auto wrapper = d2dResource ? ResourceManager::GetOrCreate(m_realizationDevice.GetWrapper(), d2dResource.Get(), 0) : nullptr;

                return CreateProperty(m_propertyValueFactory.Get(), wrapper.Get());
            }
            break;

        default:
            ThrowHR(E_NOTIMPL);
        }
    }