Fix error when deleting web item

This commit is contained in:
Brad Davis 2015-05-13 11:58:18 -07:00
parent 9b6c20d93c
commit ad5f1214bf
2 changed files with 23 additions and 9 deletions

View file

@ -39,11 +39,21 @@ RenderableWebEntityItem::~RenderableWebEntityItem() {
if (_webSurface) { if (_webSurface) {
_webSurface->pause(); _webSurface->pause();
_webSurface->disconnect(_connection); _webSurface->disconnect(_connection);
if (_texture) { // After the disconnect, ensure that we have the latest
_webSurface->releaseTexture(_texture); _textureLock.lock();
_texture = 0; _textureLock.unlock();
} // The lifetime of the QML surface MUST be managed by the main thread
_webSurface.clear(); // 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;
auto texture = _texture;
AbstractViewStateInterface::instance()->postLambdaEvent([webSurface, texture] {
if (texture) {
webSurface->releaseTexture(texture);
}
webSurface->deleteLater();
});
} }
} }
@ -51,16 +61,19 @@ void RenderableWebEntityItem::render(RenderArgs* args) {
QOpenGLContext * currentContext = QOpenGLContext::currentContext(); QOpenGLContext * currentContext = QOpenGLContext::currentContext();
QSurface * currentSurface = currentContext->surface(); QSurface * currentSurface = currentContext->surface();
if (!_webSurface) { if (!_webSurface) {
_webSurface = QSharedPointer<OffscreenQmlSurface>(new OffscreenQmlSurface()); _webSurface = new OffscreenQmlSurface();
_webSurface->create(currentContext); _webSurface->create(currentContext);
_webSurface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/")); _webSurface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/"));
_webSurface->load("WebEntity.qml"); _webSurface->load("WebEntity.qml");
_webSurface->resume(); _webSurface->resume();
updateQmlSourceUrl(); updateQmlSourceUrl();
_connection = QObject::connect(_webSurface.data(), &OffscreenQmlSurface::textureUpdated, [&](GLuint textureId) { _connection = QObject::connect(_webSurface, &OffscreenQmlSurface::textureUpdated, [&](GLuint textureId) {
_webSurface->lockTexture(textureId); _webSurface->lockTexture(textureId);
assert(!glGetError()); assert(!glGetError());
std::swap(_texture, textureId); // TODO change to atomic<GLuint>?
withLock(_textureLock, [&] {
std::swap(_texture, textureId);
});
if (textureId) { if (textureId) {
_webSurface->releaseTexture(textureId); _webSurface->releaseTexture(textureId);
} }

View file

@ -28,9 +28,10 @@ public:
private: private:
void updateQmlSourceUrl(); void updateQmlSourceUrl();
QSharedPointer<OffscreenQmlSurface> _webSurface; OffscreenQmlSurface* _webSurface;
QMetaObject::Connection _connection; QMetaObject::Connection _connection;
uint32_t _texture{ 0 }; uint32_t _texture{ 0 };
QMutex _textureLock;
}; };