mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
Eagerly cache QML surfaces for Web3D overlays to prevent stutter on loading the tablet
This commit is contained in:
parent
db5e4db79f
commit
f235a52a6d
5 changed files with 106 additions and 15 deletions
|
@ -89,6 +89,7 @@
|
|||
#include <OctalCode.h>
|
||||
#include <OctreeSceneStats.h>
|
||||
#include <OffscreenUi.h>
|
||||
#include <gl/OffscreenQmlSurfaceCache.h>
|
||||
#include <gl/OffscreenGLCanvas.h>
|
||||
#include <PathUtils.h>
|
||||
#include <PerfStat.h>
|
||||
|
@ -512,6 +513,7 @@ bool setupEssentials(int& argc, char** argv) {
|
|||
DependencyManager::set<InterfaceParentFinder>();
|
||||
DependencyManager::set<EntityTreeRenderer>(true, qApp, qApp);
|
||||
DependencyManager::set<CompositorHelper>();
|
||||
DependencyManager::set<OffscreenQmlSurfaceCache>();
|
||||
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<OffscreenQmlSurfaceCache>();
|
||||
offscreenSurfaceCache->reserve(Web3DOverlay::QML, 2);
|
||||
}
|
||||
|
||||
void Application::paintGL() {
|
||||
|
|
|
@ -28,14 +28,15 @@
|
|||
#include <AbstractViewStateInterface.h>
|
||||
|
||||
#include <gl/OffscreenQmlSurface.h>
|
||||
#include <gl/OffscreenQmlSurfaceCache.h>
|
||||
|
||||
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<OffscreenQmlSurfaceCache>()->release(QML, webSurface);
|
||||
});
|
||||
_webSurface.reset();
|
||||
}
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
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<OffscreenQmlSurface>(new OffscreenQmlSurface(), deleter);
|
||||
_webSurface = DependencyManager::get<OffscreenQmlSurfaceCache>()->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) {
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
57
libraries/gl/src/gl/OffscreenQmlSurfaceCache.cpp
Normal file
57
libraries/gl/src/gl/OffscreenQmlSurfaceCache.cpp
Normal file
|
@ -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 <QtGui/QOpenGLContext>
|
||||
#include <QtQml/QQmlContext>
|
||||
|
||||
#include <PathUtils.h>
|
||||
#include "OffscreenQmlSurface.h"
|
||||
|
||||
OffscreenQmlSurfaceCache::OffscreenQmlSurfaceCache() {
|
||||
}
|
||||
|
||||
OffscreenQmlSurfaceCache::~OffscreenQmlSurfaceCache() {
|
||||
_cache.clear();
|
||||
}
|
||||
|
||||
QSharedPointer<OffscreenQmlSurface> 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<OffscreenQmlSurface>& surface) {
|
||||
surface->pause();
|
||||
_cache[rootSource].push_back(surface);
|
||||
}
|
||||
|
||||
QSharedPointer<OffscreenQmlSurface> OffscreenQmlSurfaceCache::buildSurface(const QString& rootSource) {
|
||||
auto surface = QSharedPointer<OffscreenQmlSurface>(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;
|
||||
}
|
||||
|
34
libraries/gl/src/gl/OffscreenQmlSurfaceCache.h
Normal file
34
libraries/gl/src/gl/OffscreenQmlSurfaceCache.h
Normal file
|
@ -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 <QtCore/QSharedPointer>
|
||||
|
||||
class OffscreenQmlSurface;
|
||||
|
||||
class OffscreenQmlSurfaceCache : public Dependency {
|
||||
SINGLETON_DEPENDENCY
|
||||
|
||||
public:
|
||||
OffscreenQmlSurfaceCache();
|
||||
virtual ~OffscreenQmlSurfaceCache();
|
||||
|
||||
QSharedPointer<OffscreenQmlSurface> acquire(const QString& rootSource);
|
||||
void release(const QString& rootSource, const QSharedPointer<OffscreenQmlSurface>& surface);
|
||||
void reserve(const QString& rootSource, int count = 1);
|
||||
|
||||
private:
|
||||
QSharedPointer<OffscreenQmlSurface> buildSurface(const QString& rootSource);
|
||||
QHash<QString, QList<QSharedPointer<OffscreenQmlSurface>>> _cache;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue