mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 18:23:54 +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();
|
||||
QSurface * currentSurface = currentContext->surface();
|
||||
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->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/controls/"));
|
||||
_webSurface->load("WebView.qml");
|
||||
|
@ -95,8 +100,9 @@ void Web3DOverlay::render(RenderArgs* args) {
|
|||
}
|
||||
|
||||
if (!_texture) {
|
||||
_texture = gpu::TexturePointer(gpu::Texture::createExternal2D([this](uint32_t recycleTexture, void* recycleFence) {
|
||||
_webSurface->releaseTexture({ recycleTexture, recycleFence });
|
||||
auto webSurface = _webSurface;
|
||||
_texture = gpu::TexturePointer(gpu::Texture::createExternal2D([webSurface](uint32_t recycleTexture, void* recycleFence) {
|
||||
webSurface->releaseTexture({ recycleTexture, recycleFence });
|
||||
}));
|
||||
_texture->setSource(__FUNCTION__);
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
virtual Web3DOverlay* createClone() const override;
|
||||
|
||||
private:
|
||||
OffscreenQmlSurface* _webSurface{ nullptr };
|
||||
QSharedPointer<OffscreenQmlSurface> _webSurface;
|
||||
QMetaObject::Connection _connection;
|
||||
gpu::TexturePointer _texture;
|
||||
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
|
||||
QOpenGLContext * currentContext = QOpenGLContext::currentContext();
|
||||
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->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/controls/"));
|
||||
_webSurface->load("WebView.qml", [&](QQmlContext* context, QObject* obj) {
|
||||
|
@ -215,9 +227,11 @@ void RenderableWebEntityItem::render(RenderArgs* args) {
|
|||
_webSurface->resize(QSize(windowSize.x, windowSize.y));
|
||||
|
||||
if (!_texture) {
|
||||
_texture = gpu::TexturePointer(gpu::Texture::createExternal2D([this](uint32_t recycleTexture, void* recycleFence) {
|
||||
_webSurface->releaseTexture({ recycleTexture, recycleFence });
|
||||
}));
|
||||
auto webSurface = _webSurface;
|
||||
auto recycler = [webSurface] (uint32_t recycleTexture, void* recycleFence) {
|
||||
webSurface->releaseTexture({ recycleTexture, recycleFence });
|
||||
};
|
||||
_texture = gpu::TexturePointer(gpu::Texture::createExternal2D(recycler));
|
||||
_texture->setSource(__FUNCTION__);
|
||||
}
|
||||
OffscreenQmlSurface::TextureAndFence newTextureAndFence;
|
||||
|
@ -352,16 +366,7 @@ void RenderableWebEntityItem::destroyWebSurface() {
|
|||
_mouseMoveConnection = QMetaObject::Connection();
|
||||
QObject::disconnect(_hoverLeaveConnection);
|
||||
_hoverLeaveConnection = QMetaObject::Connection();
|
||||
|
||||
// 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;
|
||||
_webSurface.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ private:
|
|||
void destroyWebSurface();
|
||||
glm::vec2 getWindowSize() const;
|
||||
|
||||
OffscreenQmlSurface* _webSurface{ nullptr };
|
||||
QSharedPointer<OffscreenQmlSurface> _webSurface;
|
||||
QMetaObject::Connection _connection;
|
||||
gpu::TexturePointer _texture;
|
||||
ivec2 _lastPress { INT_MIN };
|
||||
|
|
|
@ -182,8 +182,11 @@ GLTexture::~GLTexture() {
|
|||
if (backend) {
|
||||
if (_external) {
|
||||
auto recycler = _gpuObject.getExternalRecycler();
|
||||
assert(recycler);
|
||||
backend->releaseExternalTexture(_id, recycler);
|
||||
if (recycler) {
|
||||
backend->releaseExternalTexture(_id, recycler);
|
||||
} else {
|
||||
qWarning() << "No recycler available for texture " << _id << " possible leak";
|
||||
}
|
||||
} else if (_id) {
|
||||
backend->releaseTexture(_id, _size);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue