mirror of
https://github.com/overte-org/overte.git
synced 2025-04-07 09:33:08 +02:00
setup qml surface contexts
This commit is contained in:
parent
4b67a79561
commit
6fd34bf1f0
9 changed files with 142 additions and 141 deletions
|
@ -2317,35 +2317,21 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
return DependencyManager::get<AvatarManager>()->getMyAvatar()->getWorldOrientation() * Vectors::UP;
|
||||
});
|
||||
|
||||
render::entities::WebEntityRenderer::setInitializeWebSurfaceOperator([](QSharedPointer<OffscreenQmlSurface> webSurface) {
|
||||
webSurface = DependencyManager::get<OffscreenQmlSurfaceCache>()->acquire(render::entities::WebEntityRenderer::QML);
|
||||
webSurface->getSurfaceContext()->setContextProperty("HMD", DependencyManager::get<HMDScriptingInterface>().data());
|
||||
webSurface->getSurfaceContext()->setContextProperty("AccountServices", AccountServicesScriptingInterface::getInstance());
|
||||
webSurface->getSurfaceContext()->setContextProperty("AddressManager", DependencyManager::get<AddressManager>().data());
|
||||
});
|
||||
render::entities::WebEntityRenderer::setAcquireWebSurfaceOperator([](const QString& url, bool htmlContent, QSharedPointer<OffscreenQmlSurface>& webSurface, bool& cachedWebSurface) {
|
||||
bool isTablet = url == TabletScriptingInterface::QML;
|
||||
if (htmlContent) {
|
||||
// FIXME use the surface cache instead of explicit creation
|
||||
webSurface = QSharedPointer<OffscreenQmlSurface>(new OffscreenQmlSurface(), [](OffscreenQmlSurface* webSurface) {
|
||||
AbstractViewStateInterface::instance()->sendLambdaEvent([webSurface] {
|
||||
// WebEngineView may run other threads (wasapi), so they must be deleted for a clean shutdown
|
||||
// if the application has already stopped its event loop, delete must be explicit
|
||||
delete webSurface;
|
||||
});
|
||||
});
|
||||
webSurface->load(render::entities::WebEntityRenderer::QML, [url](QQmlContext* context, QObject* item) {
|
||||
item->setProperty("url", url);
|
||||
});
|
||||
#if 0
|
||||
// This doesn't work for some reason
|
||||
webSurface = DependencyManager::get<OffscreenQmlSurfaceCache>()->acquire(render::entities::WebEntityRenderer::QML);
|
||||
cachedWebSurface = true;
|
||||
connect(webSurface.data(), &hifi::qml::OffscreenSurface::rootContextCreated, [url, webSurface](QQmlContext* surfaceContext) {
|
||||
webSurface->getRootItem()->setProperty("url", url);
|
||||
});
|
||||
#endif
|
||||
auto rootItemLoadedFunctor = [url, webSurface] {
|
||||
webSurface->getRootItem()->setProperty(render::entities::WebEntityRenderer::URL_PROPERTY, url);
|
||||
};
|
||||
if (webSurface->getRootItem()) {
|
||||
rootItemLoadedFunctor();
|
||||
} else {
|
||||
connect(webSurface.data(), &hifi::qml::OffscreenSurface::rootContextCreated, rootItemLoadedFunctor);
|
||||
}
|
||||
} else {
|
||||
// FIXME: the tablet should use the OffscreenQmlSurfaceCache
|
||||
webSurface = QSharedPointer<OffscreenQmlSurface>(new OffscreenQmlSurface(), [](OffscreenQmlSurface* webSurface) {
|
||||
AbstractViewStateInterface::instance()->sendLambdaEvent([webSurface] {
|
||||
// WebEngineView may run other threads (wasapi), so they must be deleted for a clean shutdown
|
||||
|
@ -2353,9 +2339,14 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
delete webSurface;
|
||||
});
|
||||
});
|
||||
connect(webSurface.data(), &hifi::qml::OffscreenSurface::rootContextCreated, [url](QQmlContext* surfaceContext) {
|
||||
//setupQmlSurface(isTablet, url == OVERLAY_LOGIN_DIALOG.toString());
|
||||
});
|
||||
auto rootItemLoadedFunctor = [webSurface, url, isTablet] {
|
||||
Application::setupQmlSurface(webSurface->getSurfaceContext(), isTablet || url == OVERLAY_LOGIN_DIALOG.toString());
|
||||
};
|
||||
if (webSurface->getRootItem()) {
|
||||
rootItemLoadedFunctor();
|
||||
} else {
|
||||
connect(webSurface.data(), &hifi::qml::OffscreenSurface::rootContextCreated, rootItemLoadedFunctor);
|
||||
}
|
||||
webSurface->load(url);
|
||||
cachedWebSurface = false;
|
||||
}
|
||||
|
@ -2394,7 +2385,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
rootItem->setProperty("url", "about:blank");
|
||||
}
|
||||
auto offscreenCache = DependencyManager::get<OffscreenQmlSurfaceCache>();
|
||||
// FIXME prevents crash on shutdown, but we shoudln't have to do this check
|
||||
if (offscreenCache) {
|
||||
offscreenCache->release(render::entities::WebEntityRenderer::QML, webSurface);
|
||||
}
|
||||
|
@ -3239,6 +3229,61 @@ void Application::onDesktopRootItemCreated(QQuickItem* rootItem) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void Application::setupQmlSurface(QQmlContext* surfaceContext, bool setAdditionalContextProperties) {
|
||||
surfaceContext->setContextProperty("Users", DependencyManager::get<UsersScriptingInterface>().data());
|
||||
surfaceContext->setContextProperty("HMD", DependencyManager::get<HMDScriptingInterface>().data());
|
||||
surfaceContext->setContextProperty("UserActivityLogger", DependencyManager::get<UserActivityLoggerScriptingInterface>().data());
|
||||
surfaceContext->setContextProperty("Preferences", DependencyManager::get<Preferences>().data());
|
||||
surfaceContext->setContextProperty("Vec3", new Vec3());
|
||||
surfaceContext->setContextProperty("Quat", new Quat());
|
||||
surfaceContext->setContextProperty("MyAvatar", DependencyManager::get<AvatarManager>()->getMyAvatar().get());
|
||||
surfaceContext->setContextProperty("Entities", DependencyManager::get<EntityScriptingInterface>().data());
|
||||
surfaceContext->setContextProperty("Snapshot", DependencyManager::get<Snapshot>().data());
|
||||
|
||||
if (setAdditionalContextProperties) {
|
||||
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
|
||||
auto flags = tabletScriptingInterface->getFlags();
|
||||
|
||||
surfaceContext->setContextProperty("offscreenFlags", flags);
|
||||
surfaceContext->setContextProperty("AddressManager", DependencyManager::get<AddressManager>().data());
|
||||
|
||||
surfaceContext->setContextProperty("Settings", SettingsScriptingInterface::getInstance());
|
||||
surfaceContext->setContextProperty("MenuInterface", MenuScriptingInterface::getInstance());
|
||||
surfaceContext->setContextProperty("KeyboardScriptingInterface", DependencyManager::get<KeyboardScriptingInterface>().data());
|
||||
|
||||
surfaceContext->setContextProperty("Account", AccountServicesScriptingInterface::getInstance()); // DEPRECATED - TO BE REMOVED
|
||||
surfaceContext->setContextProperty("GlobalServices", AccountServicesScriptingInterface::getInstance()); // DEPRECATED - TO BE REMOVED
|
||||
surfaceContext->setContextProperty("AccountServices", AccountServicesScriptingInterface::getInstance());
|
||||
|
||||
// in Qt 5.10.0 there is already an "Audio" object in the QML context
|
||||
// though I failed to find it (from QtMultimedia??). So.. let it be "AudioScriptingInterface"
|
||||
surfaceContext->setContextProperty("AudioScriptingInterface", DependencyManager::get<AudioScriptingInterface>().data());
|
||||
|
||||
surfaceContext->setContextProperty("AudioStats", DependencyManager::get<AudioClient>()->getStats().data());
|
||||
surfaceContext->setContextProperty("fileDialogHelper", new FileDialogHelper());
|
||||
surfaceContext->setContextProperty("ScriptDiscoveryService", DependencyManager::get<ScriptEngines>().data());
|
||||
surfaceContext->setContextProperty("Assets", DependencyManager::get<AssetMappingsScriptingInterface>().data());
|
||||
surfaceContext->setContextProperty("LODManager", DependencyManager::get<LODManager>().data());
|
||||
surfaceContext->setContextProperty("OctreeStats", DependencyManager::get<OctreeStatsProvider>().data());
|
||||
surfaceContext->setContextProperty("DCModel", DependencyManager::get<DomainConnectionModel>().data());
|
||||
surfaceContext->setContextProperty("AvatarInputs", AvatarInputs::getInstance());
|
||||
surfaceContext->setContextProperty("AvatarList", DependencyManager::get<AvatarManager>().data());
|
||||
surfaceContext->setContextProperty("DialogsManager", DialogsManagerScriptingInterface::getInstance());
|
||||
surfaceContext->setContextProperty("InputConfiguration", DependencyManager::get<InputConfiguration>().data());
|
||||
surfaceContext->setContextProperty("SoundCache", DependencyManager::get<SoundCacheScriptingInterface>().data());
|
||||
surfaceContext->setContextProperty("AvatarBookmarks", DependencyManager::get<AvatarBookmarks>().data());
|
||||
surfaceContext->setContextProperty("Render", AbstractViewStateInterface::instance()->getRenderEngine()->getConfiguration().get());
|
||||
surfaceContext->setContextProperty("Workload", qApp->getGameWorkload()._engine->getConfiguration().get());
|
||||
surfaceContext->setContextProperty("Controller", DependencyManager::get<controller::ScriptingInterface>().data());
|
||||
surfaceContext->setContextProperty("Pointers", DependencyManager::get<PointerScriptingInterface>().data());
|
||||
surfaceContext->setContextProperty("Window", DependencyManager::get<WindowScriptingInterface>().data());
|
||||
surfaceContext->setContextProperty("Reticle", qApp->getApplicationCompositor().getReticleInterface());
|
||||
surfaceContext->setContextProperty("HiFiAbout", AboutUtil::getInstance());
|
||||
surfaceContext->setContextProperty("WalletScriptingInterface", DependencyManager::get<WalletScriptingInterface>().data());
|
||||
surfaceContext->setContextProperty("ResourceRequestObserver", DependencyManager::get<ResourceRequestObserver>().data());
|
||||
}
|
||||
}
|
||||
|
||||
void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) {
|
||||
PROFILE_RANGE(render, __FUNCTION__);
|
||||
PerformanceTimer perfTimer("updateCamera");
|
||||
|
|
|
@ -589,6 +589,8 @@ private:
|
|||
void maybeToggleMenuVisible(QMouseEvent* event) const;
|
||||
void toggleTabletUI(bool shouldOpen = false) const;
|
||||
|
||||
static void setupQmlSurface(QQmlContext* surfaceContext, bool setAdditionalContextProperties);
|
||||
|
||||
MainWindow* _window;
|
||||
QElapsedTimer& _sessionRunTimer;
|
||||
|
||||
|
|
|
@ -82,9 +82,8 @@ Web3DOverlay::Web3DOverlay() {
|
|||
connect(this, &Web3DOverlay::requestWebSurface, this, &Web3DOverlay::buildWebSurface);
|
||||
connect(this, &Web3DOverlay::resizeWebSurface, this, &Web3DOverlay::onResizeWebSurface);
|
||||
|
||||
//need to be intialized before Tablet 1st open
|
||||
_cachedWebSurface = true;
|
||||
render::entities::WebEntityRenderer::initializeWebSurface(_webSurface);
|
||||
render::entities::WebEntityRenderer::acquireWebSurface("", true, _webSurface, _cachedWebSurface);
|
||||
_webSurface->resume();
|
||||
}
|
||||
|
||||
Web3DOverlay::Web3DOverlay(const Web3DOverlay* Web3DOverlay) :
|
||||
|
@ -145,64 +144,6 @@ bool Web3DOverlay::isWebContent() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
void Web3DOverlay::setupQmlSurface(bool isTablet, bool isLoginDialog) {
|
||||
_webSurface->getSurfaceContext()->setContextProperty("Users", DependencyManager::get<UsersScriptingInterface>().data());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("HMD", DependencyManager::get<HMDScriptingInterface>().data());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("UserActivityLogger", DependencyManager::get<UserActivityLoggerScriptingInterface>().data());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("Preferences", DependencyManager::get<Preferences>().data());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("Vec3", new Vec3());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("Quat", new Quat());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("MyAvatar", DependencyManager::get<AvatarManager>()->getMyAvatar().get());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("Entities", DependencyManager::get<EntityScriptingInterface>().data());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("Snapshot", DependencyManager::get<Snapshot>().data());
|
||||
|
||||
if (isTablet || isLoginDialog) {
|
||||
_webSurface->getSurfaceContext()->setContextProperty("Account", AccountServicesScriptingInterface::getInstance()); // DEPRECATED - TO BE REMOVED
|
||||
_webSurface->getSurfaceContext()->setContextProperty("Settings", SettingsScriptingInterface::getInstance());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("MenuInterface", MenuScriptingInterface::getInstance());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("KeyboardScriptingInterface", DependencyManager::get<KeyboardScriptingInterface>().data());
|
||||
}
|
||||
if (isTablet) {
|
||||
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
|
||||
auto flags = tabletScriptingInterface->getFlags();
|
||||
|
||||
_webSurface->getSurfaceContext()->setContextProperty("offscreenFlags", flags);
|
||||
_webSurface->getSurfaceContext()->setContextProperty("AddressManager", DependencyManager::get<AddressManager>().data());
|
||||
|
||||
_webSurface->getSurfaceContext()->setContextProperty("GlobalServices", AccountServicesScriptingInterface::getInstance()); // DEPRECATED - TO BE REMOVED
|
||||
_webSurface->getSurfaceContext()->setContextProperty("AccountServices", AccountServicesScriptingInterface::getInstance());
|
||||
|
||||
// in Qt 5.10.0 there is already an "Audio" object in the QML context
|
||||
// though I failed to find it (from QtMultimedia??). So.. let it be "AudioScriptingInterface"
|
||||
_webSurface->getSurfaceContext()->setContextProperty("AudioScriptingInterface", DependencyManager::get<AudioScriptingInterface>().data());
|
||||
|
||||
_webSurface->getSurfaceContext()->setContextProperty("AudioStats", DependencyManager::get<AudioClient>()->getStats().data());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("HMD", DependencyManager::get<HMDScriptingInterface>().data());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("fileDialogHelper", new FileDialogHelper());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("MyAvatar", DependencyManager::get<AvatarManager>()->getMyAvatar().get());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("ScriptDiscoveryService", DependencyManager::get<ScriptEngines>().data());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("Assets", DependencyManager::get<AssetMappingsScriptingInterface>().data());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("LODManager", DependencyManager::get<LODManager>().data());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("OctreeStats", DependencyManager::get<OctreeStatsProvider>().data());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("DCModel", DependencyManager::get<DomainConnectionModel>().data());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("AvatarInputs", AvatarInputs::getInstance());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("AvatarList", DependencyManager::get<AvatarManager>().data());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("DialogsManager", DialogsManagerScriptingInterface::getInstance());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("InputConfiguration", DependencyManager::get<InputConfiguration>().data());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("SoundCache", DependencyManager::get<SoundCacheScriptingInterface>().data());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("AvatarBookmarks", DependencyManager::get<AvatarBookmarks>().data());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("Render", AbstractViewStateInterface::instance()->getRenderEngine()->getConfiguration().get());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("Workload", qApp->getGameWorkload()._engine->getConfiguration().get());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("Controller", DependencyManager::get<controller::ScriptingInterface>().data());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("Pointers", DependencyManager::get<PointerScriptingInterface>().data());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("Window", DependencyManager::get<WindowScriptingInterface>().data());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("Reticle", qApp->getApplicationCompositor().getReticleInterface());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("HiFiAbout", AboutUtil::getInstance());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("WalletScriptingInterface", DependencyManager::get<WalletScriptingInterface>().data());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("ResourceRequestObserver", DependencyManager::get<ResourceRequestObserver>().data());
|
||||
}
|
||||
}
|
||||
|
||||
void Web3DOverlay::setMaxFPS(uint8_t maxFPS) {
|
||||
// FIXME, the max FPS could be better managed by being dynamic (based on the number of current surfaces and the current rendering load)
|
||||
_desiredMaxFPS = maxFPS;
|
||||
|
@ -514,14 +455,14 @@ void Web3DOverlay::setURL(const QString& url) {
|
|||
if (wasWebContent && isWebContent()) {
|
||||
// If we're just targeting a new web URL, then switch to that without messing around
|
||||
// with the underlying QML
|
||||
AbstractViewStateInterface::instance()->postLambdaEvent([this, url] {
|
||||
_webSurface->getRootItem()->setProperty("url", _url);
|
||||
AbstractViewStateInterface::instance()->postLambdaEvent([this] {
|
||||
_webSurface->getRootItem()->setProperty(render::entities::WebEntityRenderer::URL_PROPERTY, _url);
|
||||
_webSurface->getRootItem()->setProperty("scriptURL", _scriptURL);
|
||||
});
|
||||
} else {
|
||||
// If we're switching to or from web content, or between different QML content
|
||||
// we need to destroy and rebuild the entire QML surface
|
||||
AbstractViewStateInterface::instance()->postLambdaEvent([this, url] {
|
||||
AbstractViewStateInterface::instance()->postLambdaEvent([this] {
|
||||
rebuildWebSurface();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -74,13 +74,12 @@ protected:
|
|||
Transform evalRenderTransform() override;
|
||||
|
||||
private:
|
||||
void setupQmlSurface(bool isTablet, bool isLoginDialog);
|
||||
void rebuildWebSurface();
|
||||
bool isWebContent() const;
|
||||
|
||||
InputMode _inputMode { Touch };
|
||||
QSharedPointer<OffscreenQmlSurface> _webSurface;
|
||||
bool _cachedWebSurface{ false };
|
||||
bool _cachedWebSurface { false };
|
||||
gpu::TexturePointer _texture;
|
||||
QString _url;
|
||||
QString _scriptURL;
|
||||
|
|
|
@ -31,8 +31,8 @@ using namespace render;
|
|||
using namespace render::entities;
|
||||
|
||||
const QString WebEntityRenderer::QML = "Web3DSurface.qml";
|
||||
const char* WebEntityRenderer::URL_PROPERTY = "url";
|
||||
|
||||
std::function<void(QSharedPointer<OffscreenQmlSurface>)> WebEntityRenderer::_initializeWebSurfaceOperator = nullptr;
|
||||
std::function<void(QString, bool, QSharedPointer<OffscreenQmlSurface>&, bool&)> WebEntityRenderer::_acquireWebSurfaceOperator = nullptr;
|
||||
std::function<void(QSharedPointer<OffscreenQmlSurface>&, bool&, std::vector<QMetaObject::Connection>&)> WebEntityRenderer::_releaseWebSurfaceOperator = nullptr;
|
||||
|
||||
|
@ -50,7 +50,6 @@ static uint32_t _currentWebCount { 0 };
|
|||
static const uint32_t MAX_CONCURRENT_WEB_VIEWS = 20;
|
||||
|
||||
static QTouchDevice _touchDevice;
|
||||
static const char* URL_PROPERTY = "url";
|
||||
|
||||
WebEntityRenderer::ContentType WebEntityRenderer::getContentType(const QString& urlString) {
|
||||
if (urlString.isEmpty()) {
|
||||
|
@ -80,9 +79,14 @@ WebEntityRenderer::WebEntityRenderer(const EntityItemPointer& entity) : Parent(e
|
|||
_texture = gpu::Texture::createExternal(OffscreenQmlSurface::getDiscardLambda());
|
||||
_texture->setSource(__FUNCTION__);
|
||||
|
||||
// need to be intialized early
|
||||
_cachedWebSurface = true;
|
||||
WebEntityRenderer::initializeWebSurface(_webSurface);
|
||||
if (_currentWebCount < MAX_CONCURRENT_WEB_VIEWS) {
|
||||
_currentWebCount++;
|
||||
WebEntityRenderer::acquireWebSurface("", true, _webSurface, _cachedWebSurface);
|
||||
_contentType = ContentType::HtmlContent;
|
||||
_fadeStartTime = usecTimestampNow();
|
||||
_webSurface->resume();
|
||||
qDebug() << "boop" << this << _webSurface << _webSurface->getRootItem();
|
||||
}
|
||||
|
||||
_timer.setInterval(MSECS_PER_SECOND);
|
||||
connect(&_timer, &QTimer::timeout, this, &WebEntityRenderer::onTimeout);
|
||||
|
@ -149,9 +153,8 @@ bool WebEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointe
|
|||
}
|
||||
|
||||
bool WebEntityRenderer::needsRenderUpdate() const {
|
||||
if (resultWithReadLock<bool>([&] {
|
||||
// If we have rendered recently, and there is no web surface, we're going to create one
|
||||
return !_webSurface;
|
||||
if (resultWithReadLock<bool>([this] {
|
||||
return _prevHasWebSurface != hasWebSurface() || _needsURLUpdate;
|
||||
})) {
|
||||
return true;
|
||||
}
|
||||
|
@ -188,16 +191,21 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene
|
|||
});
|
||||
|
||||
if (urlChanged) {
|
||||
if (newContentType != ContentType::HtmlContent || currentContentType != ContentType::HtmlContent) {
|
||||
destroyWebSurface();
|
||||
// If we destroyed the surface, the URL change will be implicitly handled by the re-creation
|
||||
urlChanged = false;
|
||||
}
|
||||
|
||||
withWriteLock([&] {
|
||||
_needsURLUpdate = true;
|
||||
_sourceURL = newSourceUrl;
|
||||
_contentType = newContentType;
|
||||
});
|
||||
|
||||
if (newContentType != ContentType::HtmlContent || currentContentType != ContentType::HtmlContent) {
|
||||
qDebug() << "boop2" << this << _webSurface << _webSurface->getRootItem();
|
||||
destroyWebSurface();
|
||||
// If we destroyed the surface, the URL change will be implicitly handled by the re-creation
|
||||
urlChanged = false;
|
||||
withWriteLock([&] {
|
||||
_needsURLUpdate = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -209,17 +217,28 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene
|
|||
_alpha = entity->getAlpha();
|
||||
|
||||
if (_contentType == ContentType::NoContent) {
|
||||
_prevHasWebSurface = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// This work must be done on the main thread
|
||||
// If we couldn't create a new web surface, exit
|
||||
if (!hasWebSurface() && !buildWebSurface(entity)) {
|
||||
if (!_webSurface) {
|
||||
qDebug() << "boop3" << this << _webSurface << _webSurface->getRootItem();
|
||||
buildWebSurface(entity);
|
||||
}
|
||||
|
||||
_prevHasWebSurface = hasWebSurface();
|
||||
if (!_prevHasWebSurface) {
|
||||
qDebug() << "boop4" << this << _webSurface << _webSurface->getRootItem();
|
||||
return;
|
||||
}
|
||||
|
||||
if (urlChanged && _contentType == ContentType::HtmlContent) {
|
||||
qDebug() << "boop6" << this << _webSurface << _webSurface->getRootItem();
|
||||
if (_needsURLUpdate && _contentType == ContentType::HtmlContent) {
|
||||
qDebug() << "boop7" << this << _webSurface << _webSurface->getRootItem();
|
||||
_webSurface->getRootItem()->setProperty(URL_PROPERTY, _sourceURL);
|
||||
_needsURLUpdate = false;
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -252,7 +271,6 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene
|
|||
void* key = (void*)this;
|
||||
AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, entity] () {
|
||||
withWriteLock([&] {
|
||||
|
||||
glm::vec2 windowSize = getWindowSize(entity);
|
||||
_webSurface->resize(QSize(windowSize.x, windowSize.y));
|
||||
updateModelTransformAndBound();
|
||||
|
@ -305,16 +323,11 @@ void WebEntityRenderer::doRender(RenderArgs* args) {
|
|||
batch.setResourceTexture(0, nullptr);
|
||||
}
|
||||
|
||||
bool WebEntityRenderer::hasWebSurface() {
|
||||
bool WebEntityRenderer::hasWebSurface() const {
|
||||
return (bool)_webSurface && _webSurface->getRootItem();
|
||||
}
|
||||
|
||||
bool WebEntityRenderer::buildWebSurface(const TypedEntityPointer& entity) {
|
||||
if (_webSurface && !_webSurface->getRootItem()) {
|
||||
// We're waiting on the root item
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_currentWebCount >= MAX_CONCURRENT_WEB_VIEWS) {
|
||||
qWarning() << "Too many concurrent web views to create new view";
|
||||
return false;
|
||||
|
@ -366,6 +379,7 @@ void WebEntityRenderer::hoverEnterEntity(const PointerEvent& event) {
|
|||
if (_inputMode == WebInputMode::MOUSE) {
|
||||
handlePointerEvent(event);
|
||||
} else if (_webSurface) {
|
||||
qDebug() << "boop5" << this << _webSurface << _webSurface->getRootItem();
|
||||
PointerEvent webEvent = event;
|
||||
webEvent.setPos2D(event.getPos2D() * (METERS_TO_INCHES * _dpi));
|
||||
_webSurface->hoverBeginEvent(webEvent, _touchDevice);
|
||||
|
|
|
@ -31,12 +31,7 @@ public:
|
|||
Q_INVOKABLE void handlePointerEvent(const PointerEvent& event);
|
||||
|
||||
static const QString QML;
|
||||
static void setInitializeWebSurfaceOperator(std::function<void(QSharedPointer<OffscreenQmlSurface>)> initializeWebSurfaceOperator) { _initializeWebSurfaceOperator = initializeWebSurfaceOperator; }
|
||||
static void initializeWebSurface(QSharedPointer<OffscreenQmlSurface> webSurface) {
|
||||
if (_initializeWebSurfaceOperator) {
|
||||
_initializeWebSurfaceOperator(webSurface);
|
||||
}
|
||||
}
|
||||
static const char* URL_PROPERTY;
|
||||
|
||||
static void setAcquireWebSurfaceOperator(std::function<void(const QString&, bool, QSharedPointer<OffscreenQmlSurface>&, bool&)> acquireWebSurfaceOperator) { _acquireWebSurfaceOperator = acquireWebSurfaceOperator; }
|
||||
static void acquireWebSurface(const QString& url, bool htmlContent, QSharedPointer<OffscreenQmlSurface>& webSurface, bool& cachedWebSurface) {
|
||||
|
@ -72,7 +67,7 @@ private:
|
|||
void onTimeout();
|
||||
bool buildWebSurface(const TypedEntityPointer& entity);
|
||||
void destroyWebSurface();
|
||||
bool hasWebSurface();
|
||||
bool hasWebSurface() const;
|
||||
glm::vec2 getWindowSize(const TypedEntityPointer& entity) const;
|
||||
|
||||
int _geometryId{ 0 };
|
||||
|
@ -84,7 +79,9 @@ private:
|
|||
static ContentType getContentType(const QString& urlString);
|
||||
ContentType _contentType { ContentType::NoContent };
|
||||
|
||||
QSharedPointer<OffscreenQmlSurface> _webSurface;
|
||||
QSharedPointer<OffscreenQmlSurface> _webSurface { nullptr };
|
||||
bool _prevHasWebSurface { false };
|
||||
bool _needsURLUpdate { false };
|
||||
bool _cachedWebSurface { false };
|
||||
gpu::TexturePointer _texture;
|
||||
|
||||
|
@ -104,7 +101,6 @@ private:
|
|||
|
||||
std::vector<QMetaObject::Connection> _connections;
|
||||
|
||||
static std::function<void(QSharedPointer<OffscreenQmlSurface>)> _initializeWebSurfaceOperator;
|
||||
static std::function<void(QString, bool, QSharedPointer<OffscreenQmlSurface>&, bool&)> _acquireWebSurfaceOperator;
|
||||
static std::function<void(QSharedPointer<OffscreenQmlSurface>&, bool&, std::vector<QMetaObject::Connection>&)> _releaseWebSurfaceOperator;
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@ void RenderEventHandler::onInitalize() {
|
|||
qFatal("Unable to make QML rendering context current on render thread");
|
||||
}
|
||||
_shared->initializeRenderControl(_canvas.getContext());
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
void RenderEventHandler::resize() {
|
||||
|
@ -150,22 +151,24 @@ void RenderEventHandler::onRender() {
|
|||
}
|
||||
|
||||
void RenderEventHandler::onQuit() {
|
||||
if (_canvas.getContext() != QOpenGLContextWrapper::currentContext()) {
|
||||
qFatal("QML rendering context not current on render thread");
|
||||
}
|
||||
if (_initialized) {
|
||||
if (_canvas.getContext() != QOpenGLContextWrapper::currentContext()) {
|
||||
qFatal("QML rendering context not current on render thread");
|
||||
}
|
||||
|
||||
if (_depthStencil) {
|
||||
glDeleteRenderbuffers(1, &_depthStencil);
|
||||
_depthStencil = 0;
|
||||
}
|
||||
if (_depthStencil) {
|
||||
glDeleteRenderbuffers(1, &_depthStencil);
|
||||
_depthStencil = 0;
|
||||
}
|
||||
|
||||
if (_fbo) {
|
||||
glDeleteFramebuffers(1, &_fbo);
|
||||
_fbo = 0;
|
||||
}
|
||||
if (_fbo) {
|
||||
glDeleteFramebuffers(1, &_fbo);
|
||||
_fbo = 0;
|
||||
}
|
||||
|
||||
_shared->shutdownRendering(_canvas, _currentSize);
|
||||
_canvas.doneCurrent();
|
||||
_shared->shutdownRendering(_canvas, _currentSize);
|
||||
_canvas.doneCurrent();
|
||||
}
|
||||
_canvas.moveToThreadWithContext(qApp->thread());
|
||||
moveToThread(qApp->thread());
|
||||
QThread::currentThread()->quit();
|
||||
|
|
|
@ -53,6 +53,8 @@ private:
|
|||
|
||||
uint32_t _fbo{ 0 };
|
||||
uint32_t _depthStencil{ 0 };
|
||||
|
||||
bool _initialized { false };
|
||||
};
|
||||
|
||||
}}} // namespace hifi::qml::impl
|
||||
|
|
|
@ -9,9 +9,8 @@
|
|||
#include "WebInputMode.h"
|
||||
|
||||
const char* webInputModeNames[] = {
|
||||
"none",
|
||||
"yaw",
|
||||
"full"
|
||||
"touch",
|
||||
"mouse"
|
||||
};
|
||||
|
||||
static const size_t WEB_INPUT_MODE_NAMES = (sizeof(webInputModeNames) / sizeof(webInputModeNames[0]));
|
||||
|
|
Loading…
Reference in a new issue