mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 13:49:12 +02:00
Fix crash on destroying web entities and overlays
This commit is contained in:
parent
ca3572f991
commit
8c5028158f
5 changed files with 35 additions and 21 deletions
|
@ -73,7 +73,12 @@ void Web3DOverlay::render(RenderArgs* args) {
|
||||||
QOpenGLContext * currentContext = QOpenGLContext::currentContext();
|
QOpenGLContext * currentContext = QOpenGLContext::currentContext();
|
||||||
QSurface * currentSurface = currentContext->surface();
|
QSurface * currentSurface = currentContext->surface();
|
||||||
if (!_webSurface) {
|
if (!_webSurface) {
|
||||||
_webSurface = new OffscreenQmlSurface();
|
auto deleter = [](OffscreenQmlSurface* webSurface) {
|
||||||
|
AbstractViewStateInterface::instance()->postLambdaEvent([webSurface] {
|
||||||
|
webSurface->deleteLater();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
_webSurface = QSharedPointer<OffscreenQmlSurface>(new OffscreenQmlSurface(), deleter);
|
||||||
_webSurface->create(currentContext);
|
_webSurface->create(currentContext);
|
||||||
_webSurface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/controls/"));
|
_webSurface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/controls/"));
|
||||||
_webSurface->load("WebView.qml");
|
_webSurface->load("WebView.qml");
|
||||||
|
@ -95,8 +100,9 @@ void Web3DOverlay::render(RenderArgs* args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_texture) {
|
if (!_texture) {
|
||||||
_texture = gpu::TexturePointer(gpu::Texture::createExternal2D([this](uint32_t recycleTexture, void* recycleFence) {
|
auto webSurface = _webSurface;
|
||||||
_webSurface->releaseTexture({ recycleTexture, recycleFence });
|
_texture = gpu::TexturePointer(gpu::Texture::createExternal2D([webSurface](uint32_t recycleTexture, void* recycleFence) {
|
||||||
|
webSurface->releaseTexture({ recycleTexture, recycleFence });
|
||||||
}));
|
}));
|
||||||
_texture->setSource(__FUNCTION__);
|
_texture->setSource(__FUNCTION__);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ public:
|
||||||
virtual Web3DOverlay* createClone() const override;
|
virtual Web3DOverlay* createClone() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OffscreenQmlSurface* _webSurface{ nullptr };
|
QSharedPointer<OffscreenQmlSurface> _webSurface;
|
||||||
QMetaObject::Connection _connection;
|
QMetaObject::Connection _connection;
|
||||||
gpu::TexturePointer _texture;
|
gpu::TexturePointer _texture;
|
||||||
QString _url;
|
QString _url;
|
||||||
|
|
|
@ -129,7 +129,19 @@ bool RenderableWebEntityItem::buildWebSurface(EntityTreeRenderer* renderer) {
|
||||||
// Save the original GL context, because creating a QML surface will create a new context
|
// Save the original GL context, because creating a QML surface will create a new context
|
||||||
QOpenGLContext * currentContext = QOpenGLContext::currentContext();
|
QOpenGLContext * currentContext = QOpenGLContext::currentContext();
|
||||||
QSurface * currentSurface = currentContext->surface();
|
QSurface * currentSurface = currentContext->surface();
|
||||||
_webSurface = new OffscreenQmlSurface();
|
|
||||||
|
auto deleter = [](OffscreenQmlSurface* webSurface) {
|
||||||
|
AbstractViewStateInterface::instance()->postLambdaEvent([webSurface] {
|
||||||
|
webSurface->deleteLater();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
_webSurface = QSharedPointer<OffscreenQmlSurface>(new OffscreenQmlSurface(), deleter);
|
||||||
|
|
||||||
|
// The lifetime of the QML surface MUST be managed by the main thread
|
||||||
|
// Additionally, we MUST use local variables copied by value, rather than
|
||||||
|
// member variables, since they would implicitly refer to a this that
|
||||||
|
// is no longer valid
|
||||||
|
|
||||||
_webSurface->create(currentContext);
|
_webSurface->create(currentContext);
|
||||||
_webSurface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/controls/"));
|
_webSurface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/controls/"));
|
||||||
_webSurface->load("WebView.qml", [&](QQmlContext* context, QObject* obj) {
|
_webSurface->load("WebView.qml", [&](QQmlContext* context, QObject* obj) {
|
||||||
|
@ -215,9 +227,11 @@ void RenderableWebEntityItem::render(RenderArgs* args) {
|
||||||
_webSurface->resize(QSize(windowSize.x, windowSize.y));
|
_webSurface->resize(QSize(windowSize.x, windowSize.y));
|
||||||
|
|
||||||
if (!_texture) {
|
if (!_texture) {
|
||||||
_texture = gpu::TexturePointer(gpu::Texture::createExternal2D([this](uint32_t recycleTexture, void* recycleFence) {
|
auto webSurface = _webSurface;
|
||||||
_webSurface->releaseTexture({ recycleTexture, recycleFence });
|
auto recycler = [webSurface] (uint32_t recycleTexture, void* recycleFence) {
|
||||||
}));
|
webSurface->releaseTexture({ recycleTexture, recycleFence });
|
||||||
|
};
|
||||||
|
_texture = gpu::TexturePointer(gpu::Texture::createExternal2D(recycler));
|
||||||
_texture->setSource(__FUNCTION__);
|
_texture->setSource(__FUNCTION__);
|
||||||
}
|
}
|
||||||
OffscreenQmlSurface::TextureAndFence newTextureAndFence;
|
OffscreenQmlSurface::TextureAndFence newTextureAndFence;
|
||||||
|
@ -352,16 +366,7 @@ void RenderableWebEntityItem::destroyWebSurface() {
|
||||||
_mouseMoveConnection = QMetaObject::Connection();
|
_mouseMoveConnection = QMetaObject::Connection();
|
||||||
QObject::disconnect(_hoverLeaveConnection);
|
QObject::disconnect(_hoverLeaveConnection);
|
||||||
_hoverLeaveConnection = QMetaObject::Connection();
|
_hoverLeaveConnection = QMetaObject::Connection();
|
||||||
|
_webSurface.reset();
|
||||||
// The lifetime of the QML surface MUST be managed by the main thread
|
|
||||||
// Additionally, we MUST use local variables copied by value, rather than
|
|
||||||
// member variables, since they would implicitly refer to a this that
|
|
||||||
// is no longer valid
|
|
||||||
auto webSurface = _webSurface;
|
|
||||||
AbstractViewStateInterface::instance()->postLambdaEvent([webSurface] {
|
|
||||||
webSurface->deleteLater();
|
|
||||||
});
|
|
||||||
_webSurface = nullptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ private:
|
||||||
void destroyWebSurface();
|
void destroyWebSurface();
|
||||||
glm::vec2 getWindowSize() const;
|
glm::vec2 getWindowSize() const;
|
||||||
|
|
||||||
OffscreenQmlSurface* _webSurface{ nullptr };
|
QSharedPointer<OffscreenQmlSurface> _webSurface;
|
||||||
QMetaObject::Connection _connection;
|
QMetaObject::Connection _connection;
|
||||||
gpu::TexturePointer _texture;
|
gpu::TexturePointer _texture;
|
||||||
ivec2 _lastPress { INT_MIN };
|
ivec2 _lastPress { INT_MIN };
|
||||||
|
|
|
@ -182,8 +182,11 @@ GLTexture::~GLTexture() {
|
||||||
if (backend) {
|
if (backend) {
|
||||||
if (_external) {
|
if (_external) {
|
||||||
auto recycler = _gpuObject.getExternalRecycler();
|
auto recycler = _gpuObject.getExternalRecycler();
|
||||||
assert(recycler);
|
if (recycler) {
|
||||||
backend->releaseExternalTexture(_id, recycler);
|
backend->releaseExternalTexture(_id, recycler);
|
||||||
|
} else {
|
||||||
|
qWarning() << "No recycler available for texture " << _id << " possible leak";
|
||||||
|
}
|
||||||
} else if (_id) {
|
} else if (_id) {
|
||||||
backend->releaseTexture(_id, _size);
|
backend->releaseTexture(_id, _size);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue