Skip to content

Commit

Permalink
Test cleanup, etc
Browse files Browse the repository at this point in the history
  • Loading branch information
tjhorner committed Jul 11, 2021
1 parent 21b8eb2 commit ecf7e2d
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 15 deletions.
34 changes: 33 additions & 1 deletion OVRSharp.Graphics.DirectX/DirectXCompositor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,45 @@ namespace OVRSharp.Graphics.DirectX
{
public class DirectXCompositor : ICompositorAPI
{
/// <summary>
/// Global, static instance of <see cref="DirectXCompositor"/>.
/// </summary>
public static DirectXCompositor Instance
{
get
{
if (_instance == null)
_instance = new DirectXCompositor();

return _instance;
}
}

private static DirectXCompositor _instance = null;

private readonly Device device;

/// <summary>
/// A DirectX-based implementation of <see cref="ICompositorAPI"/>.<br/><br/>
///
/// Ideally, there should ever only be one instance of this class
/// at once. You can provide <see cref="Instance"/> to anything that depends
/// on <see cref="ICompositorAPI"/> to ensure that this is the case.
/// </summary>
public DirectXCompositor()
{
device = new Device(SharpDX.Direct3D.DriverType.Hardware, DeviceCreationFlags.Debug);
}

/// <summary>
/// <inheritdoc/><br/><br/>
///
/// <strong>Warning:</strong> this is a pretty slow method.
/// It's fine to use this for one-off captures, but if you require
/// something like a constant stream of the headset view, I recommend
/// digging into a lower-level implementation.
/// </summary>
/// <inheritdoc/>
public Bitmap GetMirrorImage(EVREye eye = EVREye.Eye_Left)
{
var srvPtr = IntPtr.Zero;
Expand Down Expand Up @@ -46,7 +78,7 @@ public Bitmap GetMirrorImage(EVREye eye = EVREye.Eye_Left)
Usage = ResourceUsage.Staging
}))
{
// Copy texture to CPU so we can read from it
// Copy texture to RAM so CPU can read from it
device.ImmediateContext.CopyResource(tex, cpuTex);
OpenVR.Compositor.ReleaseMirrorTextureD3D11(srvPtr);

Expand Down
2 changes: 1 addition & 1 deletion OVRSharp/Application.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public enum ApplicationType

/// <summary>
/// The application will not start SteamVR. If it is not already running
/// the call with VR_Init will fail with VRInitError_Init_NoServerForBackgroundApp.
/// the call with VR_Init will fail with <see cref="EVRInitError.Init_NoServerForBackgroundApp"/>.
/// </summary>
Background = EVRApplicationType.VRApplication_Background,

Expand Down
12 changes: 12 additions & 0 deletions OVRSharp/Graphics/ICompositorAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,20 @@

namespace OVRSharp.Graphics
{
/// <summary>
/// An interface for graphics-related compositor API methods.<br/><br/>
///
/// You can find implementations for different graphics APIs on NuGet as
/// OVRSharp.Graphics.DirectX and OVRSharp.Graphics.OpenGL. Anyone else is also
/// free to implement their own version of this for other graphics APIs and
/// publish them.
/// </summary>
public interface ICompositorAPI
{
/// <summary>
/// Capture a screenshot of the headset view.
/// </summary>
/// <param name="eye">The eye to capture.</param>
Bitmap GetMirrorImage(EVREye eye = EVREye.Eye_Left);
}
}
7 changes: 6 additions & 1 deletion tests/OVRSharp.Graphics.DirectX.Tests/CompositorTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
using NUnit.Framework;
using OVRSharp.Tests.Graphics;

namespace OVRSharp.Graphics.DirectX.Tests
{
public class DirectXCompositorTests : CompositorTests<DirectXCompositor> { }
[TestFixture]
public class DirectXCompositorTests : CompositorTests<DirectXCompositor>
{
protected override DirectXCompositor InstantiateCompositorAPI() => DirectXCompositor.Instance;
}
}
13 changes: 9 additions & 4 deletions tests/OVRSharp.Graphics.OpenGL.Tests/CompositorTests.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
using FluentAssertions;
using NUnit.Framework;
using NUnit.Framework;
using OVRSharp.Tests.Graphics;
using Valve.VR;

namespace OVRSharp.Graphics.OpenGL.Tests
{
public class OpenGLCompositorTests : CompositorTests<OpenGLCompositor> { }
[TestFixture]
public class OpenGLCompositorTests : CompositorTests<OpenGLCompositor>
{
protected override OpenGLCompositor InstantiateCompositorAPI()
{
return new OpenGLCompositor();
}
}
}
43 changes: 35 additions & 8 deletions tests/OVRSharp.Tests/Graphics/CompositorTests.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,50 @@
using FluentAssertions;
using NUnit.Framework;
using OVRSharp.Graphics;
using OVRSharp.Exceptions;
using Valve.VR;

namespace OVRSharp.Tests.Graphics
{
public class CompositorTests<T> where T : ICompositorAPI, new()
/// <summary>
/// Tests to run against <see cref="ICompositorAPI"/> implementations.
/// </summary>
/// <typeparam name="T">Your implementation of <see cref="ICompositorAPI"/> to test.</typeparam>
public abstract class CompositorTests<T> where T : ICompositorAPI
{
private Application app;
private ICompositorAPI compositor;

/// <summary>
/// Instantiates the instance of your <see cref="ICompositorAPI"/>
/// that will be used for testing.
/// </summary>
protected abstract T InstantiateCompositorAPI();

[OneTimeSetUp]
public void Setup()
{
app = new Application(Application.ApplicationType.Background);
compositor = new T();
try
{
app = new Application(Application.ApplicationType.Background);
}
catch(OpenVRSystemException<EVRInitError> e)
{
switch(e.Error)
{
case EVRInitError.Init_InstallationNotFound:
case EVRInitError.Init_VRClientDLLNotFound:
Assert.Ignore("OpenVR runtime not found; skipping integration tests.");
break;
case EVRInitError.Init_NoServerForBackgroundApp:
Assert.Ignore("OpenVR runtime not running; skipping integration tests.");
break;
default:
throw;
}
}

compositor = InstantiateCompositorAPI();
}

[Test]
Expand All @@ -29,16 +59,13 @@ public void ShouldGetMirrorTextureSuccessfully(EVREye eye)

// This test is mostly here to make sure we are deallocating resources properly.
[Test]
public void ShouldWithstandRapidCalls()
public void ShouldWorkWhenCalledRapidly()
{
Assert.Ignore();
for (var i = 0; i < 1000; i++)
for (var i = 0; i < 100; i++)
{
var bitmap = compositor.GetMirrorImage(EVREye.Eye_Left);
bitmap.Height.Should().BeGreaterThan(0);
bitmap.Width.Should().BeGreaterThan(0);

bitmap.Dispose();
}
}
}
Expand Down

0 comments on commit ecf7e2d

Please sign in to comment.