in winrt/test.internal/graphics/CanvasImageUnitTests.cpp [651:822]
static void TestComputeHistogram(float dpi)
{
auto factory = Make<CanvasImageFactory>();
auto canvasDevice = Make<StubCanvasDevice>();
auto d2dContext = Make<MockD2DDeviceContext>();
auto histogramEffect = Make<MockD2DEffect>();
auto atlasEffect = Make<MockD2DEffect>();
auto d2dBitmap = Make<StubD2DBitmap>(D2D1_BITMAP_OPTIONS_NONE, dpi);
auto canvasBitmap = CreateStubCanvasBitmap(nullptr, d2dBitmap.Get());
ComPtr<MockD2DEffectThatCountsCalls> dpiCompensator;
Rect rect{ 1, 2, 3, 4 };
auto channelSelect = EffectChannelSelect::Green;
const int numBins = 42;
ComArray<float> result;
canvasDevice->GetResourceCreationDeviceContextMethod.SetExpectedCalls(1, [&]
{
return DeviceContextLease(d2dContext);
});
canvasDevice->LeaseHistogramEffectMethod.SetExpectedCalls(1, [&](ID2D1DeviceContext* context)
{
Assert::IsTrue(IsSameInstance(context, d2dContext.Get()));
return CanvasDevice::HistogramAndAtlasEffects{ histogramEffect, atlasEffect };
});
canvasDevice->ReleaseHistogramEffectMethod.SetExpectedCalls(1, [&](CanvasDevice::HistogramAndAtlasEffects releasing)
{
Assert::IsTrue(IsSameInstance(histogramEffect.Get(), releasing.HistogramEffect.Get()));
Assert::IsTrue(IsSameInstance(atlasEffect.Get(), releasing.AtlasEffect.Get()));
});
atlasEffect->MockGetOutput = [&](ID2D1Image** output)
{
atlasEffect.CopyTo(output);
};
int setAtlasInputCallCount = 0;
atlasEffect->MockSetInput = [&](UINT32 index, ID2D1Image* input)
{
Assert::AreEqual(0u, index);
switch (setAtlasInputCallCount++)
{
case 0:
if (dpiCompensator)
Assert::IsTrue(IsSameInstance(dpiCompensator.Get(), input));
else
Assert::IsTrue(IsSameInstance(d2dBitmap.Get(), input));
break;
case 1:
Assert::IsNull(input);
break;
default:
Assert::Fail();
}
};
int setAtlasValueCallCount = 0;
atlasEffect->MockSetValue = [&](UINT32 index, D2D1_PROPERTY_TYPE type, CONST BYTE* data, UINT32 dataSize)
{
switch (setAtlasValueCallCount++)
{
case 0:
Assert::AreEqual<uint32_t>(D2D1_ATLAS_PROP_INPUT_RECT, index);
Assert::AreEqual<size_t>(sizeof(D2D1_RECT_F), dataSize);
Assert::AreEqual(*reinterpret_cast<D2D1_RECT_F const*>(data), ToD2DRect(rect));
break;
default:
Assert::Fail();
}
return S_OK;
};
int setHistogramInputCallCount = 0;
histogramEffect->MockSetInput = [&](UINT32 index, ID2D1Image* input)
{
Assert::AreEqual(0u, index);
switch (setHistogramInputCallCount++)
{
case 0:
Assert::IsTrue(IsSameInstance(atlasEffect.Get(), input));
break;
default:
Assert::Fail();
}
};
int setHistogramValueCallCount = 0;
histogramEffect->MockSetValue = [&](UINT32 index, D2D1_PROPERTY_TYPE type, CONST BYTE* data, UINT32 dataSize)
{
switch (setHistogramValueCallCount++)
{
case 0:
Assert::AreEqual<uint32_t>(D2D1_HISTOGRAM_PROP_CHANNEL_SELECT, index);
Assert::AreEqual<size_t>(sizeof(int), dataSize);
Assert::AreEqual(*reinterpret_cast<int const*>(data), static_cast<int>(channelSelect));
break;
case 1:
Assert::AreEqual<uint32_t>(D2D1_HISTOGRAM_PROP_NUM_BINS, index);
Assert::AreEqual<size_t>(sizeof(int), dataSize);
Assert::AreEqual(*reinterpret_cast<int const*>(data), numBins);
break;
default:
Assert::Fail();
}
return S_OK;
};
histogramEffect->MockGetValue = [&](UINT32 index, D2D1_PROPERTY_TYPE, BYTE*, UINT32 dataSize)
{
Assert::AreEqual<uint32_t>(D2D1_HISTOGRAM_PROP_HISTOGRAM_OUTPUT, index);
Assert::AreEqual<size_t>(numBins * sizeof(float), dataSize);
return S_OK;
};
if (dpi != DEFAULT_DPI)
{
d2dContext->CreateEffectMethod.SetExpectedCalls(1, [&](IID const& iid, ID2D1Effect** effect)
{
Assert::AreEqual(CLSID_D2D1DpiCompensation, iid);
Assert::IsNull(dpiCompensator.Get());
dpiCompensator = Make<MockD2DEffectThatCountsCalls>();
dpiCompensator->MockGetOutput = [&](ID2D1Image** output)
{
dpiCompensator.CopyTo(output);
};
return dpiCompensator.CopyTo(effect);
});
}
d2dContext->BeginDrawMethod.SetExpectedCalls(1);
d2dContext->EndDrawMethod.SetExpectedCalls(1);
d2dContext->DrawImageMethod.SetExpectedCalls(1, [&](ID2D1Image* image, D2D1_POINT_2F const*, D2D1_RECT_F const*, D2D1_INTERPOLATION_MODE actualInterpolation, D2D1_COMPOSITE_MODE)
{
Assert::IsTrue(IsSameInstance(histogramEffect.Get(), image));
});
ThrowIfFailed(factory->ComputeHistogram(canvasBitmap.Get(), rect, canvasDevice.Get(), channelSelect, numBins, result.GetAddressOfSize(), result.GetAddressOfData()));
Assert::AreEqual(2, setAtlasInputCallCount);
Assert::AreEqual(1, setAtlasValueCallCount);
Assert::AreEqual(1, setHistogramInputCallCount);
Assert::AreEqual(2, setHistogramValueCallCount);
if (dpiCompensator)
{
Assert::IsTrue(IsSameInstance(d2dBitmap.Get(), dpiCompensator->m_inputs[0].Get()));
Assert::AreEqual(sizeof(Vector2), dpiCompensator->m_properties[D2D1_DPICOMPENSATION_PROP_INPUT_DPI].size());
Assert::AreEqual(Vector2{ dpi, dpi }, *reinterpret_cast<Vector2*>(dpiCompensator->m_properties[D2D1_DPICOMPENSATION_PROP_INPUT_DPI].data()));
}
}