diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ad869ddae3..b0502a88fc 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -89,6 +89,7 @@ #include #include #include +#include #include #include #include @@ -512,6 +513,7 @@ bool setupEssentials(int& argc, char** argv) { DependencyManager::set(); DependencyManager::set(true, qApp, qApp); DependencyManager::set(); + DependencyManager::set(); return previousSessionCrashed; } @@ -2003,6 +2005,10 @@ void Application::initializeUi() { showCursor(compositorHelper->getAllowMouseCapture() ? Qt::BlankCursor : Qt::ArrowCursor); } }); + + // Pre-create a couple of Web3D overlays to speed up tablet UI + auto offscreenSurfaceCache = DependencyManager::get(); + offscreenSurfaceCache->reserve(Web3DOverlay::QML, 2); } void Application::paintGL() { diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index ee1a0f5256..c987735367 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -28,14 +28,15 @@ #include #include +#include static const float DPI = 30.47f; static const float INCHES_TO_METERS = 1.0f / 39.3701f; static const float METERS_TO_INCHES = 39.3701f; static const float OPAQUE_ALPHA_THRESHOLD = 0.99f; -QString const Web3DOverlay::TYPE = "web3d"; - +const QString Web3DOverlay::TYPE = "web3d"; +const QString Web3DOverlay::QML = "Web3DOverlay.qml"; Web3DOverlay::Web3DOverlay() : _dpi(DPI) { _touchDevice.setCapabilities(QTouchDevice::Position); _touchDevice.setType(QTouchDevice::TouchScreen); @@ -80,8 +81,9 @@ Web3DOverlay::~Web3DOverlay() { // is no longer valid auto webSurface = _webSurface; AbstractViewStateInterface::instance()->postLambdaEvent([webSurface] { - webSurface->deleteLater(); + DependencyManager::get()->release(QML, webSurface); }); + _webSurface.reset(); } auto geometryCache = DependencyManager::get(); if (geometryCache) { @@ -109,23 +111,14 @@ void Web3DOverlay::render(RenderArgs* args) { QOpenGLContext * currentContext = QOpenGLContext::currentContext(); QSurface * currentSurface = currentContext->surface(); if (!_webSurface) { - auto deleter = [](OffscreenQmlSurface* webSurface) { - AbstractViewStateInterface::instance()->postLambdaEvent([webSurface] { - webSurface->deleteLater(); - }); - }; - _webSurface = QSharedPointer(new OffscreenQmlSurface(), deleter); + _webSurface = DependencyManager::get()->acquire(QML); + _webSurface->setMaxFps(10); // FIXME, the max FPS could be better managed by being dynamic (based on the number of current surfaces // and the current rendering load) - _webSurface->setMaxFps(10); - _webSurface->create(currentContext); - _webSurface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/")); - _webSurface->load("Web3DOverlay.qml"); _webSurface->resume(); + _webSurface->resize(QSize(_resolution.x, _resolution.y)); _webSurface->getRootItem()->setProperty("url", _url); _webSurface->getRootItem()->setProperty("scriptURL", _scriptURL); - _webSurface->getRootContext()->setContextProperty("ApplicationInterface", qApp); - _webSurface->resize(QSize(_resolution.x, _resolution.y)); currentContext->makeCurrent(currentSurface); auto forwardPointerEvent = [=](unsigned int overlayID, const PointerEvent& event) { diff --git a/interface/src/ui/overlays/Web3DOverlay.h b/interface/src/ui/overlays/Web3DOverlay.h index 45ec9fbc50..c389f5e6f9 100644 --- a/interface/src/ui/overlays/Web3DOverlay.h +++ b/interface/src/ui/overlays/Web3DOverlay.h @@ -21,6 +21,7 @@ class Web3DOverlay : public Billboard3DOverlay { Q_OBJECT public: + static const QString QML; static QString const TYPE; virtual QString getType() const override { return TYPE; } diff --git a/libraries/gl/src/gl/OffscreenQmlSurfaceCache.cpp b/libraries/gl/src/gl/OffscreenQmlSurfaceCache.cpp new file mode 100644 index 0000000000..ad370a1f43 --- /dev/null +++ b/libraries/gl/src/gl/OffscreenQmlSurfaceCache.cpp @@ -0,0 +1,57 @@ +// +// Created by Bradley Austin Davis on 2017-01-11 +// Copyright 2013-2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#include "OffscreenQmlSurfaceCache.h" + +#include +#include + +#include +#include "OffscreenQmlSurface.h" + +OffscreenQmlSurfaceCache::OffscreenQmlSurfaceCache() { +} + +OffscreenQmlSurfaceCache::~OffscreenQmlSurfaceCache() { + _cache.clear(); +} + +QSharedPointer OffscreenQmlSurfaceCache::acquire(const QString& rootSource) { + auto& list = _cache[rootSource]; + if (list.empty()) { + list.push_back(buildSurface(rootSource)); + } + auto result = list.front(); + list.pop_front(); + return result; +} + +void OffscreenQmlSurfaceCache::reserve(const QString& rootSource, int count) { + auto& list = _cache[rootSource]; + while (list.size() < count) { + list.push_back(buildSurface(rootSource)); + } +} + +void OffscreenQmlSurfaceCache::release(const QString& rootSource, const QSharedPointer& surface) { + surface->pause(); + _cache[rootSource].push_back(surface); +} + +QSharedPointer OffscreenQmlSurfaceCache::buildSurface(const QString& rootSource) { + auto surface = QSharedPointer(new OffscreenQmlSurface()); + QOpenGLContext* currentContext = QOpenGLContext::currentContext(); + QSurface* currentSurface = currentContext->surface(); + surface->create(currentContext); + surface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/")); + surface->load(rootSource); + surface->getRootContext()->setContextProperty("ApplicationInterface", qApp); + surface->resize(QSize(100, 100)); + currentContext->makeCurrent(currentSurface); + return surface; +} + diff --git a/libraries/gl/src/gl/OffscreenQmlSurfaceCache.h b/libraries/gl/src/gl/OffscreenQmlSurfaceCache.h new file mode 100644 index 0000000000..02382a791b --- /dev/null +++ b/libraries/gl/src/gl/OffscreenQmlSurfaceCache.h @@ -0,0 +1,34 @@ +// +// Created by Bradley Austin Davis on 2017-01-11 +// Copyright 2013-2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#pragma once +#ifndef hifi_OffscreenQmlSurfaceCache_h +#define hifi_OffscreenQmlSurfaceCahce_h + +#include "DependencyManager.h" + +#include + +class OffscreenQmlSurface; + +class OffscreenQmlSurfaceCache : public Dependency { + SINGLETON_DEPENDENCY + +public: + OffscreenQmlSurfaceCache(); + virtual ~OffscreenQmlSurfaceCache(); + + QSharedPointer acquire(const QString& rootSource); + void release(const QString& rootSource, const QSharedPointer& surface); + void reserve(const QString& rootSource, int count = 1); + +private: + QSharedPointer buildSurface(const QString& rootSource); + QHash>> _cache; +}; + +#endif