зеркало из https://github.com/microsoft/Win2D.git
Add CanvasDevice.DeviceLost
This commit is contained in:
Родитель
31c5094fa9
Коммит
98953e3ee0
|
@ -89,7 +89,54 @@ under the License.
|
|||
<see cref="T:Microsoft.Graphics.Canvas.CanvasDrawingSession"/>, or
|
||||
<see cref="T:Microsoft.Graphics.Canvas.CanvasRenderTarget"/>.
|
||||
</remarks>
|
||||
</member>
|
||||
</member>
|
||||
|
||||
<member name="M:Microsoft.Graphics.Canvas.CanvasDevice.IsDeviceLost(System.Int32)">
|
||||
<summary>Returns whether this device has lost the ability to be operational.</summary>
|
||||
<remarks>
|
||||
<p>
|
||||
This method expects an error code from an exception that your app has caught.
|
||||
IsDeviceLost will return true if the device is indeed lost, <i>and</i> the error
|
||||
code actually corresponds to device removal.
|
||||
</p>
|
||||
<p>
|
||||
This is intended to be used like:
|
||||
<code>
|
||||
try { DrawStuff(); }
|
||||
catch (Exception e) where canvasDevice.IsDeviceLost(e.ErrorCode)
|
||||
{
|
||||
canvasDevice.RaiseDeviceLost();
|
||||
}
|
||||
</code>
|
||||
</p>
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="M:Microsoft.Graphics.Canvas.CanvasDevice.RaiseDeviceLost">
|
||||
<summary>Raises an event on the device, indicating that it is no longer operational.</summary>
|
||||
<remarks>
|
||||
<p>
|
||||
This method should be called when your app has caught a device lost exception.
|
||||
See <see cref="M:Microsoft.Graphics.Canvas.CanvasDevice.IsDeviceLost(System.Int32)"/>.
|
||||
</p>
|
||||
<p>
|
||||
Any event handlers subscribed to the <see cref="E:Microsoft.Graphics.Canvas.CanvasDevice.DeviceLost"/>
|
||||
will be issued. This will occur, even if there was no actual Direct3D device loss. This
|
||||
is just a convenience, to make application testing easier.
|
||||
</p>
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="E:Microsoft.Graphics.Canvas.CanvasDevice.DeviceLost">
|
||||
<summary>Subscribe to this event to be notified whenever the device ceases to be operational.</summary>
|
||||
<remarks>
|
||||
<p>
|
||||
Any handlers subscribed to this event will be issued whenever <see cref="M:Microsoft.Graphics.Canvas.CanvasDevice.RaiseDeviceLost"/>
|
||||
is called.
|
||||
</p>
|
||||
<p>
|
||||
An implementation of this handler is expected to re-create the device, and any device-dependent resources.
|
||||
</p>
|
||||
</remarks>
|
||||
</member>
|
||||
|
||||
</members>
|
||||
</doc>
|
||||
|
|
|
@ -74,6 +74,35 @@ namespace Microsoft.Graphics.Canvas
|
|||
[propget]
|
||||
HRESULT MaximumBitmapSizeInPixels(
|
||||
[out, retval] INT32* value);
|
||||
|
||||
//
|
||||
// This event is raised whenever the native device resource is lost-
|
||||
// for example, due to a user switch, lock screen, or unexpected
|
||||
// graphics driver behavior. Apps are expected to re-create their
|
||||
// CanvasDevice and device-dependent resources in response to this event.
|
||||
//
|
||||
[eventadd] HRESULT DeviceLost(
|
||||
[in] Windows.Foundation.TypedEventHandler<CanvasDevice*, IInspectable*>* value,
|
||||
[out, retval] EventRegistrationToken* token);
|
||||
|
||||
[eventremove] HRESULT DeviceLost([in] EventRegistrationToken token);
|
||||
|
||||
//
|
||||
// Identifies whether this error code matches a device lost.
|
||||
// If this device was not actually lost, this method always
|
||||
// returns false.
|
||||
//
|
||||
HRESULT IsDeviceLost([in] int hresult, [out, retval] boolean* value);
|
||||
|
||||
//
|
||||
// Call this method when a lost device error occurs- in particular,
|
||||
// if an exception was caught by the app, whose error code yielded
|
||||
// IsDeviceLost = true.
|
||||
//
|
||||
// This will cause invocation of the DeviceLost event. Occurs
|
||||
// regardless of whether the native device as actually lost.
|
||||
//
|
||||
HRESULT RaiseDeviceLost();
|
||||
};
|
||||
|
||||
[version(VERSION), activatable(VERSION), activatable(ICanvasDeviceFactory, VERSION), static(ICanvasDeviceStatics, VERSION)]
|
||||
|
|
|
@ -426,6 +426,69 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas
|
|||
});
|
||||
}
|
||||
|
||||
IFACEMETHODIMP CanvasDevice::add_DeviceLost(
|
||||
DeviceLostHandlerType* value,
|
||||
EventRegistrationToken* token)
|
||||
{
|
||||
return ExceptionBoundary(
|
||||
[&]
|
||||
{
|
||||
GetResource(); // this ensures that Close() hasn't been called
|
||||
CheckInPointer(value);
|
||||
CheckInPointer(token);
|
||||
|
||||
ThrowIfFailed(m_deviceLostEventList.Add(value, token));
|
||||
});
|
||||
}
|
||||
|
||||
IFACEMETHODIMP CanvasDevice::remove_DeviceLost(
|
||||
EventRegistrationToken token)
|
||||
{
|
||||
return ExceptionBoundary(
|
||||
[&]
|
||||
{
|
||||
//
|
||||
// This does not check if this object was closed, so to
|
||||
// allow shutdown paths to freely remove events.
|
||||
//
|
||||
ThrowIfFailed(m_deviceLostEventList.Remove(token));
|
||||
});
|
||||
}
|
||||
|
||||
IFACEMETHODIMP CanvasDevice::IsDeviceLost(
|
||||
int hresult,
|
||||
boolean* value)
|
||||
{
|
||||
return ExceptionBoundary(
|
||||
[&]
|
||||
{
|
||||
auto& dxgiDevice = m_dxgiDevice.EnsureNotClosed();
|
||||
|
||||
CheckInPointer(value);
|
||||
|
||||
if (DeviceLostException::IsDeviceLostHResult(hresult))
|
||||
{
|
||||
auto d3dDevice = As<ID3D11Device>(dxgiDevice);
|
||||
*value = d3dDevice->GetDeviceRemovedReason() != S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*value = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
IFACEMETHODIMP CanvasDevice::RaiseDeviceLost()
|
||||
{
|
||||
return ExceptionBoundary(
|
||||
[&]
|
||||
{
|
||||
GetResource(); // this ensures that Close() hasn't been called
|
||||
|
||||
ThrowIfFailed(m_deviceLostEventList.InvokeAll(this, nullptr));
|
||||
});
|
||||
}
|
||||
|
||||
IFACEMETHODIMP CanvasDevice::Close()
|
||||
{
|
||||
HRESULT hr = ResourceWrapper::Close();
|
||||
|
|
|
@ -146,6 +146,7 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas
|
|||
typedef CanvasDeviceManager manager_t;
|
||||
};
|
||||
|
||||
typedef ITypedEventHandler<CanvasDevice*, IInspectable*> DeviceLostHandlerType;
|
||||
|
||||
//
|
||||
// The CanvasDevice class itself.
|
||||
|
@ -172,6 +173,8 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas
|
|||
// device object is open or closed.
|
||||
ComPtr<IDXGIOutput> m_primaryOutput;
|
||||
|
||||
EventSource<DeviceLostHandlerType, InvokeModeOptions<StopOnFirstError>> m_deviceLostEventList;
|
||||
|
||||
public:
|
||||
CanvasDevice(
|
||||
std::shared_ptr<CanvasDeviceManager> manager,
|
||||
|
@ -188,6 +191,14 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas
|
|||
|
||||
IFACEMETHOD(get_MaximumBitmapSizeInPixels)(int32_t* value) override;
|
||||
|
||||
IFACEMETHOD(add_DeviceLost)(DeviceLostHandlerType* value, EventRegistrationToken* token) override;
|
||||
|
||||
IFACEMETHOD(remove_DeviceLost)(EventRegistrationToken token) override;
|
||||
|
||||
IFACEMETHOD(IsDeviceLost)(int hresult, boolean* value) override;
|
||||
|
||||
IFACEMETHOD(RaiseDeviceLost)() override;
|
||||
|
||||
//
|
||||
// ICanvasResourceCreator
|
||||
//
|
||||
|
|
|
@ -428,3 +428,214 @@ TEST_CLASS(DefaultDeviceResourceCreationAdapterTests)
|
|||
Assert::AreEqual(dxgiDevice.Get(), actualDxgiDevice.Get());
|
||||
}
|
||||
};
|
||||
|
||||
static const HRESULT deviceRemovedHResults[] = {
|
||||
DXGI_ERROR_DEVICE_HUNG,
|
||||
DXGI_ERROR_DEVICE_REMOVED,
|
||||
DXGI_ERROR_DEVICE_RESET,
|
||||
DXGI_ERROR_DRIVER_INTERNAL_ERROR,
|
||||
DXGI_ERROR_INVALID_CALL,
|
||||
D2DERR_RECREATE_TARGET
|
||||
};
|
||||
|
||||
TEST_CLASS(CanvasDeviceLostTests)
|
||||
{
|
||||
std::shared_ptr<TestDeviceResourceCreationAdapter> m_resourceCreationAdapter;
|
||||
std::shared_ptr<CanvasDeviceManager> m_deviceManager;
|
||||
|
||||
public:
|
||||
|
||||
TEST_METHOD_INITIALIZE(Reset)
|
||||
{
|
||||
m_resourceCreationAdapter = std::make_shared<TestDeviceResourceCreationAdapter>();
|
||||
m_deviceManager = std::make_shared<CanvasDeviceManager>(m_resourceCreationAdapter);
|
||||
}
|
||||
|
||||
TEST_METHOD_EX(CanvasDeviceLostTests_Closed)
|
||||
{
|
||||
auto canvasDevice = m_deviceManager->Create(CanvasDebugLevel::None, CanvasHardwareAcceleration::On);
|
||||
|
||||
Assert::AreEqual(S_OK, canvasDevice->Close());
|
||||
|
||||
EventRegistrationToken token{};
|
||||
MockEventHandler<DeviceLostHandlerType> dummyDeviceLostHandler(L"DeviceLost");
|
||||
Assert::AreEqual(RO_E_CLOSED, canvasDevice->add_DeviceLost(dummyDeviceLostHandler.Get(), &token));
|
||||
|
||||
// remove_DeviceLost is intended to not check if the object is closed, and like all EventSource
|
||||
// events it returns success if you try and remove an unregistered token.
|
||||
Assert::AreEqual(S_OK, canvasDevice->remove_DeviceLost(token));
|
||||
|
||||
boolean b;
|
||||
Assert::AreEqual(RO_E_CLOSED, canvasDevice->IsDeviceLost(0, &b));
|
||||
|
||||
Assert::AreEqual(RO_E_CLOSED, canvasDevice->RaiseDeviceLost());
|
||||
|
||||
}
|
||||
|
||||
TEST_METHOD_EX(CanvasDeviceLostTests_NullArgs)
|
||||
{
|
||||
auto canvasDevice = m_deviceManager->Create(CanvasDebugLevel::None, CanvasHardwareAcceleration::On);
|
||||
|
||||
EventRegistrationToken token{};
|
||||
MockEventHandler<DeviceLostHandlerType> dummyDeviceLostHandler(L"DeviceLost");
|
||||
Assert::AreEqual(E_INVALIDARG, canvasDevice->add_DeviceLost(nullptr, &token));
|
||||
Assert::AreEqual(E_INVALIDARG, canvasDevice->add_DeviceLost(dummyDeviceLostHandler.Get(), nullptr));
|
||||
Assert::AreEqual(E_INVALIDARG, canvasDevice->IsDeviceLost(0, nullptr));
|
||||
}
|
||||
|
||||
class DeviceLostResourceCreationAdapter : public TestDeviceResourceCreationAdapter
|
||||
{
|
||||
virtual ComPtr<StubD3D11Device> CreateStubD3D11Device() override
|
||||
{
|
||||
auto stubD3DDevice = Make<StubD3D11Device>();
|
||||
|
||||
stubD3DDevice->GetDeviceRemovedReasonMethod.AllowAnyCall(
|
||||
[] { return DXGI_ERROR_DEVICE_REMOVED; });
|
||||
|
||||
return stubD3DDevice;
|
||||
}
|
||||
};
|
||||
|
||||
class DeviceLostFixture
|
||||
{
|
||||
std::shared_ptr<DeviceLostResourceCreationAdapter> m_resourceCreationAdapter;
|
||||
|
||||
public:
|
||||
std::shared_ptr<CanvasDeviceManager> DeviceManager;
|
||||
|
||||
DeviceLostFixture()
|
||||
: m_resourceCreationAdapter(std::make_shared<DeviceLostResourceCreationAdapter>())
|
||||
, DeviceManager(std::make_shared<CanvasDeviceManager>(m_resourceCreationAdapter))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
TEST_METHOD_EX(CanvasDeviceLostTests_IsDeviceLost_DeviceRemovedHr_DeviceIsLost_ReturnsTrue)
|
||||
{
|
||||
DeviceLostFixture f;
|
||||
auto canvasDevice = f.DeviceManager->Create(CanvasDebugLevel::None, CanvasHardwareAcceleration::On);
|
||||
|
||||
for (HRESULT hr : deviceRemovedHResults)
|
||||
{
|
||||
boolean isDeviceLost;
|
||||
Assert::AreEqual(S_OK, canvasDevice->IsDeviceLost(hr, &isDeviceLost));
|
||||
Assert::IsTrue(!!isDeviceLost);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD_EX(CanvasDeviceLostTests_IsDeviceLost_SomeArbitraryHr_DeviceIsLost_ReturnsFalse)
|
||||
{
|
||||
DeviceLostFixture f;
|
||||
auto canvasDevice = f.DeviceManager->Create(CanvasDebugLevel::None, CanvasHardwareAcceleration::On);
|
||||
|
||||
boolean isDeviceLost;
|
||||
Assert::AreEqual(S_OK, canvasDevice->IsDeviceLost(E_INVALIDARG, &isDeviceLost));
|
||||
Assert::IsFalse(!!isDeviceLost);
|
||||
}
|
||||
|
||||
TEST_METHOD_EX(CanvasDeviceLostTests_IsDeviceLost_DeviceRemovedHr_DeviceNotActuallyLost_ReturnsFalse)
|
||||
{
|
||||
auto canvasDevice = m_deviceManager->Create(CanvasDebugLevel::None, CanvasHardwareAcceleration::On);
|
||||
|
||||
for (HRESULT hr : deviceRemovedHResults)
|
||||
{
|
||||
boolean isDeviceLost;
|
||||
Assert::AreEqual(S_OK, canvasDevice->IsDeviceLost(hr, &isDeviceLost));
|
||||
Assert::IsFalse(!!isDeviceLost);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD_EX(CanvasDeviceLostTests_IsDeviceLost_SomeArbitraryHr_DeviceNotActuallyLost_ReturnsFalse)
|
||||
{
|
||||
auto canvasDevice = m_deviceManager->Create(CanvasDebugLevel::None, CanvasHardwareAcceleration::On);
|
||||
|
||||
boolean isDeviceLost;
|
||||
Assert::AreEqual(S_OK, canvasDevice->IsDeviceLost(E_INVALIDARG, &isDeviceLost));
|
||||
Assert::IsFalse(!!isDeviceLost);
|
||||
}
|
||||
|
||||
TEST_METHOD_EX(CanvasDeviceLostTests_RaiseDeviceLost_RaisesSubscribedHandlers_DeviceActuallyLost)
|
||||
{
|
||||
DeviceLostFixture f;
|
||||
auto canvasDevice = f.DeviceManager->Create(CanvasDebugLevel::None, CanvasHardwareAcceleration::On);
|
||||
|
||||
MockEventHandler<DeviceLostHandlerType> deviceLostHandler(L"DeviceLost");
|
||||
deviceLostHandler.SetExpectedCalls(1);
|
||||
|
||||
EventRegistrationToken token{};
|
||||
Assert::AreEqual(S_OK, canvasDevice->add_DeviceLost(deviceLostHandler.Get(), &token));
|
||||
|
||||
Assert::AreEqual(S_OK, canvasDevice->RaiseDeviceLost());
|
||||
}
|
||||
|
||||
TEST_METHOD_EX(CanvasDeviceLostTests_RaiseDeviceLost_RaisesSubscribedHandlers_DeviceNotActuallyLost)
|
||||
{
|
||||
//
|
||||
// The unit tests testing the DeviceLost event do not exhaustively test
|
||||
// everything concerning adding/removing events, because DeviceLost is
|
||||
// implemented directly on top of EventSource<...>, which
|
||||
// already has coverage elsewhere.
|
||||
//
|
||||
auto canvasDevice = m_deviceManager->Create(CanvasDebugLevel::None, CanvasHardwareAcceleration::On);
|
||||
|
||||
MockEventHandler<DeviceLostHandlerType> deviceLostHandler(L"DeviceLost");
|
||||
deviceLostHandler.SetExpectedCalls(1);
|
||||
|
||||
EventRegistrationToken token{};
|
||||
Assert::AreEqual(S_OK, canvasDevice->add_DeviceLost(deviceLostHandler.Get(), &token));
|
||||
|
||||
Assert::AreEqual(S_OK, canvasDevice->RaiseDeviceLost());
|
||||
}
|
||||
|
||||
TEST_METHOD_EX(CanvasDeviceLostTests_RemoveEventThen_RaiseDeviceLost_DoesNotInvokeHandler)
|
||||
{
|
||||
auto canvasDevice = m_deviceManager->Create(CanvasDebugLevel::None, CanvasHardwareAcceleration::On);
|
||||
|
||||
MockEventHandler<DeviceLostHandlerType> deviceLostHandler(L"DeviceLost");
|
||||
deviceLostHandler.SetExpectedCalls(0);
|
||||
|
||||
EventRegistrationToken token{};
|
||||
Assert::AreEqual(S_OK, canvasDevice->add_DeviceLost(deviceLostHandler.Get(), &token));
|
||||
Assert::AreEqual(S_OK, canvasDevice->remove_DeviceLost(token));
|
||||
|
||||
Assert::AreEqual(S_OK, canvasDevice->RaiseDeviceLost());
|
||||
}
|
||||
|
||||
TEST_METHOD_EX(CanvasDeviceLostTests_RaiseDeviceLost_HasCorrectSenderAndArgs)
|
||||
{
|
||||
DeviceLostFixture f;
|
||||
auto canvasDevice = f.DeviceManager->Create(CanvasDebugLevel::None, CanvasHardwareAcceleration::On);
|
||||
|
||||
MockEventHandler<DeviceLostHandlerType> deviceLostHandler(L"DeviceLost");
|
||||
deviceLostHandler.SetExpectedCalls(1,
|
||||
[&](ICanvasDevice* sender, IInspectable* args)
|
||||
{
|
||||
Assert::AreEqual(static_cast<ICanvasDevice*>(canvasDevice.Get()), sender);
|
||||
Assert::IsNull(args);
|
||||
return S_OK;
|
||||
});
|
||||
|
||||
EventRegistrationToken token{};
|
||||
Assert::AreEqual(S_OK, canvasDevice->add_DeviceLost(deviceLostHandler.Get(), &token));
|
||||
|
||||
Assert::AreEqual(S_OK, canvasDevice->RaiseDeviceLost());
|
||||
}
|
||||
|
||||
TEST_METHOD_EX(CanvasDeviceLostTests_RaiseDeviceLost_ExceptionFromHandlerIsPropagated)
|
||||
{
|
||||
DeviceLostFixture f;
|
||||
auto canvasDevice = f.DeviceManager->Create(CanvasDebugLevel::None, CanvasHardwareAcceleration::On);
|
||||
|
||||
MockEventHandler<DeviceLostHandlerType> deviceLostHandler(L"DeviceLost");
|
||||
deviceLostHandler.SetExpectedCalls(1,
|
||||
[&](ICanvasDevice* sender, IInspectable* args)
|
||||
{
|
||||
return E_UNEXPECTED;
|
||||
});
|
||||
|
||||
EventRegistrationToken token{};
|
||||
Assert::AreEqual(S_OK, canvasDevice->add_DeviceLost(deviceLostHandler.Get(), &token));
|
||||
|
||||
Assert::AreEqual(E_UNEXPECTED, canvasDevice->RaiseDeviceLost());
|
||||
}
|
||||
};
|
|
@ -91,6 +91,35 @@ namespace canvas
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP add_DeviceLost(
|
||||
DeviceLostHandlerType* value,
|
||||
EventRegistrationToken* token)
|
||||
{
|
||||
Assert::Fail(L"Unexpected call to add_DeviceLost");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP remove_DeviceLost(
|
||||
EventRegistrationToken token)
|
||||
{
|
||||
Assert::Fail(L"Unexpected call to remove_DeviceLost");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP IsDeviceLost(
|
||||
int hresult,
|
||||
boolean* value)
|
||||
{
|
||||
Assert::Fail(L"Unexpected call to IsDeviceLost");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP RaiseDeviceLost()
|
||||
{
|
||||
Assert::Fail(L"Unexpected call to RaiseDeviceLost");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
//
|
||||
// ICanvasResourceCreator
|
||||
//
|
||||
|
|
|
@ -63,7 +63,7 @@ public:
|
|||
|
||||
// Stub device is used here, because, in execution of these tests, product code will
|
||||
// actually call methods on the factory and expect them to succeed.
|
||||
*device = Make<StubD3D11Device>();
|
||||
*device = CreateStubD3D11Device();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -81,6 +81,11 @@ public:
|
|||
m_allowHardware = enable;
|
||||
}
|
||||
|
||||
virtual ComPtr<StubD3D11Device> CreateStubD3D11Device()
|
||||
{
|
||||
return Make<StubD3D11Device>();
|
||||
}
|
||||
|
||||
// These are left public because it's test code and it's convenient to do so.
|
||||
int m_numD2DFactoryCreationCalls;
|
||||
CanvasDebugLevel m_debugLevel;
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use these files except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
|
||||
using Microsoft.Graphics.Canvas;
|
||||
|
||||
namespace test.managed
|
||||
{
|
||||
[TestClass]
|
||||
public class DeviceRemovedTests_WithoutControl
|
||||
{
|
||||
bool m_deviceLostRaised;
|
||||
|
||||
[TestMethod]
|
||||
public void DeviceRaisesDeviceLostEvent()
|
||||
{
|
||||
CanvasDevice device = new CanvasDevice();
|
||||
|
||||
// Verifies that the event is raised, even if the native
|
||||
// underlying device was not lost.
|
||||
Assert.IsFalse(device.IsDeviceLost(0));
|
||||
|
||||
device.DeviceLost += device_DeviceLost;
|
||||
|
||||
device.RaiseDeviceLost();
|
||||
|
||||
Assert.IsTrue(m_deviceLostRaised);
|
||||
|
||||
device.DeviceLost -= device_DeviceLost;
|
||||
|
||||
// If the event was actually removed, shout not hit the
|
||||
// assert at the top of device_DeviceLost.
|
||||
device.RaiseDeviceLost();
|
||||
}
|
||||
|
||||
void device_DeviceLost(CanvasDevice sender, object args)
|
||||
{
|
||||
Assert.IsFalse(m_deviceLostRaised);
|
||||
|
||||
Assert.IsNull(args);
|
||||
|
||||
m_deviceLostRaised = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,10 +9,11 @@
|
|||
<Import_RootNamespace>test.managed</Import_RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)DeviceLost.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)DpiTests.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)EffectTests.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)GraphicsInterop.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)VectorInterop.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)PathReceiver.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)VectorInterop.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
Загрузка…
Ссылка в новой задаче