Merge pull request #15805 from SamGondelman/shared

BUGZ-777: Clean up SharedObject code
This commit is contained in:
Shannon Romano 2019-06-20 14:35:58 -07:00 committed by GitHub
commit 7645fcfaa1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 85 additions and 79 deletions

View file

@ -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_TOOLS "Build tools" ${BUILD_TOOLS_OPTION})
option(BUILD_INSTALLER "Build installer" ${BUILD_INSTALLER_OPTION}) option(BUILD_INSTALLER "Build installer" ${BUILD_INSTALLER_OPTION})
option(USE_GLES "Use OpenGL ES" ${GLES_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_QML "Disable QML" ${DISABLE_QML_OPTION})
option(DISABLE_KTX_CACHE "Disable KTX Cache" OFF) option(DISABLE_KTX_CACHE "Disable KTX Cache" OFF)
option( option(
@ -149,6 +150,10 @@ option(
set(PLATFORM_QT_GL OpenGL) set(PLATFORM_QT_GL OpenGL)
if (USE_KHR_ROBUSTNESS)
add_definitions(-DUSE_KHR_ROBUSTNESS)
endif()
if (USE_GLES) if (USE_GLES)
add_definitions(-DUSE_GLES) add_definitions(-DUSE_GLES)
add_definitions(-DGPU_POINTER_STORAGE_SHARED) add_definitions(-DGPU_POINTER_STORAGE_SHARED)

View file

@ -27,6 +27,10 @@
#include "GLHelpers.h" #include "GLHelpers.h"
#include "QOpenGLContextWrapper.h" #include "QOpenGLContextWrapper.h"
#if defined(GL_CUSTOM_CONTEXT)
#include <QtPlatformHeaders/QWGLNativeContext>
#endif
using namespace gl; using namespace gl;
#if defined(GL_CUSTOM_CONTEXT) #if defined(GL_CUSTOM_CONTEXT)
@ -42,7 +46,10 @@ std::atomic<size_t> Context::_totalSwapchainMemoryUsage { 0 };
size_t Context::getSwapchainMemoryUsage() { return _totalSwapchainMemoryUsage.load(); } size_t Context::getSwapchainMemoryUsage() { return _totalSwapchainMemoryUsage.load(); }
size_t Context::evalSurfaceMemoryUsage(uint32_t width, uint32_t height, uint32_t pixelSize) { 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) { void Context::updateSwapchainMemoryUsage(size_t prevSize, size_t newSize) {
@ -126,7 +133,7 @@ void Context::clear() {
#if defined(GL_CUSTOM_CONTEXT) #if defined(GL_CUSTOM_CONTEXT)
static void setupPixelFormatSimple(HDC hdc) { 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 static const PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be
{ {
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
@ -176,6 +183,7 @@ static void setupPixelFormatSimple(HDC hdc) {
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
// Context create flag bits // Context create flag bits
#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001 #define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 #define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
@ -196,17 +204,17 @@ GLAPI PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context(); Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context();
#if defined(GL_CUSTOM_CONTEXT) #if defined(GL_CUSTOM_CONTEXT)
bool Context::makeCurrent() { bool Context::makeCurrent() {
BOOL result = wglMakeCurrent(_hdc, _hglrc); BOOL result = wglMakeCurrent(_hdc, _hglrc);
assert(result); assert(result);
updateSwapchainMemoryCounter(); updateSwapchainMemoryCounter();
return result; return result;
} }
void Context::swapBuffers() { void Context::swapBuffers() {
SwapBuffers(_hdc); SwapBuffers(_hdc);
} }
void Context::doneCurrent() { void Context::doneCurrent() {
wglMakeCurrent(0, 0); wglMakeCurrent(0, 0);
} }
#endif #endif
@ -305,11 +313,18 @@ void Context::create(QOpenGLContext* shareContext) {
#else #else
contextAttribs.push_back(WGL_CONTEXT_CORE_PROFILE_BIT_ARB); contextAttribs.push_back(WGL_CONTEXT_CORE_PROFILE_BIT_ARB);
#endif #endif
contextAttribs.push_back(WGL_CONTEXT_FLAGS_ARB); {
if (enableDebugLogger()) { int contextFlags = 0;
contextAttribs.push_back(WGL_CONTEXT_DEBUG_BIT_ARB); if (enableDebugLogger()) {
} else { contextFlags |= WGL_CONTEXT_DEBUG_BIT_ARB;
contextAttribs.push_back(0); }
#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); contextAttribs.push_back(0);
HGLRC shareHglrc = nullptr; HGLRC shareHglrc = nullptr;
@ -323,8 +338,8 @@ void Context::create(QOpenGLContext* shareContext) {
if (_hglrc != 0) { if (_hglrc != 0) {
createWrapperContext(); createWrapperContext();
} }
} }
if (_hglrc == 0) { if (_hglrc == 0) {
// fallback, if the context creation failed, or USE_CUSTOM_CONTEXT is false // fallback, if the context creation failed, or USE_CUSTOM_CONTEXT is false
qtCreate(shareContext); qtCreate(shareContext);

View file

@ -23,7 +23,7 @@ class QOpenGLContext;
class QThread; class QThread;
class QOpenGLDebugMessage; 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) //#if defined(Q_OS_WIN)
#define GL_CUSTOM_CONTEXT #define GL_CUSTOM_CONTEXT
#endif #endif

View file

@ -49,8 +49,8 @@ bool RenderEventHandler::event(QEvent* e) {
return QObject::event(e); return QObject::event(e);
} }
RenderEventHandler::RenderEventHandler(SharedObject* shared, QThread* targetThread) RenderEventHandler::RenderEventHandler(SharedObject* shared, QThread* targetThread) :
: _shared(shared) { _shared(shared) {
// Create the GL canvas in the same thread as the share canvas // Create the GL canvas in the same thread as the share canvas
if (!_canvas.create(SharedObject::getSharedContext())) { if (!_canvas.create(SharedObject::getSharedContext())) {
qFatal("Unable to create new offscreen GL context"); qFatal("Unable to create new offscreen GL context");
@ -136,7 +136,8 @@ void RenderEventHandler::qmlRender(bool sceneGraphSync) {
resize(); resize();
{
if (_currentSize != QSize()) {
PROFILE_RANGE(render_qml_gl, "render"); PROFILE_RANGE(render_qml_gl, "render");
GLuint texture = SharedObject::getTextureCache().acquireTexture(_currentSize); GLuint texture = SharedObject::getTextureCache().acquireTexture(_currentSize);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo);
@ -146,7 +147,7 @@ void RenderEventHandler::qmlRender(bool sceneGraphSync) {
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
} else { } else {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_shared->_quickWindow->setRenderTarget(_fbo, _currentSize); _shared->setRenderTarget(_fbo, _currentSize);
_shared->_renderControl->render(); _shared->_renderControl->render();
} }
_shared->_lastRenderTime = usecTimestampNow(); _shared->_lastRenderTime = usecTimestampNow();
@ -179,7 +180,7 @@ void RenderEventHandler::onQuit() {
_fbo = 0; _fbo = 0;
} }
_shared->shutdownRendering(_canvas, _currentSize); _shared->shutdownRendering(_currentSize);
_canvas.doneCurrent(); _canvas.doneCurrent();
} }
_canvas.moveToThreadWithContext(qApp->thread()); _canvas.moveToThreadWithContext(qApp->thread());

View file

@ -78,7 +78,6 @@ SharedObject::SharedObject() {
QObject::connect(qApp, &QCoreApplication::aboutToQuit, this, &SharedObject::onAboutToQuit); QObject::connect(qApp, &QCoreApplication::aboutToQuit, this, &SharedObject::onAboutToQuit);
} }
SharedObject::~SharedObject() { SharedObject::~SharedObject() {
// After destroy returns, the rendering thread should be gone // After destroy returns, the rendering thread should be gone
destroy(); destroy();
@ -173,7 +172,6 @@ void SharedObject::setRootItem(QQuickItem* rootItem) {
QObject::connect(_renderControl, &QQuickRenderControl::renderRequested, this, &SharedObject::requestRender); QObject::connect(_renderControl, &QQuickRenderControl::renderRequested, this, &SharedObject::requestRender);
QObject::connect(_renderControl, &QQuickRenderControl::sceneChanged, this, &SharedObject::requestRenderSync); QObject::connect(_renderControl, &QQuickRenderControl::sceneChanged, this, &SharedObject::requestRenderSync);
#endif #endif
} }
void SharedObject::destroy() { void SharedObject::destroy() {
@ -210,7 +208,7 @@ void SharedObject::destroy() {
} }
// Block until the rendering thread has stopped // Block until the rendering thread has stopped
// FIXME this is undesirable because this is blocking the main thread, // 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 // shutdown
if (_renderThread) { if (_renderThread) {
_renderThread->wait(); _renderThread->wait();
@ -220,10 +218,8 @@ void SharedObject::destroy() {
#endif #endif
} }
#define SINGLE_QML_ENGINE 0 #define SINGLE_QML_ENGINE 0
#if SINGLE_QML_ENGINE #if SINGLE_QML_ENGINE
static QQmlEngine* globalEngine{ nullptr }; static QQmlEngine* globalEngine{ nullptr };
static size_t globalEngineRefCount{ 0 }; static size_t globalEngineRefCount{ 0 };
@ -344,6 +340,11 @@ void SharedObject::setSize(const QSize& size) {
#endif #endif
} }
void SharedObject::setMaxFps(uint8_t maxFps) {
QMutexLocker locker(&_mutex);
_maxFps = maxFps;
}
bool SharedObject::preRender(bool sceneGraphSync) { bool SharedObject::preRender(bool sceneGraphSync) {
#ifndef DISABLE_QML #ifndef DISABLE_QML
QMutexLocker lock(&_mutex); QMutexLocker lock(&_mutex);
@ -370,9 +371,9 @@ bool SharedObject::preRender(bool sceneGraphSync) {
return true; return true;
} }
void SharedObject::shutdownRendering(OffscreenGLCanvas& canvas, const QSize& size) { void SharedObject::shutdownRendering(const QSize& size) {
QMutexLocker locker(&_mutex); QMutexLocker locker(&_mutex);
if (size != QSize(0, 0)) { if (size != QSize()) {
getTextureCache().releaseSize(size); getTextureCache().releaseSize(size);
if (_latestTextureAndFence.first) { if (_latestTextureAndFence.first) {
getTextureCache().releaseTexture(_latestTextureAndFence); getTextureCache().releaseTexture(_latestTextureAndFence);
@ -380,19 +381,17 @@ void SharedObject::shutdownRendering(OffscreenGLCanvas& canvas, const QSize& siz
} }
#ifndef DISABLE_QML #ifndef DISABLE_QML
_renderControl->invalidate(); _renderControl->invalidate();
canvas.doneCurrent();
#endif #endif
wake(); wake();
} }
bool SharedObject::isQuit() { bool SharedObject::isQuit() const {
QMutexLocker locker(&_mutex); QMutexLocker locker(&_mutex);
return _quit; return _quit;
} }
void SharedObject::requestRender() { void SharedObject::requestRender() {
// Don't queue multiple renders if (_quit) {
if (_renderRequested) {
return; return;
} }
_renderRequested = true; _renderRequested = true;
@ -402,18 +401,13 @@ void SharedObject::requestRenderSync() {
if (_quit) { if (_quit) {
return; return;
} }
_renderRequested = true;
{ _syncRequested = true;
QMutexLocker lock(&_mutex);
_syncRequested = true;
}
requestRender();
} }
bool SharedObject::fetchTexture(TextureAndFence& textureAndFence) { bool SharedObject::fetchTexture(TextureAndFence& textureAndFence) {
QMutexLocker locker(&_mutex); QMutexLocker locker(&_mutex);
if (0 == _latestTextureAndFence.first) { if (!_latestTextureAndFence.first) {
return false; return false;
} }
textureAndFence = { 0, 0 }; textureAndFence = { 0, 0 };
@ -421,8 +415,7 @@ bool SharedObject::fetchTexture(TextureAndFence& textureAndFence) {
return true; return true;
} }
void hifi::qml::impl::SharedObject::addToDeletionList(QObject * object) void SharedObject::addToDeletionList(QObject* object) {
{
_deletionList.append(QPointer<QObject>(object)); _deletionList.append(QPointer<QObject>(object));
} }
@ -469,11 +462,9 @@ void SharedObject::onRender() {
return; return;
} }
QMutexLocker lock(&_mutex);
if (_syncRequested) { if (_syncRequested) {
lock.unlock();
_renderControl->polishItems(); _renderControl->polishItems();
lock.relock(); QMutexLocker lock(&_mutex);
QCoreApplication::postEvent(_renderObject, new OffscreenEvent(OffscreenEvent::RenderSync)); QCoreApplication::postEvent(_renderObject, new OffscreenEvent(OffscreenEvent::RenderSync));
// sync and render request, main and render threads must be synchronized // sync and render request, main and render threads must be synchronized
wait(); wait();
@ -494,13 +485,11 @@ void SharedObject::onTimer() {
{ {
QMutexLocker locker(&_mutex); QMutexLocker locker(&_mutex);
// Don't queue more than one frame at a time // Don't queue more than one frame at a time
if (0 != _latestTextureAndFence.first) { if (_latestTextureAndFence.first) {
return; return;
} }
}
{ if (!_maxFps) {
if (_maxFps == 0) {
return; return;
} }
auto minRenderInterval = USECS_PER_SECOND / _maxFps; auto minRenderInterval = USECS_PER_SECOND / _maxFps;

View file

@ -16,7 +16,6 @@
#include "TextureCache.h" #include "TextureCache.h"
class QWindow; class QWindow;
class QTimer; class QTimer;
class QQuickWindow; class QQuickWindow;
@ -24,7 +23,6 @@ class QQuickItem;
class QOpenGLContext; class QOpenGLContext;
class QQmlEngine; class QQmlEngine;
class QQmlContext; class QQmlContext;
class OffscreenGLCanvas;
namespace hifi { namespace qml { namespace hifi { namespace qml {
@ -51,11 +49,11 @@ public:
void create(OffscreenSurface* surface); void create(OffscreenSurface* surface);
void setRootItem(QQuickItem* rootItem); void setRootItem(QQuickItem* rootItem);
void destroy(); void destroy();
bool isQuit(); bool isQuit() const;
QSize getSize() const; QSize getSize() const;
void setSize(const QSize& size); void setSize(const QSize& size);
void setMaxFps(uint8_t maxFps) { _maxFps = maxFps; } void setMaxFps(uint8_t maxFps);
QQuickWindow* getWindow() { return _quickWindow; } QQuickWindow* getWindow() { return _quickWindow; }
QQuickItem* getRootItem() { return _rootItem; } QQuickItem* getRootItem() { return _rootItem; }
@ -72,7 +70,7 @@ private:
bool event(QEvent* e) override; bool event(QEvent* e) override;
bool preRender(bool sceneGraphSync); 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 // Called by the render event handler, from the render thread
void initializeRenderControl(QOpenGLContext* context); void initializeRenderControl(QOpenGLContext* context);
void releaseTextureAndFence(); void releaseTextureAndFence();
@ -94,31 +92,30 @@ private:
QList<QPointer<QObject>> _deletionList; QList<QPointer<QObject>> _deletionList;
// Texture management // Texture management
TextureAndFence _latestTextureAndFence{ 0, 0 }; TextureAndFence _latestTextureAndFence { 0, 0 };
QQuickItem* _item{ nullptr }; QQuickItem* _rootItem { nullptr };
QQuickItem* _rootItem{ nullptr }; QQuickWindow* _quickWindow { nullptr };
QQuickWindow* _quickWindow{ nullptr }; QQmlContext* _qmlContext { nullptr };
QQmlContext* _qmlContext{ nullptr };
mutable QMutex _mutex; mutable QMutex _mutex;
QWaitCondition _cond; QWaitCondition _cond;
#ifndef DISABLE_QML #ifndef DISABLE_QML
QWindow* _proxyWindow{ nullptr }; QWindow* _proxyWindow { nullptr };
RenderControl* _renderControl{ nullptr }; RenderControl* _renderControl { nullptr };
RenderEventHandler* _renderObject{ nullptr }; RenderEventHandler* _renderObject { nullptr };
QTimer* _renderTimer{ nullptr }; QTimer* _renderTimer { nullptr };
QThread* _renderThread{ nullptr }; QThread* _renderThread { nullptr };
#endif #endif
uint64_t _lastRenderTime{ 0 }; uint64_t _lastRenderTime { 0 };
QSize _size{ 100, 100 }; QSize _size { 100, 100 };
uint8_t _maxFps{ 60 }; uint8_t _maxFps { 60 };
bool _renderRequested{ false }; bool _renderRequested { false };
bool _syncRequested{ false }; bool _syncRequested { false };
bool _quit{ false }; bool _quit { false };
bool _paused{ false }; bool _paused { false };
}; };
} // namespace impl } // namespace impl

View file

@ -35,9 +35,8 @@ public:
using Size = uint64_t; using Size = uint64_t;
struct TextureSet { struct TextureSet {
Size textureSize;
// The number of surfaces with this size // The number of surfaces with this size
size_t clientCount{ 0 }; size_t clientCount { 0 };
ValueList returnedTextures; ValueList returnedTextures;
}; };
@ -66,7 +65,7 @@ private:
std::unordered_map<uint32_t, QSize> _textureSizes; std::unordered_map<uint32_t, QSize> _textureSizes;
Mutex _mutex; Mutex _mutex;
std::list<Value> _returnedTextures; std::list<Value> _returnedTextures;
size_t _totalTextureUsage{ 0 }; size_t _totalTextureUsage { 0 };
}; };
}}} // namespace hifi::qml::impl }}} // namespace hifi::qml::impl