forked from qt-creator/qt-creator
QmdDesigner: Enable rendering single items again for render puppet
Change the form editor rendering to be done by item basis instead of just rendering the entire scene (unified rendering). Fixes: QDS-2933 Change-Id: I999cbc834791bc6e96334eab8273d97e4f58975f Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io> Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
@@ -218,6 +218,7 @@ public:
|
|||||||
virtual void handleInstanceHidden(const ServerNodeInstance &instance, bool enable, bool checkAncestors);
|
virtual void handleInstanceHidden(const ServerNodeInstance &instance, bool enable, bool checkAncestors);
|
||||||
|
|
||||||
virtual QImage grabWindow() = 0;
|
virtual QImage grabWindow() = 0;
|
||||||
|
virtual QImage grabItem(QQuickItem *item) = 0;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void refreshLocalFileProperty(const QString &path);
|
void refreshLocalFileProperty(const QString &path);
|
||||||
|
@@ -761,7 +761,8 @@ void Qt5InformationNodeInstanceServer::updateNodesRecursive(QQuickItem *item)
|
|||||||
const auto childItems = item->childItems();
|
const auto childItems = item->childItems();
|
||||||
for (QQuickItem *childItem : childItems)
|
for (QQuickItem *childItem : childItems)
|
||||||
updateNodesRecursive(childItem);
|
updateNodesRecursive(childItem);
|
||||||
if (Internal::QuickItemNodeInstance::unifiedRenderPath()) {
|
|
||||||
|
if (Internal::QuickItemNodeInstance::unifiedRenderPathOrQt6()) {
|
||||||
if (item->flags() & QQuickItem::ItemHasContents)
|
if (item->flags() & QQuickItem::ItemHasContents)
|
||||||
item->update();
|
item->update();
|
||||||
} else {
|
} else {
|
||||||
@@ -773,7 +774,7 @@ QQuickItem *Qt5InformationNodeInstanceServer::getContentItemForRendering(QQuickI
|
|||||||
{
|
{
|
||||||
QQuickItem *contentItem = QQmlProperty::read(rootItem, "contentItem").value<QQuickItem *>();
|
QQuickItem *contentItem = QQmlProperty::read(rootItem, "contentItem").value<QQuickItem *>();
|
||||||
if (contentItem) {
|
if (contentItem) {
|
||||||
if (!Internal::QuickItemNodeInstance::unifiedRenderPath())
|
if (!Internal::QuickItemNodeInstance::unifiedRenderPathOrQt6())
|
||||||
designerSupport()->refFromEffectItem(contentItem, false);
|
designerSupport()->refFromEffectItem(contentItem, false);
|
||||||
QmlDesigner::Internal::QmlPrivateGate::disableNativeTextRendering(contentItem);
|
QmlDesigner::Internal::QmlPrivateGate::disableNativeTextRendering(contentItem);
|
||||||
}
|
}
|
||||||
@@ -899,7 +900,7 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView()
|
|||||||
instanceObj = instance.internalObject();
|
instanceObj = instance.internalObject();
|
||||||
}
|
}
|
||||||
QSize renderSize = m_modelNodePreviewImageCommand.size();
|
QSize renderSize = m_modelNodePreviewImageCommand.size();
|
||||||
if (Internal::QuickItemNodeInstance::unifiedRenderPath()) {
|
if (Internal::QuickItemNodeInstance::unifiedRenderPathOrQt6()) {
|
||||||
// Requested size is already adjusted for target pixel ratio, so we have to adjust
|
// Requested size is already adjusted for target pixel ratio, so we have to adjust
|
||||||
// back if ratio is not default for our window.
|
// back if ratio is not default for our window.
|
||||||
double ratio = m_modelNode3DImageViewData.window->devicePixelRatio();
|
double ratio = m_modelNode3DImageViewData.window->devicePixelRatio();
|
||||||
@@ -1106,7 +1107,7 @@ Qt5InformationNodeInstanceServer::~Qt5InformationNodeInstanceServer()
|
|||||||
if (m_editView3DData.rootItem)
|
if (m_editView3DData.rootItem)
|
||||||
QMetaObject::invokeMethod(m_editView3DData.rootItem, "aboutToShutDown", Qt::DirectConnection);
|
QMetaObject::invokeMethod(m_editView3DData.rootItem, "aboutToShutDown", Qt::DirectConnection);
|
||||||
|
|
||||||
if (!Internal::QuickItemNodeInstance::unifiedRenderPath()) {
|
if (!Internal::QuickItemNodeInstance::unifiedRenderPathOrQt6()) {
|
||||||
if (m_editView3DData.contentItem)
|
if (m_editView3DData.contentItem)
|
||||||
designerSupport()->derefFromEffectItem(m_editView3DData.contentItem);
|
designerSupport()->derefFromEffectItem(m_editView3DData.contentItem);
|
||||||
if (m_modelNode3DImageViewData.contentItem)
|
if (m_modelNode3DImageViewData.contentItem)
|
||||||
|
@@ -64,11 +64,11 @@ Qt5NodeInstanceClientProxy::Qt5NodeInstanceClientProxy(QObject *parent) :
|
|||||||
const bool qt6 = true;
|
const bool qt6 = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const bool unifiedRenderPath = qt6 || qEnvironmentVariableIsSet("QMLPUPPET_UNIFIED_RENDER_PATH");
|
const bool unifiedRenderPath = qEnvironmentVariableIsSet("QMLPUPPET_UNIFIED_RENDER_PATH");
|
||||||
|
|
||||||
if (unifiedRenderPath)
|
if (unifiedRenderPath)
|
||||||
Internal::QuickItemNodeInstance::enableUnifiedRenderPath(true);
|
Internal::QuickItemNodeInstance::enableUnifiedRenderPath(true);
|
||||||
else
|
else if (!qt6)
|
||||||
DesignerSupport::activateDesignerWindowManager();
|
DesignerSupport::activateDesignerWindowManager();
|
||||||
|
|
||||||
if (QCoreApplication::arguments().at(1) == QLatin1String("--readcapturedstream")) {
|
if (QCoreApplication::arguments().at(1) == QLatin1String("--readcapturedstream")) {
|
||||||
|
@@ -44,10 +44,13 @@
|
|||||||
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
#include <QtGui/private/qrhi_p.h>
|
#include <QtGui/private/qrhi_p.h>
|
||||||
#include <QtQuick/private/qquickwindow_p.h>
|
#include <QtQuick/private/qquickitem_p.h>
|
||||||
#include <QtQuick/private/qsgrenderer_p.h>
|
|
||||||
#include <QtQuick/private/qquickrendercontrol_p.h>
|
#include <QtQuick/private/qquickrendercontrol_p.h>
|
||||||
#include <QtQuick/private/qquickrendertarget_p.h>
|
#include <QtQuick/private/qquickrendertarget_p.h>
|
||||||
|
#include <QtQuick/private/qquickwindow_p.h>
|
||||||
|
#include <QtQuick/private/qsgcontext_p.h>
|
||||||
|
#include <QtQuick/private/qsgrenderer_p.h>
|
||||||
|
#include <QtQuick/private/qsgrhilayer_p.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
@@ -332,6 +335,80 @@ QImage Qt5NodeInstanceServer::grabWindow()
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QImage Qt5NodeInstanceServer::grabItem(QQuickItem *item)
|
||||||
|
{
|
||||||
|
QImage renderImage;
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
if (!m_viewData.rootItem || (m_viewData.bufferDirty && !initRhi(m_viewData)))
|
||||||
|
return {};
|
||||||
|
|
||||||
|
QQuickItemPrivate *pItem = QQuickItemPrivate::get(item);
|
||||||
|
pItem->refFromEffectItem(false);
|
||||||
|
|
||||||
|
ServerNodeInstance instance = instanceForObject(item);
|
||||||
|
const auto childInstances = instance.childItems();
|
||||||
|
|
||||||
|
// Hide immediate children that have instances and are QQuickItems so we get only
|
||||||
|
// the parent item's content, as compositing is handled on creator side.
|
||||||
|
for (const auto &childInstance : childInstances) {
|
||||||
|
QQuickItem *childItem = qobject_cast<QQuickItem *>(childInstance.internalObject());
|
||||||
|
if (childItem) {
|
||||||
|
QQuickItemPrivate *pChild = QQuickItemPrivate::get(childItem);
|
||||||
|
pChild->refFromEffectItem(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_viewData.renderControl->polishItems();
|
||||||
|
m_viewData.renderControl->beginFrame();
|
||||||
|
m_viewData.renderControl->sync();
|
||||||
|
|
||||||
|
// Connection to afterRendering is necessary, as this needs to be done before
|
||||||
|
// call to endNextRhiFrame which happens inside QQuickRenderControl::render()
|
||||||
|
QMetaObject::Connection connection = QObject::connect(m_viewData.window.data(),
|
||||||
|
&QQuickWindow::afterRendering,
|
||||||
|
this, [&]() {
|
||||||
|
// To get only the single item, we need to make a layer out of it, which enables
|
||||||
|
// us to render it to a texture that we can grab to an image.
|
||||||
|
QSGRenderContext *rc = QQuickWindowPrivate::get(m_viewData.window.data())->context;
|
||||||
|
QSGLayer *layer = rc->sceneGraphContext()->createLayer(rc);
|
||||||
|
layer->setItem(pItem->itemNode());
|
||||||
|
QSizeF itemSize = QSizeF(item->width(), item->height());
|
||||||
|
layer->setRect(QRectF(0, itemSize.height(), itemSize.width(), -itemSize.height()));
|
||||||
|
const QSize minSize = rc->sceneGraphContext()->minimumFBOSize();
|
||||||
|
layer->setSize(QSize(qMax(minSize.width(), int(itemSize.width())),
|
||||||
|
qMax(minSize.height(), int(itemSize.height()))));
|
||||||
|
layer->scheduleUpdate();
|
||||||
|
|
||||||
|
if (layer->updateTexture())
|
||||||
|
renderImage = layer->toImage();
|
||||||
|
else
|
||||||
|
qWarning() << __FUNCTION__ << "Failed to update layer texture";
|
||||||
|
|
||||||
|
delete layer;
|
||||||
|
layer = nullptr;
|
||||||
|
});
|
||||||
|
|
||||||
|
m_viewData.renderControl->render();
|
||||||
|
|
||||||
|
QObject::disconnect(connection);
|
||||||
|
|
||||||
|
m_viewData.renderControl->endFrame();
|
||||||
|
|
||||||
|
// Restore visibility of immediate children that have instances and are QQuickItems
|
||||||
|
for (const auto &childInstance : childInstances) {
|
||||||
|
QQuickItem *childItem = qobject_cast<QQuickItem *>(childInstance.internalObject());
|
||||||
|
if (childItem) {
|
||||||
|
QQuickItemPrivate *pChild = QQuickItemPrivate::get(childItem);
|
||||||
|
pChild->derefFromEffectItem(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pItem->derefFromEffectItem(false);
|
||||||
|
#else
|
||||||
|
Q_UNUSED(item)
|
||||||
|
#endif
|
||||||
|
return renderImage;
|
||||||
|
}
|
||||||
|
|
||||||
void Qt5NodeInstanceServer::refreshBindings()
|
void Qt5NodeInstanceServer::refreshBindings()
|
||||||
{
|
{
|
||||||
DesignerSupport::refreshExpressions(context());
|
DesignerSupport::refreshExpressions(context());
|
||||||
|
@@ -69,6 +69,7 @@ public:
|
|||||||
void reparentInstances(const ReparentInstancesCommand &command) override;
|
void reparentInstances(const ReparentInstancesCommand &command) override;
|
||||||
|
|
||||||
QImage grabWindow() override;
|
QImage grabWindow() override;
|
||||||
|
QImage grabItem(QQuickItem *item) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void initializeView() override;
|
void initializeView() override;
|
||||||
|
@@ -102,9 +102,6 @@ void Qt5RenderNodeInstanceServer::collectItemChangesAndSendChangeCommands()
|
|||||||
clearChangedPropertyList();
|
clearChangedPropertyList();
|
||||||
|
|
||||||
if (Internal::QuickItemNodeInstance::unifiedRenderPath()) {
|
if (Internal::QuickItemNodeInstance::unifiedRenderPath()) {
|
||||||
/* QQuickItem::grabToImage render path */
|
|
||||||
/* TODO implement QQuickItem::grabToImage based rendering */
|
|
||||||
/* sheduleRootItemRender(); */
|
|
||||||
if (windowDirty)
|
if (windowDirty)
|
||||||
nodeInstanceClient()->pixmapChanged(createPixmapChangedCommand({rootNodeInstance()}));
|
nodeInstanceClient()->pixmapChanged(createPixmapChangedCommand({rootNodeInstance()}));
|
||||||
} else {
|
} else {
|
||||||
|
@@ -171,10 +171,15 @@ void QuickItemNodeInstance::enableUnifiedRenderPath(bool unifiedRenderPath)
|
|||||||
|
|
||||||
bool QuickItemNodeInstance::checkIfRefFromEffect(qint32 id)
|
bool QuickItemNodeInstance::checkIfRefFromEffect(qint32 id)
|
||||||
{
|
{
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||||
if (s_unifiedRenderPath)
|
if (s_unifiedRenderPath)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return (s_createEffectItem || id == 0);
|
return (s_createEffectItem || id == 0);
|
||||||
|
#else
|
||||||
|
Q_UNUSED(id)
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuickItemNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNodeInstance,
|
void QuickItemNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNodeInstance,
|
||||||
@@ -267,9 +272,13 @@ QStringList QuickItemNodeInstance::allStates() const
|
|||||||
|
|
||||||
void QuickItemNodeInstance::updateDirtyNode(QQuickItem *item)
|
void QuickItemNodeInstance::updateDirtyNode(QQuickItem *item)
|
||||||
{
|
{
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||||
if (s_unifiedRenderPath)
|
if (s_unifiedRenderPath)
|
||||||
return;
|
return;
|
||||||
DesignerSupport::updateDirtyNode(item);
|
DesignerSupport::updateDirtyNode(item);
|
||||||
|
#else
|
||||||
|
Q_UNUSED(item)
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QuickItemNodeInstance::unifiedRenderPath()
|
bool QuickItemNodeInstance::unifiedRenderPath()
|
||||||
@@ -277,6 +286,15 @@ bool QuickItemNodeInstance::unifiedRenderPath()
|
|||||||
return s_unifiedRenderPath;
|
return s_unifiedRenderPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QuickItemNodeInstance::unifiedRenderPathOrQt6()
|
||||||
|
{
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return s_unifiedRenderPath;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
QRectF QuickItemNodeInstance::contentItemBoundingBox() const
|
QRectF QuickItemNodeInstance::contentItemBoundingBox() const
|
||||||
{
|
{
|
||||||
if (contentItem()) {
|
if (contentItem()) {
|
||||||
@@ -415,16 +433,15 @@ QImage QuickItemNodeInstance::renderImage() const
|
|||||||
updateDirtyNodesRecursive(quickItem());
|
updateDirtyNodesRecursive(quickItem());
|
||||||
|
|
||||||
QRectF renderBoundingRect = boundingRect();
|
QRectF renderBoundingRect = boundingRect();
|
||||||
|
QImage renderImage;
|
||||||
|
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||||
QSize size = renderBoundingRect.size().toSize();
|
QSize size = renderBoundingRect.size().toSize();
|
||||||
static double devicePixelRatio = qgetenv("FORMEDITOR_DEVICE_PIXEL_RATIO").toDouble();
|
static double devicePixelRatio = qgetenv("FORMEDITOR_DEVICE_PIXEL_RATIO").toDouble();
|
||||||
if (size.width() * size.height() > 4000 * 4000)
|
if (size.width() * size.height() > 4000 * 4000)
|
||||||
size = QSize(0,0);
|
size = QSize(0,0);
|
||||||
size *= devicePixelRatio;
|
size *= devicePixelRatio;
|
||||||
|
|
||||||
QImage renderImage;
|
|
||||||
|
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
|
||||||
if (s_unifiedRenderPath) {
|
if (s_unifiedRenderPath) {
|
||||||
renderImage = nodeInstanceServer()->quickWindow()->grabWindow();
|
renderImage = nodeInstanceServer()->quickWindow()->grabWindow();
|
||||||
} else {
|
} else {
|
||||||
@@ -438,8 +455,12 @@ QImage QuickItemNodeInstance::renderImage() const
|
|||||||
}
|
}
|
||||||
renderImage.setDevicePixelRatio(devicePixelRatio);
|
renderImage.setDevicePixelRatio(devicePixelRatio);
|
||||||
#else
|
#else
|
||||||
|
if (s_unifiedRenderPath)
|
||||||
renderImage = nodeInstanceServer()->grabWindow();
|
renderImage = nodeInstanceServer()->grabWindow();
|
||||||
|
else
|
||||||
|
renderImage = nodeInstanceServer()->grabItem(quickItem());
|
||||||
renderImage = renderImage.copy(renderBoundingRect.toRect());
|
renderImage = renderImage.copy(renderBoundingRect.toRect());
|
||||||
|
|
||||||
/* When grabbing an offscren window the device pixel ratio is 1 */
|
/* When grabbing an offscren window the device pixel ratio is 1 */
|
||||||
renderImage.setDevicePixelRatio(1);
|
renderImage.setDevicePixelRatio(1);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -104,6 +104,7 @@ public:
|
|||||||
|
|
||||||
static void updateDirtyNode(QQuickItem *item);
|
static void updateDirtyNode(QQuickItem *item);
|
||||||
static bool unifiedRenderPath();
|
static bool unifiedRenderPath();
|
||||||
|
static bool unifiedRenderPathOrQt6();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit QuickItemNodeInstance(QQuickItem*);
|
explicit QuickItemNodeInstance(QQuickItem*);
|
||||||
|
Reference in New Issue
Block a user