Browse Source

Platform: merge WindowlessWindowsEglApplication into EglApp and remove.

The whole class was a bad idea, why create something that's 99% similar
to another application and has just one platform-specific workaround? Of
course it resulted in this code being completely untested and not even
built anywhere, because it served a tiny insignificant use case.

To avoid losing all the code, I did my best in attempting to merge this
into the WindowlessEglApplication. But since, again, EGL isn't
really used on any Windows platform, I can't even say it builds
properly. Maybe not even the original code built.
pull/580/head
Vladimír Vondruš 4 years ago
parent
commit
da569a41de
  1. 17
      CMakeLists.txt
  2. 3
      doc/building.dox
  3. 2
      doc/changelog-old.dox
  4. 12
      doc/changelog.dox
  5. 1
      doc/cmake.dox
  6. 16
      modules/FindMagnum.cmake
  7. 6
      src/Magnum/GL/OpenGLTester.h
  8. 40
      src/Magnum/Platform/CMakeLists.txt
  9. 5
      src/Magnum/Platform/Test/CMakeLists.txt
  10. 55
      src/Magnum/Platform/Test/WindowlessWindowsEglApplicationTest.cpp
  11. 72
      src/Magnum/Platform/WindowlessEglApplication.cpp
  12. 7
      src/Magnum/Platform/WindowlessEglApplication.h
  13. 238
      src/Magnum/Platform/WindowlessWindowsEglApplication.cpp
  14. 538
      src/Magnum/Platform/WindowlessWindowsEglApplication.h
  15. 4
      src/Magnum/Platform/gl-info.cpp
  16. 2
      src/Magnum/Text/CMakeLists.txt
  17. 2
      src/Magnum/Text/fontconverter.cpp
  18. 2
      src/Magnum/TextureTools/CMakeLists.txt
  19. 2
      src/Magnum/TextureTools/distancefieldconverter.cpp

17
CMakeLists.txt

@ -91,7 +91,6 @@ set(_MAGNUM_DEPRECATED_UNPREFIXED_OPTIONS
WITH_WINDOWLESSGLXAPPLICATION
WITH_WINDOWLESSIOSAPPLICATION
WITH_WINDOWLESSWGLAPPLICATION
WITH_WINDOWLESSWINDOWSEGLAPPLICATION
WITH_CGLCONTEXT
WITH_EGLCONTEXT
WITH_GLXCONTEXT
@ -206,7 +205,7 @@ cmake_dependent_option(MAGNUM_WITH_SHADERTOOLS "Build ShaderTools library" ON "N
cmake_dependent_option(MAGNUM_WITH_TEXT "Build Text library" ON "NOT MAGNUM_WITH_FONTCONVERTER;NOT MAGNUM_WITH_MAGNUMFONT;NOT MAGNUM_WITH_MAGNUMFONTCONVERTER" ON)
cmake_dependent_option(MAGNUM_WITH_TEXTURETOOLS "Build TextureTools library" ON "NOT MAGNUM_WITH_TEXT;NOT MAGNUM_WITH_DISTANCEFIELDCONVERTER" ON)
cmake_dependent_option(MAGNUM_WITH_TRADE "Build Trade library" ON "NOT MAGNUM_WITH_MESHTOOLS;NOT MAGNUM_WITH_PRIMITIVES;NOT MAGNUM_WITH_SCENETOOLS;NOT MAGNUM_WITH_IMAGECONVERTER;NOT MAGNUM_WITH_ANYIMAGEIMPORTER;NOT MAGNUM_WITH_ANYIMAGECONVERTER;NOT MAGNUM_WITH_ANYSCENEIMPORTER;NOT MAGNUM_WITH_OBJIMPORTER;NOT MAGNUM_WITH_TGAIMAGECONVERTER;NOT MAGNUM_WITH_TGAIMPORTER" ON)
cmake_dependent_option(MAGNUM_WITH_GL "Build GL library" ON "NOT MAGNUM_WITH_SHADERS;NOT MAGNUM_WITH_GL_INFO;NOT MAGNUM_WITH_ANDROIDAPPLICATION;NOT MAGNUM_WITH_WINDOWLESSIOSAPPLICATION;NOT MAGNUM_WITH_CGLCONTEXT;NOT MAGNUM_WITH_GLXAPPLICATION;NOT MAGNUM_WITH_GLXCONTEXT;NOT MAGNUM_WITH_XEGLAPPLICATION;NOT MAGNUM_WITH_WINDOWLESSWGLAPPLICATION;NOT MAGNUM_WITH_WGLCONTEXT;NOT MAGNUM_WITH_WINDOWLESSWINDOWSEGLAPPLICATION;NOT MAGNUM_WITH_DISTANCEFIELDCONVERTER" ON)
cmake_dependent_option(MAGNUM_WITH_GL "Build GL library" ON "NOT MAGNUM_WITH_SHADERS;NOT MAGNUM_WITH_GL_INFO;NOT MAGNUM_WITH_ANDROIDAPPLICATION;NOT MAGNUM_WITH_WINDOWLESSIOSAPPLICATION;NOT MAGNUM_WITH_WINDOWLESSCGLAPPLICATION;NOT MAGNUM_WITH_WINDOWLESSGLXAPPLICATION;NOT MAGNUM_WITH_CGLCONTEXT;NOT MAGNUM_WITH_GLXAPPLICATION;NOT MAGNUM_WITH_GLXCONTEXT;NOT MAGNUM_WITH_XEGLAPPLICATION;NOT MAGNUM_WITH_WINDOWLESSWGLAPPLICATION;NOT MAGNUM_WITH_WGLCONTEXT;NOT MAGNUM_WITH_DISTANCEFIELDCONVERTER" ON)
option(MAGNUM_WITH_PRIMITIVES "Build Primitives library" ON)
cmake_dependent_option(MAGNUM_TARGET_HEADLESS "Build command-line utilities for use on a headless machines" OFF "MAGNUM_WITH_GL" OFF)
@ -253,8 +252,6 @@ elseif(CORRADE_TARGET_WINDOWS)
if(NOT MAGNUM_TARGET_GLES OR MAGNUM_TARGET_DESKTOP_GLES)
cmake_dependent_option(MAGNUM_WITH_WINDOWLESSWGLAPPLICATION "Build WindowlessWglApplication library" OFF "NOT MAGNUM_WITH_GL_INFO;NOT MAGNUM_WITH_FONTCONVERTER;NOT MAGNUM_WITH_DISTANCEFIELDCONVERTER" ON)
option(MAGNUM_WITH_WGLCONTEXT "Build WglContext library" OFF)
else()
cmake_dependent_option(MAGNUM_WITH_WINDOWLESSWINDOWSEGLAPPLICATION "Build WindowlessWindowsEglApplication library" OFF "NOT MAGNUM_WITH_GL_INFO;NOT MAGNUM_WITH_FONTCONVERTER;NOT MAGNUM_WITH_DISTANCEFIELDCONVERTER" ON)
endif()
endif()
@ -404,8 +401,8 @@ if(_MAGNUM_ACCEPT_DEPRECATED_UNPREFIXED_OPTIONS AND MAGNUM_BUILD_DEPRECATED)
set(WITH_WINDOWLESSWGLAPPLICATION ON)
endif()
else()
if(NOT DEFINED WITH_WINDOWLESSWINDOWSEGLAPPLICATION)
set(WITH_WINDOWLESSWINDOWSEGLAPPLICATION ON)
if(NOT DEFINED WITH_WINDOWLESSEGLAPPLICATION)
set(WITH_WINDOWLESSEGLAPPLICATION ON)
endif()
endif()
endif()
@ -544,12 +541,12 @@ if(MAGNUM_WITH_OPENGLTESTER)
set(OPENGLTESTER_APPLICATION MagnumWindowlessGlxApplication)
endif()
elseif(CORRADE_TARGET_WINDOWS)
if(NOT MAGNUM_TARGET_GLES OR MAGNUM_TARGET_DESKTOP_GLES)
if(MAGNUM_TARGET_GLES AND NOT MAGNUM_TARGET_DESKTOP_GLES)
set(MAGNUM_WITH_WINDOWLESSEGLAPPLICATION ON)
set(OPENGLTESTER_APPLICATION MagnumWindowlessEglApplication)
else()
set(MAGNUM_WITH_WINDOWLESSWGLAPPLICATION ON)
set(OPENGLTESTER_APPLICATION MagnumWindowlessWglApplication)
else()
set(MAGNUM_WITH_WINDOWLESSWINDOWSEGLAPPLICATION ON)
set(OPENGLTESTER_APPLICATION MagnumWindowlessWindowsEglApplication)
endif()
else()
# Assuming this gets hit only if MAGNUM_BUILD_GL_TESTS are enabled

3
doc/building.dox

@ -546,9 +546,6 @@ going to build any of the @ref example-index "examples", you'll need it.
- `MAGNUM_WITH_WINDOWLESSWGLAPPLICATION` --- Build the
@ref Platform::WindowlessWglApplication "WindowlessWglApplication" library.
Requires `MAGNUM_TARGET_GL` to be enabled.
- `MAGNUM_WITH_WINDOWLESSWINDOWSEGLAPPLICATION` --- Build the
@ref Platform::WindowlessWindowsEglApplication "WindowlessWindowsEglApplication"
library. Requires `MAGNUM_TARGET_GL` to be enabled.
None of the context libraries is built by default. Similarly to the application
libraries, they are always built as static. You need them only if you chose to

2
doc/changelog-old.dox

@ -744,7 +744,7 @@ a high-level overview.
[mosra/magnum-bootstrap#6](https://github.com/mosra/magnum-bootstrap/pull/6))
- Text input support in @ref Platform::Sdl2Application and
@ref Platform::GlfwApplication (see [mosra/magnum#129](https://github.com/mosra/magnum/issues/129))
- Added @ref Platform::WindowlessWindowsEglApplication and
- Added @cpp Platform::WindowlessWindowsEglApplication @ce and
@ref Platform::WindowlessIosApplication for ANGLE and iOS
- New @ref Platform::WindowlessEglApplication that works on headless NVidia,
Mesa drivers and Emscripten (see [mosra/magnum#133](https://github.com/mosra/magnum/pull/133))

12
doc/changelog.dox

@ -205,8 +205,7 @@ See also:
- Implemented @relativeref{Platform::WindowlessEglApplication,Configuration::Flag::NoError}
in @ref Platform::WindowlessEglApplication,
@ref Platform::WindowlessGlxApplication,
@ref Platform::WindowlessWglApplication,
@ref Platform::WindowlessWindowsEglApplication and
@ref Platform::WindowlessWglApplication and
@ref Platform::Sdl2Application
@subsubsection changelog-latest-new-scenegraph SceneGraph library
@ -1084,6 +1083,12 @@ See also:
@ref Math::RectangularMatrix::data() are no longer @cpp constexpr @ce in
order to make them return a reference to a fixed-size array instead of a
pointer, which was deemed a more useful property.
- @cpp Platform::WindowlessWindowsEglApplication @ce is now merged into
@ref Platform::WindowlessEglApplication. Since its use case was rather rare
(windowless applications on ANGLE on Windows) and it wasn't even built in
any packages, it's completely removed without providing any backwards
compatibility --- switch to @ref Platform::WindowlessEglApplication
instead.
- @ref SceneGraph::Object::addChild() no longer requires the type constructor
to have the last parameter a parent object object pointer, as that was
quite limiting. Instead it's calling @ref SceneGraph::Object::setParent()
@ -1372,7 +1377,8 @@ Released 2020-06-27, tagged as
@ref Platform::WindowlessEglApplication,
@ref Platform::WindowlessGlxApplication,
@ref Platform::WindowlessWglApplication and
@ref Platform::WindowlessWindowsEglApplication (see [mosra/magnum#433](https://github.com/mosra/magnum/pull/433)
@cpp Platform::WindowlessWindowsEglApplication @ce (see
[mosra/magnum#433](https://github.com/mosra/magnum/pull/433)
and [mosra/magnum#437](https://github.com/mosra/magnum/pull/437))
- CUDA device selection in @ref Platform::WindowlessEglApplication (see
[mosra/magnum#449](https://github.com/mosra/magnum/pull/449))

1
doc/cmake.dox

@ -217,7 +217,6 @@ Platform namespace is split into more components:
- `WindowlessGlxApplication` --- @ref Platform::WindowlessGlxApplication "WindowlessGlxApplication"
- `WindowlessIosApplication` --- @ref Platform::WindowlessIosApplication "WindowlessIosApplication"
- `WindowlessWglApplication` --- @ref Platform::WindowlessWglApplication "WindowlessWglApplication"
- `WindowlessWindowsEglApplication` --- @ref Platform::WindowlessWindowsEglApplication "WindowlessWindowsEglApplication"
For manual context creation (without application wrappers) there are also
platform-specific context libraries (see @ref platform-custom for more

16
modules/FindMagnum.cmake

@ -78,7 +78,6 @@
# WindowlessGlxApplication - Windowless GLX application
# WindowlessIosApplication - Windowless iOS application
# WindowlessWglApplication - Windowless WGL application
# WindowlessWindowsEglApplication - Windowless Windows/EGL application
# CglContext - CGL context
# EglContext - EGL context
# GlxContext - GLX context
@ -395,7 +394,7 @@ if(CORRADE_TARGET_UNIX AND NOT CORRADE_TARGET_APPLE)
list(APPEND _MAGNUM_LIBRARY_COMPONENTS GlxApplication XEglApplication WindowlessGlxApplication GlxContext)
endif()
if(CORRADE_TARGET_WINDOWS)
list(APPEND _MAGNUM_LIBRARY_COMPONENTS WindowlessWglApplication WglContext WindowlessWindowsEglApplication)
list(APPEND _MAGNUM_LIBRARY_COMPONENTS WindowlessWglApplication WglContext)
endif()
if(CORRADE_TARGET_UNIX OR CORRADE_TARGET_WINDOWS)
list(APPEND _MAGNUM_EXECUTABLE_COMPONENTS fontconverter distancefieldconverter)
@ -439,10 +438,10 @@ elseif(CORRADE_TARGET_UNIX)
list(APPEND _MAGNUM_OpenGLTester_DEPENDENCIES WindowlessGlxApplication)
endif()
elseif(CORRADE_TARGET_WINDOWS)
if(NOT MAGNUM_TARGET_GLES OR MAGNUM_TARGET_DESKTOP_GLES)
list(APPEND _MAGNUM_OpenGLTester_DEPENDENCIES WindowlessWglApplication)
if(MAGNUM_TARGET_GLES AND NOT MAGNUM_TARGET_DESKTOP_GLES)
list(APPEND _MAGNUM_OpenGLTester_DEPENDENCIES WindowlessEglApplication)
else()
list(APPEND _MAGNUM_OpenGLTester_DEPENDENCIES WindowlessWindowsEglApplication)
list(APPEND _MAGNUM_OpenGLTester_DEPENDENCIES WindowlessWglApplication)
endif()
endif()
@ -492,7 +491,6 @@ set(_MAGNUM_WindowlessEglApplication_DEPENDENCIES GL)
set(_MAGNUM_WindowlessGlxApplication_DEPENDENCIES GL)
set(_MAGNUM_WindowlessIosApplication_DEPENDENCIES GL)
set(_MAGNUM_WindowlessWglApplication_DEPENDENCIES GL)
set(_MAGNUM_WindowlessWindowsEglApplication_DEPENDENCIES GL)
set(_MAGNUM_XEglApplication_DEPENDENCIES GL)
set(_MAGNUM_CglContext_DEPENDENCIES GL)
set(_MAGNUM_EglContext_DEPENDENCIES GL)
@ -799,12 +797,6 @@ foreach(_component ${Magnum_FIND_COMPONENTS})
# Windowless WGL application has no additional dependencies
# Windowless Windows/EGL application dependencies
elseif(_component STREQUAL WindowlessWindowsEglApplication)
find_package(EGL)
set_property(TARGET Magnum::${_component} APPEND PROPERTY
INTERFACE_LINK_LIBRARIES EGL::EGL)
# X/EGL application dependencies
elseif(_component STREQUAL XEglApplication)
find_package(EGL)

6
src/Magnum/GL/OpenGLTester.h

@ -50,10 +50,10 @@
#include "Magnum/Platform/WindowlessGlxApplication.h"
#endif
#elif defined(CORRADE_TARGET_WINDOWS)
#if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_DESKTOP_GLES)
#include "Magnum/Platform/WindowlessWglApplication.h"
#if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_DESKTOP_GLES)
#include "Magnum/Platform/WindowlessEglApplication.h"
#else
#include "Magnum/Platform/WindowlessWindowsEglApplication.h"
#include "Magnum/Platform/WindowlessWglApplication.h"
#endif
#else
#error cannot run OpenGL tests on this platform

40
src/Magnum/Platform/CMakeLists.txt

@ -623,44 +623,6 @@ if(MAGNUM_WITH_WINDOWLESSWGLAPPLICATION)
add_library(Magnum::WindowlessWglApplication ALIAS MagnumWindowlessWglApplication)
endif()
# Windowless Windows/EGL application
if(MAGNUM_WITH_WINDOWLESSWINDOWSEGLAPPLICATION)
if(NOT MAGNUM_TARGET_GL)
message(SEND_ERROR "WindowlessWindowsEglApplication is available only if MAGNUM_TARGET_GL is enabled")
endif()
set(NEED_EGLCONTEXT 1)
set(MagnumWindowlessWindowsEglApplication_SRCS
WindowlessWindowsEglApplication.cpp
Implementation/Egl.cpp
$<TARGET_OBJECTS:MagnumEglContextObjects>)
set(MagnumWindowlessWindowsEglApplication_HEADERS
WindowlessWindowsEglApplication.h)
set(MagnumWindowlessWindowsEglApplication_PRIVATE_HEADERS
Implementation/Egl.h)
add_library(MagnumWindowlessWindowsEglApplication STATIC
${MagnumWindowlessWindowsEglApplication_SRCS}
${MagnumWindowlessWindowsEglApplication_HEADERS}
${MagnumWindowlessWindowsEglApplication_PRIVATE_HEADERS})
set_target_properties(MagnumWindowlessWindowsEglApplication PROPERTIES
DEBUG_POSTFIX "-d")
if(NOT MAGNUM_BUILD_STATIC OR MAGNUM_BUILD_STATIC_PIC)
set_target_properties(MagnumWindowlessWindowsEglApplication PROPERTIES POSITION_INDEPENDENT_CODE ON)
endif()
target_link_libraries(MagnumWindowlessWindowsEglApplication PUBLIC MagnumGL EGL::EGL)
install(FILES ${MagnumWindowlessWindowsEglApplication_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Platform)
install(TARGETS MagnumWindowlessWindowsEglApplication
RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR}
LIBRARY DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}
ARCHIVE DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR})
# Magnum WindowlessWindowsEglApplication target alias for superprojects
add_library(Magnum::WindowlessWindowsEglApplication ALIAS MagnumWindowlessWindowsEglApplication)
endif()
# Windowless CGL application
if(MAGNUM_WITH_WINDOWLESSCGLAPPLICATION)
if(NOT MAGNUM_TARGET_GL)
@ -955,7 +917,7 @@ if(MAGNUM_WITH_GL_INFO)
endif()
elseif(CORRADE_TARGET_WINDOWS)
if(MAGNUM_TARGET_GLES AND NOT MAGNUM_TARGET_DESKTOP_GLES)
target_link_libraries(magnum-gl-info PRIVATE MagnumWindowlessWindowsEglApplication)
target_link_libraries(magnum-gl-info PRIVATE MagnumWindowlessEglApplication)
else()
target_link_libraries(magnum-gl-info PRIVATE MagnumWindowlessWglApplication)
endif()

5
src/Magnum/Platform/Test/CMakeLists.txt

@ -176,8 +176,3 @@ if(MAGNUM_WITH_WINDOWLESSWGLAPPLICATION)
add_executable(PlatformWindowlessWglApplicationTest WindowlessWglApplicationTest.cpp)
target_link_libraries(PlatformWindowlessWglApplicationTest PRIVATE MagnumWindowlessWglApplication)
endif()
if(MAGNUM_WITH_WINDOWLESSWINDOWSEGLAPPLICATION)
add_executable(PlatformWindowlessWindowsEglApplicationTest WindowlessWindowsEglApplicationTest.cpp)
target_link_libraries(PlatformWindowlessWindowsEglApplicationTest PRIVATE MagnumWindowlessWindowsEglApplication)
endif()

55
src/Magnum/Platform/Test/WindowlessWindowsEglApplicationTest.cpp

@ -1,55 +0,0 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include <Corrade/Utility/Arguments.h>
#include "Magnum/Platform/WindowlessWindowsEglApplication.h"
namespace Magnum { namespace Platform { namespace Test { namespace {
struct WindowlessWindowsEglApplicationTest: Platform::WindowlessApplication {
explicit WindowlessWindowsEglApplicationTest(const Arguments& arguments);
int exec() override { return 0; }
};
WindowlessWindowsEglApplicationTest::WindowlessWindowsEglApplicationTest(const Arguments& arguments): Platform::WindowlessApplication{arguments, NoCreate} {
Utility::Arguments args;
args.addSkippedPrefix("magnum", "engine-specific options")
.addBooleanOption("quiet").setHelp("quiet", "like --magnum-log quiet, but specified via a Context::Configuration instead")
.addBooleanOption("gpu-validation").setHelp("gpu-validation", "like --magnum-gpu-validation, but specified via a Context::Configuration instead")
.parse(arguments.argc, arguments.argv);
Configuration conf;
if(args.isSet("quiet"))
conf.addFlags(Configuration::Flag::QuietLog);
/* No verbose logs in this app */
if(args.isSet("gpu-validation"))
conf.addFlags(Configuration::Flag::GpuValidation);
createContext(conf);
}
}}}}
MAGNUM_WINDOWLESSAPPLICATION_MAIN(Magnum::Platform::Test::WindowlessWindowsEglApplicationTest)

72
src/Magnum/Platform/WindowlessEglApplication.cpp

@ -39,6 +39,14 @@
#include "Implementation/Egl.h"
/* ANGLE's EGL on Windows needs an actual window */
/** @todo investigate if this is still needed */
#ifdef CORRADE_TARGET_WINDOWS
#define WIN32_LEAN_AND_MEAN 1
#define VC_EXTRALEAN
#include <windows.h>
#endif
/* None of this is in the Emscripten emulation layer, so no need to include
that there */
#ifndef MAGNUM_TARGET_WEBGL
@ -252,10 +260,44 @@ WindowlessEglContext::WindowlessEglContext(const Configuration& configuration, G
}
#endif
/* ANGLE's EGL on Windows needs to get a display from an actual
window. Elsewhere EGL_DEFAULT_DISPLAY is fine. */
/** @todo investigate if this is still needed */
#ifdef CORRADE_TARGET_WINDOWS
/* Register the window class (if not yet done) */
WNDCLASSW wc;
if(!GetClassInfoW(GetModuleHandleW(nullptr), L"Magnum Windowless Application", &wc)) {
wc = WNDCLASSW{
0,
DefWindowProcW,
0,
0,
GetModuleHandleW(nullptr),
nullptr,
nullptr,
HBRUSH(COLOR_BACKGROUND),
nullptr,
L"Magnum Windowless Application"
};
if(!RegisterClassW(&wc)) {
Error() << "Platform::WindowlessWglContext: cannot create window class:" << GetLastError();
return;
}
}
/* Create the window */
_window = CreateWindowW(wc.lpszClassName, L"Magnum Windowless Application",
WS_OVERLAPPEDWINDOW, 0, 0, 32, 32, 0, 0, wc.hInstance, 0);
/* Initialize */
_display = eglGetDisplay(GetDC(_window));
#else
if(!(_display = eglGetDisplay(EGL_DEFAULT_DISPLAY))) {
Error{} << "Platform::WindowlessEglApplication::tryCreateContext(): cannot get default EGL display:" << Implementation::eglErrorString(eglGetError());
return;
}
#endif
}
if(!eglInitialize(_display, nullptr, nullptr)) {
@ -489,7 +531,14 @@ WindowlessEglContext::WindowlessEglContext(const Configuration& configuration, G
return;
}
#if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL)
#ifdef CORRADE_TARGET_WINDOWS
/* ANGLE's EGL on Windows needs has an actual window, and so it also needs
a surface */
/** @todo investigate if this is still needed */
if(!(_surface = eglCreateWindowSurface(_display, config, _window, nullptr)))
Error() << "Platform::WindowlessEglContext: cannot create window surface:" << Implementation::eglErrorString(eglGetError());
#elif defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL)
/* Android Emulator can run with a SwiftShader GPU and thus needs some of
the SwiftShader context creation workarounds. However, it's impossible
to detect, as EGL_VERSION is always "1.4 Android META-EGL" and
@ -525,17 +574,23 @@ WindowlessEglContext::WindowlessEglContext(WindowlessEglContext&& other) noexcep
#ifndef MAGNUM_TARGET_WEBGL
_sharedContext{other._sharedContext},
#endif
#ifdef CORRADE_TARGET_WINDOWS
_window{other._window},
#endif
_display{other._display}, _context{other._context}
#if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL)
#if defined(CORRADE_TARGET_WINDOWS) || (defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL))
, _surface{other._surface}
#endif
{
#ifndef MAGNUM_TARGET_WEBGL
other._sharedContext = false;
#endif
#ifdef CORRADE_TARGET_WINDOWS
other._window = {};
#endif
other._display = {};
other._context = {};
#if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL)
#if defined(CORRADE_TARGET_WINDOWS) || (defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL))
other._surface = {};
#endif
}
@ -554,7 +609,7 @@ WindowlessEglContext::~WindowlessEglContext() {
eglMakeCurrent(_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(_display, _context);
}
#if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL)
#if defined(CORRADE_TARGET_WINDOWS) || (defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL))
if(_surface) eglDestroySurface(_display, _surface);
#endif
@ -567,6 +622,10 @@ WindowlessEglContext::~WindowlessEglContext() {
!_sharedContext &&
#endif
_display) eglTerminate(_display);
#ifdef CORRADE_TARGET_WINDOWS
if(_window) DestroyWindow(_window);
#endif
}
WindowlessEglContext& WindowlessEglContext::operator=(WindowlessEglContext&& other) noexcept {
@ -576,9 +635,12 @@ WindowlessEglContext& WindowlessEglContext::operator=(WindowlessEglContext&& oth
#endif
swap(other._display, _display);
swap(other._context, _context);
#if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL)
#if defined(CORRADE_TARGET_WINDOWS) || (defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL))
swap(other._surface, _surface);
#endif
#ifdef CORRADE_TARGET_WINDOWS
swap(other._window, _window);
#endif
return *this;
}

7
src/Magnum/Platform/WindowlessEglApplication.h

@ -162,9 +162,14 @@ class WindowlessEglContext {
#ifndef MAGNUM_TARGET_WEBGL
bool _sharedContext = false;
#endif
#ifdef CORRADE_TARGET_WINDOWS
/* It's a HWND, which is HANDLE, which is PVOID, which is void*. FFS
Windows you're really mad with the typedefs. */
void* _window{};
#endif
EGLDisplay _display{};
EGLContext _context{};
#if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL)
#if defined(CORRADE_TARGET_WINDOWS) || (defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_WEBGL))
/* Needed only by SwiftShader, using EGL_NO_SURFACE everywhere else */
EGLSurface _surface = EGL_NO_SURFACE;
#endif

238
src/Magnum/Platform/WindowlessWindowsEglApplication.cpp

@ -1,238 +0,0 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "WindowlessWindowsEglApplication.h"
#include <Corrade/Utility/Assert.h>
#include <Corrade/Utility/Debug.h>
#include "Magnum/GL/Version.h"
#include "Implementation/Egl.h"
#ifndef EGL_KHR_create_context_no_error
#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31B3
#endif
namespace Magnum { namespace Platform {
WindowlessWindowsEglContext::WindowlessWindowsEglContext(const Configuration& configuration, GLContext* const magnumContext) {
/** @todo device selection and skipping of eglInitialize()/Terminate() the
same way as with WindowlessEglContext */
/* Register the window class (if not yet done) */
WNDCLASSW wc;
if(!GetClassInfoW(GetModuleHandleW(nullptr), L"Magnum Windowless Application", &wc)) {
wc = WNDCLASSW{
0,
DefWindowProcW,
0,
0,
GetModuleHandleW(nullptr),
nullptr,
nullptr,
HBRUSH(COLOR_BACKGROUND),
nullptr,
L"Magnum Windowless Application"
};
if(!RegisterClassW(&wc)) {
Error() << "Platform::WindowlessWglContext: cannot create window class:" << GetLastError();
return;
}
}
/* Create the window */
_window = CreateWindowW(wc.lpszClassName, L"Magnum Windowless Application",
WS_OVERLAPPEDWINDOW, 0, 0, 32, 32, 0, 0, wc.hInstance, 0);
/* Initialize */
_display = eglGetDisplay(GetDC(_window));
if(!eglInitialize(_display, nullptr, nullptr)) {
Error() << "Platform::WindowlessWindowsEglApplication::tryCreateContext(): cannot initialize EGL:" << Implementation::eglErrorString(eglGetError());
return;
}
const EGLenum api =
#ifndef MAGNUM_TARGET_GLES
EGL_OPENGL_API
#else
EGL_OPENGL_ES_API
#endif
;
if(!eglBindAPI(api)) {
Error() << "Platform::WindowlessWindowsEglApplication::tryCreateContext(): cannot bind EGL API:" << Implementation::eglErrorString(eglGetError());
return;
}
/* Choose EGL config */
static const EGLint attribs[] = {
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_DEPTH_SIZE, 1,
#ifndef MAGNUM_TARGET_GLES
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
#elif defined(MAGNUM_TARGET_GLES3)
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT,
#elif defined(MAGNUM_TARGET_GLES2)
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
#else
#error unsupported OpenGL edition
#endif
EGL_NONE
};
EGLint configCount;
EGLConfig config;
if(!eglChooseConfig(_display, attribs, &config, 1, &configCount)) {
Error() << "Platform::WindowlessWindowsEglApplication::tryCreateContext(): cannot get EGL visual config:" << Implementation::eglErrorString(eglGetError());
return;
}
if(!configCount) {
Error() << "Platform::WindowlessWindowsEglApplication::tryCreateContext(): no matching EGL visual config available";
return;
}
/* Request debug context if GpuValidation is enabled either via the
configuration or via command-line */
Configuration::Flags flags = configuration.flags();
if((flags & Configuration::Flag::GpuValidation) || (magnumContext && magnumContext->configurationFlags() & GL::Context::Configuration::Flag::GpuValidation))
flags |= Configuration::Flag::Debug;
else if((flags & Configuration::Flag::GpuValidationNoError) || (magnumContext && magnumContext->configurationFlags() & GL::Context::Configuration::Flag::GpuValidationNoError))
flags |= Configuration::Flag::NoError;
/** @todo needs a growable DynamicArray with disabled alloc or somesuch */
EGLint attributes[7] = {
#ifdef MAGNUM_TARGET_GLES
EGL_CONTEXT_CLIENT_VERSION,
#ifdef MAGNUM_TARGET_GLES3
3,
#elif defined(MAGNUM_TARGET_GLES2)
2,
#else
#error unsupported OpenGL ES version
#endif
#endif
/* Mask out the upper 32bits used for other flags */
EGL_CONTEXT_FLAGS_KHR, EGLint(UnsignedLong(flags) & 0xffffffffu),
/* The rest is added optionally */
EGL_NONE, EGL_NONE, /* EGL_CONTEXT_OPENGL_NO_ERROR_KHR */
EGL_NONE
};
std::size_t nextAttribute = 4;
CORRADE_INTERNAL_ASSERT(attributes[nextAttribute] == EGL_NONE);
if(flags & Configuration::Flag::NoError) {
attributes[nextAttribute++] = EGL_CONTEXT_OPENGL_NO_ERROR_KHR;
attributes[nextAttribute++] = true;
}
CORRADE_INTERNAL_ASSERT(nextAttribute < Containers::arraySize(attributes));
if(!(_context = eglCreateContext(_display, config, configuration.sharedContext(), attributes))) {
Error() << "Platform::WindowlessWindowsEglContext: cannot create EGL context:" << Implementation::eglErrorString(eglGetError());
return;
}
if(!(_surface = eglCreateWindowSurface(_display, config, _window, nullptr)))
Error() << "Platform::WindowlessWindowsEglContext: cannot create window surface:" << Implementation::eglErrorString(eglGetError());
}
WindowlessWindowsEglContext::WindowlessWindowsEglContext(WindowlessWindowsEglContext&& other) noexcept: _window{other._window}, _display{other._display}, _surface{other._surface}, _context{other._context} {
other._window = {};
other._display = {};
other._surface = {};
other._context = {};
}
WindowlessWindowsEglContext::~WindowlessWindowsEglContext() {
if(_context) eglDestroyContext(_display, _context);
if(_surface) eglDestroySurface(_display, _surface);
if(_display) eglTerminate(_display);
if(_window) DestroyWindow(_window);
}
WindowlessWindowsEglContext& WindowlessWindowsEglContext::operator=(WindowlessWindowsEglContext&& other) noexcept {
using std::swap;
swap(other._window, _window);
swap(other._display, _display);
swap(other._surface, _surface);
swap(other._context, _context);
return *this;
}
bool WindowlessWindowsEglContext::makeCurrent() {
if(eglMakeCurrent(_display, _surface, _surface, _context))
return true;
Error() << "Platform::WindowlessWindowsEglContext::makeCurrent(): cannot make context current:" << GetLastError();
return false;
}
bool WindowlessWindowsEglContext::release() {
if(eglMakeCurrent(_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
return true;
Error() << "Platform::WindowlessWindowsEglApplication::release(): cannot release current context:" << GetLastError();
return false;
}
WindowlessWindowsEglContext::Configuration::Configuration() {
GL::Context::Configuration::addFlags(GL::Context::Configuration::Flag::Windowless);
}
#ifndef DOXYGEN_GENERATING_OUTPUT
WindowlessWindowsEglApplication::WindowlessWindowsEglApplication(const Arguments& arguments): WindowlessWindowsEglApplication{arguments, Configuration{}} {}
#endif
WindowlessWindowsEglApplication::WindowlessWindowsEglApplication(const Arguments& arguments, const Configuration& configuration): WindowlessWindowsEglApplication{arguments, NoCreate} {
createContext(configuration);
}
WindowlessWindowsEglApplication::WindowlessWindowsEglApplication(const Arguments& arguments, NoCreateT): _glContext{NoCreate}, _context{NoCreate, arguments.argc, arguments.argv} {}
void WindowlessWindowsEglApplication::createContext() { createContext({}); }
void WindowlessWindowsEglApplication::createContext(const Configuration& configuration) {
if(!tryCreateContext(configuration)) std::exit(1);
}
bool WindowlessWindowsEglApplication::tryCreateContext(const Configuration& configuration) {
CORRADE_ASSERT(_context.version() == Version::None, "Platform::WindowlessWindowsEglApplication::tryCreateContext(): context already created", false);
WindowlessWindowsEglContext glContext{configuration, &_context};
if(!glContext.isCreated() || !glContext.makeCurrent() || !_context.tryCreate(configuration))
return false;
_glContext = std::move(glContext);
return true;
}
WindowlessWindowsEglApplication::~WindowlessWindowsEglApplication() = default;
}}

538
src/Magnum/Platform/WindowlessWindowsEglApplication.h

@ -1,538 +0,0 @@
#ifndef Magnum_Platform_WindowlessWindowsEglApplication_h
#define Magnum_Platform_WindowlessWindowsEglApplication_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
/** @file
* @brief Class @ref Magnum::Platform::WindowlessWindowsEglApplication, @ref Magnum::Platform::WindowlessWindowsEglContext, macro @ref MAGNUM_WINDOWLESSWINDOWSEGLAPPLICATION_MAIN()
*/
#include "Magnum/configure.h"
#ifdef MAGNUM_TARGET_GL
#ifndef DOXYGEN_GENERATING_OUTPUT
#define WIN32_LEAN_AND_MEAN 1
#define VC_EXTRALEAN
#endif
#include <windows.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <Corrade/Containers/EnumSet.h>
#include "Magnum/Magnum.h"
#include "Magnum/Tags.h"
#include "Magnum/Platform/GLContext.h"
namespace Magnum { namespace Platform {
/**
@brief Windowless Windows/EGL context
@m_keywords{WindowlessGLContext EGL}
GL context using pure WINAPI and EGL, used in @ref WindowlessWindowsEglApplication.
Meant to be used when there is a need to manage (multiple) GL contexts
manually. See @ref platform-windowless-contexts for more information. If no
other application header is included, this class is also aliased to
@cpp Platform::WindowlessGLContext @ce.
@note This class is available only if Magnum is compiled with
@ref MAGNUM_TARGET_GL enabled (done by default). See @ref building-features
for more information.
*/
class WindowlessWindowsEglContext {
public:
class Configuration;
/**
* @brief Constructor
* @param configuration Context configuration
* @param context Optional Magnum context instance constructed
* using @ref NoCreate to manage driver workarounds
*
* Once the context is created, make it current using
* @ref makeCurrent() and create @ref Platform::GLContext instance to
* be able to use Magnum.
* @see @ref isCreated()
*/
explicit WindowlessWindowsEglContext(const Configuration& configuration, GLContext* context = nullptr);
/**
* @brief Construct without creating the context
*
* Move a instance with created context over to make it usable.
*/
explicit WindowlessWindowsEglContext(NoCreateT) {}
/** @brief Copying is not allowed */
WindowlessWindowsEglContext(const WindowlessWindowsEglContext&) = delete;
/** @brief Move constructor */
WindowlessWindowsEglContext(WindowlessWindowsEglContext&& other) noexcept;
/** @brief Copying is not allowed */
WindowlessWindowsEglContext& operator=(const WindowlessWindowsEglContext&) = delete;
/** @brief Move assignment */
WindowlessWindowsEglContext& operator=(WindowlessWindowsEglContext&& other) noexcept;
/**
* @brief Destructor
*
* Destroys the context, if any.
*/
~WindowlessWindowsEglContext();
/** @brief Whether the context is created */
bool isCreated() const { return _context; }
/**
* @brief Make the context current
*
* Prints error message and returns @cpp false @ce on failure,
* otherwise returns @cpp true @ce. If the context is current on
* another thread, you have to @ref release() it there first --- an
* OpenGL context can't be current in multiple threads at the same
* time.
*/
bool makeCurrent();
/**
* @brief Release current context
* @m_since_latest
*
* Releases a context previously made current using @ref makeCurrent().
* Prints error message and returns @cpp false @ce on failure,
* otherwise returns @cpp true @ce.
*/
bool release();
/**
* @brief Underlying OpenGL context
* @m_since{2020,06}
*
* Use in case you need to call EGL functionality directly or in order
* to create a shared context. Returns @cpp nullptr @ce in case the
* context was not created yet.
* @see @ref Configuration::setSharedContext()
*/
EGLContext glContext() { return _context; }
private:
HWND _window{};
EGLDisplay _display{};
EGLSurface _surface{};
EGLContext _context{};
};
/**
@brief Configuration
@see @ref WindowlessWindowsEglContext(),
@ref WindowlessWindowsEglApplication::WindowlessWindowsEglApplication(),
@ref WindowlessWindowsEglApplication::createContext(),
@ref WindowlessWindowsEglApplication::tryCreateContext()
*/
class WindowlessWindowsEglContext::Configuration: public GL::Context::Configuration {
public:
/**
* @brief Context flag
*
* Includes also everything from @ref GL::Context::Configuration::Flag
* except for @relativeref{GL::Context::Configuration,Flag::Windowless},
* which is enabled implicitly by default.
* @see @ref Flags, @ref setFlags(), @ref GL::Context::Flag
*/
enum class Flag: UnsignedLong {
/**
* Debug context. Enabled automatically if supported by the driver
* and the @ref Flag::GpuValidation flag is set or if the
* `--magnum-gpu-validation` @ref GL-Context-usage-command-line "command-line option"
* is set to `on`.
*/
Debug = EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR,
/**
* Context without error reporting. Might result in better
* performance, but situations that would have generated errors
* instead cause undefined behavior. Enabled automatically if
* supported by the driver and the @ref Flag::GpuValidationNoError
* flag is set or if the `--magnum-gpu-validation` @ref GL-Context-usage-command-line "command-line option"
* is set to `no-error`.
* @m_since_latest
*/
/* Treated as a separate attribute and not a flag in EGL, thus
handling manually. */
NoError = 1ull << 32,
/**
* @copydoc GL::Context::Configuration::Flag::QuietLog
* @m_since_latest
*/
QuietLog = UnsignedLong(GL::Context::Configuration::Flag::QuietLog),
/**
* @copydoc GL::Context::Configuration::Flag::VerboseLog
* @m_since_latest
*/
VerboseLog = UnsignedLong(GL::Context::Configuration::Flag::VerboseLog),
/**
* @copydoc GL::Context::Configuration::Flag::GpuValidation
* @m_since_latest
*/
GpuValidation = UnsignedLong(GL::Context::Configuration::Flag::GpuValidation),
/**
* @copydoc GL::Context::Configuration::Flag::GpuValidationNoError
* @m_since_latest
*/
GpuValidationNoError = UnsignedLong(GL::Context::Configuration::Flag::GpuValidationNoError)
};
/**
* @brief Context flags
*
* @see @ref setFlags(), @ref Context::Flags
*/
typedef Containers::EnumSet<Flag> Flags;
/*implicit*/ Configuration();
/** @brief Context flags */
Flags flags() const {
return Flag(UnsignedLong(GL::Context::Configuration::flags()));
}
/**
* @brief Set context flags
* @return Reference to self (for method chaining)
*
* Default is no flag. To avoid clearing default flags by accident,
* prefer to use @ref addFlags() and @ref clearFlags() instead.
* @see @ref GL::Context::flags()
*/
Configuration& setFlags(Flags flags) {
GL::Context::Configuration::setFlags(GL::Context::Configuration::Flag(UnsignedLong(flags)));
return *this;
}
/**
* @brief Add context flags
* @return Reference to self (for method chaining)
*
* Unlike @ref setFlags(), ORs the flags with existing instead of
* replacing them. Useful for preserving the defaults.
* @see @ref clearFlags()
*/
Configuration& addFlags(Flags flags) {
GL::Context::Configuration::addFlags(GL::Context::Configuration::Flag(UnsignedLong(flags)));
return *this;
}
/**
* @brief Clear context flags
* @return Reference to self (for method chaining)
*
* Unlike @ref setFlags(), ANDs the inverse of @p flags with existing
* instead of replacing them. Useful for removing default flags.
* @see @ref addFlags()
*/
Configuration& clearFlags(Flags flags) {
GL::Context::Configuration::clearFlags(GL::Context::Configuration::Flag(UnsignedLong(flags)));
return *this;
}
/**
* @brief Create a shared context
* @return Reference to self (for method chaining)
* @m_since{2020,06}
*
* When set, the created context will share a subset of OpenGL objects
* with @p context, instead of being independent. Many caveats and
* limitations apply to shared OpenGL contexts, please consult the
* OpenGL specification for details. Default is `EGL_NO_CONTEXT`, i.e.
* no sharing.
* @see @ref WindowlessWindowsEglContext::glContext(),
* @ref WindowlessWindowsEglApplication::glContext()
*/
Configuration& setSharedContext(EGLContext context) {
_sharedContext = context;
return *this;
}
/**
* @brief Shared context
* @m_since{2020,06}
*/
EGLContext sharedContext() const { return _sharedContext; }
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
MAGNUM_GL_CONTEXT_CONFIGURATION_SUBCLASS_IMPLEMENTATION(Configuration)
#endif
private:
EGLContext _sharedContext = EGL_NO_CONTEXT;
};
CORRADE_ENUMSET_OPERATORS(WindowlessWindowsEglContext::Configuration::Flags)
/**
@brief Windowless Windows/EGL application
@m_keywords{WindowlessApplication EGL}
Application for offscreen rendering using @ref WindowlessWindowsEglContext.
This application library is available on OpenGL ES (also ANGLE) on Windows.
@section Platform-WindowlessWindowsEglApplication-bootstrap Bootstrap application
Fully contained windowless application using @ref WindowlessWindowsEglApplication
along with CMake setup is available in `windowless` branch of
[Magnum Bootstrap](https://github.com/mosra/magnum-bootstrap) repository,
download it as [tar.gz](https://github.com/mosra/magnum-bootstrap/archive/windowless.tar.gz)
or [zip](https://github.com/mosra/magnum-bootstrap/archive/windowless.zip)
file. After extracting the downloaded archive you can build and run the
application with these four commands:
@code{.sh}
mkdir build && cd build
cmake ..
cmake --build .
./src/MyApplication # or ./src/Debug/MyApplication
@endcode
See @ref cmake for more information.
@section Platform-WindowlessWindowsEglApplication-usage General usage
This application library is built if `MAGNUM_WITH_WINDOWLESSWINDOWSEGLAPPLICATION`
is enabled when building Magnum. To use this library from CMake, put
[FindEGL.cmake](https://github.com/mosra/magnum/blob/master/modules/FindEGL.cmake)
into your `modules/` directory, request the `WindowlessWindowsEglApplication`
component of the `Magnum` package and link to the
`Magnum::WindowlessWindowsEglApplication` target:
@code{.cmake}
find_package(Magnum REQUIRED)
if(CORRADE_TARGET_WINDOWS)
find_package(Magnum REQUIRED WindowlessWindowsEglApplication)
endif()
# ...
if(CORRADE_TARGET_WINDOWS)
target_link_libraries(your-app PRIVATE Magnum::WindowlessWindowsEglApplication)
endif()
@endcode
Additionally, if you're using Magnum as a CMake subproject, do the following
* *before* calling @cmake find_package() @ce to ensure it's enabled, as the
library is not built by default:
@code{.cmake}
set(MAGNUM_WITH_WINDOWLESSWINDOWSEGLAPPLICATION ON CACHE BOOL "" FORCE)
add_subdirectory(magnum EXCLUDE_FROM_ALL)
@endcode
If no other application is requested, you can also use the generic
`Magnum::WindowlessApplication` alias to simplify porting. Again, see
@ref building and @ref cmake for more information.
Place your code into @ref exec(). The subclass can be then used in main
function using @ref MAGNUM_WINDOWLESSWINDOWSEGLAPPLICATION_MAIN() macro. See
@ref platform for more information.
@code{.cpp}
class MyApplication: public Platform::WindowlessWindowsEglApplication {
// implement required methods...
};
MAGNUM_WINDOWLESSWINDOWSEGLAPPLICATION_MAIN(MyApplication)
@endcode
If no other application header is included, this class is also aliased to
@cpp Platform::WindowlessApplication @ce and the macro is aliased to
@cpp MAGNUM_WINDOWLESSAPPLICATION_MAIN() @ce to simplify porting.
@note This class is available only if Magnum is compiled with
@ref MAGNUM_TARGET_GL enabled (done by default). See @ref building-features
for more information.
*/
class WindowlessWindowsEglApplication {
public:
/** @brief Application arguments */
struct Arguments {
/** @brief Constructor */
/*implicit*/ constexpr Arguments(int& argc, char** argv) noexcept: argc{argc}, argv{argv} {}
int& argc; /**< @brief Argument count */
char** argv; /**< @brief Argument values */
};
/**
* @brief Configuration
*
* @see @ref WindowlessWindowsEglApplication(), @ref createContext(),
* @ref tryCreateContext()
*/
typedef WindowlessWindowsEglContext::Configuration Configuration;
/**
* @brief Default constructor
* @param arguments Application arguments
* @param configuration Configuration
*
* Creates application with default or user-specified configuration.
* See @ref Configuration for more information. The program exits if
* the context cannot be created, see @ref tryCreateContext() for an
* alternative.
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
explicit WindowlessWindowsEglApplication(const Arguments& arguments, const Configuration& configuration = Configuration());
#else
/* To avoid "invalid use of incomplete type" */
explicit WindowlessWindowsEglApplication(const Arguments& arguments, const Configuration& configuration);
explicit WindowlessWindowsEglApplication(const Arguments& arguments);
#endif
/**
* @brief Constructor
* @param arguments Application arguments
*
* Unlike above, the context is not created and must be created later
* with @ref createContext() or @ref tryCreateContext().
*/
explicit WindowlessWindowsEglApplication(const Arguments& arguments, NoCreateT);
/** @brief Copying is not allowed */
WindowlessWindowsEglApplication(const WindowlessWindowsEglApplication&) = delete;
/** @brief Moving is not allowed */
WindowlessWindowsEglApplication(WindowlessWindowsEglApplication&&) = delete;
/** @brief Copying is not allowed */
WindowlessWindowsEglApplication& operator=(const WindowlessWindowsEglApplication&) = delete;
/** @brief Moving is not allowed */
WindowlessWindowsEglApplication& operator=(WindowlessWindowsEglApplication&&) = delete;
/**
* @brief Execute application
* @return Value for returning from @cpp main() @ce
*
* See @ref MAGNUM_WINDOWLESSWINDOWSEGLAPPLICATION_MAIN() for usage
* information.
*/
virtual int exec() = 0;
/**
* @brief Underlying OpenGL context
* @m_since{2020,06}
*
* Use in case you need to call EGL functionality directly or in order
* to create a shared context. Returns @cpp nullptr @ce in case the
* context was not created yet.
* @see @ref Configuration::setSharedContext()
*/
EGLContext glContext() { return _glContext.glContext(); }
protected:
/* Nobody will need to have (and delete) WindowlessWindowsEglApplication*,
thus this is faster than public pure virtual destructor */
~WindowlessWindowsEglApplication();
/**
* @brief Create context with given configuration
*
* Must be called if and only if the context wasn't created by the
* constructor itself. Error message is printed and the program exits
* if the context cannot be created, see @ref tryCreateContext() for an
* alternative.
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
void createContext(const Configuration& configuration = Configuration());
#else
/* To avoid "invalid use of incomplete type" */
void createContext(const Configuration& configuration);
void createContext();
#endif
/**
* @brief Try to create context with given configuration
*
* Unlike @ref createContext() returns @cpp false @ce if the context
* cannot be created, @cpp true @ce otherwise.
*/
bool tryCreateContext(const Configuration& configuration);
private:
WindowlessWindowsEglContext _glContext;
Platform::GLContext _context;
};
/** @hideinitializer
@brief Entry point for windowless Windows/EGL application
@param className Class name
@m_keywords{MAGNUM_WINDOWLESSAPPLICATION_MAIN()}
See @ref Magnum::Platform::WindowlessWindowsEglApplication "Platform::WindowlessWindowsEglApplication"
for usage information.This macro abstracts out platform-specific entry point
code and is equivalent to the following, see @ref portability-applications for
more information.
@code{.cpp}
int main(int argc, char** argv) {
className app({argc, argv});
return app.exec();
}
@endcode
When no other windowless application header is included this macro is also
aliased to @cpp MAGNUM_WINDOWLESSAPPLICATION_MAIN() @ce.
*/
#define MAGNUM_WINDOWLESSWINDOWSEGLAPPLICATION_MAIN(className) \
int main(int argc, char** argv) { \
className app({argc, argv}); \
return app.exec(); \
}
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_WINDOWLESSAPPLICATION_MAIN
typedef WindowlessWindowsEglApplication WindowlessApplication;
typedef WindowlessWindowsEglContext WindowlessGLContext;
#define MAGNUM_WINDOWLESSAPPLICATION_MAIN(className) MAGNUM_WINDOWLESSWINDOWSEGLAPPLICATION_MAIN(className)
#else
#undef MAGNUM_WINDOWLESSAPPLICATION_MAIN
#endif
#endif
}}
#else
#error this header is available only in the OpenGL build
#endif
#endif

4
src/Magnum/Platform/gl-info.cpp

@ -72,7 +72,7 @@
#endif
#elif defined(CORRADE_TARGET_WINDOWS)
#if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_DESKTOP_GLES)
#include "Magnum/Platform/WindowlessWindowsEglApplication.h"
#include "Magnum/Platform/WindowlessEglApplication.h"
#else
#include "Magnum/Platform/WindowlessWglApplication.h"
#endif
@ -241,8 +241,6 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat
Debug{} << "Used application: Platform::WindowlessGlxApplication";
#elif defined(MAGNUM_WINDOWLESSWGLAPPLICATION_MAIN)
Debug{} << "Used application: Platform::WindowlessWglApplication";
#elif defined(MAGNUM_WINDOWLESSWINDOWSEGLAPPLICATION_MAIN)
Debug{} << "Used application: Platform::WindowlessWindowsEglApplication";
#else
#error no windowless application available on this platform
#endif

2
src/Magnum/Text/CMakeLists.txt

@ -131,7 +131,7 @@ if(MAGNUM_WITH_FONTCONVERTER)
endif()
elseif(CORRADE_TARGET_WINDOWS)
if(MAGNUM_TARGET_GLES AND NOT MAGNUM_TARGET_DESKTOP_GLES)
target_link_libraries(magnum-fontconverter PRIVATE MagnumWindowlessWindowsEglApplication)
target_link_libraries(magnum-fontconverter PRIVATE MagnumWindowlessEglApplication)
else()
target_link_libraries(magnum-fontconverter PRIVATE MagnumWindowlessWglApplication)
endif()

2
src/Magnum/Text/fontconverter.cpp

@ -48,7 +48,7 @@
#endif
#elif defined(CORRADE_TARGET_WINDOWS)
#if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_DESKTOP_GLES)
#include "Magnum/Platform/WindowlessWindowsEglApplication.h"
#include "Magnum/Platform/WindowlessEglApplication.h"
#else
#include "Magnum/Platform/WindowlessWglApplication.h"
#endif

2
src/Magnum/TextureTools/CMakeLists.txt

@ -99,7 +99,7 @@ if(MAGNUM_WITH_DISTANCEFIELDCONVERTER)
endif()
elseif(CORRADE_TARGET_WINDOWS)
if(MAGNUM_TARGET_GLES AND NOT MAGNUM_TARGET_DESKTOP_GLES)
target_link_libraries(magnum-distancefieldconverter PRIVATE MagnumWindowlessWindowsEglApplication)
target_link_libraries(magnum-distancefieldconverter PRIVATE MagnumWindowlessEglApplication)
else()
target_link_libraries(magnum-distancefieldconverter PRIVATE MagnumWindowlessWglApplication)
endif()

2
src/Magnum/TextureTools/distancefieldconverter.cpp

@ -56,7 +56,7 @@
#endif
#elif defined(CORRADE_TARGET_WINDOWS)
#if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_DESKTOP_GLES)
#include "Magnum/Platform/WindowlessWindowsEglApplication.h"
#include "Magnum/Platform/WindowlessEglApplication.h"
#else
#include "Magnum/Platform/WindowlessWglApplication.h"
#endif

Loading…
Cancel
Save