aboutsummaryrefslogtreecommitdiffstats
path: root/share/qtcreator/qml/qmlpuppet/qml2puppet/iconrenderer/iconrenderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'share/qtcreator/qml/qmlpuppet/qml2puppet/iconrenderer/iconrenderer.cpp')
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/iconrenderer/iconrenderer.cpp176
1 files changed, 120 insertions, 56 deletions
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/iconrenderer/iconrenderer.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/iconrenderer/iconrenderer.cpp
index a54373f983..d3dc35f221 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/iconrenderer/iconrenderer.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/iconrenderer/iconrenderer.cpp
@@ -45,6 +45,12 @@
#include <QtQuick3D/private/qquick3dviewport_p.h>
#endif
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+#include <QtGui/private/qrhi_p.h>
+#include <QtQuick/private/qquickrendercontrol_p.h>
+#include <QtQuick/private/qquickrendertarget_p.h>
+#endif
+
#include <private/qquickdesignersupportitems_p.h>
IconRenderer::IconRenderer(int size, const QString &filePath, const QString &source)
@@ -62,23 +68,26 @@ void IconRenderer::setupRender()
DesignerSupport::activateDesignerWindowManager();
#endif
- m_quickView = new QQuickView;
-
+ QQmlEngine *engine = nullptr;
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- QSurfaceFormat surfaceFormat = m_quickView->requestedFormat();
+ auto view = new QQuickView;
+ engine = view->engine();
+ m_window = view;
+ QSurfaceFormat surfaceFormat = view->requestedFormat();
surfaceFormat.setVersion(4, 1);
surfaceFormat.setProfile(QSurfaceFormat::CoreProfile);
- m_quickView->setFormat(surfaceFormat);
-
- DesignerSupport::createOpenGLContext(m_quickView);
+ view->setFormat(surfaceFormat);
+ DesignerSupport::createOpenGLContext(view);
#else
- m_quickView->setDefaultAlphaBuffer(true);
- m_quickView->setColor(Qt::transparent);
- m_ratio = m_quickView->devicePixelRatio();
- m_quickView->installEventFilter(this);
+ engine = new QQmlEngine;
+ m_renderControl = new QQuickRenderControl;
+ m_window = new QQuickWindow(m_renderControl);
+ m_window->setDefaultAlphaBuffer(true);
+ m_window->setColor(Qt::transparent);
+ m_renderControl->initialize();
#endif
- QQmlComponent component(m_quickView->engine());
+ QQmlComponent component(engine);
component.loadUrl(QUrl::fromLocalFile(m_source));
QObject *iconItem = component.create();
@@ -86,13 +95,19 @@ void IconRenderer::setupRender()
#ifdef QUICK3D_MODULE
if (auto scene = qobject_cast<QQuick3DNode *>(iconItem)) {
qmlRegisterType<QmlDesigner::Internal::SelectionBoxGeometry>("SelectionBoxGeometry", 1, 0, "SelectionBoxGeometry");
- QQmlComponent component(m_quickView->engine());
+ QQmlComponent component(engine);
component.loadUrl(QUrl("qrc:/qtquickplugin/mockfiles/IconRenderer3D.qml"));
m_containerItem = qobject_cast<QQuickItem *>(component.create());
- DesignerSupport::setRootItem(m_quickView, m_containerItem);
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ DesignerSupport::setRootItem(view, m_containerItem);
+#else
+ m_window->contentItem()->setSize(m_containerItem->size());
+ m_window->setGeometry(0, 0, m_containerItem->width(), m_containerItem->height());
+ m_containerItem->setParentItem(m_window->contentItem());
+#endif
auto helper = new QmlDesigner::Internal::GeneralHelper();
- m_quickView->engine()->rootContext()->setContextProperty("_generalHelper", helper);
+ engine->rootContext()->setContextProperty("_generalHelper", helper);
m_contentItem = QQmlProperty::read(m_containerItem, "view3D").value<QQuickItem *>();
auto view3D = qobject_cast<QQuick3DViewport *>(m_contentItem);
@@ -104,21 +119,21 @@ void IconRenderer::setupRender()
m_contentItem = scene;
m_containerItem = new QQuickItem();
m_containerItem->setSize(QSizeF(1024, 1024));
- DesignerSupport::setRootItem(m_quickView, m_containerItem);
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ DesignerSupport::setRootItem(view, m_containerItem);
+#else
+ m_window->contentItem()->setSize(m_containerItem->size());
+ m_window->setGeometry(0, 0, m_containerItem->width(), m_containerItem->height());
+ m_containerItem->setParentItem(m_window->contentItem());
+#endif
m_contentItem->setParentItem(m_containerItem);
}
if (m_containerItem && m_contentItem) {
resizeContent(m_size);
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ if (!initRhi())
+ QTimer::singleShot(0, qGuiApp, &QGuiApplication::quit);
QTimer::singleShot(0, this, &IconRenderer::createIcon);
-#else
- m_quickView->show();
- m_quickView->lower();
-
- // Failsafe to exit eventually if window fails to expose
- QTimer::singleShot(10000, qGuiApp, &QGuiApplication::quit);
-#endif
} else {
QTimer::singleShot(0, qGuiApp, &QGuiApplication::quit);
}
@@ -127,25 +142,12 @@ void IconRenderer::setupRender()
}
}
-bool IconRenderer::eventFilter(QObject *watched, QEvent *event)
-{
-#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
- if (watched == m_quickView && event->type() == QEvent::Expose)
- QTimer::singleShot(0, this, &IconRenderer::createIcon);
-#else
- Q_UNUSED(watched)
- Q_UNUSED(event)
-#endif
- return false;
-}
-
void IconRenderer::createIcon()
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- m_designerSupport.refFromEffectItem(m_quickView->rootObject(), false);
+ m_designerSupport.refFromEffectItem(m_containerItem, false);
#endif
- QQuickDesignerSupportItems::disableNativeTextRendering(m_quickView->rootObject());
-
+ QQuickDesignerSupportItems::disableNativeTextRendering(m_containerItem);
#ifdef QUICK3D_MODULE
if (m_is3D) {
// Render once to make sure scene is up to date before we set up the selection box
@@ -166,6 +168,8 @@ void IconRenderer::createIcon()
// Render @2x image
resizeContent(m_size * 2);
+ if (!initRhi())
+ QTimer::singleShot(1000, qGuiApp, &QGuiApplication::quit);
QString saveFile;
saveFile = fi.absolutePath() + '/' + fi.completeBaseName() + "@2x";
@@ -194,23 +198,39 @@ void IconRenderer::render(const QString &fileName)
item->update();
#endif
};
- updateNodesRecursive(m_quickView->rootObject());
+ updateNodesRecursive(m_containerItem);
QRect rect(QPoint(), m_contentItem->size().toSize());
+ QImage renderImage;
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- QImage renderImage = m_designerSupport.renderImageForItem(m_quickView->rootObject(),
- rect, rect.size());
+ renderImage = m_designerSupport.renderImageForItem(m_containerItem, rect, rect.size());
#else
- QImage renderImage = m_quickView->grabWindow();
+ m_renderControl->polishItems();
+ m_renderControl->beginFrame();
+ m_renderControl->sync();
+ m_renderControl->render();
+
+ bool readCompleted = false;
+ QRhiReadbackResult readResult;
+ readResult.completed = [&] {
+ readCompleted = true;
+ QImage wrapperImage(reinterpret_cast<const uchar *>(readResult.data.constData()),
+ readResult.pixelSize.width(), readResult.pixelSize.height(),
+ QImage::Format_RGBA8888_Premultiplied);
+ if (m_rhi->isYUpInFramebuffer())
+ renderImage = wrapperImage.mirrored().copy(0, 0, rect.width(), rect.height());
+ else
+ renderImage = wrapperImage.copy(0, 0, rect.width(), rect.height());
+ };
+ QRhiResourceUpdateBatch *readbackBatch = m_rhi->nextResourceUpdateBatch();
+ readbackBatch->readBackTexture(m_texture, &readResult);
+
+ QQuickRenderControlPrivate *rd = QQuickRenderControlPrivate::get(m_renderControl);
+ rd->cb->resourceUpdate(readbackBatch);
+
+ m_renderControl->endFrame();
#endif
if (!fileName.isEmpty()) {
-#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
- if (m_ratio != 1.) {
- rect.setWidth(qRound(rect.size().width() * m_ratio));
- rect.setHeight(qRound(rect.size().height() * m_ratio));
- }
- renderImage = renderImage.copy(rect);
-#endif
QFileInfo fi(fileName);
if (fi.suffix().isEmpty())
renderImage.save(fileName, "PNG");
@@ -219,16 +239,60 @@ void IconRenderer::render(const QString &fileName)
}
}
-void IconRenderer::resizeContent(int size)
+void IconRenderer::resizeContent(int dimensions)
{
- int theSize = size;
-#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
- if (m_ratio != 1.)
- theSize = qRound(qreal(size) / m_quickView->devicePixelRatio());
-#endif
- m_contentItem->setSize(QSizeF(theSize, theSize));
+ QSizeF size(dimensions, dimensions);
+ m_contentItem->setSize(size);
if (m_contentItem->width() > m_containerItem->width())
m_containerItem->setWidth(m_contentItem->width());
if (m_contentItem->height() > m_containerItem->height())
m_containerItem->setHeight(m_contentItem->height());
}
+
+bool IconRenderer::initRhi()
+{
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ if (!m_rhi) {
+ QQuickRenderControlPrivate *rd = QQuickRenderControlPrivate::get(m_renderControl);
+ m_rhi = rd->rhi;
+ if (!m_rhi) {
+ qWarning() << __FUNCTION__ << "Rhi is null";
+ return false;
+ }
+ }
+
+ // Don't bother deleting old ones as iconrender is a single shot executable
+ m_texTarget = nullptr;
+ m_rpDesc = nullptr;
+ m_buffer = nullptr;
+ m_texture = nullptr;
+
+ const QSize size = m_containerItem->size().toSize();
+ m_texture = m_rhi->newTexture(QRhiTexture::RGBA8, size, 1,
+ QRhiTexture::RenderTarget | QRhiTexture::UsedAsTransferSource);
+ if (!m_texture->create()) {
+ qWarning() << __FUNCTION__ << "QRhiTexture creation failed";
+ return false;
+ }
+
+ m_buffer = m_rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil, size, 1);
+ if (!m_buffer->create()) {
+ qWarning() << __FUNCTION__ << "Depth/stencil buffer creation failed";
+ return false;
+ }
+
+ QRhiTextureRenderTargetDescription rtDesc {QRhiColorAttachment(m_texture)};
+ rtDesc.setDepthStencilBuffer(m_buffer);
+ m_texTarget = m_rhi->newTextureRenderTarget(rtDesc);
+ m_rpDesc = m_texTarget->newCompatibleRenderPassDescriptor();
+ m_texTarget->setRenderPassDescriptor(m_rpDesc);
+ if (!m_texTarget->create()) {
+ qWarning() << __FUNCTION__ << "Texture render target creation failed";
+ return false;
+ }
+
+ // redirect Qt Quick rendering into our texture
+ m_window->setRenderTarget(QQuickRenderTarget::fromRhiRenderTarget(m_texTarget));
+#endif
+ return true;
+}