Skip to content
Permalink
Browse files

Hololens port

  • Loading branch information...
paulrouget committed Jun 21, 2019
1 parent 5beac07 commit acde7e04cb1c0b172313d8b7819c5e27f37152d2
@@ -44,3 +44,42 @@ capture_webrender/

/unminified-js

# Hololens artifacts

support/hololens/x64/
support/hololens/ARM/
support/hololens/Generated\ Files

# Ignore thumbnails created by Windows
support/hololens/Thumbs.db

# Ignore files built by Visual Studio
support/hololens/*.obj
support/hololens/*.exe
support/hololens/*.pdb
support/hololens/*.user
support/hololens/*.aps
support/hololens/*.pch
support/hololens/*.vspscc
support/hololens/*_i.c
support/hololens/*_p.c
support/hololens/*.ncb
support/hololens/*.suo
support/hololens/*.tlb
support/hololens/*.tlh
support/hololens/*.bak
support/hololens/*.cache
support/hololens/*.ilk
support/hololens/*.log
support/hololens/[Bb]in
support/hololens/[Dd]ebug*/
support/hololens/*.lib
support/hololens/*.sbr
support/hololens/obj/
support/hololens/[Rr]elease*/
support/hololens/_ReSharper*/
support/hololens/[Tt]est[Rr]esult*
support/hololens/.vs/

# Nuget packages folder
support/hololens/packages/
@@ -0,0 +1,7 @@
<Application
x:Class="hlservo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:hlservo">

</Application>
@@ -0,0 +1,29 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

#include "pch.h"
#include "App.xaml.h"

using namespace hlservo;

App::App()
{
InitializeComponent();
}

void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs ^ e)
{
#if _DEBUG
if (IsDebuggerPresent()) {
DebugSettings->EnableFrameRateCounter = true;
}
#endif

if (mPage == nullptr) {
mPage = ref new OpenGLESPage(&mOpenGLES);
}

Windows::UI::Xaml::Window::Current->Content = mPage;
Windows::UI::Xaml::Window::Current->Activate();
}
@@ -0,0 +1,21 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

#pragma once

#include "OpenGLES.h"
#include "app.g.h"
#include "openglespage.xaml.h"

namespace hlservo {
ref class App sealed {
public:
App();
virtual void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs ^ e) override;

private:
OpenGLESPage ^ mPage;
OpenGLES mOpenGLES;
};
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,232 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

#include "pch.h"
#include "OpenGLES.h"

using namespace Platform;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;

OpenGLES::OpenGLES()
: mEglConfig(nullptr)
, mEglDisplay(EGL_NO_DISPLAY)
, mEglContext(EGL_NO_CONTEXT)
{
Initialize();
}

OpenGLES::~OpenGLES()
{
Cleanup();
}

void OpenGLES::Initialize()
{
const EGLint configAttributes[] = {
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_DEPTH_SIZE, 24,
EGL_STENCIL_SIZE, 8,
EGL_NONE
};

const EGLint contextAttributes[] = {
EGL_CONTEXT_CLIENT_VERSION, 3,
EGL_NONE
};

// Based on Angle MS template.

const EGLint defaultDisplayAttributes[] = {
// These are the default display attributes, used to request ANGLE's D3D11 renderer.
// eglInitialize will only succeed with these attributes if the hardware supports D3D11 Feature Level 10_0+.
EGL_PLATFORM_ANGLE_TYPE_ANGLE,
EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,

// EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER is an optimization that can have large performance benefits on
// mobile devices. Its syntax is subject to change, though. Please update your Visual Studio templates if you
// experience compilation issues with it.
EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER,
EGL_TRUE,

// EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE is an option that enables ANGLE to automatically call
// the IDXGIDevice3::Trim method on behalf of the application when it gets suspended.
// Calling IDXGIDevice3::Trim when an application is suspended is a Windows Store application certification
// requirement.
EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE,
EGL_TRUE,
EGL_NONE,
};

const EGLint fl9_3DisplayAttributes[] = {
// These can be used to request ANGLE's D3D11 renderer, with D3D11 Feature Level 9_3.
// These attributes are used if the call to eglInitialize fails with the default display attributes.
EGL_PLATFORM_ANGLE_TYPE_ANGLE,
EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE,
9,
EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE,
3,
EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER,
EGL_TRUE,
EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE,
EGL_TRUE,
EGL_NONE,
};

const EGLint warpDisplayAttributes[] = {
// These attributes can be used to request D3D11 WARP.
// They are used if eglInitialize fails with both the default display attributes and the 9_3 display attributes.
EGL_PLATFORM_ANGLE_TYPE_ANGLE,
EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE,
EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE,
EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER,
EGL_TRUE,
EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE,
EGL_TRUE,
EGL_NONE,
};

EGLConfig config = NULL;

// eglGetPlatformDisplayEXT is an alternative to eglGetDisplay.
// It allows us to pass in display attributes, used to configure D3D11.
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT =
reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT"));
if (!eglGetPlatformDisplayEXT) {
throw Exception::CreateException(E_FAIL, L"Failed to get function eglGetPlatformDisplayEXT");
}

//
// To initialize the display, we make three sets of calls to eglGetPlatformDisplayEXT and eglInitialize,
// with varying parameters passed to eglGetPlatformDisplayEXT:
// 1) The first calls uses "defaultDisplayAttributes" as a parameter. This corresponds to D3D11 Feature Level 10_0+.
// 2) If eglInitialize fails for step 1 (e.g. because 10_0+ isn't supported by the default GPU), then we try again
// using "fl9_3DisplayAttributes". This corresponds to D3D11 Feature Level 9_3.
// 3) If eglInitialize fails for step 2 (e.g. because 9_3+ isn't supported by the default GPU), then we try again
// using "warpDisplayAttributes". This corresponds to D3D11 Feature Level 11_0 on WARP, a D3D11 software
// rasterizer.
//

// This tries to initialize EGL to D3D11 Feature Level 10_0+. See above comment for details.
mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, defaultDisplayAttributes);
if (mEglDisplay == EGL_NO_DISPLAY) {
throw Exception::CreateException(E_FAIL, L"Failed to get EGL display");
}

if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE) {
// This tries to initialize EGL to D3D11 Feature Level 9_3, if 10_0+ is unavailable (e.g. on some mobile
// devices).
mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, fl9_3DisplayAttributes);
if (mEglDisplay == EGL_NO_DISPLAY) {
throw Exception::CreateException(E_FAIL, L"Failed to get EGL display");
}

if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE) {
// This initializes EGL to D3D11 Feature Level 11_0 on WARP, if 9_3+ is unavailable on the default GPU.
mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY,
warpDisplayAttributes);
if (mEglDisplay == EGL_NO_DISPLAY) {
throw Exception::CreateException(E_FAIL, L"Failed to get EGL display");
}

if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE) {
// If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred.
throw Exception::CreateException(E_FAIL, L"Failed to initialize EGL");
}
}
}

EGLint numConfigs = 0;
if ((eglChooseConfig(mEglDisplay, configAttributes, &mEglConfig, 1, &numConfigs) == EGL_FALSE) ||
(numConfigs == 0)) {
throw Exception::CreateException(E_FAIL, L"Failed to choose first EGLConfig");
}

mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT, contextAttributes);
if (mEglContext == EGL_NO_CONTEXT) {
throw Exception::CreateException(E_FAIL, L"Failed to create EGL context");
}
}

void OpenGLES::Cleanup()
{
if (mEglDisplay != EGL_NO_DISPLAY && mEglContext != EGL_NO_CONTEXT) {
eglDestroyContext(mEglDisplay, mEglContext);
mEglContext = EGL_NO_CONTEXT;
}

if (mEglDisplay != EGL_NO_DISPLAY) {
eglTerminate(mEglDisplay);
mEglDisplay = EGL_NO_DISPLAY;
}
}

void OpenGLES::Reset()
{
Cleanup();
Initialize();
}

EGLSurface OpenGLES::CreateSurface(SwapChainPanel ^ panel)
{
if (!panel) {
throw Exception::CreateException(E_INVALIDARG, L"SwapChainPanel parameter is invalid");
}

EGLSurface surface = EGL_NO_SURFACE;

const EGLint surfaceAttributes[] = {
EGL_ANGLE_SURFACE_RENDER_TO_BACK_BUFFER, EGL_TRUE,
EGL_NONE
};

PropertySet ^ surfaceCreationProperties = ref new PropertySet();
surfaceCreationProperties->Insert(ref new String(EGLNativeWindowTypeProperty), panel);

// How to set size and or scale:
// surfaceCreationProperties->Insert(ref new String(EGLRenderSurfaceSizeProperty),
// PropertyValue::CreateSize(*renderSurfaceSize));
// surfaceCreationProperties->Insert(ref new String(EGLRenderResolutionScaleProperty),
// PropertyValue::CreateSingle(*resolutionScale));

surface = eglCreateWindowSurface(mEglDisplay, mEglConfig,
reinterpret_cast<IInspectable*>(surfaceCreationProperties), surfaceAttributes);
if (surface == EGL_NO_SURFACE) {
throw Exception::CreateException(E_FAIL, L"Failed to create EGL surface");
}

return surface;
}

void OpenGLES::GetSurfaceDimensions(const EGLSurface surface, EGLint* width, EGLint* height)
{
eglQuerySurface(mEglDisplay, surface, EGL_WIDTH, width);
eglQuerySurface(mEglDisplay, surface, EGL_HEIGHT, height);
}

void OpenGLES::DestroySurface(const EGLSurface surface)
{
if (mEglDisplay != EGL_NO_DISPLAY && surface != EGL_NO_SURFACE) {
eglDestroySurface(mEglDisplay, surface);
}
}

void OpenGLES::MakeCurrent(const EGLSurface surface)
{
if (eglMakeCurrent(mEglDisplay, surface, surface, mEglContext) == EGL_FALSE) {
throw Exception::CreateException(E_FAIL, L"Failed to make EGLSurface current");
}
}

EGLBoolean OpenGLES::SwapBuffers(const EGLSurface surface)
{
return (eglSwapBuffers(mEglDisplay, surface));
}
@@ -0,0 +1,27 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

#pragma once

class OpenGLES {
public:
OpenGLES();
~OpenGLES();

EGLSurface CreateSurface(Windows::UI::Xaml::Controls::SwapChainPanel ^ panel);
void GetSurfaceDimensions(const EGLSurface surface, EGLint* width, EGLint* height);
void DestroySurface(const EGLSurface surface);
void MakeCurrent(const EGLSurface surface);
EGLBoolean SwapBuffers(const EGLSurface surface);
void Reset();

private:
void Initialize();
void Cleanup();

private:
EGLDisplay mEglDisplay;
EGLContext mEglContext;
EGLConfig mEglConfig;
};
@@ -0,0 +1,13 @@
<Page
x:Class="hlservo.OpenGLESPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:hlservo"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<SwapChainPanel x:Name="swapChainPanel">
<TextBlock Text="OpenGL ES and XAML" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="30" />
</SwapChainPanel>
</Page>

0 comments on commit acde7e0

Please sign in to comment.
You can’t perform that action at this time.