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 QImage grabWindow() = 0;
|
||||
virtual QImage grabItem(QQuickItem *item) = 0;
|
||||
|
||||
public slots:
|
||||
void refreshLocalFileProperty(const QString &path);
|
||||
|
@@ -761,7 +761,8 @@ void Qt5InformationNodeInstanceServer::updateNodesRecursive(QQuickItem *item)
|
||||
const auto childItems = item->childItems();
|
||||
for (QQuickItem *childItem : childItems)
|
||||
updateNodesRecursive(childItem);
|
||||
if (Internal::QuickItemNodeInstance::unifiedRenderPath()) {
|
||||
|
||||
if (Internal::QuickItemNodeInstance::unifiedRenderPathOrQt6()) {
|
||||
if (item->flags() & QQuickItem::ItemHasContents)
|
||||
item->update();
|
||||
} else {
|
||||
@@ -773,7 +774,7 @@ QQuickItem *Qt5InformationNodeInstanceServer::getContentItemForRendering(QQuickI
|
||||
{
|
||||
QQuickItem *contentItem = QQmlProperty::read(rootItem, "contentItem").value<QQuickItem *>();
|
||||
if (contentItem) {
|
||||
if (!Internal::QuickItemNodeInstance::unifiedRenderPath())
|
||||
if (!Internal::QuickItemNodeInstance::unifiedRenderPathOrQt6())
|
||||
designerSupport()->refFromEffectItem(contentItem, false);
|
||||
QmlDesigner::Internal::QmlPrivateGate::disableNativeTextRendering(contentItem);
|
||||
}
|
||||
@@ -899,7 +900,7 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView()
|
||||
instanceObj = instance.internalObject();
|
||||
}
|
||||
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
|
||||
// back if ratio is not default for our window.
|
||||
double ratio = m_modelNode3DImageViewData.window->devicePixelRatio();
|
||||
@@ -1106,7 +1107,7 @@ Qt5InformationNodeInstanceServer::~Qt5InformationNodeInstanceServer()
|
||||
if (m_editView3DData.rootItem)
|
||||
QMetaObject::invokeMethod(m_editView3DData.rootItem, "aboutToShutDown", Qt::DirectConnection);
|
||||
|
||||
if (!Internal::QuickItemNodeInstance::unifiedRenderPath()) {
|
||||
if (!Internal::QuickItemNodeInstance::unifiedRenderPathOrQt6()) {
|
||||
if (m_editView3DData.contentItem)
|
||||
designerSupport()->derefFromEffectItem(m_editView3DData.contentItem);
|
||||
if (m_modelNode3DImageViewData.contentItem)
|
||||
|
@@ -64,11 +64,11 @@ Qt5NodeInstanceClientProxy::Qt5NodeInstanceClientProxy(QObject *parent) :
|
||||
const bool qt6 = true;
|
||||
#endif
|
||||
|
||||
const bool unifiedRenderPath = qt6 || qEnvironmentVariableIsSet("QMLPUPPET_UNIFIED_RENDER_PATH");
|
||||
const bool unifiedRenderPath = qEnvironmentVariableIsSet("QMLPUPPET_UNIFIED_RENDER_PATH");
|
||||
|
||||
if (unifiedRenderPath)
|
||||
Internal::QuickItemNodeInstance::enableUnifiedRenderPath(true);
|
||||
else
|
||||
else if (!qt6)
|
||||
DesignerSupport::activateDesignerWindowManager();
|
||||
|
||||
if (QCoreApplication::arguments().at(1) == QLatin1String("--readcapturedstream")) {
|
||||
|
@@ -44,10 +44,13 @@
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
#include <QtGui/private/qrhi_p.h>
|
||||
#include <QtQuick/private/qquickwindow_p.h>
|
||||
#include <QtQuick/private/qsgrenderer_p.h>
|
||||
#include <QtQuick/private/qquickitem_p.h>
|
||||
#include <QtQuick/private/qquickrendercontrol_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
|
||||
|
||||
namespace QmlDesigner {
|
||||
@@ -332,6 +335,80 @@ QImage Qt5NodeInstanceServer::grabWindow()
|
||||
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()
|
||||
{
|
||||
DesignerSupport::refreshExpressions(context());
|
||||
|
@@ -69,6 +69,7 @@ public:
|
||||
void reparentInstances(const ReparentInstancesCommand &command) override;
|
||||
|
||||
QImage grabWindow() override;
|
||||
QImage grabItem(QQuickItem *item) override;
|
||||
|
||||
protected:
|
||||
void initializeView() override;
|
||||
|
@@ -102,9 +102,6 @@ void Qt5RenderNodeInstanceServer::collectItemChangesAndSendChangeCommands()
|
||||
clearChangedPropertyList();
|
||||
|
||||
if (Internal::QuickItemNodeInstance::unifiedRenderPath()) {
|
||||
/* QQuickItem::grabToImage render path */
|
||||
/* TODO implement QQuickItem::grabToImage based rendering */
|
||||
/* sheduleRootItemRender(); */
|
||||
if (windowDirty)
|
||||
nodeInstanceClient()->pixmapChanged(createPixmapChangedCommand({rootNodeInstance()}));
|
||||
} else {
|
||||
|
@@ -171,10 +171,15 @@ void QuickItemNodeInstance::enableUnifiedRenderPath(bool unifiedRenderPath)
|
||||
|
||||
bool QuickItemNodeInstance::checkIfRefFromEffect(qint32 id)
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
if (s_unifiedRenderPath)
|
||||
return false;
|
||||
|
||||
return (s_createEffectItem || id == 0);
|
||||
#else
|
||||
Q_UNUSED(id)
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void QuickItemNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNodeInstance,
|
||||
@@ -267,9 +272,13 @@ QStringList QuickItemNodeInstance::allStates() const
|
||||
|
||||
void QuickItemNodeInstance::updateDirtyNode(QQuickItem *item)
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
if (s_unifiedRenderPath)
|
||||
return;
|
||||
DesignerSupport::updateDirtyNode(item);
|
||||
#else
|
||||
Q_UNUSED(item)
|
||||
#endif
|
||||
}
|
||||
|
||||
bool QuickItemNodeInstance::unifiedRenderPath()
|
||||
@@ -277,6 +286,15 @@ bool QuickItemNodeInstance::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
|
||||
{
|
||||
if (contentItem()) {
|
||||
@@ -415,16 +433,15 @@ QImage QuickItemNodeInstance::renderImage() const
|
||||
updateDirtyNodesRecursive(quickItem());
|
||||
|
||||
QRectF renderBoundingRect = boundingRect();
|
||||
QImage renderImage;
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
QSize size = renderBoundingRect.size().toSize();
|
||||
static double devicePixelRatio = qgetenv("FORMEDITOR_DEVICE_PIXEL_RATIO").toDouble();
|
||||
if (size.width() * size.height() > 4000 * 4000)
|
||||
size = QSize(0,0);
|
||||
size *= devicePixelRatio;
|
||||
|
||||
QImage renderImage;
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
if (s_unifiedRenderPath) {
|
||||
renderImage = nodeInstanceServer()->quickWindow()->grabWindow();
|
||||
} else {
|
||||
@@ -438,8 +455,12 @@ QImage QuickItemNodeInstance::renderImage() const
|
||||
}
|
||||
renderImage.setDevicePixelRatio(devicePixelRatio);
|
||||
#else
|
||||
if (s_unifiedRenderPath)
|
||||
renderImage = nodeInstanceServer()->grabWindow();
|
||||
else
|
||||
renderImage = nodeInstanceServer()->grabItem(quickItem());
|
||||
renderImage = renderImage.copy(renderBoundingRect.toRect());
|
||||
|
||||
/* When grabbing an offscren window the device pixel ratio is 1 */
|
||||
renderImage.setDevicePixelRatio(1);
|
||||
#endif
|
||||
|
@@ -104,6 +104,7 @@ public:
|
||||
|
||||
static void updateDirtyNode(QQuickItem *item);
|
||||
static bool unifiedRenderPath();
|
||||
static bool unifiedRenderPathOrQt6();
|
||||
|
||||
protected:
|
||||
explicit QuickItemNodeInstance(QQuickItem*);
|
||||
|
Reference in New Issue
Block a user