From 6b34b0971f4f63cde025309237611b587f9b1472 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 14 Jun 2019 11:09:28 -0700 Subject: [PATCH 1/2] Enable KHR_robustness option --- CMakeLists.txt | 5 +++ libraries/gl/src/gl/Context.cpp | 55 +++++++++++++++++++++------------ libraries/gl/src/gl/Context.h | 2 +- 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f6cffb7c1..9876a0d7ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -139,6 +139,7 @@ option(BUILD_MANUAL_TESTS "Build manual tests" ${BUILD_MANUAL_TESTS_OPTION}) option(BUILD_TOOLS "Build tools" ${BUILD_TOOLS_OPTION}) option(BUILD_INSTALLER "Build installer" ${BUILD_INSTALLER_OPTION}) option(USE_GLES "Use OpenGL ES" ${GLES_OPTION}) +option(USE_KHR_ROBUSTNESS "Use KHR_robustness" OFF) option(DISABLE_QML "Disable QML" ${DISABLE_QML_OPTION}) option(DISABLE_KTX_CACHE "Disable KTX Cache" OFF) option( @@ -149,6 +150,10 @@ option( set(PLATFORM_QT_GL OpenGL) +if (USE_KHR_ROBUSTNESS) + add_definitions(-DUSE_KHR_ROBUSTNESS) +endif() + if (USE_GLES) add_definitions(-DUSE_GLES) add_definitions(-DGPU_POINTER_STORAGE_SHARED) diff --git a/libraries/gl/src/gl/Context.cpp b/libraries/gl/src/gl/Context.cpp index a0d52ee223..d5d06d1195 100644 --- a/libraries/gl/src/gl/Context.cpp +++ b/libraries/gl/src/gl/Context.cpp @@ -27,6 +27,10 @@ #include "GLHelpers.h" #include "QOpenGLContextWrapper.h" +#if defined(GL_CUSTOM_CONTEXT) +#include +#endif + using namespace gl; #if defined(GL_CUSTOM_CONTEXT) @@ -42,7 +46,10 @@ std::atomic Context::_totalSwapchainMemoryUsage { 0 }; size_t Context::getSwapchainMemoryUsage() { return _totalSwapchainMemoryUsage.load(); } size_t Context::evalSurfaceMemoryUsage(uint32_t width, uint32_t height, uint32_t pixelSize) { - return width * height * pixelSize; + size_t result = width; + result *= height; + result *= pixelSize; + return result; } void Context::updateSwapchainMemoryUsage(size_t prevSize, size_t newSize) { @@ -126,7 +133,7 @@ void Context::clear() { #if defined(GL_CUSTOM_CONTEXT) static void setupPixelFormatSimple(HDC hdc) { - // FIXME build the PFD based on the + // FIXME build the PFD based on the static const PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be { sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor @@ -176,6 +183,7 @@ static void setupPixelFormatSimple(HDC hdc) { #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 // Context create flag bits +#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 #define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001 #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 #define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 @@ -196,17 +204,17 @@ GLAPI PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB; Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context(); #if defined(GL_CUSTOM_CONTEXT) -bool Context::makeCurrent() { - BOOL result = wglMakeCurrent(_hdc, _hglrc); - assert(result); - updateSwapchainMemoryCounter(); - return result; -} - void Context::swapBuffers() { - SwapBuffers(_hdc); -} - void Context::doneCurrent() { - wglMakeCurrent(0, 0); +bool Context::makeCurrent() { + BOOL result = wglMakeCurrent(_hdc, _hglrc); + assert(result); + updateSwapchainMemoryCounter(); + return result; +} +void Context::swapBuffers() { + SwapBuffers(_hdc); +} +void Context::doneCurrent() { + wglMakeCurrent(0, 0); } #endif @@ -305,11 +313,18 @@ void Context::create(QOpenGLContext* shareContext) { #else contextAttribs.push_back(WGL_CONTEXT_CORE_PROFILE_BIT_ARB); #endif - contextAttribs.push_back(WGL_CONTEXT_FLAGS_ARB); - if (enableDebugLogger()) { - contextAttribs.push_back(WGL_CONTEXT_DEBUG_BIT_ARB); - } else { - contextAttribs.push_back(0); + { + int contextFlags = 0; + if (enableDebugLogger()) { + contextFlags |= WGL_CONTEXT_DEBUG_BIT_ARB; + } +#ifdef USE_KHR_ROBUSTNESS + contextFlags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB; +#endif + if (contextFlags != 0) { + contextAttribs.push_back(WGL_CONTEXT_FLAGS_ARB); + contextAttribs.push_back(contextFlags); + } } contextAttribs.push_back(0); HGLRC shareHglrc = nullptr; @@ -323,8 +338,8 @@ void Context::create(QOpenGLContext* shareContext) { if (_hglrc != 0) { createWrapperContext(); } - } - + } + if (_hglrc == 0) { // fallback, if the context creation failed, or USE_CUSTOM_CONTEXT is false qtCreate(shareContext); diff --git a/libraries/gl/src/gl/Context.h b/libraries/gl/src/gl/Context.h index 5254d58d38..7beb59e33f 100644 --- a/libraries/gl/src/gl/Context.h +++ b/libraries/gl/src/gl/Context.h @@ -23,7 +23,7 @@ class QOpenGLContext; class QThread; class QOpenGLDebugMessage; -#if defined(Q_OS_WIN) && defined(USE_GLES) +#if defined(Q_OS_WIN) && (defined(USE_GLES) || defined(USE_KHR_ROBUSTNESS)) //#if defined(Q_OS_WIN) #define GL_CUSTOM_CONTEXT #endif From 50df5e0bc52634287bc954b2656247df6f21b7d4 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 19 Jun 2019 16:56:45 -0700 Subject: [PATCH 2/2] small cleanup to shared object etc. --- .../qml/src/qml/impl/RenderEventHandler.cpp | 11 ++--- libraries/qml/src/qml/impl/SharedObject.cpp | 45 +++++++------------ libraries/qml/src/qml/impl/SharedObject.h | 41 ++++++++--------- libraries/qml/src/qml/impl/TextureCache.h | 5 +-- 4 files changed, 44 insertions(+), 58 deletions(-) diff --git a/libraries/qml/src/qml/impl/RenderEventHandler.cpp b/libraries/qml/src/qml/impl/RenderEventHandler.cpp index a1edfd6789..cc9fe34edc 100644 --- a/libraries/qml/src/qml/impl/RenderEventHandler.cpp +++ b/libraries/qml/src/qml/impl/RenderEventHandler.cpp @@ -49,8 +49,8 @@ bool RenderEventHandler::event(QEvent* e) { return QObject::event(e); } -RenderEventHandler::RenderEventHandler(SharedObject* shared, QThread* targetThread) - : _shared(shared) { +RenderEventHandler::RenderEventHandler(SharedObject* shared, QThread* targetThread) : + _shared(shared) { // Create the GL canvas in the same thread as the share canvas if (!_canvas.create(SharedObject::getSharedContext())) { qFatal("Unable to create new offscreen GL context"); @@ -136,7 +136,8 @@ void RenderEventHandler::qmlRender(bool sceneGraphSync) { resize(); - { + + if (_currentSize != QSize()) { PROFILE_RANGE(render_qml_gl, "render"); GLuint texture = SharedObject::getTextureCache().acquireTexture(_currentSize); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo); @@ -146,7 +147,7 @@ void RenderEventHandler::qmlRender(bool sceneGraphSync) { glClear(GL_COLOR_BUFFER_BIT); } else { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - _shared->_quickWindow->setRenderTarget(_fbo, _currentSize); + _shared->setRenderTarget(_fbo, _currentSize); _shared->_renderControl->render(); } _shared->_lastRenderTime = usecTimestampNow(); @@ -179,7 +180,7 @@ void RenderEventHandler::onQuit() { _fbo = 0; } - _shared->shutdownRendering(_canvas, _currentSize); + _shared->shutdownRendering(_currentSize); _canvas.doneCurrent(); } _canvas.moveToThreadWithContext(qApp->thread()); diff --git a/libraries/qml/src/qml/impl/SharedObject.cpp b/libraries/qml/src/qml/impl/SharedObject.cpp index b72f37481b..55788c8a02 100644 --- a/libraries/qml/src/qml/impl/SharedObject.cpp +++ b/libraries/qml/src/qml/impl/SharedObject.cpp @@ -78,7 +78,6 @@ SharedObject::SharedObject() { QObject::connect(qApp, &QCoreApplication::aboutToQuit, this, &SharedObject::onAboutToQuit); } - SharedObject::~SharedObject() { // After destroy returns, the rendering thread should be gone destroy(); @@ -173,7 +172,6 @@ void SharedObject::setRootItem(QQuickItem* rootItem) { QObject::connect(_renderControl, &QQuickRenderControl::renderRequested, this, &SharedObject::requestRender); QObject::connect(_renderControl, &QQuickRenderControl::sceneChanged, this, &SharedObject::requestRenderSync); #endif - } void SharedObject::destroy() { @@ -210,7 +208,7 @@ void SharedObject::destroy() { } // Block until the rendering thread has stopped // FIXME this is undesirable because this is blocking the main thread, - // but I haven't found a reliable way to do this only at application + // but I haven't found a reliable way to do this only at application // shutdown if (_renderThread) { _renderThread->wait(); @@ -220,10 +218,8 @@ void SharedObject::destroy() { #endif } - #define SINGLE_QML_ENGINE 0 - #if SINGLE_QML_ENGINE static QQmlEngine* globalEngine{ nullptr }; static size_t globalEngineRefCount{ 0 }; @@ -344,6 +340,11 @@ void SharedObject::setSize(const QSize& size) { #endif } +void SharedObject::setMaxFps(uint8_t maxFps) { + QMutexLocker locker(&_mutex); + _maxFps = maxFps; +} + bool SharedObject::preRender(bool sceneGraphSync) { #ifndef DISABLE_QML QMutexLocker lock(&_mutex); @@ -370,9 +371,9 @@ bool SharedObject::preRender(bool sceneGraphSync) { return true; } -void SharedObject::shutdownRendering(OffscreenGLCanvas& canvas, const QSize& size) { +void SharedObject::shutdownRendering(const QSize& size) { QMutexLocker locker(&_mutex); - if (size != QSize(0, 0)) { + if (size != QSize()) { getTextureCache().releaseSize(size); if (_latestTextureAndFence.first) { getTextureCache().releaseTexture(_latestTextureAndFence); @@ -380,19 +381,17 @@ void SharedObject::shutdownRendering(OffscreenGLCanvas& canvas, const QSize& siz } #ifndef DISABLE_QML _renderControl->invalidate(); - canvas.doneCurrent(); #endif wake(); } -bool SharedObject::isQuit() { +bool SharedObject::isQuit() const { QMutexLocker locker(&_mutex); return _quit; } void SharedObject::requestRender() { - // Don't queue multiple renders - if (_renderRequested) { + if (_quit) { return; } _renderRequested = true; @@ -402,18 +401,13 @@ void SharedObject::requestRenderSync() { if (_quit) { return; } - - { - QMutexLocker lock(&_mutex); - _syncRequested = true; - } - - requestRender(); + _renderRequested = true; + _syncRequested = true; } bool SharedObject::fetchTexture(TextureAndFence& textureAndFence) { QMutexLocker locker(&_mutex); - if (0 == _latestTextureAndFence.first) { + if (!_latestTextureAndFence.first) { return false; } textureAndFence = { 0, 0 }; @@ -421,8 +415,7 @@ bool SharedObject::fetchTexture(TextureAndFence& textureAndFence) { return true; } -void hifi::qml::impl::SharedObject::addToDeletionList(QObject * object) -{ +void SharedObject::addToDeletionList(QObject* object) { _deletionList.append(QPointer(object)); } @@ -469,11 +462,9 @@ void SharedObject::onRender() { return; } - QMutexLocker lock(&_mutex); if (_syncRequested) { - lock.unlock(); _renderControl->polishItems(); - lock.relock(); + QMutexLocker lock(&_mutex); QCoreApplication::postEvent(_renderObject, new OffscreenEvent(OffscreenEvent::RenderSync)); // sync and render request, main and render threads must be synchronized wait(); @@ -494,13 +485,11 @@ void SharedObject::onTimer() { { QMutexLocker locker(&_mutex); // Don't queue more than one frame at a time - if (0 != _latestTextureAndFence.first) { + if (_latestTextureAndFence.first) { return; } - } - { - if (_maxFps == 0) { + if (!_maxFps) { return; } auto minRenderInterval = USECS_PER_SECOND / _maxFps; diff --git a/libraries/qml/src/qml/impl/SharedObject.h b/libraries/qml/src/qml/impl/SharedObject.h index c9c0ef7bd0..50c56ad714 100644 --- a/libraries/qml/src/qml/impl/SharedObject.h +++ b/libraries/qml/src/qml/impl/SharedObject.h @@ -16,7 +16,6 @@ #include "TextureCache.h" - class QWindow; class QTimer; class QQuickWindow; @@ -24,7 +23,6 @@ class QQuickItem; class QOpenGLContext; class QQmlEngine; class QQmlContext; -class OffscreenGLCanvas; namespace hifi { namespace qml { @@ -51,11 +49,11 @@ public: void create(OffscreenSurface* surface); void setRootItem(QQuickItem* rootItem); void destroy(); - bool isQuit(); + bool isQuit() const; QSize getSize() const; void setSize(const QSize& size); - void setMaxFps(uint8_t maxFps) { _maxFps = maxFps; } + void setMaxFps(uint8_t maxFps); QQuickWindow* getWindow() { return _quickWindow; } QQuickItem* getRootItem() { return _rootItem; } @@ -72,7 +70,7 @@ private: bool event(QEvent* e) override; bool preRender(bool sceneGraphSync); - void shutdownRendering(OffscreenGLCanvas& canvas, const QSize& size); + void shutdownRendering(const QSize& size); // Called by the render event handler, from the render thread void initializeRenderControl(QOpenGLContext* context); void releaseTextureAndFence(); @@ -94,31 +92,30 @@ private: QList> _deletionList; // Texture management - TextureAndFence _latestTextureAndFence{ 0, 0 }; - QQuickItem* _item{ nullptr }; - QQuickItem* _rootItem{ nullptr }; - QQuickWindow* _quickWindow{ nullptr }; - QQmlContext* _qmlContext{ nullptr }; + TextureAndFence _latestTextureAndFence { 0, 0 }; + QQuickItem* _rootItem { nullptr }; + QQuickWindow* _quickWindow { nullptr }; + QQmlContext* _qmlContext { nullptr }; mutable QMutex _mutex; QWaitCondition _cond; #ifndef DISABLE_QML - QWindow* _proxyWindow{ nullptr }; - RenderControl* _renderControl{ nullptr }; - RenderEventHandler* _renderObject{ nullptr }; + QWindow* _proxyWindow { nullptr }; + RenderControl* _renderControl { nullptr }; + RenderEventHandler* _renderObject { nullptr }; - QTimer* _renderTimer{ nullptr }; - QThread* _renderThread{ nullptr }; + QTimer* _renderTimer { nullptr }; + QThread* _renderThread { nullptr }; #endif - uint64_t _lastRenderTime{ 0 }; - QSize _size{ 100, 100 }; - uint8_t _maxFps{ 60 }; + uint64_t _lastRenderTime { 0 }; + QSize _size { 100, 100 }; + uint8_t _maxFps { 60 }; - bool _renderRequested{ false }; - bool _syncRequested{ false }; - bool _quit{ false }; - bool _paused{ false }; + bool _renderRequested { false }; + bool _syncRequested { false }; + bool _quit { false }; + bool _paused { false }; }; } // namespace impl diff --git a/libraries/qml/src/qml/impl/TextureCache.h b/libraries/qml/src/qml/impl/TextureCache.h index c146d0bdbf..29f88955a4 100644 --- a/libraries/qml/src/qml/impl/TextureCache.h +++ b/libraries/qml/src/qml/impl/TextureCache.h @@ -35,9 +35,8 @@ public: using Size = uint64_t; struct TextureSet { - Size textureSize; // The number of surfaces with this size - size_t clientCount{ 0 }; + size_t clientCount { 0 }; ValueList returnedTextures; }; @@ -66,7 +65,7 @@ private: std::unordered_map _textureSizes; Mutex _mutex; std::list _returnedTextures; - size_t _totalTextureUsage{ 0 }; + size_t _totalTextureUsage { 0 }; }; }}} // namespace hifi::qml::impl