Ensure we actually delete the QML scenegraph!

This commit is contained in:
Brad Davis 2018-04-27 15:08:10 -07:00
parent 5f8149fd68
commit 575520fe30
3 changed files with 78 additions and 28 deletions

View file

@ -90,14 +90,17 @@ SharedObject::~SharedObject() {
_renderControl = nullptr; _renderControl = nullptr;
} }
if (_rootItem) {
delete _rootItem;
_rootItem = nullptr;
}
if (_quickWindow) { if (_quickWindow) {
_quickWindow->destroy(); _quickWindow->destroy();
delete _quickWindow; delete _quickWindow;
_quickWindow = nullptr; _quickWindow = nullptr;
} }
// _rootItem is parented to the quickWindow, so needs no explicit destruction
if (_qmlContext) { if (_qmlContext) {
auto engine = _qmlContext->engine(); auto engine = _qmlContext->engine();
delete _qmlContext; delete _qmlContext;

View file

@ -10,6 +10,21 @@
import QtQuick 2.5 import QtQuick 2.5
import QtWebEngine 1.5 import QtWebEngine 1.5
import Hifi 1.0
/*
TestItem {
Rectangle {
anchors.fill: parent
anchors.margins: 10
color: "blue"
property string url: ""
ColorAnimation on color {
loops: Animation.Infinite; from: "blue"; to: "yellow"; duration: 1000
}
}
}
*/
WebEngineView { WebEngineView {
id: webViewCore id: webViewCore

View file

@ -48,6 +48,17 @@ namespace gl {
extern void initModuleGl(); extern void initModuleGl();
} }
class QTestItem : public QQuickItem {
Q_OBJECT
public:
QTestItem(QQuickItem* parent = nullptr) : QQuickItem(parent) {
qDebug() << __FUNCTION__;
}
~QTestItem() {
qDebug() << __FUNCTION__;
}
};
QUrl getTestResource(const QString& relativePath) { QUrl getTestResource(const QString& relativePath) {
static QString dir; static QString dir;
@ -89,9 +100,10 @@ private:
GLuint _fbo{ 0 }; GLuint _fbo{ 0 };
const QSize _qmlSize{ 640, 480 }; const QSize _qmlSize{ 640, 480 };
bool _aboutToQuit{ false }; bool _aboutToQuit{ false };
uint64_t _createStopTime;
void initGl(); void initGl();
void updateSurfaces(); void updateSurfaces();
void buildSurface(QmlInfo& qmlInfo); void buildSurface(QmlInfo& qmlInfo, bool allowVideo);
void destroySurface(QmlInfo& qmlInfo); void destroySurface(QmlInfo& qmlInfo);
void resizeWindow(const QSize& size); void resizeWindow(const QSize& size);
void draw(); void draw();
@ -111,8 +123,10 @@ TestWindow::TestWindow() {
QSurfaceFormat::setDefaultFormat(format); QSurfaceFormat::setDefaultFormat(format);
setFormat(format); setFormat(format);
show(); qmlRegisterType<QTestItem>("Hifi", 1, 0, "TestItem");
show();
_createStopTime = usecTimestampNow() + (3000u * USECS_PER_SECOND);
resize(QSize(800, 600)); resize(QSize(800, 600));
@ -167,40 +181,56 @@ QString getSourceUrl() {
return SOURCE_URLS[index]; return SOURCE_URLS[index];
} }
#define CACHE_WEBVIEWS 0
#if CACHE_WEBVIEWS
static std::list<QmlPtr> _cache;
#endif
void TestWindow::buildSurface(QmlInfo& qmlInfo) { hifi::qml::QmlContextObjectCallback callback = [](QQmlContext* context, QQuickItem* item) {
item->setProperty(URL_PROPERTY, getSourceUrl());
};
void TestWindow::buildSurface(QmlInfo& qmlInfo, bool allowVideo) {
++_surfaceCount; ++_surfaceCount;
auto lifetimeSecs = (uint32_t)(2.0f + (randFloat() * 10.0f)); auto lifetimeSecs = (uint32_t)(5.0f + (randFloat() * 10.0f));
auto lifetimeUsecs = (USECS_PER_SECOND * lifetimeSecs); auto lifetimeUsecs = (USECS_PER_SECOND * lifetimeSecs);
qmlInfo.lifetime = lifetimeUsecs + usecTimestampNow(); qmlInfo.lifetime = lifetimeUsecs + usecTimestampNow();
qmlInfo.texture = 0; qmlInfo.texture = 0;
auto& surface = qmlInfo.surface; #if CACHE_WEBVIEWS
surface.reset(new hifi::qml::OffscreenSurface()); if (_cache.empty()) {
_cache.emplace_back(new hifi::qml::OffscreenSurface());
auto& surface = _cache.back();
surface->load(getTestResource(CONTROL_URL));
surface->setMaxFps(DEFAULT_MAX_FPS); surface->setMaxFps(DEFAULT_MAX_FPS);
surface->resize(_qmlSize); }
surface->setMaxFps(DEFAULT_MAX_FPS); qmlInfo.surface = _cache.front();
hifi::qml::QmlContextObjectCallback callback = [](QQmlContext* context, QQuickItem* item) { _cache.pop_front();
item->setProperty(URL_PROPERTY, getSourceUrl()); #else
}; qmlInfo.surface.reset(new hifi::qml::OffscreenSurface());
surface->load(getTestResource(CONTROL_URL), callback); qmlInfo.surface->load(getTestResource(CONTROL_URL));
surface->resume(); qmlInfo.surface->setMaxFps(DEFAULT_MAX_FPS);
#endif
qmlInfo.surface->resize(_qmlSize);
auto url = allowVideo ? "https://www.youtube.com/watch?v=gDXwhHm4GhM" : getSourceUrl();
qmlInfo.surface->getRootItem()->setProperty(URL_PROPERTY, url);
qmlInfo.surface->resume();
} }
void TestWindow::destroySurface(QmlInfo& qmlInfo) { void TestWindow::destroySurface(QmlInfo& qmlInfo) {
auto& surface = qmlInfo.surface; auto& surface = qmlInfo.surface;
QQuickItem* rootItem = surface->getRootItem(); auto webView = surface->getRootItem();
if (rootItem) { if (webView) {
QObject* obj = rootItem->findChild<QObject*>("webEngineView");
if (!obj && rootItem->objectName() == "webEngineView") {
obj = rootItem;
}
if (obj) {
// stop loading // stop loading
QMetaObject::invokeMethod(obj, "stop"); QMetaObject::invokeMethod(webView, "stop");
} webView->setProperty(URL_PROPERTY, "about:blank");
} }
surface->pause(); surface->pause();
#if CACHE_WEBVIEWS
_cache.push_back(surface);
#endif
surface.reset(); surface.reset();
} }
@ -211,8 +241,8 @@ void TestWindow::updateSurfaces() {
for (size_t y = 0; y < DIVISIONS_Y; ++y) { for (size_t y = 0; y < DIVISIONS_Y; ++y) {
auto& qmlInfo = _surfaces[x][y]; auto& qmlInfo = _surfaces[x][y];
if (!qmlInfo.surface) { if (!qmlInfo.surface) {
if (randFloat() > 0.99f) { if (now < _createStopTime && randFloat() > 0.99f) {
buildSurface(qmlInfo); buildSurface(qmlInfo, x == 0 && y == 0);
} else { } else {
continue; continue;
} }
@ -298,3 +328,5 @@ int main(int argc, char** argv) {
app.exec(); app.exec();
return 0; return 0;
} }
#include "main.moc"