diff options
533 files changed, 2571 insertions, 19668 deletions
diff --git a/.qmake.conf b/.qmake.conf index e6642580b9..7f338d0c85 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -1,7 +1,6 @@ load(qt_build_config) CONFIG += warning_clean -DEFINES += QT_NO_LINKED_LIST DEFINES += QT_NO_JAVA_STYLE_ITERATORS -MODULE_VERSION = 5.15.0 +MODULE_VERSION = 6.0.0 diff --git a/config.tests/d3d12/d3d12.cpp b/config.tests/d3d12/d3d12.cpp deleted file mode 100644 index 0bf90cc457..0000000000 --- a/config.tests/d3d12/d3d12.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <d3d12.h> -#include <dxgi1_4.h> -#include <wrl/client.h> - -using namespace Microsoft::WRL; - -int main(int, char **) -{ - ID3D12Device *dev = 0; - - return 0; -} diff --git a/config.tests/d3d12/d3d12.pro b/config.tests/d3d12/d3d12.pro deleted file mode 100644 index 451e7427b9..0000000000 --- a/config.tests/d3d12/d3d12.pro +++ /dev/null @@ -1,4 +0,0 @@ -SOURCES = d3d12.cpp -CONFIG -= qt dylib -CONFIG += console -LIBS += -ldxgi -ld3d12 -ld3dcompiler -ldcomp diff --git a/dependencies.yaml b/dependencies.yaml new file mode 100644 index 0000000000..1c6c876e61 --- /dev/null +++ b/dependencies.yaml @@ -0,0 +1,7 @@ +dependencies: + ../qtbase: + ref: bd4635009d3ba6ea560bc5f70811fa0afee518fc + required: true + ../qtsvg: + ref: 3fc521f262863a2c13d52be66b384d786594ce39 + required: false diff --git a/examples/quick/quickwidgets/quickwidget/fbitem.cpp b/examples/quick/quickwidgets/quickwidget/fbitem.cpp index 95ff2da2e0..3e98168dcf 100644 --- a/examples/quick/quickwidgets/quickwidget/fbitem.cpp +++ b/examples/quick/quickwidgets/quickwidget/fbitem.cpp @@ -49,9 +49,9 @@ ****************************************************************************/ #include "fbitem.h" -#include <QtGui/QOpenGLFramebufferObject> -#include <QtGui/QOpenGLContext> -#include <QtGui/QOpenGLFunctions> +#include <QOpenGLFramebufferObject> +#include <QOpenGLContext> +#include <QOpenGLFunctions> #include <QtCore/QDebug> #if QT_CONFIG(opengl) diff --git a/examples/quick/scenegraph/fboitem/fboinsgrenderer.cpp b/examples/quick/scenegraph/fboitem/fboinsgrenderer.cpp index 8ba5bddb2a..1c7be258be 100644 --- a/examples/quick/scenegraph/fboitem/fboinsgrenderer.cpp +++ b/examples/quick/scenegraph/fboitem/fboinsgrenderer.cpp @@ -51,7 +51,7 @@ #include "fboinsgrenderer.h" #include "logorenderer.h" -#include <QtGui/QOpenGLFramebufferObject> +#include <QOpenGLFramebufferObject> #include <QtQuick/QQuickWindow> #include <qsgsimpletexturenode.h> diff --git a/examples/quick/scenegraph/openglunderqml/squircle.cpp b/examples/quick/scenegraph/openglunderqml/squircle.cpp index 828857fe24..1c4563baa5 100644 --- a/examples/quick/scenegraph/openglunderqml/squircle.cpp +++ b/examples/quick/scenegraph/openglunderqml/squircle.cpp @@ -51,8 +51,8 @@ #include "squircle.h" #include <QtQuick/qquickwindow.h> -#include <QtGui/QOpenGLShaderProgram> -#include <QtGui/QOpenGLContext> +#include <QOpenGLShaderProgram> +#include <QOpenGLContext> #include <QtCore/QRunnable> //! [7] diff --git a/examples/quick/scenegraph/openglunderqml/squircle.h b/examples/quick/scenegraph/openglunderqml/squircle.h index c24fdd50c2..ecd92161fc 100644 --- a/examples/quick/scenegraph/openglunderqml/squircle.h +++ b/examples/quick/scenegraph/openglunderqml/squircle.h @@ -52,8 +52,8 @@ #define SQUIRCLE_H #include <QtQuick/QQuickItem> -#include <QtGui/QOpenGLShaderProgram> -#include <QtGui/QOpenGLFunctions> +#include <QOpenGLShaderProgram> +#include <QOpenGLFunctions> diff --git a/examples/quick/scenegraph/rendernode/customrenderitem.cpp b/examples/quick/scenegraph/rendernode/customrenderitem.cpp index 5f51522c47..aae91120a7 100644 --- a/examples/quick/scenegraph/rendernode/customrenderitem.cpp +++ b/examples/quick/scenegraph/rendernode/customrenderitem.cpp @@ -56,9 +56,6 @@ #ifdef Q_OS_MACOS #include "metalrenderer.h" #endif -#if QT_CONFIG(d3d12) -#include "d3d12renderer.h" -#endif #include "softwarerenderer.h" //! [1] @@ -105,14 +102,6 @@ QSGNode *CustomRenderItem::updatePaintNode(QSGNode *node, UpdatePaintNodeData *) #endif break; - case QSGRendererInterface::Direct3D12: // ### Qt 6: remove -#if QT_CONFIG(d3d12) - if (!n) - n = new D3D12RenderNode; - static_cast<D3D12RenderNode *>(n)->sync(this); -#endif - break; - case QSGRendererInterface::Software: if (!n) n = new SoftwareRenderNode; diff --git a/examples/quick/scenegraph/rendernode/d3d12renderer.cpp b/examples/quick/scenegraph/rendernode/d3d12renderer.cpp deleted file mode 100644 index e85811c089..0000000000 --- a/examples/quick/scenegraph/rendernode/d3d12renderer.cpp +++ /dev/null @@ -1,309 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "d3d12renderer.h" -#include <QQuickItem> -#include <QQuickWindow> -#include <QSGRendererInterface> -#include <QFile> - -// ### Qt 6: remove - -#if QT_CONFIG(d3d12) - -D3D12RenderNode::~D3D12RenderNode() -{ - releaseResources(); -} - -void D3D12RenderNode::releaseResources() -{ - if (vbPtr) { - vertexBuffer->Unmap(0, nullptr); - vbPtr = nullptr; - } - if (cbPtr) { - constantBuffer->Unmap(0, nullptr); - cbPtr = nullptr; - } - constantBuffer = nullptr; - vertexBuffer = nullptr; - rootSignature = nullptr; - pipelineState = nullptr; - m_device = nullptr; -} - -void D3D12RenderNode::init() -{ - QSGRendererInterface *rif = m_window->rendererInterface(); - m_device = static_cast<ID3D12Device *>(rif->getResource(m_window, QSGRendererInterface::DeviceResource)); - Q_ASSERT(m_device); - - D3D12_ROOT_PARAMETER rootParameter; - rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; - rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; - rootParameter.Descriptor.ShaderRegister = 0; // b0 - rootParameter.Descriptor.RegisterSpace = 0; - - D3D12_ROOT_SIGNATURE_DESC desc; - desc.NumParameters = 1; - desc.pParameters = &rootParameter; - desc.NumStaticSamplers = 0; - desc.pStaticSamplers = nullptr; - desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; - - ComPtr<ID3DBlob> signature; - ComPtr<ID3DBlob> error; - if (FAILED(D3D12SerializeRootSignature(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error))) { - qWarning("Failed to serialize root signature"); - return; - } - if (FAILED(m_device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), - IID_PPV_ARGS(&rootSignature)))) { - qWarning("Failed to create root signature"); - return; - } - - D3D12_INPUT_ELEMENT_DESC inputElementDescs[] = { - { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, - { "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 8, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 } - }; - - QFile f(QStringLiteral(":/scenegraph/rendernode/shader_vert.cso")); - if (!f.open(QIODevice::ReadOnly)) { - qWarning("Failed to open file with vertex shader bytecode"); - return; - } - QByteArray vshader_cso = f.readAll(); - f.close(); - f.setFileName(QStringLiteral(":/scenegraph/rendernode/shader_frag.cso")); - if (!f.open(QIODevice::ReadOnly)) { - qWarning("Failed to open file with fragment shader bytecode"); - return; - } - QByteArray fshader_cso = f.readAll(); - D3D12_SHADER_BYTECODE vshader; - vshader.pShaderBytecode = vshader_cso.constData(); - vshader.BytecodeLength = vshader_cso.size(); - D3D12_SHADER_BYTECODE pshader; - pshader.pShaderBytecode = fshader_cso.constData(); - pshader.BytecodeLength = fshader_cso.size(); - - D3D12_RASTERIZER_DESC rastDesc = {}; - rastDesc.FillMode = D3D12_FILL_MODE_SOLID; - rastDesc.CullMode = D3D12_CULL_MODE_BACK; - rastDesc.FrontCounterClockwise = TRUE; // Vertices are given CCW - - // Enable color write and blending (premultiplied alpha). The latter is - // needed because the example changes the item's opacity and we pass - // inheritedOpacity() into the pixel shader. If that wasn't the case, - // blending could have stayed disabled. - const D3D12_RENDER_TARGET_BLEND_DESC premulBlendDesc = { - TRUE, FALSE, - D3D12_BLEND_ONE, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD, - D3D12_BLEND_ONE, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD, - D3D12_LOGIC_OP_NOOP, - D3D12_COLOR_WRITE_ENABLE_ALL - }; - D3D12_BLEND_DESC blendDesc = {}; - blendDesc.RenderTarget[0] = premulBlendDesc; - - D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; - psoDesc.InputLayout = { inputElementDescs, _countof(inputElementDescs) }; - psoDesc.pRootSignature = rootSignature.Get(); - psoDesc.VS = vshader; - psoDesc.PS = pshader; - psoDesc.RasterizerState = rastDesc; - psoDesc.BlendState = blendDesc; - // No depth. The correct stacking of the item is ensured by the projection matrix. - // Note that this does not support clipping. - // If clipping is desired, render() needs to set a different PSO - // with stencil enabled whenever the RenderState indicates so. - psoDesc.SampleMask = UINT_MAX; - psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; - psoDesc.NumRenderTargets = 1; - psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; - psoDesc.DSVFormat = DXGI_FORMAT_D24_UNORM_S8_UINT; // not in use due to !DepthEnable, but this would be the correct format otherwise - // We are rendering on the default render target so if the QuickWindow/View - // has requested samples > 0 then we have to follow suit. - const uint samples = qMax(1, m_window->format().samples()); - psoDesc.SampleDesc.Count = samples; - if (samples > 1) { - D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS msaaInfo = {}; - msaaInfo.Format = psoDesc.RTVFormats[0]; - msaaInfo.SampleCount = samples; - if (SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, &msaaInfo, sizeof(msaaInfo)))) { - if (msaaInfo.NumQualityLevels > 0) - psoDesc.SampleDesc.Quality = msaaInfo.NumQualityLevels - 1; - } - } - - if (FAILED(m_device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&pipelineState)))) { - qWarning("Failed to create graphics pipeline state"); - return; - } - - const UINT vertexBufferSize = (2 + 3) * 3 * sizeof(float); - - D3D12_HEAP_PROPERTIES heapProp = {}; - heapProp.Type = D3D12_HEAP_TYPE_UPLOAD; - - D3D12_RESOURCE_DESC bufDesc; - bufDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - bufDesc.Alignment = 0; - bufDesc.Width = vertexBufferSize; - bufDesc.Height = 1; - bufDesc.DepthOrArraySize = 1; - bufDesc.MipLevels = 1; - bufDesc.Format = DXGI_FORMAT_UNKNOWN; - bufDesc.SampleDesc.Count = 1; - bufDesc.SampleDesc.Quality = 0; - bufDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; - bufDesc.Flags = D3D12_RESOURCE_FLAG_NONE; - - if (FAILED(m_device->CreateCommittedResource(&heapProp, D3D12_HEAP_FLAG_NONE, &bufDesc, - D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, - IID_PPV_ARGS(&vertexBuffer)))) { - qWarning("Failed to create committed resource (vertex buffer)"); - return; - } - - vertexBufferView.BufferLocation = vertexBuffer->GetGPUVirtualAddress(); - vertexBufferView.StrideInBytes = vertexBufferSize / 3; - vertexBufferView.SizeInBytes = vertexBufferSize; - - bufDesc.Width = 256; - if (FAILED(m_device->CreateCommittedResource(&heapProp, D3D12_HEAP_FLAG_NONE, &bufDesc, - D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, - IID_PPV_ARGS(&constantBuffer)))) { - qWarning("Failed to create committed resource (constant buffer)"); - return; - } - - const D3D12_RANGE readRange = { 0, 0 }; - if (FAILED(vertexBuffer->Map(0, &readRange, reinterpret_cast<void **>(&vbPtr)))) { - qWarning("Map failed"); - return; - } - - if (FAILED(constantBuffer->Map(0, &readRange, reinterpret_cast<void **>(&cbPtr)))) { - qWarning("Map failed (constant buffer)"); - return; - } - - float *vp = reinterpret_cast<float *>(vbPtr); - vp += 2; - *vp++ = 1.0f; *vp++ = 0.0f; *vp++ = 0.0f; - vp += 2; - *vp++ = 0.0f; *vp++ = 1.0f; *vp++ = 0.0f; - vp += 2; - *vp++ = 0.0f; *vp++ = 0.0f; *vp++ = 1.0f; -} - -void D3D12RenderNode::render(const RenderState *state) -{ - if (!m_device) - init(); - - QSGRendererInterface *rif = m_window->rendererInterface(); - ID3D12GraphicsCommandList *commandList = static_cast<ID3D12GraphicsCommandList *>( - rif->getResource(m_window, QSGRendererInterface::CommandListResource)); - Q_ASSERT(commandList); - - const int msize = 16 * sizeof(float); - memcpy(cbPtr, matrix()->constData(), msize); - memcpy(cbPtr + msize, state->projectionMatrix()->constData(), msize); - const float opacity = inheritedOpacity(); - memcpy(cbPtr + 2 * msize, &opacity, sizeof(float)); - - const QPointF p0(m_width - 1, m_height - 1); - const QPointF p1(0, 0); - const QPointF p2(0, m_height - 1); - - float *vp = reinterpret_cast<float *>(vbPtr); - *vp++ = p0.x(); - *vp++ = p0.y(); - vp += 3; - *vp++ = p1.x(); - *vp++ = p1.y(); - vp += 3; - *vp++ = p2.x(); - *vp++ = p2.y(); - - commandList->SetPipelineState(pipelineState.Get()); - commandList->SetGraphicsRootSignature(rootSignature.Get()); - commandList->SetGraphicsRootConstantBufferView(0, constantBuffer->GetGPUVirtualAddress()); - commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - commandList->IASetVertexBuffers(0, 1, &vertexBufferView); - - commandList->DrawInstanced(3, 1, 0, 0); -} - -// No need to reimplement changedStates() because no relevant commands are -// added to the command list in render(). - -QSGRenderNode::RenderingFlags D3D12RenderNode::flags() const -{ - return BoundedRectRendering | DepthAwareRendering; -} - -QRectF D3D12RenderNode::rect() const -{ - return QRect(0, 0, m_width, m_height); -} - -void D3D12RenderNode::sync(QQuickItem *item) -{ - m_window = item->window(); - m_width = item->width(); - m_height = item->height(); -} - -#endif // d3d12 diff --git a/examples/quick/scenegraph/rendernode/d3d12renderer.h b/examples/quick/scenegraph/rendernode/d3d12renderer.h deleted file mode 100644 index 7186b72c04..0000000000 --- a/examples/quick/scenegraph/rendernode/d3d12renderer.h +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef D3D12RENDERER_H -#define D3D12RENDERER_H - -#include <qsgrendernode.h> -#include <QQuickItem> - -#if QT_CONFIG(d3d12) - -#include <d3d12.h> -#include <wrl/client.h> - -using namespace Microsoft::WRL; - -class D3D12RenderNode : public QSGRenderNode -{ -public: - ~D3D12RenderNode(); - - void render(const RenderState *state) override; - void releaseResources() override; - RenderingFlags flags() const override; - QRectF rect() const override; - - void sync(QQuickItem *item); - -private: - void init(); - - QQuickWindow *m_window = nullptr; - int m_width = 0; - int m_height = 0; - - ID3D12Device *m_device = nullptr; - ComPtr<ID3D12PipelineState> pipelineState; - ComPtr<ID3D12RootSignature> rootSignature; - ComPtr<ID3D12Resource> vertexBuffer; - ComPtr<ID3D12Resource> constantBuffer; - D3D12_VERTEX_BUFFER_VIEW vertexBufferView; - quint8 *vbPtr = nullptr; - quint8 *cbPtr = nullptr; -}; - -#endif // d3d12 - -#endif diff --git a/examples/quick/scenegraph/rendernode/main.qml b/examples/quick/scenegraph/rendernode/main.qml index 5631df317c..a02fa128d5 100644 --- a/examples/quick/scenegraph/rendernode/main.qml +++ b/examples/quick/scenegraph/rendernode/main.qml @@ -143,7 +143,6 @@ Item { var apiStr; switch (api) { case GraphicsInfo.OpenGL: apiStr = "OpenGL (direct)"; break; - case GraphicsInfo.Direct3D12: apiStr = "Direct3D 12 (direct)"; break; case GraphicsInfo.Software: apiStr = "Software (QPainter)"; break; case GraphicsInfo.OpenGLRhi: apiStr = "OpenGL (RHI)"; break; case GraphicsInfo.MetalRhi: apiStr = "Metal (RHI)"; break; diff --git a/examples/quick/scenegraph/rendernode/rendernode.pro b/examples/quick/scenegraph/rendernode/rendernode.pro index cfec905764..4ae46de2a4 100644 --- a/examples/quick/scenegraph/rendernode/rendernode.pro +++ b/examples/quick/scenegraph/rendernode/rendernode.pro @@ -21,12 +21,6 @@ INSTALLS += target OTHER_FILES += \ main.qml -qtConfig(d3d12) { - HEADERS += d3d12renderer.h - SOURCES += d3d12renderer.cpp - LIBS += -ld3d12 -} - macos { HEADERS += metalrenderer.h SOURCES += metalrenderer.mm diff --git a/examples/quick/scenegraph/rendernode/rendernode.qrc b/examples/quick/scenegraph/rendernode/rendernode.qrc index 5907eab62c..a93fd0270f 100644 --- a/examples/quick/scenegraph/rendernode/rendernode.qrc +++ b/examples/quick/scenegraph/rendernode/rendernode.qrc @@ -1,8 +1,6 @@ <RCC> <qresource prefix="/scenegraph/rendernode"> <file>main.qml</file> - <file>shader_vert.cso</file> - <file>shader_frag.cso</file> <file>metalshader.vert</file> <file>metalshader.frag</file> </qresource> diff --git a/examples/quick/scenegraph/rendernode/shader_frag.cso b/examples/quick/scenegraph/rendernode/shader_frag.cso Binary files differdeleted file mode 100644 index 686c6af3fc..0000000000 --- a/examples/quick/scenegraph/rendernode/shader_frag.cso +++ /dev/null diff --git a/examples/quick/scenegraph/rendernode/shader_vert.cso b/examples/quick/scenegraph/rendernode/shader_vert.cso Binary files differdeleted file mode 100644 index fa13be5160..0000000000 --- a/examples/quick/scenegraph/rendernode/shader_vert.cso +++ /dev/null diff --git a/examples/quick/scenegraph/shared/logorenderer.h b/examples/quick/scenegraph/shared/logorenderer.h index 6e7c4b897f..03821919a9 100644 --- a/examples/quick/scenegraph/shared/logorenderer.h +++ b/examples/quick/scenegraph/shared/logorenderer.h @@ -53,8 +53,8 @@ #include <QtGui/qvector3d.h> #include <QtGui/qmatrix4x4.h> -#include <QtGui/qopenglshaderprogram.h> -#include <QtGui/qopenglfunctions.h> +#include <qopenglshaderprogram.h> +#include <qopenglfunctions.h> #include <QTime> #include <QVector> diff --git a/examples/quick/scenegraph/textureinthread/threadrenderer.cpp b/examples/quick/scenegraph/textureinthread/threadrenderer.cpp index c364d0b7dd..5fd8037193 100644 --- a/examples/quick/scenegraph/textureinthread/threadrenderer.cpp +++ b/examples/quick/scenegraph/textureinthread/threadrenderer.cpp @@ -54,8 +54,8 @@ #include <QtCore/QMutex> #include <QtCore/QThread> -#include <QtGui/QOpenGLContext> -#include <QtGui/QOpenGLFramebufferObject> +#include <QOpenGLContext> +#include <QOpenGLFramebufferObject> #include <QtGui/QGuiApplication> #include <QtGui/QOffscreenSurface> diff --git a/examples/quick/scenegraph/twotextureproviders/xorblender.cpp b/examples/quick/scenegraph/twotextureproviders/xorblender.cpp index d5881b9adc..667b0bf8c7 100644 --- a/examples/quick/scenegraph/twotextureproviders/xorblender.cpp +++ b/examples/quick/scenegraph/twotextureproviders/xorblender.cpp @@ -52,8 +52,8 @@ #include <QtCore/QPointer> -#include <QtGui/QOpenGLContext> -#include <QtGui/QOpenGLFunctions> +#include <QOpenGLContext> +#include <QOpenGLFunctions> #include <QtQuick/QSGMaterial> #include <QtQuick/QSGTexture> diff --git a/examples/quick/shadereffects/content/shaders/+hlsl/blur.frag b/examples/quick/shadereffects/content/shaders/+hlsl/blur.frag deleted file mode 100644 index 481a238d2a..0000000000 --- a/examples/quick/shadereffects/content/shaders/+hlsl/blur.frag +++ /dev/null @@ -1,18 +0,0 @@ -cbuffer ConstantBuffer : register(b0) -{ - float4x4 qt_Matrix; - float qt_Opacity; - float2 delta; -}; - -Texture2D source : register(t0); -SamplerState sourceSampler : register(s0); - -float4 main(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET -{ - return (0.0538 * source.Sample(sourceSampler, coord - 3.182 * delta) - + 0.3229 * source.Sample(sourceSampler, coord - 1.364 * delta) - + 0.2466 * source.Sample(sourceSampler, coord) - + 0.3229 * source.Sample(sourceSampler, coord + 1.364 * delta) - + 0.0538 * source.Sample(sourceSampler, coord + 3.182 * delta)) * qt_Opacity; -} diff --git a/examples/quick/shadereffects/content/shaders/+hlsl/colorize.frag b/examples/quick/shadereffects/content/shaders/+hlsl/colorize.frag deleted file mode 100644 index d6e65b6b10..0000000000 --- a/examples/quick/shadereffects/content/shaders/+hlsl/colorize.frag +++ /dev/null @@ -1,17 +0,0 @@ -cbuffer ConstantBuffer : register(b0) -{ - float4x4 qt_Matrix; - float qt_Opacity; - float4 tint; -}; - -Texture2D source : register(t0); -SamplerState sourceSampler : register(s0); - -float4 main(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET -{ - float4 c = source.Sample(sourceSampler, coord); - float lo = min(min(c.x, c.y), c.z); - float hi = max(max(c.x, c.y), c.z); - return float4(lerp(float3(lo, lo, lo), float3(hi, hi, hi), tint.xyz), c.w) * qt_Opacity; -} diff --git a/examples/quick/shadereffects/content/shaders/+hlsl/genie.vert b/examples/quick/shadereffects/content/shaders/+hlsl/genie.vert deleted file mode 100644 index 40876e7996..0000000000 --- a/examples/quick/shadereffects/content/shaders/+hlsl/genie.vert +++ /dev/null @@ -1,31 +0,0 @@ -cbuffer ConstantBuffer : register(b0) -{ - float4x4 qt_Matrix; - float qt_Opacity; - float bend; - float minimize; - float side; - float width; - float height; -}; - -struct PSInput -{ - float4 position : SV_POSITION; - float2 coord : TEXCOORD0; -}; - -PSInput main(float4 position : POSITION, float2 coord : TEXCOORD0) -{ - PSInput result; - result.coord = coord; - - float4 pos = position; - pos.y = lerp(position.y, height, minimize); - float t = pos.y / height; - t = (3.0 - 2.0 * t) * t * t; - pos.x = lerp(position.x, side * width, t * bend); - result.position = mul(qt_Matrix, pos); - - return result; -} diff --git a/examples/quick/shadereffects/content/shaders/+hlsl/outline.frag b/examples/quick/shadereffects/content/shaders/+hlsl/outline.frag deleted file mode 100644 index b6e7e51f35..0000000000 --- a/examples/quick/shadereffects/content/shaders/+hlsl/outline.frag +++ /dev/null @@ -1,21 +0,0 @@ -cbuffer ConstantBuffer : register(b0) -{ - float4x4 qt_Matrix; - float qt_Opacity; - float2 delta; -}; - -Texture2D source : register(t0); -SamplerState sourceSampler : register(s0); - -float4 main(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET -{ - float4 tl = source.Sample(sourceSampler, coord - delta); - float4 tr = source.Sample(sourceSampler, coord + float2(delta.x, -delta.y)); - float4 bl = source.Sample(sourceSampler, coord - float2(delta.x, -delta.y)); - float4 br = source.Sample(sourceSampler, coord + delta); - float4 gx = (tl + bl) - (tr + br); - float4 gy = (tl + tr) - (bl + br); - return float4(0.0, 0.0, 0.0, - clamp(dot(sqrt(gx * gx + gy * gy), float4(1.0, 1.0, 1.0, 1.0)), 0.0, 1.0) * qt_Opacity); -} diff --git a/examples/quick/shadereffects/content/shaders/+hlsl/shadow.frag b/examples/quick/shadereffects/content/shaders/+hlsl/shadow.frag deleted file mode 100644 index a86a25e007..0000000000 --- a/examples/quick/shadereffects/content/shaders/+hlsl/shadow.frag +++ /dev/null @@ -1,20 +0,0 @@ -cbuffer ConstantBuffer : register(b0) -{ - float4x4 qt_Matrix; - float qt_Opacity; - float2 offset; - float2 delta; - float darkness; -}; - -Texture2D source : register(t0); -SamplerState sourceSampler : register(s0); -Texture2D shadow : register(t1); -SamplerState shadowSampler : register(s1); - -float4 main(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET -{ - float4 fg = source.Sample(sourceSampler, coord); - float4 bg = shadow.Sample(shadowSampler, coord + delta); - return (fg + float4(0.0, 0.0, 0.0, darkness * bg.a) * (1.0 - fg.a)) * qt_Opacity; -} diff --git a/examples/quick/shadereffects/content/shaders/+hlsl/wobble.frag b/examples/quick/shadereffects/content/shaders/+hlsl/wobble.frag deleted file mode 100644 index c28612a2fd..0000000000 --- a/examples/quick/shadereffects/content/shaders/+hlsl/wobble.frag +++ /dev/null @@ -1,17 +0,0 @@ -cbuffer ConstantBuffer : register(b0) -{ - float4x4 qt_Matrix; - float qt_Opacity; - float amplitude; - float frequency; - float time; -}; - -Texture2D source : register(t0); -SamplerState sourceSampler : register(s0); - -float4 main(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET -{ - float2 p = sin(time + frequency * coord); - return source.Sample(sourceSampler, coord + amplitude * float2(p.y, -p.x)) * qt_Opacity; -} diff --git a/examples/quick/shadereffects/doc/src/shadereffects.qdoc b/examples/quick/shadereffects/doc/src/shadereffects.qdoc index d35989c262..d217c956ad 100644 --- a/examples/quick/shadereffects/doc/src/shadereffects.qdoc +++ b/examples/quick/shadereffects/doc/src/shadereffects.qdoc @@ -59,21 +59,6 @@ Direct 3D, or OpenGL. Qt automatically selects the file under the \c qsb selector, for example \c{shaders/+qsb/wobble.frag}, when present. - On the traditional code path, which can mean using OpenGL or Direct3D 12, - file selectors are used to select the correct variant at runtime. Based on - the Qt Quick backend in use, Qt will automatically select either - \c{shaders/wobble.frag} with the GLSL source code or - \c{shaders/+hlsl/wobble.frag} with the HLSL source code. - - \note For simplicity shader source code is used in all variants of the - files. However, with the Direct3D backend of Qt Quick pre-compiled shaders - are also supported. For example, try the following commands in the - \c{content/shaders/+hlsl} directory: \c{move wobble.frag wobble.frag.src} - followed by \c{fxc /E main /T ps_5_0 /Fo wobble.frag wobble.frag.src}. Now - \c wobble.frag contains Direct3D bytecode and that is what gets shipped - with the application instead of the shader source. Further changes are not - necessary, the application will function like before. - You can use any custom property on the ShaderEffect in your shader. This makes animated shader code very easy: \snippet shadereffects/shadereffects.qml properties diff --git a/examples/quick/shadereffects/shadereffects.qrc b/examples/quick/shadereffects/shadereffects.qrc index 762ad0d037..72ad2d9054 100644 --- a/examples/quick/shadereffects/shadereffects.qrc +++ b/examples/quick/shadereffects/shadereffects.qrc @@ -5,22 +5,16 @@ <file>content/qt-logo.png</file> <file>content/Slider.qml</file> <file>content/shaders/wobble.frag</file> - <file>content/shaders/+hlsl/wobble.frag</file> <file>content/shaders/+qsb/wobble.frag</file> <file>content/shaders/blur.frag</file> - <file>content/shaders/+hlsl/blur.frag</file> <file>content/shaders/+qsb/blur.frag</file> <file>content/shaders/shadow.frag</file> - <file>content/shaders/+hlsl/shadow.frag</file> <file>content/shaders/+qsb/shadow.frag</file> <file>content/shaders/outline.frag</file> - <file>content/shaders/+hlsl/outline.frag</file> <file>content/shaders/+qsb/outline.frag</file> <file>content/shaders/colorize.frag</file> - <file>content/shaders/+hlsl/colorize.frag</file> <file>content/shaders/+qsb/colorize.frag</file> <file>content/shaders/genie.vert</file> - <file>content/shaders/+hlsl/genie.vert</file> <file>content/shaders/+qsb/genie.vert</file> </qresource> </RCC> diff --git a/examples/quick/shared/SimpleLauncherDelegate.qml b/examples/quick/shared/SimpleLauncherDelegate.qml index dd29b8b821..11d34a187e 100644 --- a/examples/quick/shared/SimpleLauncherDelegate.qml +++ b/examples/quick/shared/SimpleLauncherDelegate.qml @@ -51,6 +51,9 @@ import QtQuick 2.12 Rectangle { id: container + required property string name + required property string description + property Item exampleItem width: ListView.view.width height: button.implicitHeight + 22 diff --git a/examples/quick/text/doc/src/text.qdoc b/examples/quick/text/doc/src/text.qdoc index d8bd8d349a..6378e3efe6 100644 --- a/examples/quick/text/doc/src/text.qdoc +++ b/examples/quick/text/doc/src/text.qdoc @@ -49,9 +49,6 @@ Simply by name, using the font.family property directly: \snippet text/fonts/fonts.qml name - or using a \l FontLoader type: - \snippet text/fonts/fonts.qml fontloader - or using a FontLoader and specifying a local font file: \snippet text/fonts/fonts.qml fontloaderlocal diff --git a/examples/quick/text/fonts/fonts.qml b/examples/quick/text/fonts/fonts.qml index 4478db0135..aeb17c48e2 100644 --- a/examples/quick/text/fonts/fonts.qml +++ b/examples/quick/text/fonts/fonts.qml @@ -57,9 +57,6 @@ Rectangle { width: 320; height: 480 color: "steelblue" -//! [fontloader] - FontLoader { id: fixedFont; name: "Courier" } -//! [fontloader] //! [fontloaderlocal] FontLoader { id: localFont; source: "content/fonts/tarzeau_ocr_a.ttf" } //! [fontloaderlocal] @@ -95,14 +92,14 @@ Rectangle { width: parent.width horizontalAlignment: Text.AlignRight wrapMode: Text.WordWrap - font { family: fixedFont.name; pixelSize: 20; weight: Font.Bold; capitalization: Font.AllLowercase } + font { family: "Courier"; pixelSize: 20; weight: Font.Bold; capitalization: Font.AllLowercase } } Text { text: root.myText color: "lightsteelblue" width: parent.width wrapMode: Text.WordWrap - font { family: fixedFont.name; pixelSize: 20; italic: true; capitalization: Font.SmallCaps } + font { family: "Courier"; pixelSize: 20; italic: true; capitalization: Font.SmallCaps } } Text { text: root.myText diff --git a/src/imports/folderlistmodel/folderlistmodel.pro b/src/imports/folderlistmodel/folderlistmodel.pro index fd05653879..c95a88430d 100644 --- a/src/imports/folderlistmodel/folderlistmodel.pro +++ b/src/imports/folderlistmodel/folderlistmodel.pro @@ -1,7 +1,7 @@ CXX_MODULE = qml TARGET = qmlfolderlistmodelplugin TARGETPATH = Qt/labs/folderlistmodel -IMPORT_VERSION = 2.$$QT_MINOR_VERSION +QML_IMPORT_VERSION = $$QT_VERSION QT = core-private qml-private diff --git a/src/imports/folderlistmodel/qquickfolderlistmodel.h b/src/imports/folderlistmodel/qquickfolderlistmodel.h index 5897bd2e0f..d7429efeda 100644 --- a/src/imports/folderlistmodel/qquickfolderlistmodel.h +++ b/src/imports/folderlistmodel/qquickfolderlistmodel.h @@ -67,19 +67,20 @@ class QQuickFolderListModel : public QAbstractListModel, public QQmlParserStatus Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters) Q_PROPERTY(SortField sortField READ sortField WRITE setSortField) Q_PROPERTY(bool sortReversed READ sortReversed WRITE setSortReversed) - Q_PROPERTY(bool showFiles READ showFiles WRITE setShowFiles REVISION 1) + Q_PROPERTY(bool showFiles READ showFiles WRITE setShowFiles REVISION(2, 1)) Q_PROPERTY(bool showDirs READ showDirs WRITE setShowDirs) Q_PROPERTY(bool showDirsFirst READ showDirsFirst WRITE setShowDirsFirst) Q_PROPERTY(bool showDotAndDotDot READ showDotAndDotDot WRITE setShowDotAndDotDot) - Q_PROPERTY(bool showHidden READ showHidden WRITE setShowHidden REVISION 1) + Q_PROPERTY(bool showHidden READ showHidden WRITE setShowHidden REVISION(2, 1)) Q_PROPERTY(bool showOnlyReadable READ showOnlyReadable WRITE setShowOnlyReadable) - Q_PROPERTY(bool caseSensitive READ caseSensitive WRITE setCaseSensitive REVISION 2) + Q_PROPERTY(bool caseSensitive READ caseSensitive WRITE setCaseSensitive REVISION(2, 2)) Q_PROPERTY(int count READ count NOTIFY countChanged) - Q_PROPERTY(Status status READ status NOTIFY statusChanged REVISION 11) - Q_PROPERTY(bool sortCaseSensitive READ sortCaseSensitive WRITE setSortCaseSensitive REVISION 12) + Q_PROPERTY(Status status READ status NOTIFY statusChanged REVISION(2, 11)) + Q_PROPERTY(bool sortCaseSensitive READ sortCaseSensitive WRITE setSortCaseSensitive REVISION(2, 12)) //![class props] QML_NAMED_ELEMENT(FolderListModel) + QML_ADDED_IN_VERSION(2, 0) //![abslistmodel] public: QQuickFolderListModel(QObject *parent = nullptr); @@ -163,8 +164,8 @@ public: Q_SIGNALS: void folderChanged(); void rowCountChanged() const; - Q_REVISION(1) void countChanged() const; - Q_REVISION(11) void statusChanged(); + Q_REVISION(2, 1) void countChanged() const; + Q_REVISION(2, 11) void statusChanged(); //![notifier] //![class end] diff --git a/src/imports/labsanimation/labsanimation.pro b/src/imports/labsanimation/labsanimation.pro index f64ae775c6..7254e49a7d 100644 --- a/src/imports/labsanimation/labsanimation.pro +++ b/src/imports/labsanimation/labsanimation.pro @@ -1,7 +1,7 @@ CXX_MODULE = qml TARGET = labsanimationplugin TARGETPATH = Qt/labs/animation -IMPORT_VERSION = 1.0 +QML_IMPORT_VERSION = 1.0 SOURCES += \ qquickboundaryrule.cpp \ diff --git a/src/imports/labsanimation/qquickboundaryrule_p.h b/src/imports/labsanimation/qquickboundaryrule_p.h index 1681558304..33cf0bb094 100644 --- a/src/imports/labsanimation/qquickboundaryrule_p.h +++ b/src/imports/labsanimation/qquickboundaryrule_p.h @@ -78,6 +78,7 @@ class QQuickBoundaryRule : public QObject, public QQmlPropertyValueInterceptor Q_PROPERTY(QEasingCurve easing READ easing WRITE setEasing NOTIFY easingChanged) Q_PROPERTY(int returnDuration READ returnDuration WRITE setReturnDuration NOTIFY returnDurationChanged) QML_NAMED_ELEMENT(BoundaryRule) + QML_ADDED_IN_VERSION(1, 0) public: enum OvershootFilter { diff --git a/src/imports/labsmodels/labsmodels.pro b/src/imports/labsmodels/labsmodels.pro index 13468348cb..951f6fbce8 100644 --- a/src/imports/labsmodels/labsmodels.pro +++ b/src/imports/labsmodels/labsmodels.pro @@ -1,7 +1,7 @@ CXX_MODULE = qml TARGET = labsmodelsplugin TARGETPATH = Qt/labs/qmlmodels -IMPORT_VERSION = 1.0 +QML_IMPORT_VERSION = 1.0 QT = qml-private qmlmodels-private diff --git a/src/imports/labsmodels/qqmldelegatecomponent_p.h b/src/imports/labsmodels/qqmldelegatecomponent_p.h index 8473831b1d..6f3170e19a 100644 --- a/src/imports/labsmodels/qqmldelegatecomponent_p.h +++ b/src/imports/labsmodels/qqmldelegatecomponent_p.h @@ -69,6 +69,8 @@ class QQmlDelegateChoice : public QObject Q_PROPERTY(QQmlComponent* delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) Q_CLASSINFO("DefaultProperty", "delegate") QML_NAMED_ELEMENT(DelegateChoice) + QML_ADDED_IN_VERSION(1, 0) + public: QVariant roleValue() const; void setRoleValue(const QVariant &roleValue); diff --git a/src/imports/labsmodels/qqmltablemodel_p.h b/src/imports/labsmodels/qqmltablemodel_p.h index 75e2768849..ae46cbe35c 100644 --- a/src/imports/labsmodels/qqmltablemodel_p.h +++ b/src/imports/labsmodels/qqmltablemodel_p.h @@ -74,6 +74,7 @@ class QQmlTableModel : public QAbstractTableModel, public QQmlParserStatus Q_INTERFACES(QQmlParserStatus) Q_CLASSINFO("DefaultProperty", "columns") QML_NAMED_ELEMENT(TableModel) + QML_ADDED_IN_VERSION(1, 0) public: QQmlTableModel(QObject *parent = nullptr); diff --git a/src/imports/labsmodels/qqmltablemodelcolumn_p.h b/src/imports/labsmodels/qqmltablemodelcolumn_p.h index a18f21ab4f..2860a915cc 100644 --- a/src/imports/labsmodels/qqmltablemodelcolumn_p.h +++ b/src/imports/labsmodels/qqmltablemodelcolumn_p.h @@ -97,6 +97,7 @@ class QQmlTableModelColumn : public QObject Q_PROPERTY(QJSValue sizeHint READ sizeHint WRITE setSizeHint NOTIFY sizeHintChanged FINAL) Q_PROPERTY(QJSValue setSizeHint READ getSetSizeHint WRITE setSetSizeHint NOTIFY setSizeHintChanged FINAL) QML_NAMED_ELEMENT(TableModelColumn) + QML_ADDED_IN_VERSION(1, 0) public: QQmlTableModelColumn(QObject *parent = nullptr); diff --git a/src/imports/layouts/layouts.pro b/src/imports/layouts/layouts.pro index ea7940e4ad..1ae269da32 100644 --- a/src/imports/layouts/layouts.pro +++ b/src/imports/layouts/layouts.pro @@ -1,7 +1,7 @@ CXX_MODULE = qml TARGET = qquicklayoutsplugin TARGETPATH = QtQuick/Layouts -IMPORT_VERSION = 1.$$QT_MINOR_VERSION +QML_IMPORT_VERSION = $$QT_VERSION QT *= qml-private quick-private gui-private core-private diff --git a/src/imports/layouts/qquicklayout_p.h b/src/imports/layouts/qquicklayout_p.h index 3322d03636..a2594f4274 100644 --- a/src/imports/layouts/qquicklayout_p.h +++ b/src/imports/layouts/qquicklayout_p.h @@ -62,6 +62,7 @@ class QQuickLayout : public QQuickItem, public QQuickItemChangeListener { Q_OBJECT QML_NAMED_ELEMENT(Layout) + QML_ADDED_IN_VERSION(1, 0) QML_UNCREATABLE("Do not create objects of type Layout.") QML_ATTACHED(QQuickLayoutAttached) diff --git a/src/imports/layouts/qquicklinearlayout.cpp b/src/imports/layouts/qquicklinearlayout.cpp index 1004ed8593..e47eba4164 100644 --- a/src/imports/layouts/qquicklinearlayout.cpp +++ b/src/imports/layouts/qquicklinearlayout.cpp @@ -788,7 +788,7 @@ QQuickLinearLayout::QQuickLinearLayout(Qt::Orientation orientation, \since QtQuick.Layouts 1.1 This property holds the layout direction of the row layout - it controls whether items are laid - out from left ro right or right to left. If \c Qt.RightToLeft is specified, + out from left to right or right to left. If \c Qt.RightToLeft is specified, left-aligned items will be right-aligned and right-aligned items will be left-aligned. Possible values: @@ -805,7 +805,7 @@ QQuickLinearLayout::QQuickLinearLayout(Qt::Orientation orientation, \since QtQuick.Layouts 1.1 This property holds the layout direction of the column layout - it controls whether items are laid - out from left ro right or right to left. If \c Qt.RightToLeft is specified, + out from left to right or right to left. If \c Qt.RightToLeft is specified, left-aligned items will be right-aligned and right-aligned items will be left-aligned. Possible values: diff --git a/src/imports/layouts/qquicklinearlayout_p.h b/src/imports/layouts/qquicklinearlayout_p.h index f36f99741d..1780ba8807 100644 --- a/src/imports/layouts/qquicklinearlayout_p.h +++ b/src/imports/layouts/qquicklinearlayout_p.h @@ -56,9 +56,10 @@ class QQuickGridLayoutBase : public QQuickLayout { Q_OBJECT - Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged REVISION 1) + Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection + NOTIFY layoutDirectionChanged REVISION(1, 1)) QML_ANONYMOUS - QML_ADDED_IN_MINOR_VERSION(1) + QML_ADDED_IN_VERSION(1, 1) public: @@ -92,7 +93,7 @@ protected: virtual void insertLayoutItems() {} signals: - Q_REVISION(1) void layoutDirectionChanged(); + Q_REVISION(1, 1) void layoutDirectionChanged(); private: void removeGridItem(QGridLayoutItem *gridItem); @@ -145,6 +146,7 @@ class QQuickGridLayout : public QQuickGridLayoutBase Q_PROPERTY(int rows READ rows WRITE setRows NOTIFY rowsChanged) Q_PROPERTY(Flow flow READ flow WRITE setFlow NOTIFY flowChanged) QML_NAMED_ELEMENT(GridLayout) + QML_ADDED_IN_VERSION(1, 0) public: explicit QQuickGridLayout(QQuickItem *parent = 0); qreal columnSpacing() const; @@ -229,6 +231,7 @@ class QQuickRowLayout : public QQuickLinearLayout { Q_OBJECT QML_NAMED_ELEMENT(RowLayout) + QML_ADDED_IN_VERSION(1, 0) public: explicit QQuickRowLayout(QQuickItem *parent = 0) @@ -245,6 +248,7 @@ class QQuickColumnLayout : public QQuickLinearLayout { Q_OBJECT QML_NAMED_ELEMENT(ColumnLayout) + QML_ADDED_IN_VERSION(1, 0) public: explicit QQuickColumnLayout(QQuickItem *parent = 0) diff --git a/src/imports/layouts/qquickstacklayout_p.h b/src/imports/layouts/qquickstacklayout_p.h index 537d54900f..07f9e48178 100644 --- a/src/imports/layouts/qquickstacklayout_p.h +++ b/src/imports/layouts/qquickstacklayout_p.h @@ -52,7 +52,7 @@ class QQuickStackLayout : public QQuickLayout Q_PROPERTY(int count READ count NOTIFY countChanged) Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged) QML_NAMED_ELEMENT(StackLayout) - QML_ADDED_IN_MINOR_VERSION(3) + QML_ADDED_IN_VERSION(1, 3) public: explicit QQuickStackLayout(QQuickItem *parent = 0); diff --git a/src/imports/localstorage/localstorage.pro b/src/imports/localstorage/localstorage.pro index a95fa04401..6dff4862c7 100644 --- a/src/imports/localstorage/localstorage.pro +++ b/src/imports/localstorage/localstorage.pro @@ -1,7 +1,7 @@ CXX_MODULE = qml TARGET = qmllocalstorageplugin TARGETPATH = QtQuick/LocalStorage -IMPORT_VERSION = 2.$$QT_MINOR_VERSION +QML_IMPORT_VERSION = $$QT_VERSION QT = sql qml-private core-private diff --git a/src/imports/localstorage/qquicklocalstorage_p.h b/src/imports/localstorage/qquicklocalstorage_p.h index d2ebc85ce9..f90d6bad28 100644 --- a/src/imports/localstorage/qquicklocalstorage_p.h +++ b/src/imports/localstorage/qquicklocalstorage_p.h @@ -61,6 +61,7 @@ class QQuickLocalStorage : public QObject { Q_OBJECT QML_NAMED_ELEMENT(LocalStorage) + QML_ADDED_IN_VERSION(2, 0) QML_SINGLETON public: diff --git a/src/imports/models/models.pro b/src/imports/models/models.pro index fd13b12401..9a22049068 100644 --- a/src/imports/models/models.pro +++ b/src/imports/models/models.pro @@ -1,7 +1,7 @@ CXX_MODULE = qml TARGET = modelsplugin -TARGETPATH = QtQml/Models.2 -IMPORT_VERSION = 2.$$QT_MINOR_VERSION +TARGETPATH = QtQml/Models +QML_IMPORT_VERSION = $$QT_VERSION SOURCES += \ plugin.cpp diff --git a/src/imports/particles/particles.pro b/src/imports/particles/particles.pro index 41146c75b0..c0f2f990b5 100644 --- a/src/imports/particles/particles.pro +++ b/src/imports/particles/particles.pro @@ -1,7 +1,7 @@ CXX_MODULE = qml TARGET = particlesplugin -TARGETPATH = QtQuick/Particles.2 -IMPORT_VERSION = 2.$$QT_MINOR_VERSION +TARGETPATH = QtQuick/Particles +QML_IMPORT_VERSION = $$QT_VERSION SOURCES += \ plugin.cpp diff --git a/src/imports/qtqml/plugin.cpp b/src/imports/qtqml/plugin.cpp index 854ef6d2e6..a32d86eeb1 100644 --- a/src/imports/qtqml/plugin.cpp +++ b/src/imports/qtqml/plugin.cpp @@ -40,10 +40,6 @@ #include <QtQml/private/qtqmlglobal_p.h> #include <QtQml/qqmlextensionplugin.h> -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) -#include <QtQmlModels/private/qqmlmodelsmodule_p.h> -#endif - QT_BEGIN_NAMESPACE /*! @@ -63,21 +59,6 @@ QT_BEGIN_NAMESPACE */ //![class decl] -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) -class QtQmlPlugin : public QQmlExtensionPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) -public: - QtQmlPlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) - { - volatile auto registration = &qml_register_types_QtQml; - Q_UNUSED(registration); - } - - void registerTypes(const char *) override { QQmlModelsModule::registerQmlTypes(); } -}; -#else class QtQmlPlugin : public QQmlEngineExtensionPlugin { Q_OBJECT @@ -89,7 +70,6 @@ public: Q_UNUSED(registration); } }; -#endif //![class decl] QT_END_NAMESPACE diff --git a/src/imports/qtqml/qmldir b/src/imports/qtqml/qmldir deleted file mode 100644 index f6b51c7970..0000000000 --- a/src/imports/qtqml/qmldir +++ /dev/null @@ -1,4 +0,0 @@ -module QtQml -plugin qmlplugin -classname QtQmlPlugin -typeinfo plugins.qmltypes diff --git a/src/imports/qtqml/qtqml.pro b/src/imports/qtqml/qtqml.pro index 7a5169b8fc..eac19954b6 100644 --- a/src/imports/qtqml/qtqml.pro +++ b/src/imports/qtqml/qtqml.pro @@ -1,7 +1,7 @@ TARGETPATH = QtQml CXX_MODULE = qml TARGET = qmlplugin -IMPORT_VERSION = 2.$$QT_MINOR_VERSION +QML_IMPORT_VERSION = $$QT_VERSION SOURCES += \ plugin.cpp @@ -9,4 +9,15 @@ SOURCES += \ # In Qt6 we won't need qmlmodels-private here QT = qml-private qmlmodels-private +DYNAMIC_QMLDIR = \ + "module QtQml" \ + "plugin qmlplugin" \ + "classname QtQmlPlugin" \ + "typeinfo plugins.qmltypes" \ + "designersupported" \ + "import QtQml.Models" + +qtConfig(qml-worker-script): DYNAMIC_QMLDIR += \ + "import QtQml.WorkerScript" + load(qml_plugin) diff --git a/src/imports/qtquick2/plugin.cpp b/src/imports/qtquick2/plugin.cpp index 20bc4a3cc0..4e14aff15e 100644 --- a/src/imports/qtquick2/plugin.cpp +++ b/src/imports/qtquick2/plugin.cpp @@ -38,14 +38,7 @@ ****************************************************************************/ #include <QtQml/qqmlextensionplugin.h> - -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) -#include <QtQml/private/qqmlengine_p.h> -#include <QtQmlModels/private/qqmlmodelsmodule_p.h> -#if QT_CONFIG(qml_worker_script) -#include <QtQmlWorkerScript/private/qqmlworkerscriptmodule_p.h> -#endif -#endif // QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +#include <QtQml/QQmlEngine> #include <private/qtquick2_p.h> @@ -68,13 +61,6 @@ public: Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick")); Q_UNUSED(uri); moduleDefined = true; -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - QQmlEnginePrivate::registerQuickTypes(); - QQmlModelsModule::registerQuickTypes(); -#if QT_CONFIG(qml_worker_script) - QQmlWorkerScriptModule::registerQuickTypes(); -#endif -#endif QQmlQtQuick2Module::defineModule(); } diff --git a/src/imports/qtquick2/qmldir b/src/imports/qtquick2/qmldir index 8167e813df..d74aabd9e9 100644 --- a/src/imports/qtquick2/qmldir +++ b/src/imports/qtquick2/qmldir @@ -3,3 +3,4 @@ plugin qtquick2plugin classname QtQuick2Plugin typeinfo plugins.qmltypes designersupported +import QtQml diff --git a/src/imports/qtquick2/qtquick2.pro b/src/imports/qtquick2/qtquick2.pro index 8543049ead..35430d0638 100644 --- a/src/imports/qtquick2/qtquick2.pro +++ b/src/imports/qtquick2/qtquick2.pro @@ -1,7 +1,7 @@ CXX_MODULE = qml TARGET = qtquick2plugin -TARGETPATH = QtQuick.2 -IMPORT_VERSION = 2.$$QT_MINOR_VERSION +TARGETPATH = QtQuick +QML_IMPORT_VERSION = $$QT_VERSION SOURCES += \ plugin.cpp diff --git a/src/imports/settings/qqmlsettings_p.h b/src/imports/settings/qqmlsettings_p.h index 3f1b83f541..100d0136ff 100644 --- a/src/imports/settings/qqmlsettings_p.h +++ b/src/imports/settings/qqmlsettings_p.h @@ -67,6 +67,7 @@ class QQmlSettings : public QObject, public QQmlParserStatus Q_PROPERTY(QString category READ category WRITE setCategory FINAL) Q_PROPERTY(QString fileName READ fileName WRITE setFileName FINAL) QML_NAMED_ELEMENT(Settings) + QML_ADDED_IN_VERSION(1, 0) public: explicit QQmlSettings(QObject *parent = 0); diff --git a/src/imports/settings/settings.pro b/src/imports/settings/settings.pro index d8062a2e55..a67a268f91 100644 --- a/src/imports/settings/settings.pro +++ b/src/imports/settings/settings.pro @@ -1,7 +1,7 @@ CXX_MODULE = qml TARGET = qmlsettingsplugin TARGETPATH = Qt/labs/settings -IMPORT_VERSION = 1.1 +QML_IMPORT_VERSION = 1.1 QT = core qml diff --git a/src/imports/shapes/shapes.pro b/src/imports/shapes/shapes.pro index 857fcd7564..b5f75343d7 100644 --- a/src/imports/shapes/shapes.pro +++ b/src/imports/shapes/shapes.pro @@ -1,7 +1,7 @@ CXX_MODULE = qml TARGET = qmlshapesplugin TARGETPATH = QtQuick/Shapes -IMPORT_VERSION = 1.$$QT_MINOR_VERSION +QML_IMPORT_VERSION = $$QT_VERSION QT = core gui-private qml quick-private quickshapes-private diff --git a/src/imports/sharedimage/sharedimage.pro b/src/imports/sharedimage/sharedimage.pro index 8ab4f10405..c91ccd593d 100644 --- a/src/imports/sharedimage/sharedimage.pro +++ b/src/imports/sharedimage/sharedimage.pro @@ -1,7 +1,7 @@ CXX_MODULE = qml TARGET = sharedimageplugin TARGETPATH = Qt/labs/sharedimage -IMPORT_VERSION = 1.0 +QML_IMPORT_VERSION = 1.0 QT *= quick-private qml gui-private core-private diff --git a/src/imports/statemachine/finalstate.h b/src/imports/statemachine/finalstate.h index 117a358e53..fef0e9c092 100644 --- a/src/imports/statemachine/finalstate.h +++ b/src/imports/statemachine/finalstate.h @@ -56,6 +56,7 @@ class FinalState : public QFinalState Q_PROPERTY(QQmlListProperty<QObject> children READ children NOTIFY childrenChanged) Q_CLASSINFO("DefaultProperty", "children") QML_ELEMENT + QML_ADDED_IN_VERSION(1, 0) public: explicit FinalState(QState *parent = 0); diff --git a/src/imports/statemachine/signaltransition.h b/src/imports/statemachine/signaltransition.h index 748e230b3e..4d73368eb0 100644 --- a/src/imports/statemachine/signaltransition.h +++ b/src/imports/statemachine/signaltransition.h @@ -58,6 +58,7 @@ class SignalTransition : public QSignalTransition, public QQmlParserStatus Q_PROPERTY(QJSValue signal READ signal WRITE setSignal NOTIFY qmlSignalChanged) Q_PROPERTY(QQmlScriptString guard READ guard WRITE setGuard NOTIFY guardChanged) QML_ELEMENT + QML_ADDED_IN_VERSION(1, 0) public: explicit SignalTransition(QState *parent = nullptr); diff --git a/src/imports/statemachine/state.h b/src/imports/statemachine/state.h index 68184775ab..8cb454f3cf 100644 --- a/src/imports/statemachine/state.h +++ b/src/imports/statemachine/state.h @@ -56,6 +56,7 @@ class State : public QState, public QQmlParserStatus Q_PROPERTY(QQmlListProperty<QObject> children READ children NOTIFY childrenChanged) Q_CLASSINFO("DefaultProperty", "children") QML_ELEMENT + QML_ADDED_IN_VERSION(1, 0) public: explicit State(QState *parent = 0); diff --git a/src/imports/statemachine/statemachine.h b/src/imports/statemachine/statemachine.h index cc0360db54..85ac4cf26b 100644 --- a/src/imports/statemachine/statemachine.h +++ b/src/imports/statemachine/statemachine.h @@ -60,6 +60,7 @@ class StateMachine : public QStateMachine, public QQmlParserStatus Q_CLASSINFO("DefaultProperty", "children") QML_ELEMENT + QML_ADDED_IN_VERSION(1, 0) public: explicit StateMachine(QObject *parent = 0); diff --git a/src/imports/statemachine/statemachine.pro b/src/imports/statemachine/statemachine.pro index d4977d8eb8..cff81c2416 100644 --- a/src/imports/statemachine/statemachine.pro +++ b/src/imports/statemachine/statemachine.pro @@ -1,7 +1,7 @@ CXX_MODULE = qml TARGET = qtqmlstatemachine TARGETPATH = QtQml/StateMachine -IMPORT_VERSION = 1.$$QT_MINOR_VERSION +QML_IMPORT_VERSION = $$QT_VERSION QT = core-private qml-private diff --git a/src/imports/statemachine/statemachineforeign.h b/src/imports/statemachine/statemachineforeign.h index 363c9d0e31..7543d55fdf 100644 --- a/src/imports/statemachine/statemachineforeign.h +++ b/src/imports/statemachine/statemachineforeign.h @@ -51,6 +51,7 @@ struct QHistoryStateForeign Q_GADGET QML_FOREIGN(QHistoryState) QML_NAMED_ELEMENT(HistoryState) + QML_ADDED_IN_VERSION(1, 0) }; struct QStateForeign @@ -58,6 +59,7 @@ struct QStateForeign Q_GADGET QML_FOREIGN(QState) QML_NAMED_ELEMENT(QState) + QML_ADDED_IN_VERSION(1, 0) QML_UNCREATABLE("Don't use this, use State instead.") }; @@ -66,6 +68,7 @@ struct QAbstractStateForeign Q_GADGET QML_FOREIGN(QAbstractState) QML_NAMED_ELEMENT(QAbstractState) + QML_ADDED_IN_VERSION(1, 0) QML_UNCREATABLE("Don't use this, use State instead.") }; @@ -74,6 +77,7 @@ struct QSignalTransitionForeign Q_GADGET QML_FOREIGN(QSignalTransition) QML_NAMED_ELEMENT(QSignalTransition) + QML_ADDED_IN_VERSION(1, 0) QML_UNCREATABLE("Don't use this, use SignalTransition instead.") }; diff --git a/src/imports/statemachine/timeouttransition.h b/src/imports/statemachine/timeouttransition.h index cc3a22e0e5..3d056b5e41 100644 --- a/src/imports/statemachine/timeouttransition.h +++ b/src/imports/statemachine/timeouttransition.h @@ -53,6 +53,7 @@ class TimeoutTransition : public QSignalTransition, public QQmlParserStatus Q_PROPERTY(int timeout READ timeout WRITE setTimeout NOTIFY timeoutChanged) Q_INTERFACES(QQmlParserStatus) QML_ELEMENT + QML_ADDED_IN_VERSION(1, 0) public: TimeoutTransition(QState *parent = nullptr); diff --git a/src/imports/testlib/qmldir b/src/imports/testlib/qmldir index be9039abbb..9c1e8dd61f 100644 --- a/src/imports/testlib/qmldir +++ b/src/imports/testlib/qmldir @@ -3,6 +3,5 @@ plugin qmltestplugin classname QTestQmlModule typeinfo plugins.qmltypes TestCase 1.0 TestCase.qml -TestCase 1.2 TestCase.qml SignalSpy 1.0 SignalSpy.qml depends QtQuick.Window 2.0 diff --git a/src/imports/testlib/quicktestevent_p.h b/src/imports/testlib/quicktestevent_p.h index f452e4ff82..0bbae8434f 100644 --- a/src/imports/testlib/quicktestevent_p.h +++ b/src/imports/testlib/quicktestevent_p.h @@ -63,6 +63,7 @@ class QQuickTouchEventSequence : public QObject { Q_OBJECT QML_ANONYMOUS + QML_ADDED_IN_VERSION(1, 0) public: explicit QQuickTouchEventSequence(QuickTestEvent *testEvent, QObject *item = nullptr); @@ -83,6 +84,7 @@ class QuickTestEvent : public QObject Q_OBJECT Q_PROPERTY(int defaultMouseDelay READ defaultMouseDelay FINAL) QML_NAMED_ELEMENT(TestEvent) + QML_ADDED_IN_VERSION(1, 0) public: QuickTestEvent(QObject *parent = nullptr); ~QuickTestEvent() override; @@ -97,7 +99,7 @@ public Q_SLOTS: bool keyReleaseChar(const QString &character, int modifiers, int delay); bool keyClickChar(const QString &character, int modifiers, int delay); - Q_REVISION(2) bool keySequence(const QVariant &keySequence); + Q_REVISION(1, 2) bool keySequence(const QVariant &keySequence); bool mousePress(QObject *item, qreal x, qreal y, int button, int modifiers, int delay); diff --git a/src/imports/testlib/quicktestresultforeign_p.h b/src/imports/testlib/quicktestresultforeign_p.h index 92ff8e8a5a..e9dd12fa93 100644 --- a/src/imports/testlib/quicktestresultforeign_p.h +++ b/src/imports/testlib/quicktestresultforeign_p.h @@ -61,6 +61,7 @@ struct QuickTestResultForeign Q_GADGET QML_FOREIGN(QuickTestResult) QML_NAMED_ELEMENT(TestResult) + QML_ADDED_IN_VERSION(1, 0) }; QT_END_NAMESPACE diff --git a/src/imports/testlib/quicktestutil_p.h b/src/imports/testlib/quicktestutil_p.h index 2456bf88a7..7e90c1cd1d 100644 --- a/src/imports/testlib/quicktestutil_p.h +++ b/src/imports/testlib/quicktestutil_p.h @@ -63,6 +63,7 @@ class QuickTestUtil : public QObject Q_PROPERTY(bool printAvailableFunctions READ printAvailableFunctions NOTIFY printAvailableFunctionsChanged) Q_PROPERTY(int dragThreshold READ dragThreshold NOTIFY dragThresholdChanged) QML_NAMED_ELEMENT(TestUtil) + QML_ADDED_IN_VERSION(1, 0) public: QuickTestUtil(QObject *parent = nullptr) :QObject(parent) {} ~QuickTestUtil() override {} diff --git a/src/imports/testlib/testlib.pro b/src/imports/testlib/testlib.pro index d5e315d7da..2a97213e29 100644 --- a/src/imports/testlib/testlib.pro +++ b/src/imports/testlib/testlib.pro @@ -1,7 +1,7 @@ CXX_MODULE = qml TARGET = qmltestplugin TARGETPATH = QtTest -IMPORT_VERSION = 1.$$QT_MINOR_VERSION +QML_IMPORT_VERSION = $$QT_VERSION QT += quick qmltest-private qml-private core-private testlib gui-private diff --git a/src/imports/wavefrontmesh/qwavefrontmesh.h b/src/imports/wavefrontmesh/qwavefrontmesh.h index a8a40c1a6a..67e0527e5d 100644 --- a/src/imports/wavefrontmesh/qwavefrontmesh.h +++ b/src/imports/wavefrontmesh/qwavefrontmesh.h @@ -56,6 +56,7 @@ class QWavefrontMesh : public QQuickShaderEffectMesh Q_PROPERTY(QVector3D projectionPlaneV READ projectionPlaneV WRITE setProjectionPlaneV NOTIFY projectionPlaneVChanged) Q_PROPERTY(QVector3D projectionPlaneW READ projectionPlaneW WRITE setProjectionPlaneW NOTIFY projectionPlaneWChanged) QML_NAMED_ELEMENT(WavefrontMesh) + QML_ADDED_IN_VERSION(1, 0) public: enum Error { diff --git a/src/imports/wavefrontmesh/wavefrontmesh.pro b/src/imports/wavefrontmesh/wavefrontmesh.pro index 0b28410750..4aa06b97bf 100644 --- a/src/imports/wavefrontmesh/wavefrontmesh.pro +++ b/src/imports/wavefrontmesh/wavefrontmesh.pro @@ -1,7 +1,7 @@ CXX_MODULE = qml TARGET = qmlwavefrontmeshplugin TARGETPATH = Qt/labs/wavefrontmesh -IMPORT_VERSION = 1.$$QT_MINOR_VERSION +QML_IMPORT_VERSION = $$QT_VERSION QT = core-private qml-private quick-private diff --git a/src/imports/window/plugin.h b/src/imports/window/plugin.h index 9f58ca9ac7..5497030bb0 100644 --- a/src/imports/window/plugin.h +++ b/src/imports/window/plugin.h @@ -65,7 +65,7 @@ struct QWindowForeign Q_GADGET QML_FOREIGN(QWindow) QML_ANONYMOUS - QML_ADDED_IN_MINOR_VERSION(1) + QML_ADDED_IN_VERSION(2, 1) }; struct QQuickWindowForeign @@ -73,8 +73,8 @@ struct QQuickWindowForeign Q_GADGET QML_FOREIGN(QQuickWindow) QML_NAMED_ELEMENT(Window) - QML_ADDED_IN_MINOR_VERSION(0) - QML_REMOVED_IN_MINOR_VERSION(1) + QML_ADDED_IN_VERSION(2, 0) + QML_REMOVED_IN_VERSION(2, 1) }; struct QQuickWindowForeignAttached @@ -82,6 +82,7 @@ struct QQuickWindowForeignAttached Q_GADGET QML_FOREIGN(QQuickWindowAttached) QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) }; struct QQuickScreenInfoForeign @@ -89,7 +90,7 @@ struct QQuickScreenInfoForeign Q_GADGET QML_FOREIGN(QQuickScreenInfo) QML_NAMED_ELEMENT(ScreenInfo) - QML_ADDED_IN_MINOR_VERSION(3) + QML_ADDED_IN_VERSION(2, 3) QML_UNCREATABLE("ScreenInfo can only be used via the attached property.") }; @@ -98,6 +99,7 @@ struct QQuickScreenForeignAttached Q_GADGET QML_FOREIGN(QQuickScreenAttached) QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) }; struct QQuickScreenForeign @@ -105,6 +107,7 @@ struct QQuickScreenForeign Q_GADGET QML_FOREIGN(QQuickScreen) QML_NAMED_ELEMENT(Screen) + QML_ADDED_IN_VERSION(2, 0) QML_UNCREATABLE("Screen can only be used via the attached property.") }; @@ -113,7 +116,7 @@ struct QQuickWindowQmlImplForeign Q_GADGET QML_FOREIGN(QQuickWindowQmlImpl) QML_NAMED_ELEMENT(Window) - QML_ADDED_IN_MINOR_VERSION(1) + QML_ADDED_IN_VERSION(2, 1) }; QT_END_NAMESPACE diff --git a/src/imports/window/window.pro b/src/imports/window/window.pro index 068169b36f..d8f9b16df4 100644 --- a/src/imports/window/window.pro +++ b/src/imports/window/window.pro @@ -1,7 +1,7 @@ CXX_MODULE = qml TARGET = windowplugin -TARGETPATH = QtQuick/Window.2 -IMPORT_VERSION = 2.$$QT_MINOR_VERSION +TARGETPATH = QtQuick/Window +QML_IMPORT_VERSION = $$QT_VERSION SOURCES += \ plugin.cpp diff --git a/src/imports/workerscript/qmldir b/src/imports/workerscript/qmldir index 1606400a23..02ff9ea188 100644 --- a/src/imports/workerscript/qmldir +++ b/src/imports/workerscript/qmldir @@ -1,3 +1,4 @@ module QtQml.WorkerScript plugin workerscriptplugin classname QtQmlWorkerScriptPlugin +designersupported diff --git a/src/imports/workerscript/workerscript.pro b/src/imports/workerscript/workerscript.pro index d48e285bda..9c6a65eb05 100644 --- a/src/imports/workerscript/workerscript.pro +++ b/src/imports/workerscript/workerscript.pro @@ -1,7 +1,7 @@ CXX_MODULE = qml TARGET = workerscriptplugin -TARGETPATH = QtQml/WorkerScript.2 -IMPORT_VERSION = 2.$$QT_MINOR_VERSION +TARGETPATH = QtQml/WorkerScript +QML_IMPORT_VERSION = $$QT_VERSION SOURCES += \ plugin.cpp diff --git a/src/particles/particles.pro b/src/particles/particles.pro index aaaa83419a..6a117c65fe 100644 --- a/src/particles/particles.pro +++ b/src/particles/particles.pro @@ -17,9 +17,9 @@ exists("qqml_enable_gcov") { include(particles.pri) QMLTYPES_FILENAME = plugins.qmltypes -QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQuick/Particles.2 +QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQuick/Particles QML_IMPORT_NAME = QtQuick.Particles -IMPORT_VERSION = 2.$$QT_MINOR_VERSION +QML_IMPORT_VERSION = $$QT_VERSION CONFIG += qmltypes install_qmltypes install_metatypes load(qt_module) diff --git a/src/particles/qquickage_p.h b/src/particles/qquickage_p.h index 890c6a63c1..1730c25c28 100644 --- a/src/particles/qquickage_p.h +++ b/src/particles/qquickage_p.h @@ -60,6 +60,7 @@ class QQuickAgeAffector : public QQuickParticleAffector Q_PROPERTY(int lifeLeft READ lifeLeft WRITE setLifeLeft NOTIFY lifeLeftChanged) Q_PROPERTY(bool advancePosition READ advancePosition WRITE setAdvancePosition NOTIFY advancePositionChanged) QML_NAMED_ELEMENT(Age) + QML_ADDED_IN_VERSION(2, 0) public: explicit QQuickAgeAffector(QQuickItem *parent = 0); diff --git a/src/particles/qquickangledirection_p.h b/src/particles/qquickangledirection_p.h index d0fdf5a68c..9ec9e49d1a 100644 --- a/src/particles/qquickangledirection_p.h +++ b/src/particles/qquickangledirection_p.h @@ -63,6 +63,7 @@ class QQuickAngleDirection : public QQuickDirection Q_PROPERTY(qreal angleVariation READ angleVariation WRITE setAngleVariation NOTIFY angleVariationChanged) Q_PROPERTY(qreal magnitudeVariation READ magnitudeVariation WRITE setMagnitudeVariation NOTIFY magnitudeVariationChanged) QML_NAMED_ELEMENT(AngleDirection) + QML_ADDED_IN_VERSION(2, 0) public: explicit QQuickAngleDirection(QObject *parent = 0); QPointF sample(const QPointF &from) override; diff --git a/src/particles/qquickcumulativedirection_p.h b/src/particles/qquickcumulativedirection_p.h index 5160d8f09a..0a54d5dd22 100644 --- a/src/particles/qquickcumulativedirection_p.h +++ b/src/particles/qquickcumulativedirection_p.h @@ -62,6 +62,7 @@ class QQuickCumulativeDirection : public QQuickDirection Q_PROPERTY(QQmlListProperty<QQuickDirection> directions READ directions) Q_CLASSINFO("DefaultProperty", "directions") QML_NAMED_ELEMENT(CumulativeDirection) + QML_ADDED_IN_VERSION(2, 0) public: explicit QQuickCumulativeDirection(QObject *parent = 0); QQmlListProperty<QQuickDirection> directions(); diff --git a/src/particles/qquickcustomaffector_p.h b/src/particles/qquickcustomaffector_p.h index 5e8671514d..4506ae9d62 100644 --- a/src/particles/qquickcustomaffector_p.h +++ b/src/particles/qquickcustomaffector_p.h @@ -68,6 +68,7 @@ class QQuickCustomAffector : public QQuickParticleAffector Q_PROPERTY(QQuickDirection *velocity READ velocity WRITE setVelocity NOTIFY velocityChanged RESET velocityReset) Q_PROPERTY(QQuickDirection *acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged RESET accelerationReset) QML_NAMED_ELEMENT(Affector) + QML_ADDED_IN_VERSION(2, 0) public: explicit QQuickCustomAffector(QQuickItem *parent = 0); diff --git a/src/particles/qquickcustomparticle.cpp b/src/particles/qquickcustomparticle.cpp index 91fd63302a..ecb71cb913 100644 --- a/src/particles/qquickcustomparticle.cpp +++ b/src/particles/qquickcustomparticle.cpp @@ -39,7 +39,7 @@ #include "qquickcustomparticle_p.h" #include <QtCore/qrandom.h> -#include <QtGui/qopenglcontext.h> +#include <qopenglcontext.h> #include <QtQuick/private/qquickshadereffectmesh_p.h> #include <QtQuick/private/qsgshadersourcebuilder_p.h> #include <QtQml/qqmlinfo.h> diff --git a/src/particles/qquickcustomparticle_p.h b/src/particles/qquickcustomparticle_p.h index 444f7ad215..90643fe3e4 100644 --- a/src/particles/qquickcustomparticle_p.h +++ b/src/particles/qquickcustomparticle_p.h @@ -68,6 +68,7 @@ class QQuickCustomParticle : public QQuickParticlePainter Q_PROPERTY(QByteArray fragmentShader READ fragmentShader WRITE setFragmentShader NOTIFY fragmentShaderChanged) Q_PROPERTY(QByteArray vertexShader READ vertexShader WRITE setVertexShader NOTIFY vertexShaderChanged) QML_NAMED_ELEMENT(CustomParticle) + QML_ADDED_IN_VERSION(2, 0) public: explicit QQuickCustomParticle(QQuickItem* parent=0); diff --git a/src/particles/qquickdirection_p.h b/src/particles/qquickdirection_p.h index 60b4d8eb1d..e671868ed2 100644 --- a/src/particles/qquickdirection_p.h +++ b/src/particles/qquickdirection_p.h @@ -61,6 +61,7 @@ class QQuickDirection : public QObject { Q_OBJECT QML_NAMED_ELEMENT(NullVector) + QML_ADDED_IN_VERSION(2, 0) QML_UNCREATABLE("Abstract type. Use one of the inheriting types instead.") public: diff --git a/src/particles/qquickellipseextruder_p.h b/src/particles/qquickellipseextruder_p.h index c92443fedf..3268923480 100644 --- a/src/particles/qquickellipseextruder_p.h +++ b/src/particles/qquickellipseextruder_p.h @@ -59,6 +59,7 @@ class QQuickEllipseExtruder : public QQuickParticleExtruder Q_OBJECT Q_PROPERTY(bool fill READ fill WRITE setFill NOTIFY fillChanged)//###Use base class? If it's still box QML_NAMED_ELEMENT(EllipseShape) + QML_ADDED_IN_VERSION(2, 0) public: explicit QQuickEllipseExtruder(QObject *parent = 0); QPointF extrude(const QRectF &) override; diff --git a/src/particles/qquickfriction_p.h b/src/particles/qquickfriction_p.h index 5686bb37d5..952f47b141 100644 --- a/src/particles/qquickfriction_p.h +++ b/src/particles/qquickfriction_p.h @@ -60,6 +60,7 @@ class QQuickFrictionAffector : public QQuickParticleAffector Q_PROPERTY(qreal factor READ factor WRITE setFactor NOTIFY factorChanged) Q_PROPERTY(qreal threshold READ threshold WRITE setThreshold NOTIFY thresholdChanged) QML_NAMED_ELEMENT(Friction) + QML_ADDED_IN_VERSION(2, 0) public: explicit QQuickFrictionAffector(QQuickItem *parent = 0); diff --git a/src/particles/qquickgravity_p.h b/src/particles/qquickgravity_p.h index ef7cc770b7..351cbb93b1 100644 --- a/src/particles/qquickgravity_p.h +++ b/src/particles/qquickgravity_p.h @@ -62,6 +62,7 @@ class QQuickGravityAffector : public QQuickParticleAffector Q_PROPERTY(qreal acceleration READ magnitude WRITE setAcceleration NOTIFY magnitudeChanged) Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged) QML_NAMED_ELEMENT(Gravity) + QML_ADDED_IN_VERSION(2, 0) public: explicit QQuickGravityAffector(QQuickItem *parent = 0); qreal magnitude() const; diff --git a/src/particles/qquickgroupgoal_p.h b/src/particles/qquickgroupgoal_p.h index 022b244ed7..5589483aa6 100644 --- a/src/particles/qquickgroupgoal_p.h +++ b/src/particles/qquickgroupgoal_p.h @@ -62,6 +62,7 @@ class QQuickGroupGoalAffector : public QQuickParticleAffector Q_PROPERTY(QString goalState READ goalState WRITE setGoalState NOTIFY goalStateChanged) Q_PROPERTY(bool jump READ jump WRITE setJump NOTIFY jumpChanged) QML_NAMED_ELEMENT(GroupGoal) + QML_ADDED_IN_VERSION(2, 0) public: explicit QQuickGroupGoalAffector(QQuickItem *parent = 0); diff --git a/src/particles/qquickimageparticle_p.h b/src/particles/qquickimageparticle_p.h index fdb404861c..266054f28e 100644 --- a/src/particles/qquickimageparticle_p.h +++ b/src/particles/qquickimageparticle_p.h @@ -203,6 +203,7 @@ class QQuickImageParticle : public QQuickParticlePainter Q_PROPERTY(EntryEffect entryEffect READ entryEffect WRITE setEntryEffect NOTIFY entryEffectChanged) QML_NAMED_ELEMENT(ImageParticle) + QML_ADDED_IN_VERSION(2, 0) public: explicit QQuickImageParticle(QQuickItem *parent = 0); virtual ~QQuickImageParticle(); diff --git a/src/particles/qquickitemparticle_p.h b/src/particles/qquickitemparticle_p.h index 32c9881691..fce9e95548 100644 --- a/src/particles/qquickitemparticle_p.h +++ b/src/particles/qquickitemparticle_p.h @@ -64,6 +64,7 @@ class QQuickItemParticle : public QQuickParticlePainter Q_PROPERTY(bool fade READ fade WRITE setFade NOTIFY fadeChanged) Q_PROPERTY(QQmlComponent* delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) QML_NAMED_ELEMENT(ItemParticle) + QML_ADDED_IN_VERSION(2, 0) QML_ATTACHED(QQuickItemParticleAttached) public: explicit QQuickItemParticle(QQuickItem *parent = 0); diff --git a/src/particles/qquicklineextruder_p.h b/src/particles/qquicklineextruder_p.h index 76ac5aaf11..a337324c6a 100644 --- a/src/particles/qquicklineextruder_p.h +++ b/src/particles/qquicklineextruder_p.h @@ -58,6 +58,7 @@ class QQuickLineExtruder : public QQuickParticleExtruder //Default is topleft to bottom right. Flipped makes it topright to bottom left Q_PROPERTY(bool mirrored READ mirrored WRITE setMirrored NOTIFY mirroredChanged) QML_NAMED_ELEMENT(LineShape) + QML_ADDED_IN_VERSION(2, 0) public: explicit QQuickLineExtruder(QObject *parent = 0); diff --git a/src/particles/qquickmaskextruder_p.h b/src/particles/qquickmaskextruder_p.h index 419d162811..0d3fa9c15a 100644 --- a/src/particles/qquickmaskextruder_p.h +++ b/src/particles/qquickmaskextruder_p.h @@ -62,6 +62,7 @@ class QQuickMaskExtruder : public QQuickParticleExtruder Q_OBJECT Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) QML_NAMED_ELEMENT(MaskShape) + QML_ADDED_IN_VERSION(2, 0) public: explicit QQuickMaskExtruder(QObject *parent = 0); QPointF extrude(const QRectF &) override; diff --git a/src/particles/qquickparticleaffector_p.h b/src/particles/qquickparticleaffector_p.h index fd4887333e..22cebbead1 100644 --- a/src/particles/qquickparticleaffector_p.h +++ b/src/particles/qquickparticleaffector_p.h @@ -69,6 +69,7 @@ class Q_QUICKPARTICLES_PRIVATE_EXPORT QQuickParticleAffector : public QQuickItem Q_PROPERTY(QQuickParticleExtruder* shape READ shape WRITE setShape NOTIFY shapeChanged) QML_NAMED_ELEMENT(ParticleAffector) + QML_ADDED_IN_VERSION(2, 0) QML_UNCREATABLE("Abstract type. Use one of the inheriting types instead.") public: diff --git a/src/particles/qquickparticleemitter_p.h b/src/particles/qquickparticleemitter_p.h index b97d3f812a..8c9ca622fb 100644 --- a/src/particles/qquickparticleemitter_p.h +++ b/src/particles/qquickparticleemitter_p.h @@ -84,6 +84,7 @@ class Q_QUICKPARTICLES_PRIVATE_EXPORT QQuickParticleEmitter : public QQuickItem Q_PROPERTY(QQuickDirection *acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged) Q_PROPERTY(qreal velocityFromMovement READ velocityFromMovement WRITE setVelocityFromMovement NOTIFY velocityFromMovementChanged) QML_NAMED_ELEMENT(Emitter) + QML_ADDED_IN_VERSION(2, 0) public: explicit QQuickParticleEmitter(QQuickItem *parent = 0); diff --git a/src/particles/qquickparticleextruder_p.h b/src/particles/qquickparticleextruder_p.h index 24f7a0a2fa..7be0ead245 100644 --- a/src/particles/qquickparticleextruder_p.h +++ b/src/particles/qquickparticleextruder_p.h @@ -63,6 +63,7 @@ class QQuickParticleExtruder : public QObject Q_OBJECT QML_NAMED_ELEMENT(ParticleExtruder) + QML_ADDED_IN_VERSION(2, 0) QML_UNCREATABLE("Abstract type. Use one of the inheriting types instead.") public: diff --git a/src/particles/qquickparticlegroup_p.h b/src/particles/qquickparticlegroup_p.h index 8d068fbe9c..9b13153a95 100644 --- a/src/particles/qquickparticlegroup_p.h +++ b/src/particles/qquickparticlegroup_p.h @@ -67,6 +67,7 @@ class QQuickParticleGroup : public QQuickStochasticState, public QQmlParserStatu Q_PROPERTY(QQmlListProperty<QObject> particleChildren READ particleChildren DESIGNABLE false)//### Hidden property for in-state system definitions - ought not to be used in actual "Sprite" states Q_CLASSINFO("DefaultProperty", "particleChildren") QML_NAMED_ELEMENT(ParticleGroup) + QML_ADDED_IN_VERSION(2, 0) Q_INTERFACES(QQmlParserStatus) public: diff --git a/src/particles/qquickparticlepainter_p.h b/src/particles/qquickparticlepainter_p.h index e3d13b8a21..5236bb6569 100644 --- a/src/particles/qquickparticlepainter_p.h +++ b/src/particles/qquickparticlepainter_p.h @@ -65,6 +65,7 @@ class QQuickParticlePainter : public QQuickItem Q_PROPERTY(QStringList groups READ groups WRITE setGroups NOTIFY groupsChanged) QML_NAMED_ELEMENT(ParticlePainter) + QML_ADDED_IN_VERSION(2, 0) QML_UNCREATABLE("Abstract type. Use one of the inheriting types instead.") public: // data diff --git a/src/particles/qquickparticlesystem_p.h b/src/particles/qquickparticlesystem_p.h index 7c0a1ffd7d..b7812c6ea5 100644 --- a/src/particles/qquickparticlesystem_p.h +++ b/src/particles/qquickparticlesystem_p.h @@ -352,6 +352,7 @@ class Q_QUICKPARTICLES_PRIVATE_EXPORT QQuickParticleSystem : public QQuickItem Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged) Q_PROPERTY(bool empty READ isEmpty NOTIFY emptyChanged) QML_NAMED_ELEMENT(ParticleSystem) + QML_ADDED_IN_VERSION(2, 0) public: explicit QQuickParticleSystem(QQuickItem *parent = nullptr); diff --git a/src/particles/qquickpointattractor_p.h b/src/particles/qquickpointattractor_p.h index 28bbaaa84f..b3314f1a96 100644 --- a/src/particles/qquickpointattractor_p.h +++ b/src/particles/qquickpointattractor_p.h @@ -63,6 +63,7 @@ class QQuickAttractorAffector : public QQuickParticleAffector Q_PROPERTY(AffectableParameters affectedParameter READ affectedParameter WRITE setAffectedParameter NOTIFY affectedParameterChanged) Q_PROPERTY(Proportion proportionalToDistance READ proportionalToDistance WRITE setProportionalToDistance NOTIFY proportionalToDistanceChanged) QML_NAMED_ELEMENT(Attractor) + QML_ADDED_IN_VERSION(2, 0) public: enum Proportion{ diff --git a/src/particles/qquickpointdirection_p.h b/src/particles/qquickpointdirection_p.h index 9103a570c9..39109d8331 100644 --- a/src/particles/qquickpointdirection_p.h +++ b/src/particles/qquickpointdirection_p.h @@ -62,6 +62,7 @@ class QQuickPointDirection : public QQuickDirection Q_PROPERTY(qreal xVariation READ xVariation WRITE setXVariation NOTIFY xVariationChanged) Q_PROPERTY(qreal yVariation READ yVariation WRITE setYVariation NOTIFY yVariationChanged) QML_NAMED_ELEMENT(PointDirection) + QML_ADDED_IN_VERSION(2, 0) public: explicit QQuickPointDirection(QObject *parent = 0); QPointF sample(const QPointF &from) override; diff --git a/src/particles/qquickrectangleextruder_p.h b/src/particles/qquickrectangleextruder_p.h index 7c0a6c2bf1..f6f39579c4 100644 --- a/src/particles/qquickrectangleextruder_p.h +++ b/src/particles/qquickrectangleextruder_p.h @@ -60,6 +60,7 @@ class QQuickRectangleExtruder : public QQuickParticleExtruder Q_OBJECT Q_PROPERTY(bool fill READ fill WRITE setFill NOTIFY fillChanged) QML_NAMED_ELEMENT(RectangleShape) + QML_ADDED_IN_VERSION(2, 0) public: explicit QQuickRectangleExtruder(QObject *parent = 0); diff --git a/src/particles/qquickspritegoal_p.h b/src/particles/qquickspritegoal_p.h index d5f9bb88ae..efd9b1ab39 100644 --- a/src/particles/qquickspritegoal_p.h +++ b/src/particles/qquickspritegoal_p.h @@ -64,6 +64,7 @@ class QQuickSpriteGoalAffector : public QQuickParticleAffector Q_PROPERTY(bool jump READ jump WRITE setJump NOTIFY jumpChanged) Q_PROPERTY(bool systemStates READ systemStates WRITE setSystemStates NOTIFY systemStatesChanged) QML_NAMED_ELEMENT(SpriteGoal) + QML_ADDED_IN_VERSION(2, 0) public: explicit QQuickSpriteGoalAffector(QQuickItem *parent = 0); diff --git a/src/particles/qquicktargetdirection_p.h b/src/particles/qquicktargetdirection_p.h index 232d375d8c..ea6ac24893 100644 --- a/src/particles/qquicktargetdirection_p.h +++ b/src/particles/qquicktargetdirection_p.h @@ -71,6 +71,7 @@ class QQuickTargetDirection : public QQuickDirection Q_PROPERTY(qreal magnitude READ magnitude WRITE setMagnitude NOTIFY magnitudeChanged) Q_PROPERTY(qreal magnitudeVariation READ magnitudeVariation WRITE setMagnitudeVariation NOTIFY magnitudeVariationChanged) QML_NAMED_ELEMENT(TargetDirection) + QML_ADDED_IN_VERSION(2, 0) public: explicit QQuickTargetDirection(QObject *parent = 0); diff --git a/src/particles/qquicktrailemitter_p.h b/src/particles/qquicktrailemitter_p.h index 270bec52cf..bf21b66fb6 100644 --- a/src/particles/qquicktrailemitter_p.h +++ b/src/particles/qquicktrailemitter_p.h @@ -65,6 +65,7 @@ class QQuickTrailEmitter : public QQuickParticleEmitter Q_PROPERTY(qreal emitHeight READ emitterYVariation WRITE setEmitterYVariation NOTIFY emitterYVariationChanged) Q_PROPERTY(qreal emitWidth READ emitterXVariation WRITE setEmitterXVariation NOTIFY emitterXVariationChanged) QML_NAMED_ELEMENT(TrailEmitter) + QML_ADDED_IN_VERSION(2, 0) public: enum EmitSize { diff --git a/src/particles/qquickturbulence_p.h b/src/particles/qquickturbulence_p.h index 52011381e4..77239660d8 100644 --- a/src/particles/qquickturbulence_p.h +++ b/src/particles/qquickturbulence_p.h @@ -63,6 +63,7 @@ class QQuickTurbulenceAffector : public QQuickParticleAffector Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged) Q_PROPERTY(QUrl noiseSource READ noiseSource WRITE setNoiseSource NOTIFY noiseSourceChanged) QML_NAMED_ELEMENT(Turbulence) + QML_ADDED_IN_VERSION(2, 0) public: explicit QQuickTurbulenceAffector(QQuickItem *parent = 0); diff --git a/src/particles/qquickwander_p.h b/src/particles/qquickwander_p.h index bf7acdacfb..174b780562 100644 --- a/src/particles/qquickwander_p.h +++ b/src/particles/qquickwander_p.h @@ -72,6 +72,7 @@ class QQuickWanderAffector : public QQuickParticleAffector Q_PROPERTY(qreal yVariance READ yVariance WRITE setYVariance NOTIFY yVarianceChanged) Q_PROPERTY(AffectableParameters affectedParameter READ affectedParameter WRITE setAffectedParameter NOTIFY affectedParameterChanged) QML_NAMED_ELEMENT(Wander) + QML_ADDED_IN_VERSION(2, 0) public: enum AffectableParameters { diff --git a/src/plugins/scenegraph/d3d12/d3d12.json b/src/plugins/scenegraph/d3d12/d3d12.json deleted file mode 100644 index c450a38556..0000000000 --- a/src/plugins/scenegraph/d3d12/d3d12.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "Keys": ["d3d12"] -} diff --git a/src/plugins/scenegraph/d3d12/d3d12.pro b/src/plugins/scenegraph/d3d12/d3d12.pro deleted file mode 100644 index 7192efe449..0000000000 --- a/src/plugins/scenegraph/d3d12/d3d12.pro +++ /dev/null @@ -1,73 +0,0 @@ -TARGET = qsgd3d12backend - -QT += core-private gui-private qml-private quick-private - -PLUGIN_TYPE = scenegraph -PLUGIN_CLASS_NAME = QSGD3D12Adaptation -load(qt_plugin) - -TRACEPOINT_PROVIDER = $$PWD/d3d12.tracepoints -CONFIG += qt_tracepoints -debug_and_release { - CONFIG(debug, debug|release) { - INCLUDEPATH += $$OUT_PWD/../../../quick/.tracegen/debug - } else { - INCLUDEPATH += $$OUT_PWD/../../../quick/.tracegen/release - } -} else { - INCLUDEPATH += $$OUT_PWD/../../../quick/.tracegen/ -} - -QMAKE_TARGET_PRODUCT = "Qt Quick D3D12 Renderer (Qt $$QT_VERSION)" -QMAKE_TARGET_DESCRIPTION = "Quick D3D12 Renderer for Qt." - -SOURCES += \ - $$PWD/qsgd3d12adaptation.cpp \ - $$PWD/qsgd3d12renderloop.cpp \ - $$PWD/qsgd3d12threadedrenderloop.cpp \ - $$PWD/qsgd3d12renderer.cpp \ - $$PWD/qsgd3d12context.cpp \ - $$PWD/qsgd3d12rendercontext.cpp \ - $$PWD/qsgd3d12internalrectanglenode.cpp \ - $$PWD/qsgd3d12material.cpp \ - $$PWD/qsgd3d12builtinmaterials.cpp \ - $$PWD/qsgd3d12texture.cpp \ - $$PWD/qsgd3d12internalimagenode.cpp \ - $$PWD/qsgd3d12glyphnode.cpp \ - $$PWD/qsgd3d12glyphcache.cpp \ - $$PWD/qsgd3d12layer.cpp \ - $$PWD/qsgd3d12shadereffectnode.cpp \ - $$PWD/qsgd3d12painternode.cpp \ - $$PWD/qsgd3d12publicnodes.cpp \ - $$PWD/qsgd3d12spritenode.cpp - -NO_PCH_SOURCES += \ - $$PWD/qsgd3d12engine.cpp - -HEADERS += \ - $$PWD/qsgd3d12adaptation_p.h \ - $$PWD/qsgd3d12renderloop_p.h \ - $$PWD/qsgd3d12threadedrenderloop_p.h \ - $$PWD/qsgd3d12renderer_p.h \ - $$PWD/qsgd3d12context_p.h \ - $$PWD/qsgd3d12rendercontext_p.h \ - $$PWD/qsgd3d12engine_p.h \ - $$PWD/qsgd3d12engine_p_p.h \ - $$PWD/qsgd3d12internalrectanglenode_p.h \ - $$PWD/qsgd3d12material_p.h \ - $$PWD/qsgd3d12builtinmaterials_p.h \ - $$PWD/qsgd3d12texture_p.h \ - $$PWD/qsgd3d12internalimagenode_p.h \ - $$PWD/qsgd3d12glyphnode_p.h \ - $$PWD/qsgd3d12glyphcache_p.h \ - $$PWD/qsgd3d12layer_p.h \ - $$PWD/qsgd3d12shadereffectnode_p.h \ - $$PWD/qsgd3d12painternode_p.h \ - $$PWD/qsgd3d12publicnodes_p.h \ - $$PWD/qsgd3d12spritenode_p.h - -LIBS += -ldxgi -ld3d12 -ld3dcompiler -ldcomp - -include($$PWD/shaders/shaders.pri) - -OTHER_FILES += $$PWD/d3d12.json diff --git a/src/plugins/scenegraph/d3d12/d3d12.tracepoints b/src/plugins/scenegraph/d3d12/d3d12.tracepoints deleted file mode 100644 index e69de29bb2..0000000000 --- a/src/plugins/scenegraph/d3d12/d3d12.tracepoints +++ /dev/null diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12adaptation.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12adaptation.cpp deleted file mode 100644 index b93da0ae01..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12adaptation.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsgd3d12adaptation_p.h" -#include "qsgd3d12renderloop_p.h" -#include "qsgd3d12threadedrenderloop_p.h" -#include "qsgd3d12context_p.h" - -QT_BEGIN_NAMESPACE - -QSGD3D12Adaptation::QSGD3D12Adaptation(QObject *parent) - : QSGContextPlugin(parent) -{ -} - -QStringList QSGD3D12Adaptation::keys() const -{ - return QStringList() << QLatin1String("d3d12"); -} - -QSGContext *QSGD3D12Adaptation::create(const QString &) const -{ - if (!contextInstance) - contextInstance = new QSGD3D12Context; - - return contextInstance; -} - -QSGContextFactoryInterface::Flags QSGD3D12Adaptation::flags(const QString &) const -{ - return QSGContextFactoryInterface::SupportsShaderEffectNode; -} - -QSGRenderLoop *QSGD3D12Adaptation::createWindowManager() -{ - static bool threaded = false; - static bool envChecked = false; - if (!envChecked) { - envChecked = true; - threaded = qgetenv("QSG_RENDER_LOOP") == QByteArrayLiteral("threaded"); - } - - if (threaded) - return new QSGD3D12ThreadedRenderLoop; - - return new QSGD3D12RenderLoop; -} - -QSGD3D12Context *QSGD3D12Adaptation::contextInstance = nullptr; - -QT_END_NAMESPACE diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12adaptation_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12adaptation_p.h deleted file mode 100644 index 035c3408ff..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12adaptation_p.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSGD3D12ADAPTATION_P_H -#define QSGD3D12ADAPTATION_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qsgcontextplugin_p.h> - -QT_BEGIN_NAMESPACE - -class QSGD3D12Context; -class QSGContext; -class QSGRenderLoop; - -class QSGD3D12Adaptation : public QSGContextPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QSGContextFactoryInterface" FILE "d3d12.json") - -public: - QSGD3D12Adaptation(QObject *parent = 0); - - QStringList keys() const override; - QSGContext *create(const QString &key) const override; - QSGContextFactoryInterface::Flags flags(const QString &key) const override; - QSGRenderLoop *createWindowManager() override; - -private: - static QSGD3D12Context *contextInstance; -}; - -QT_END_NAMESPACE - -#endif // QSGD3D12ADAPTATION_P_H diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials.cpp deleted file mode 100644 index 312e8c19cd..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials.cpp +++ /dev/null @@ -1,737 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsgd3d12builtinmaterials_p.h" -#include "qsgd3d12rendercontext_p.h" -#include <QQuickWindow> -#include <QtCore/qmath.h> -#include <QtGui/private/qfixed_p.h> - -#include "vs_vertexcolor.hlslh" -#include "ps_vertexcolor.hlslh" -#include "vs_flatcolor.hlslh" -#include "ps_flatcolor.hlslh" -#include "vs_smoothcolor.hlslh" -#include "ps_smoothcolor.hlslh" -#include "vs_texture.hlslh" -#include "ps_texture.hlslh" -#include "vs_smoothtexture.hlslh" -#include "ps_smoothtexture.hlslh" -#include "vs_textmask.hlslh" -#include "ps_textmask24.hlslh" -#include "ps_textmask32.hlslh" -#include "ps_textmask8.hlslh" -#include "vs_styledtext.hlslh" -#include "ps_styledtext.hlslh" -#include "vs_outlinedtext.hlslh" -#include "ps_outlinedtext.hlslh" - -QT_BEGIN_NAMESPACE - -// NB! In HLSL constant buffer data is packed into 4-byte boundaries and, more -// importantly, it is packed so that it does not cross a 16-byte (float4) -// boundary. Hence the need for padding in some cases. - -static inline QVector4D qsg_premultiply(const QVector4D &c, float globalOpacity) -{ - const float o = c.w() * globalOpacity; - return QVector4D(c.x() * o, c.y() * o, c.z() * o, o); -} - -static inline QVector4D qsg_premultiply(const QColor &c, float globalOpacity) -{ - const float o = c.alphaF() * globalOpacity; - return QVector4D(c.redF() * o, c.greenF() * o, c.blueF() * o, o); -} - -static inline int qsg_colorDiff(const QVector4D &a, const QVector4D &b) -{ - if (a.x() != b.x()) - return a.x() > b.x() ? 1 : -1; - if (a.y() != b.y()) - return a.y() > b.y() ? 1 : -1; - if (a.z() != b.z()) - return a.z() > b.z() ? 1 : -1; - if (a.w() != b.w()) - return a.w() > b.w() ? 1 : -1; - return 0; -} - -QSGMaterialType QSGD3D12VertexColorMaterial::mtype; - -QSGMaterialType *QSGD3D12VertexColorMaterial::type() const -{ - return &QSGD3D12VertexColorMaterial::mtype; -} - -int QSGD3D12VertexColorMaterial::compare(const QSGMaterial *other) const -{ - Q_UNUSED(other); - Q_ASSERT(other && type() == other->type()); - // As the vertex color material has all its state in the vertex attributes - // defined by the geometry, all such materials will be equal. - return 0; -} - -static const int VERTEX_COLOR_CB_SIZE_0 = 16 * sizeof(float); // float4x4 -static const int VERTEX_COLOR_CB_SIZE_1 = sizeof(float); // float -static const int VERTEX_COLOR_CB_SIZE = VERTEX_COLOR_CB_SIZE_0 + VERTEX_COLOR_CB_SIZE_1; - -int QSGD3D12VertexColorMaterial::constantBufferSize() const -{ - return QSGD3D12Engine::alignedConstantBufferSize(VERTEX_COLOR_CB_SIZE); -} - -void QSGD3D12VertexColorMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState) -{ - pipelineState->shaders.vs = g_VS_VertexColor; - pipelineState->shaders.vsSize = sizeof(g_VS_VertexColor); - pipelineState->shaders.ps = g_PS_VertexColor; - pipelineState->shaders.psSize = sizeof(g_PS_VertexColor); -} - -QSGD3D12Material::UpdateResults QSGD3D12VertexColorMaterial::updatePipeline(const QSGD3D12MaterialRenderState &state, - QSGD3D12PipelineState *, - ExtraState *, - quint8 *constantBuffer) -{ - QSGD3D12Material::UpdateResults r = 0; - quint8 *p = constantBuffer; - - if (state.isMatrixDirty()) { - memcpy(p, state.combinedMatrix().constData(), VERTEX_COLOR_CB_SIZE_0); - r |= UpdatedConstantBuffer; - } - p += VERTEX_COLOR_CB_SIZE_0; - - if (state.isOpacityDirty()) { - const float opacity = state.opacity(); - memcpy(p, &opacity, VERTEX_COLOR_CB_SIZE_1); - r |= UpdatedConstantBuffer; - } - - return r; -} - -QSGD3D12FlatColorMaterial::QSGD3D12FlatColorMaterial() - : m_color(QColor(255, 255, 255)) -{ -} - -QSGMaterialType QSGD3D12FlatColorMaterial::mtype; - -QSGMaterialType *QSGD3D12FlatColorMaterial::type() const -{ - return &QSGD3D12FlatColorMaterial::mtype; -} - -int QSGD3D12FlatColorMaterial::compare(const QSGMaterial *other) const -{ - Q_ASSERT(other && type() == other->type()); - const QSGD3D12FlatColorMaterial *o = static_cast<const QSGD3D12FlatColorMaterial *>(other); - return m_color.rgba() - o->color().rgba(); -} - -static const int FLAT_COLOR_CB_SIZE_0 = 16 * sizeof(float); // float4x4 -static const int FLAT_COLOR_CB_SIZE_1 = 4 * sizeof(float); // float4 -static const int FLAT_COLOR_CB_SIZE = FLAT_COLOR_CB_SIZE_0 + FLAT_COLOR_CB_SIZE_1; - -int QSGD3D12FlatColorMaterial::constantBufferSize() const -{ - return QSGD3D12Engine::alignedConstantBufferSize(FLAT_COLOR_CB_SIZE); -} - -void QSGD3D12FlatColorMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState) -{ - pipelineState->shaders.vs = g_VS_FlatColor; - pipelineState->shaders.vsSize = sizeof(g_VS_FlatColor); - pipelineState->shaders.ps = g_PS_FlatColor; - pipelineState->shaders.psSize = sizeof(g_PS_FlatColor); -} - -QSGD3D12Material::UpdateResults QSGD3D12FlatColorMaterial::updatePipeline(const QSGD3D12MaterialRenderState &state, - QSGD3D12PipelineState *, - ExtraState *, - quint8 *constantBuffer) -{ - QSGD3D12Material::UpdateResults r = 0; - quint8 *p = constantBuffer; - - if (state.isMatrixDirty()) { - memcpy(p, state.combinedMatrix().constData(), FLAT_COLOR_CB_SIZE_0); - r |= UpdatedConstantBuffer; - } - p += FLAT_COLOR_CB_SIZE_0; - - const QVector4D color = qsg_premultiply(m_color, state.opacity()); - const float f[] = { color.x(), color.y(), color.z(), color.w() }; - if (state.isOpacityDirty() || memcmp(p, f, FLAT_COLOR_CB_SIZE_1)) { - memcpy(p, f, FLAT_COLOR_CB_SIZE_1); - r |= UpdatedConstantBuffer; - } - - return r; -} - -void QSGD3D12FlatColorMaterial::setColor(const QColor &color) -{ - m_color = color; - setFlag(Blending, m_color.alpha() != 0xFF); -} - -QSGD3D12SmoothColorMaterial::QSGD3D12SmoothColorMaterial() -{ - setFlag(RequiresFullMatrixExceptTranslate, true); - setFlag(Blending, true); -} - -QSGMaterialType QSGD3D12SmoothColorMaterial::mtype; - -QSGMaterialType *QSGD3D12SmoothColorMaterial::type() const -{ - return &QSGD3D12SmoothColorMaterial::mtype; -} - -int QSGD3D12SmoothColorMaterial::compare(const QSGMaterial *other) const -{ - Q_UNUSED(other); - Q_ASSERT(other && type() == other->type()); - return 0; -} - -static const int SMOOTH_COLOR_CB_SIZE_0 = 16 * sizeof(float); // float4x4 -static const int SMOOTH_COLOR_CB_SIZE_1 = sizeof(float); // float -static const int SMOOTH_COLOR_CB_SIZE_2 = 2 * sizeof(float); // float2 -static const int SMOOTH_COLOR_CB_SIZE = SMOOTH_COLOR_CB_SIZE_0 + SMOOTH_COLOR_CB_SIZE_1 + SMOOTH_COLOR_CB_SIZE_2; - -int QSGD3D12SmoothColorMaterial::constantBufferSize() const -{ - return QSGD3D12Engine::alignedConstantBufferSize(SMOOTH_COLOR_CB_SIZE); -} - -void QSGD3D12SmoothColorMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState) -{ - pipelineState->shaders.vs = g_VS_SmoothColor; - pipelineState->shaders.vsSize = sizeof(g_VS_SmoothColor); - pipelineState->shaders.ps = g_PS_SmoothColor; - pipelineState->shaders.psSize = sizeof(g_PS_SmoothColor); -} - -QSGD3D12Material::UpdateResults QSGD3D12SmoothColorMaterial::updatePipeline(const QSGD3D12MaterialRenderState &state, - QSGD3D12PipelineState *, - ExtraState *, - quint8 *constantBuffer) -{ - QSGD3D12Material::UpdateResults r = 0; - quint8 *p = constantBuffer; - - if (state.isMatrixDirty()) { - memcpy(p, state.combinedMatrix().constData(), SMOOTH_COLOR_CB_SIZE_0); - r |= UpdatedConstantBuffer; - } - p += SMOOTH_COLOR_CB_SIZE_0; - - if (state.isOpacityDirty()) { - const float opacity = state.opacity(); - memcpy(p, &opacity, SMOOTH_COLOR_CB_SIZE_1); - r |= UpdatedConstantBuffer; - } - p += SMOOTH_COLOR_CB_SIZE_1; - - if (state.isMatrixDirty()) { - const QRect viewport = state.viewportRect(); - const float v[] = { 2.0f / viewport.width(), 2.0f / viewport.height() }; - memcpy(p, v, SMOOTH_COLOR_CB_SIZE_2); - r |= UpdatedConstantBuffer; - } - - return r; -} - -QSGMaterialType QSGD3D12TextureMaterial::mtype; - -QSGMaterialType *QSGD3D12TextureMaterial::type() const -{ - return &QSGD3D12TextureMaterial::mtype; -} - -int QSGD3D12TextureMaterial::compare(const QSGMaterial *other) const -{ - Q_ASSERT(other && type() == other->type()); - const QSGD3D12TextureMaterial *o = static_cast<const QSGD3D12TextureMaterial *>(other); - if (int diff = m_texture->textureId() - o->texture()->textureId()) - return diff; - return int(m_filtering) - int(o->m_filtering); -} - -static const int TEXTURE_CB_SIZE_0 = 16 * sizeof(float); // float4x4 -static const int TEXTURE_CB_SIZE_1 = sizeof(float); // float -static const int TEXTURE_CB_SIZE = TEXTURE_CB_SIZE_0 + TEXTURE_CB_SIZE_1; - -int QSGD3D12TextureMaterial::constantBufferSize() const -{ - return QSGD3D12Engine::alignedConstantBufferSize(TEXTURE_CB_SIZE); -} - -void QSGD3D12TextureMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState) -{ - pipelineState->shaders.vs = g_VS_Texture; - pipelineState->shaders.vsSize = sizeof(g_VS_Texture); - pipelineState->shaders.ps = g_PS_Texture; - pipelineState->shaders.psSize = sizeof(g_PS_Texture); - - pipelineState->shaders.rootSig.textureViewCount = 1; -} - -QSGD3D12Material::UpdateResults QSGD3D12TextureMaterial::updatePipeline(const QSGD3D12MaterialRenderState &state, - QSGD3D12PipelineState *pipelineState, - ExtraState *, - quint8 *constantBuffer) -{ - QSGD3D12Material::UpdateResults r = 0; - quint8 *p = constantBuffer; - - if (state.isMatrixDirty()) { - memcpy(p, state.combinedMatrix().constData(), TEXTURE_CB_SIZE_0); - r |= UpdatedConstantBuffer; - } - p += TEXTURE_CB_SIZE_0; - - if (state.isOpacityDirty()) { - const float opacity = state.opacity(); - memcpy(p, &opacity, TEXTURE_CB_SIZE_1); - r |= UpdatedConstantBuffer; - } - - Q_ASSERT(m_texture); - m_texture->setFiltering(m_filtering); - m_texture->setMipmapFiltering(m_mipmap_filtering); - m_texture->setHorizontalWrapMode(m_horizontal_wrap); - m_texture->setVerticalWrapMode(m_vertical_wrap); - - QSGD3D12TextureView &tv(pipelineState->shaders.rootSig.textureViews[0]); - if (m_filtering == QSGTexture::Linear) - tv.filter = m_mipmap_filtering == QSGTexture::Linear - ? QSGD3D12TextureView::FilterLinear : QSGD3D12TextureView::FilterMinMagLinearMipNearest; - else - tv.filter = m_mipmap_filtering == QSGTexture::Linear - ? QSGD3D12TextureView::FilterMinMagNearestMipLinear : QSGD3D12TextureView::FilterNearest; - tv.addressModeHoriz = m_horizontal_wrap == QSGTexture::ClampToEdge ? QSGD3D12TextureView::AddressClamp : QSGD3D12TextureView::AddressWrap; - tv.addressModeVert = m_vertical_wrap == QSGTexture::ClampToEdge ? QSGD3D12TextureView::AddressClamp : QSGD3D12TextureView::AddressWrap; - - m_texture->bind(); - - return r; -} - -void QSGD3D12TextureMaterial::setTexture(QSGTexture *texture) -{ - m_texture = texture; - setFlag(Blending, m_texture ? m_texture->hasAlphaChannel() : false); -} - -QSGD3D12SmoothTextureMaterial::QSGD3D12SmoothTextureMaterial() -{ - setFlag(RequiresFullMatrixExceptTranslate, true); - setFlag(Blending, true); -} - -QSGMaterialType QSGD3D12SmoothTextureMaterial::mtype; - -QSGMaterialType *QSGD3D12SmoothTextureMaterial::type() const -{ - return &QSGD3D12SmoothTextureMaterial::mtype; -} - -int QSGD3D12SmoothTextureMaterial::compare(const QSGMaterial *other) const -{ - Q_ASSERT(other && type() == other->type()); - const QSGD3D12SmoothTextureMaterial *o = static_cast<const QSGD3D12SmoothTextureMaterial *>(other); - if (int diff = m_texture->textureId() - o->texture()->textureId()) - return diff; - return int(m_filtering) - int(o->m_filtering); -} - -static const int SMOOTH_TEXTURE_CB_SIZE_0 = 16 * sizeof(float); // float4x4 -static const int SMOOTH_TEXTURE_CB_SIZE_1 = sizeof(float); // float -static const int SMOOTH_TEXTURE_CB_SIZE_2 = 2 * sizeof(float); // float2 -static const int SMOOTH_TEXTURE_CB_SIZE = SMOOTH_TEXTURE_CB_SIZE_0 + SMOOTH_TEXTURE_CB_SIZE_1 + SMOOTH_TEXTURE_CB_SIZE_2; - -int QSGD3D12SmoothTextureMaterial::constantBufferSize() const -{ - return QSGD3D12Engine::alignedConstantBufferSize(SMOOTH_TEXTURE_CB_SIZE); -} - -void QSGD3D12SmoothTextureMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState) -{ - pipelineState->shaders.vs = g_VS_SmoothTexture; - pipelineState->shaders.vsSize = sizeof(g_VS_SmoothTexture); - pipelineState->shaders.ps = g_PS_SmoothTexture; - pipelineState->shaders.psSize = sizeof(g_PS_SmoothTexture); - - pipelineState->shaders.rootSig.textureViewCount = 1; -} - -QSGD3D12Material::UpdateResults QSGD3D12SmoothTextureMaterial::updatePipeline(const QSGD3D12MaterialRenderState &state, - QSGD3D12PipelineState *pipelineState, - ExtraState *, - quint8 *constantBuffer) -{ - QSGD3D12Material::UpdateResults r = 0; - quint8 *p = constantBuffer; - - if (state.isMatrixDirty()) { - memcpy(p, state.combinedMatrix().constData(), SMOOTH_TEXTURE_CB_SIZE_0); - r |= UpdatedConstantBuffer; - } - p += SMOOTH_TEXTURE_CB_SIZE_0; - - if (state.isOpacityDirty()) { - const float opacity = state.opacity(); - memcpy(p, &opacity, SMOOTH_TEXTURE_CB_SIZE_1); - r |= UpdatedConstantBuffer; - } - p += SMOOTH_TEXTURE_CB_SIZE_1; - - if (state.isMatrixDirty()) { - const QRect viewport = state.viewportRect(); - const float v[] = { 2.0f / viewport.width(), 2.0f / viewport.height() }; - memcpy(p, v, SMOOTH_TEXTURE_CB_SIZE_2); - r |= UpdatedConstantBuffer; - } - - Q_ASSERT(m_texture); - m_texture->setFiltering(m_filtering); - m_texture->setMipmapFiltering(m_mipmap_filtering); - m_texture->setHorizontalWrapMode(m_horizontal_wrap); - m_texture->setVerticalWrapMode(m_vertical_wrap); - - QSGD3D12TextureView &tv(pipelineState->shaders.rootSig.textureViews[0]); - if (m_filtering == QSGTexture::Linear) - tv.filter = m_mipmap_filtering == QSGTexture::Linear - ? QSGD3D12TextureView::FilterLinear : QSGD3D12TextureView::FilterMinMagLinearMipNearest; - else - tv.filter = m_mipmap_filtering == QSGTexture::Linear - ? QSGD3D12TextureView::FilterMinMagNearestMipLinear : QSGD3D12TextureView::FilterNearest; - tv.addressModeHoriz = m_horizontal_wrap == QSGTexture::ClampToEdge ? QSGD3D12TextureView::AddressClamp : QSGD3D12TextureView::AddressWrap; - tv.addressModeVert = m_vertical_wrap == QSGTexture::ClampToEdge ? QSGD3D12TextureView::AddressClamp : QSGD3D12TextureView::AddressWrap; - - m_texture->bind(); - - return r; -} - -QSGD3D12TextMaterial::QSGD3D12TextMaterial(StyleType styleType, QSGD3D12RenderContext *rc, - const QRawFont &font, QFontEngine::GlyphFormat glyphFormat) - : m_styleType(styleType), - m_rc(rc), - m_font(font) -{ - setFlag(Blending, true); - - QRawFontPrivate *fontD = QRawFontPrivate::get(m_font); - if (QFontEngine *fontEngine = fontD->fontEngine) { - if (glyphFormat == QFontEngine::Format_None) - glyphFormat = fontEngine->glyphFormat != QFontEngine::Format_None - ? fontEngine->glyphFormat : QFontEngine::Format_A32; - - QSGD3D12Engine *d3dengine = rc->engine(); - const float devicePixelRatio = d3dengine->windowDevicePixelRatio(); - QTransform glyphCacheTransform = QTransform::fromScale(devicePixelRatio, devicePixelRatio); - if (!fontEngine->supportsTransformation(glyphCacheTransform)) - glyphCacheTransform = QTransform(); - - m_glyphCache = fontEngine->glyphCache(d3dengine, glyphFormat, glyphCacheTransform); - if (!m_glyphCache || int(m_glyphCache->glyphFormat()) != glyphFormat) { - m_glyphCache = new QSGD3D12GlyphCache(d3dengine, glyphFormat, glyphCacheTransform); - fontEngine->setGlyphCache(d3dengine, m_glyphCache.data()); - rc->registerFontengineForCleanup(fontEngine); - } - } -} - -QSGMaterialType QSGD3D12TextMaterial::mtype[QSGD3D12TextMaterial::NTextMaterialTypes]; - -QSGMaterialType *QSGD3D12TextMaterial::type() const -{ - // Format_A32 has special blend settings and therefore two materials with - // the same style but different formats where one is A32 are treated as - // different. This way the renderer can manage the pipeline state properly. - const int matStyle = m_styleType * 2; - const int matFormat = glyphCache()->glyphFormat() != QFontEngine::Format_A32 ? 0 : 1; - return &QSGD3D12TextMaterial::mtype[matStyle + matFormat]; -} - -int QSGD3D12TextMaterial::compare(const QSGMaterial *other) const -{ - Q_ASSERT(other && type() == other->type()); - const QSGD3D12TextMaterial *o = static_cast<const QSGD3D12TextMaterial *>(other); - if (m_styleType != o->m_styleType) - return m_styleType - o->m_styleType; - if (m_glyphCache != o->m_glyphCache) - return m_glyphCache.data() < o->m_glyphCache.data() ? -1 : 1; - if (m_styleShift != o->m_styleShift) - return m_styleShift.y() - o->m_styleShift.y(); - int styleColorDiff = qsg_colorDiff(m_styleColor, o->m_styleColor); - if (styleColorDiff) - return styleColorDiff; - return qsg_colorDiff(m_color, o->m_color); -} - -static const int TEXT_CB_SIZE_0 = 16 * sizeof(float); // float4x4 mvp -static const int TEXT_CB_SIZE_1 = 2 * sizeof(float); // float2 textureScale -static const int TEXT_CB_SIZE_2 = sizeof(float); // float dpr -static const int TEXT_CB_SIZE_3 = sizeof(float); // float color -static const int TEXT_CB_SIZE_4 = 4 * sizeof(float); // float4 colorVec -static const int TEXT_CB_SIZE_5 = 2 * sizeof(float); // float2 shift -static const int TEXT_CB_SIZE_5_PADDING = 2 * sizeof(float); // float2 padding (the next float4 would cross the 16-byte boundary) -static const int TEXT_CB_SIZE_6 = 4 * sizeof(float); // float4 styleColor -static const int TEXT_CB_SIZE = TEXT_CB_SIZE_0 + TEXT_CB_SIZE_1 + TEXT_CB_SIZE_2 + TEXT_CB_SIZE_3 - + TEXT_CB_SIZE_4 + TEXT_CB_SIZE_5 + TEXT_CB_SIZE_5_PADDING + TEXT_CB_SIZE_6; - -int QSGD3D12TextMaterial::constantBufferSize() const -{ - return QSGD3D12Engine::alignedConstantBufferSize(TEXT_CB_SIZE); -} - -void QSGD3D12TextMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState) -{ - if (m_styleType == Normal) { - pipelineState->shaders.vs = g_VS_TextMask; - pipelineState->shaders.vsSize = sizeof(g_VS_TextMask); - switch (glyphCache()->glyphFormat()) { - case QFontEngine::Format_A32: - pipelineState->shaders.ps = g_PS_TextMask24; - pipelineState->shaders.psSize = sizeof(g_PS_TextMask24); - break; - case QFontEngine::Format_ARGB: - pipelineState->shaders.ps = g_PS_TextMask32; - pipelineState->shaders.psSize = sizeof(g_PS_TextMask32); - break; - default: - pipelineState->shaders.ps = g_PS_TextMask8; - pipelineState->shaders.psSize = sizeof(g_PS_TextMask8); - break; - } - } else if (m_styleType == Outlined) { - pipelineState->shaders.vs = g_VS_OutlinedText; - pipelineState->shaders.vsSize = sizeof(g_VS_OutlinedText); - pipelineState->shaders.ps = g_PS_OutlinedText; - pipelineState->shaders.psSize = sizeof(g_PS_OutlinedText); - } else { - pipelineState->shaders.vs = g_VS_StyledText; - pipelineState->shaders.vsSize = sizeof(g_VS_StyledText); - pipelineState->shaders.ps = g_PS_StyledText; - pipelineState->shaders.psSize = sizeof(g_PS_StyledText); - } - - pipelineState->shaders.rootSig.textureViewCount = 1; -} - -QSGD3D12Material::UpdateResults QSGD3D12TextMaterial::updatePipeline(const QSGD3D12MaterialRenderState &state, - QSGD3D12PipelineState *pipelineState, - ExtraState *extraState, - quint8 *constantBuffer) -{ - QSGD3D12Material::UpdateResults r = 0; - quint8 *p = constantBuffer; - - if (glyphCache()->glyphFormat() == QFontEngine::Format_A32) { - // can freely change the state due to the way type() works - pipelineState->blend = QSGD3D12PipelineState::BlendColor; - extraState->blendFactor = m_color; - r |= UpdatedBlendFactor; // must be set always as this affects the command list - } - - if (state.isMatrixDirty()) { - memcpy(p, state.combinedMatrix().constData(), TEXT_CB_SIZE_0); - r |= UpdatedConstantBuffer; - } - p += TEXT_CB_SIZE_0; - - const QSize sz = glyphCache()->currentSize(); - const float textureScale[] = { 1.0f / sz.width(), 1.0f / sz.height() }; - if (state.isCachedMaterialDataDirty() || memcmp(p, textureScale, TEXT_CB_SIZE_1)) { - memcpy(p, textureScale, TEXT_CB_SIZE_1); - r |= UpdatedConstantBuffer; - } - p += TEXT_CB_SIZE_1; - - const float dpr = m_rc->engine()->windowDevicePixelRatio(); - if (state.isCachedMaterialDataDirty() || memcmp(p, &dpr, TEXT_CB_SIZE_2)) { - memcpy(p, &dpr, TEXT_CB_SIZE_2); - r |= UpdatedConstantBuffer; - } - p += TEXT_CB_SIZE_2; - - if (glyphCache()->glyphFormat() == QFontEngine::Format_A32) { - const QVector4D color = qsg_premultiply(m_color, state.opacity()); - const float alpha = color.w(); - if (state.isOpacityDirty() || memcmp(p, &alpha, TEXT_CB_SIZE_3)) { - memcpy(p, &alpha, TEXT_CB_SIZE_3); - r |= UpdatedConstantBuffer; - } - } else if (glyphCache()->glyphFormat() == QFontEngine::Format_ARGB) { - const float opacity = m_color.w() * state.opacity(); - if (state.isOpacityDirty() || memcmp(p, &opacity, TEXT_CB_SIZE_3)) { - memcpy(p, &opacity, TEXT_CB_SIZE_3); - r |= UpdatedConstantBuffer; - } - } else { - const QVector4D color = qsg_premultiply(m_color, state.opacity()); - const float f[] = { color.x(), color.y(), color.z(), color.w() }; - if (state.isOpacityDirty() || memcmp(p, f, TEXT_CB_SIZE_4)) { - memcpy(p + TEXT_CB_SIZE_3, f, TEXT_CB_SIZE_4); - r |= UpdatedConstantBuffer; - } - } - p += TEXT_CB_SIZE_3 + TEXT_CB_SIZE_4; - - if (m_styleType == Styled) { - const float f[] = { m_styleShift.x(), m_styleShift.y() }; - if (state.isCachedMaterialDataDirty() || memcmp(p, f, TEXT_CB_SIZE_5)) { - memcpy(p, f, TEXT_CB_SIZE_5); - r |= UpdatedConstantBuffer; - } - } - p += TEXT_CB_SIZE_5 + TEXT_CB_SIZE_5_PADDING; - - if (m_styleType == Styled || m_styleType == Outlined) { - const QVector4D color = qsg_premultiply(m_styleColor, state.opacity()); - const float f[] = { color.x(), color.y(), color.z(), color.w() }; - if (state.isOpacityDirty() || memcmp(p, f, TEXT_CB_SIZE_6)) { - memcpy(p, f, TEXT_CB_SIZE_6); - r |= UpdatedConstantBuffer; - } - } - - QSGD3D12TextureView &tv(pipelineState->shaders.rootSig.textureViews[0]); - tv.filter = QSGD3D12TextureView::FilterNearest; - tv.addressModeHoriz = QSGD3D12TextureView::AddressClamp; - tv.addressModeVert = QSGD3D12TextureView::AddressClamp; - - glyphCache()->useTexture(); - - return r; -} - -void QSGD3D12TextMaterial::populate(const QPointF &p, - const QVector<quint32> &glyphIndexes, - const QVector<QPointF> &glyphPositions, - QSGGeometry *geometry, - QRectF *boundingRect, - QPointF *baseLine, - const QMargins &margins) -{ - Q_ASSERT(m_font.isValid()); - QVector<QFixedPoint> fixedPointPositions; - const int glyphPositionsSize = glyphPositions.size(); - fixedPointPositions.reserve(glyphPositionsSize); - for (int i=0; i < glyphPositionsSize; ++i) - fixedPointPositions.append(QFixedPoint::fromPointF(glyphPositions.at(i))); - - QSGD3D12GlyphCache *cache = glyphCache(); - QRawFontPrivate *fontD = QRawFontPrivate::get(m_font); - cache->populate(fontD->fontEngine, glyphIndexes.size(), glyphIndexes.constData(), - fixedPointPositions.data()); - cache->fillInPendingGlyphs(); - - int margin = fontD->fontEngine->glyphMargin(cache->glyphFormat()); - - float glyphCacheScaleX = cache->transform().m11(); - float glyphCacheScaleY = cache->transform().m22(); - float glyphCacheInverseScaleX = 1.0 / glyphCacheScaleX; - float glyphCacheInverseScaleY = 1.0 / glyphCacheScaleY; - - Q_ASSERT(geometry->indexType() == QSGGeometry::UnsignedShortType); - geometry->allocate(glyphIndexes.size() * 4, glyphIndexes.size() * 6); - QVector4D *vp = reinterpret_cast<QVector4D *>(geometry->vertexDataAsTexturedPoint2D()); - Q_ASSERT(geometry->sizeOfVertex() == sizeof(QVector4D)); - ushort *ip = geometry->indexDataAsUShort(); - - QPointF position(p.x(), p.y() - m_font.ascent()); - bool supportsSubPixelPositions = fontD->fontEngine->supportsSubPixelPositions(); - for (int i = 0; i < glyphIndexes.size(); ++i) { - QFixed subPixelPosition; - if (supportsSubPixelPositions) - subPixelPosition = fontD->fontEngine->subPixelPositionForX(QFixed::fromReal(glyphPositions.at(i).x())); - - QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphIndexes.at(i), subPixelPosition); - const QTextureGlyphCache::Coord &c = cache->coords.value(glyph); - - QPointF glyphPosition = glyphPositions.at(i) + position; - float x = (qFloor(glyphPosition.x() * glyphCacheScaleX) * glyphCacheInverseScaleX) - + (c.baseLineX * glyphCacheInverseScaleX) - margin; - float y = (qRound(glyphPosition.y() * glyphCacheScaleY) * glyphCacheInverseScaleY) - - (c.baseLineY * glyphCacheInverseScaleY) - margin; - - float w = c.w * glyphCacheInverseScaleX; - float h = c.h * glyphCacheInverseScaleY; - - *boundingRect |= QRectF(x + margin, y + margin, w, h); - - float cx1 = x - margins.left(); - float cx2 = x + w + margins.right(); - float cy1 = y - margins.top(); - float cy2 = y + h + margins.bottom(); - - float tx1 = c.x - margins.left(); - float tx2 = c.x + c.w + margins.right(); - float ty1 = c.y - margins.top(); - float ty2 = c.y + c.h + margins.bottom(); - - if (baseLine->isNull()) - *baseLine = glyphPosition; - - vp[4 * i + 0] = QVector4D(cx1, cy1, tx1, ty1); - vp[4 * i + 1] = QVector4D(cx2, cy1, tx2, ty1); - vp[4 * i + 2] = QVector4D(cx1, cy2, tx1, ty2); - vp[4 * i + 3] = QVector4D(cx2, cy2, tx2, ty2); - - int o = i * 4; - ip[6 * i + 0] = o + 0; - ip[6 * i + 1] = o + 2; - ip[6 * i + 2] = o + 3; - ip[6 * i + 3] = o + 3; - ip[6 * i + 4] = o + 1; - ip[6 * i + 5] = o + 0; - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials_p.h deleted file mode 100644 index 8e488f8cd1..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials_p.h +++ /dev/null @@ -1,253 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSGD3D12BUILTINMATERIALS_P_H -#define QSGD3D12BUILTINMATERIALS_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qsgd3d12material_p.h" -#include "qsgd3d12glyphcache_p.h" -#include <private/qsgtexture_p.h> -#include <QRawFont> - -QT_BEGIN_NAMESPACE - -class QSGD3D12RenderContext; - -class QSGD3D12VertexColorMaterial : public QSGD3D12Material -{ -public: - QSGMaterialType *type() const override; - int compare(const QSGMaterial *other) const override; - - int constantBufferSize() const override; - void preparePipeline(QSGD3D12PipelineState *pipelineState) override; - UpdateResults updatePipeline(const QSGD3D12MaterialRenderState &state, - QSGD3D12PipelineState *pipelineState, - ExtraState *extraState, - quint8 *constantBuffer) override; - -private: - static QSGMaterialType mtype; -}; - -class QSGD3D12FlatColorMaterial : public QSGD3D12Material -{ -public: - QSGD3D12FlatColorMaterial(); - QSGMaterialType *type() const override; - int compare(const QSGMaterial *other) const override; - - int constantBufferSize() const override; - void preparePipeline(QSGD3D12PipelineState *pipelineState) override; - UpdateResults updatePipeline(const QSGD3D12MaterialRenderState &state, - QSGD3D12PipelineState *pipelineState, - ExtraState *extraState, - quint8 *constantBuffer) override; - - void setColor(const QColor &color); - QColor color() const { return m_color; } - -private: - static QSGMaterialType mtype; - QColor m_color; -}; - -class QSGD3D12SmoothColorMaterial : public QSGD3D12Material -{ -public: - QSGD3D12SmoothColorMaterial(); - QSGMaterialType *type() const override; - int compare(const QSGMaterial *other) const override; - - int constantBufferSize() const override; - void preparePipeline(QSGD3D12PipelineState *pipelineState) override; - UpdateResults updatePipeline(const QSGD3D12MaterialRenderState &state, - QSGD3D12PipelineState *pipelineState, - ExtraState *extraState, - quint8 *constantBuffer) override; - -private: - static QSGMaterialType mtype; -}; - -class QSGD3D12TextureMaterial : public QSGD3D12Material -{ -public: - QSGMaterialType *type() const override; - int compare(const QSGMaterial *other) const override; - - int constantBufferSize() const override; - void preparePipeline(QSGD3D12PipelineState *pipelineState) override; - UpdateResults updatePipeline(const QSGD3D12MaterialRenderState &state, - QSGD3D12PipelineState *pipelineState, - ExtraState *extraState, - quint8 *constantBuffer) override; - - void setTexture(QSGTexture *texture); - QSGTexture *texture() const { return m_texture; } - - void setMipmapFiltering(QSGTexture::Filtering filter) { m_mipmap_filtering = filter; } - QSGTexture::Filtering mipmapFiltering() const { return m_mipmap_filtering; } - - void setFiltering(QSGTexture::Filtering filter) { m_filtering = filter; } - QSGTexture::Filtering filtering() const { return m_filtering; } - - void setHorizontalWrapMode(QSGTexture::WrapMode hwrap) { m_horizontal_wrap = hwrap; } - QSGTexture::WrapMode horizontalWrapMode() const { return m_horizontal_wrap; } - - void setVerticalWrapMode(QSGTexture::WrapMode vwrap) { m_vertical_wrap = vwrap; } - QSGTexture::WrapMode verticalWrapMode() const { return m_vertical_wrap; } - -private: - static QSGMaterialType mtype; - - QSGTexture *m_texture = nullptr; - QSGTexture::Filtering m_filtering = QSGTexture::Nearest; - QSGTexture::Filtering m_mipmap_filtering = QSGTexture::None; - QSGTexture::WrapMode m_horizontal_wrap = QSGTexture::ClampToEdge; - QSGTexture::WrapMode m_vertical_wrap = QSGTexture::ClampToEdge; -}; - -class QSGD3D12SmoothTextureMaterial : public QSGD3D12Material -{ -public: - QSGD3D12SmoothTextureMaterial(); - - QSGMaterialType *type() const override; - int compare(const QSGMaterial *other) const override; - - int constantBufferSize() const override; - void preparePipeline(QSGD3D12PipelineState *pipelineState) override; - UpdateResults updatePipeline(const QSGD3D12MaterialRenderState &state, - QSGD3D12PipelineState *pipelineState, - ExtraState *extraState, - quint8 *constantBuffer) override; - - void setTexture(QSGTexture *texture) { m_texture = texture; } - QSGTexture *texture() const { return m_texture; } - - void setMipmapFiltering(QSGTexture::Filtering filter) { m_mipmap_filtering = filter; } - QSGTexture::Filtering mipmapFiltering() const { return m_mipmap_filtering; } - - void setFiltering(QSGTexture::Filtering filter) { m_filtering = filter; } - QSGTexture::Filtering filtering() const { return m_filtering; } - - void setHorizontalWrapMode(QSGTexture::WrapMode hwrap) { m_horizontal_wrap = hwrap; } - QSGTexture::WrapMode horizontalWrapMode() const { return m_horizontal_wrap; } - - void setVerticalWrapMode(QSGTexture::WrapMode vwrap) { m_vertical_wrap = vwrap; } - QSGTexture::WrapMode verticalWrapMode() const { return m_vertical_wrap; } - -private: - static QSGMaterialType mtype; - - QSGTexture *m_texture = nullptr; - QSGTexture::Filtering m_filtering = QSGTexture::Nearest; - QSGTexture::Filtering m_mipmap_filtering = QSGTexture::None; - QSGTexture::WrapMode m_horizontal_wrap = QSGTexture::ClampToEdge; - QSGTexture::WrapMode m_vertical_wrap = QSGTexture::ClampToEdge; -}; - -class QSGD3D12TextMaterial : public QSGD3D12Material -{ -public: - enum StyleType { - Normal, - Styled, - Outlined, - - NStyleTypes - }; - QSGD3D12TextMaterial(StyleType styleType, QSGD3D12RenderContext *rc, const QRawFont &font, - QFontEngine::GlyphFormat glyphFormat = QFontEngine::Format_None); - - QSGMaterialType *type() const override; - int compare(const QSGMaterial *other) const override; - - int constantBufferSize() const override; - void preparePipeline(QSGD3D12PipelineState *pipelineState) override; - UpdateResults updatePipeline(const QSGD3D12MaterialRenderState &state, - QSGD3D12PipelineState *pipelineState, - ExtraState *extraState, - quint8 *constantBuffer) override; - - void setColor(const QColor &c) { m_color = QVector4D(c.redF(), c.greenF(), c.blueF(), c.alphaF()); } - void setColor(const QVector4D &color) { m_color = color; } - const QVector4D &color() const { return m_color; } - - void setStyleShift(const QVector2D &shift) { m_styleShift = shift; } - const QVector2D &styleShift() const { return m_styleShift; } - - void setStyleColor(const QColor &c) { m_styleColor = QVector4D(c.redF(), c.greenF(), c.blueF(), c.alphaF()); } - void setStyleColor(const QVector4D &color) { m_styleColor = color; } - const QVector4D &styleColor() const { return m_styleColor; } - - void populate(const QPointF &position, - const QVector<quint32> &glyphIndexes, const QVector<QPointF> &glyphPositions, - QSGGeometry *geometry, QRectF *boundingRect, QPointF *baseLine, - const QMargins &margins = QMargins(0, 0, 0, 0)); - - QSGD3D12GlyphCache *glyphCache() const { return static_cast<QSGD3D12GlyphCache *>(m_glyphCache.data()); } - -private: - static const int NTextMaterialTypes = NStyleTypes * 2; - static QSGMaterialType mtype[NTextMaterialTypes]; - StyleType m_styleType; - QSGD3D12RenderContext *m_rc; - QVector4D m_color; - QVector2D m_styleShift; - QVector4D m_styleColor; - QRawFont m_font; - QExplicitlySharedDataPointer<QFontEngineGlyphCache> m_glyphCache; -}; - -QT_END_NAMESPACE - -#endif // QSGD3D12BUILTINMATERIALS_P_H diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12context.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12context.cpp deleted file mode 100644 index f9bd04aa54..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12context.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsgd3d12context_p.h" -#include "qsgd3d12rendercontext_p.h" -#include "qsgd3d12internalrectanglenode_p.h" -#include "qsgd3d12internalimagenode_p.h" -#include "qsgd3d12glyphnode_p.h" -#include "qsgd3d12layer_p.h" -#include "qsgd3d12shadereffectnode_p.h" -#include "qsgd3d12painternode_p.h" -#include "qsgd3d12publicnodes_p.h" -#include "qsgd3d12spritenode_p.h" -#include <QtQuick/qquickwindow.h> - -QT_BEGIN_NAMESPACE - -QSGRenderContext *QSGD3D12Context::createRenderContext() -{ - return new QSGD3D12RenderContext(this); -} - -QSGInternalRectangleNode *QSGD3D12Context::createInternalRectangleNode() -{ - return new QSGD3D12InternalRectangleNode; -} - -QSGInternalImageNode *QSGD3D12Context::createInternalImageNode(QSGRenderContext *renderContext) -{ - Q_UNUSED(renderContext); - return new QSGD3D12InternalImageNode; -} - -QSGPainterNode *QSGD3D12Context::createPainterNode(QQuickPaintedItem *item) -{ - return new QSGD3D12PainterNode(item); -} - -QSGGlyphNode *QSGD3D12Context::createGlyphNode(QSGRenderContext *renderContext, bool preferNativeGlyphNode) -{ - Q_UNUSED(preferNativeGlyphNode); - // ### distance field text rendering is not supported atm - - QSGD3D12RenderContext *rc = static_cast<QSGD3D12RenderContext *>(renderContext); - return new QSGD3D12GlyphNode(rc); -} - -QSGLayer *QSGD3D12Context::createLayer(QSGRenderContext *renderContext) -{ - QSGD3D12RenderContext *rc = static_cast<QSGD3D12RenderContext *>(renderContext); - return new QSGD3D12Layer(rc); -} - -QSGGuiThreadShaderEffectManager *QSGD3D12Context::createGuiThreadShaderEffectManager() -{ - return new QSGD3D12GuiThreadShaderEffectManager; -} - -QSGShaderEffectNode *QSGD3D12Context::createShaderEffectNode(QSGRenderContext *renderContext, - QSGGuiThreadShaderEffectManager *mgr) -{ - QSGD3D12RenderContext *rc = static_cast<QSGD3D12RenderContext *>(renderContext); - QSGD3D12GuiThreadShaderEffectManager *dmgr = static_cast<QSGD3D12GuiThreadShaderEffectManager *>(mgr); - return new QSGD3D12ShaderEffectNode(rc, dmgr); -} - -QSize QSGD3D12Context::minimumFBOSize() const -{ - return QSize(16, 16); -} - -QSurfaceFormat QSGD3D12Context::defaultSurfaceFormat() const -{ - QSurfaceFormat format = QSurfaceFormat::defaultFormat(); - - if (QQuickWindow::hasDefaultAlphaBuffer()) - format.setAlphaBufferSize(8); - - return format; -} - -QSGRendererInterface *QSGD3D12Context::rendererInterface(QSGRenderContext *renderContext) -{ - return static_cast<QSGD3D12RenderContext *>(renderContext); -} - -QSGRectangleNode *QSGD3D12Context::createRectangleNode() -{ - return new QSGD3D12RectangleNode; -} - -QSGImageNode *QSGD3D12Context::createImageNode() -{ - return new QSGD3D12ImageNode; -} - -QSGNinePatchNode *QSGD3D12Context::createNinePatchNode() -{ - return new QSGD3D12NinePatchNode; -} - -QSGSpriteNode *QSGD3D12Context::createSpriteNode() -{ - return new QSGD3D12SpriteNode; -} - -QT_END_NAMESPACE diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12context_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12context_p.h deleted file mode 100644 index 382183fef6..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12context_p.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSGD3D12CONTEXT_P_H -#define QSGD3D12CONTEXT_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qsgcontext_p.h> - -QT_BEGIN_NAMESPACE - -class QSGD3D12Context : public QSGContext -{ -public: - QSGD3D12Context(QObject *parent = 0) : QSGContext(parent) { } - - QSGRenderContext *createRenderContext() override; - QSGInternalRectangleNode *createInternalRectangleNode() override; - QSGInternalImageNode *createInternalImageNode(QSGRenderContext *renderContext) override; - QSGPainterNode *createPainterNode(QQuickPaintedItem *item) override; - QSGGlyphNode *createGlyphNode(QSGRenderContext *renderContext, bool preferNativeGlyphNode) override; - QSGLayer *createLayer(QSGRenderContext *renderContext) override; - QSGGuiThreadShaderEffectManager *createGuiThreadShaderEffectManager() override; - QSGShaderEffectNode *createShaderEffectNode(QSGRenderContext *renderContext, - QSGGuiThreadShaderEffectManager *mgr) override; - QSize minimumFBOSize() const override; - QSurfaceFormat defaultSurfaceFormat() const override; - QSGRendererInterface *rendererInterface(QSGRenderContext *renderContext) override; - QSGRectangleNode *createRectangleNode() override; - QSGImageNode *createImageNode() override; - QSGNinePatchNode *createNinePatchNode() override; - QSGSpriteNode *createSpriteNode() override; - -}; - -QT_END_NAMESPACE - -#endif // QSGD3D12CONTEXT_P_H diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp deleted file mode 100644 index 75bde2c66b..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp +++ /dev/null @@ -1,3280 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsgd3d12engine_p.h" -#include "qsgd3d12engine_p_p.h" -#include "cs_mipmapgen.hlslh" -#include <QString> -#include <QColor> -#include <QLoggingCategory> -#include <qmath.h> -#include <qalgorithms.h> - -// Comment out to disable DeviceLossTester functionality in order to reduce -// code size and improve startup perf a tiny bit. -#define DEVLOSS_TEST - -#ifdef DEVLOSS_TEST -#include "cs_tdr.hlslh" -#endif - -#ifdef Q_OS_WINRT -#include <QtCore/private/qeventdispatcher_winrt_p.h> -#include <functional> -#include <windows.ui.xaml.h> -#include <windows.ui.xaml.media.dxinterop.h> -#endif - -#include <comdef.h> - -QT_BEGIN_NAMESPACE - -// NOTE: Avoid categorized logging. It is slow. - -#define DECLARE_DEBUG_VAR(variable) \ - static bool debug_ ## variable() \ - { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; } - -DECLARE_DEBUG_VAR(render) -DECLARE_DEBUG_VAR(descheap) -DECLARE_DEBUG_VAR(buffer) -DECLARE_DEBUG_VAR(texture) - -// Except for system info on startup. -Q_LOGGING_CATEGORY(QSG_LOG_INFO_GENERAL, "qt.scenegraph.general") - - -// Any changes to the defaults below must be reflected in adaptations.qdoc as -// well and proven by qmlbench or similar. - -static const int DEFAULT_SWAP_CHAIN_BUFFER_COUNT = 3; -static const int DEFAULT_FRAME_IN_FLIGHT_COUNT = 2; -static const int DEFAULT_WAITABLE_SWAP_CHAIN_MAX_LATENCY = 0; - -static const int MAX_DRAW_CALLS_PER_LIST = 4096; - -static const int MAX_CACHED_ROOTSIG = 16; -static const int MAX_CACHED_PSO = 64; - -static const int GPU_CBVSRVUAV_DESCRIPTORS = 512; - -static const DXGI_FORMAT RT_COLOR_FORMAT = DXGI_FORMAT_R8G8B8A8_UNORM; - -static const int BUCKETS_PER_HEAP = 8; // must match freeMap -static const int DESCRIPTORS_PER_BUCKET = 32; // the bit map (freeMap) is quint32 -static const int MAX_DESCRIPTORS_PER_HEAP = BUCKETS_PER_HEAP * DESCRIPTORS_PER_BUCKET; - -static QString comErrorMessage(HRESULT hr) -{ -#ifndef Q_OS_WINRT - const _com_error comError(hr); -#else - const _com_error comError(hr, nullptr); -#endif - QString result = QLatin1String("Error 0x") + QString::number(ulong(hr), 16); - if (const wchar_t *msg = comError.ErrorMessage()) - result += QLatin1String(": ") + QString::fromWCharArray(msg); - return result; -} - -D3D12_CPU_DESCRIPTOR_HANDLE QSGD3D12CPUDescriptorHeapManager::allocate(D3D12_DESCRIPTOR_HEAP_TYPE type) -{ - D3D12_CPU_DESCRIPTOR_HANDLE h = {}; - for (Heap &heap : m_heaps) { - if (heap.type == type) { - for (int bucket = 0; bucket < _countof(heap.freeMap); ++bucket) - if (heap.freeMap[bucket]) { - uint freePos = qCountTrailingZeroBits(heap.freeMap[bucket]); - heap.freeMap[bucket] &= ~(1UL << freePos); - if (Q_UNLIKELY(debug_descheap())) - qDebug("descriptor handle heap %p type %x reserve in bucket %d index %d", &heap, type, bucket, freePos); - freePos += bucket * DESCRIPTORS_PER_BUCKET; - h = heap.start; - h.ptr += freePos * heap.handleSize; - return h; - } - } - } - - Heap heap; - heap.type = type; - heap.handleSize = m_handleSizes[type]; - - D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {}; - heapDesc.NumDescriptors = MAX_DESCRIPTORS_PER_HEAP; - heapDesc.Type = type; - // The heaps created here are _never_ shader-visible. - - HRESULT hr = m_device->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&heap.heap)); - if (FAILED(hr)) { - qWarning("Failed to create heap with type 0x%x: %s", - type, qPrintable(comErrorMessage(hr))); - return h; - } - - heap.start = heap.heap->GetCPUDescriptorHandleForHeapStart(); - - if (Q_UNLIKELY(debug_descheap())) - qDebug("new descriptor heap, type %x, start %llu", type, heap.start.ptr); - - heap.freeMap[0] = 0xFFFFFFFE; - for (int i = 1; i < _countof(heap.freeMap); ++i) - heap.freeMap[i] = 0xFFFFFFFF; - - h = heap.start; - - m_heaps.append(heap); - - return h; -} - -void QSGD3D12CPUDescriptorHeapManager::release(D3D12_CPU_DESCRIPTOR_HANDLE handle, D3D12_DESCRIPTOR_HEAP_TYPE type) -{ - for (Heap &heap : m_heaps) { - if (heap.type == type - && handle.ptr >= heap.start.ptr - && handle.ptr < heap.start.ptr + heap.handleSize * MAX_DESCRIPTORS_PER_HEAP) { - unsigned long pos = (handle.ptr - heap.start.ptr) / heap.handleSize; - const int bucket = pos / DESCRIPTORS_PER_BUCKET; - const int indexInBucket = pos - bucket * DESCRIPTORS_PER_BUCKET; - heap.freeMap[bucket] |= 1UL << indexInBucket; - if (Q_UNLIKELY(debug_descheap())) - qDebug("free descriptor handle heap %p type %x bucket %d index %d", &heap, type, bucket, indexInBucket); - return; - } - } - qWarning("QSGD3D12CPUDescriptorHeapManager: Attempted to release untracked descriptor handle %llu of type %d", handle.ptr, type); -} - -void QSGD3D12CPUDescriptorHeapManager::initialize(ID3D12Device *device) -{ - m_device = device; - - for (int i = 0; i < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; ++i) - m_handleSizes[i] = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE(i)); -} - -void QSGD3D12CPUDescriptorHeapManager::releaseResources() -{ - for (Heap &heap : m_heaps) - heap.heap = nullptr; - - m_heaps.clear(); - - m_device = nullptr; -} - -// One device per process, one everything else (engine) per window. -Q_GLOBAL_STATIC(QSGD3D12DeviceManager, deviceManager) - -static void getHardwareAdapter(IDXGIFactory1 *factory, IDXGIAdapter1 **outAdapter) -{ - const D3D_FEATURE_LEVEL fl = D3D_FEATURE_LEVEL_11_0; - ComPtr<IDXGIAdapter1> adapter; - DXGI_ADAPTER_DESC1 desc; - - for (int adapterIndex = 0; factory->EnumAdapters1(adapterIndex, &adapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) { - DXGI_ADAPTER_DESC1 desc; - adapter->GetDesc1(&desc); - const QString name = QString::fromUtf16((char16_t *) desc.Description); - qCDebug(QSG_LOG_INFO_GENERAL, "Adapter %d: '%s' (flags 0x%x)", adapterIndex, qPrintable(name), desc.Flags); - } - - if (qEnvironmentVariableIsSet("QT_D3D_ADAPTER_INDEX")) { - const int adapterIndex = qEnvironmentVariableIntValue("QT_D3D_ADAPTER_INDEX"); - if (SUCCEEDED(factory->EnumAdapters1(adapterIndex, &adapter))) { - adapter->GetDesc1(&desc); - const QString name = QString::fromUtf16((char16_t *) desc.Description); - HRESULT hr = D3D12CreateDevice(adapter.Get(), fl, _uuidof(ID3D12Device), nullptr); - if (SUCCEEDED(hr)) { - qCDebug(QSG_LOG_INFO_GENERAL, "Using requested adapter '%s'", qPrintable(name)); - *outAdapter = adapter.Detach(); - return; - } else { - qWarning("Failed to create device for requested adapter '%s': %s", - qPrintable(name), qPrintable(comErrorMessage(hr))); - } - } - } - - for (int adapterIndex = 0; factory->EnumAdapters1(adapterIndex, &adapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) { - adapter->GetDesc1(&desc); - if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) - continue; - - if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), fl, _uuidof(ID3D12Device), nullptr))) { - const QString name = QString::fromUtf16((char16_t *) desc.Description); - qCDebug(QSG_LOG_INFO_GENERAL, "Using adapter '%s'", qPrintable(name)); - break; - } - } - - *outAdapter = adapter.Detach(); -} - -ID3D12Device *QSGD3D12DeviceManager::ref() -{ - ensureCreated(); - m_ref.ref(); - return m_device.Get(); -} - -void QSGD3D12DeviceManager::unref() -{ - if (!m_ref.deref()) { - if (Q_UNLIKELY(debug_render())) - qDebug("destroying d3d device"); - m_device = nullptr; - m_factory = nullptr; - } -} - -void QSGD3D12DeviceManager::deviceLossDetected() -{ - for (DeviceLossObserver *observer : qAsConst(m_observers)) - observer->deviceLost(); - - // Nothing else to do here. All windows are expected to release their - // resources and call unref() in response immediately. -} - -IDXGIFactory4 *QSGD3D12DeviceManager::dxgi() -{ - ensureCreated(); - return m_factory.Get(); -} - -void QSGD3D12DeviceManager::ensureCreated() -{ - if (m_device) - return; - - HRESULT hr = CreateDXGIFactory2(0, IID_PPV_ARGS(&m_factory)); - if (FAILED(hr)) { - qWarning("Failed to create DXGI: %s", qPrintable(comErrorMessage(hr))); - return; - } - - ComPtr<IDXGIAdapter1> adapter; - getHardwareAdapter(m_factory.Get(), &adapter); - - bool warp = true; - if (adapter) { - HRESULT hr = D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device)); - if (SUCCEEDED(hr)) - warp = false; - else - qWarning("Failed to create device: %s", qPrintable(comErrorMessage(hr))); - } - - if (warp) { - qCDebug(QSG_LOG_INFO_GENERAL, "Using WARP"); - m_factory->EnumWarpAdapter(IID_PPV_ARGS(&adapter)); - HRESULT hr = D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device)); - if (FAILED(hr)) { - qWarning("Failed to create WARP device: %s", qPrintable(comErrorMessage(hr))); - return; - } - } - - ComPtr<IDXGIAdapter3> adapter3; - if (SUCCEEDED(adapter.As(&adapter3))) { - DXGI_QUERY_VIDEO_MEMORY_INFO vidMemInfo; - if (SUCCEEDED(adapter3->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &vidMemInfo))) { - qCDebug(QSG_LOG_INFO_GENERAL, "Video memory info: LOCAL: Budget %llu KB CurrentUsage %llu KB AvailableForReservation %llu KB CurrentReservation %llu KB", - vidMemInfo.Budget / 1024, vidMemInfo.CurrentUsage / 1024, - vidMemInfo.AvailableForReservation / 1024, vidMemInfo.CurrentReservation / 1024); - } - if (SUCCEEDED(adapter3->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, &vidMemInfo))) { - qCDebug(QSG_LOG_INFO_GENERAL, "Video memory info: NON-LOCAL: Budget %llu KB CurrentUsage %llu KB AvailableForReservation %llu KB CurrentReservation %llu KB", - vidMemInfo.Budget / 1024, vidMemInfo.CurrentUsage / 1024, - vidMemInfo.AvailableForReservation / 1024, vidMemInfo.CurrentReservation / 1024); - } - } -} - -void QSGD3D12DeviceManager::registerDeviceLossObserver(DeviceLossObserver *observer) -{ - if (!m_observers.contains(observer)) - m_observers.append(observer); -} - -QSGD3D12Engine::QSGD3D12Engine() -{ - d = new QSGD3D12EnginePrivate; -} - -QSGD3D12Engine::~QSGD3D12Engine() -{ - d->waitGPU(); - d->releaseResources(); - delete d; -} - -bool QSGD3D12Engine::attachToWindow(WId window, const QSize &size, float dpr, int surfaceFormatSamples, bool alpha) -{ - if (d->isInitialized()) { - qWarning("QSGD3D12Engine: Cannot attach active engine to window"); - return false; - } - - d->initialize(window, size, dpr, surfaceFormatSamples, alpha); - return d->isInitialized(); -} - -void QSGD3D12Engine::releaseResources() -{ - d->releaseResources(); -} - -bool QSGD3D12Engine::hasResources() const -{ - // An explicit releaseResources() or a device loss results in initialized == false. - return d->isInitialized(); -} - -void QSGD3D12Engine::setWindowSize(const QSize &size, float dpr) -{ - d->setWindowSize(size, dpr); -} - -WId QSGD3D12Engine::window() const -{ - return d->currentWindow(); -} - -QSize QSGD3D12Engine::windowSize() const -{ - return d->currentWindowSize(); -} - -float QSGD3D12Engine::windowDevicePixelRatio() const -{ - return d->currentWindowDpr(); -} - -uint QSGD3D12Engine::windowSamples() const -{ - return d->currentWindowSamples(); -} - -void QSGD3D12Engine::beginFrame() -{ - d->beginFrame(); -} - -void QSGD3D12Engine::endFrame() -{ - d->endFrame(); -} - -void QSGD3D12Engine::beginLayer() -{ - d->beginLayer(); -} - -void QSGD3D12Engine::endLayer() -{ - d->endLayer(); -} - -void QSGD3D12Engine::invalidateCachedFrameState() -{ - d->invalidateCachedFrameState(); -} - -void QSGD3D12Engine::restoreFrameState(bool minimal) -{ - d->restoreFrameState(minimal); -} - -void QSGD3D12Engine::finalizePipeline(const QSGD3D12PipelineState &pipelineState) -{ - d->finalizePipeline(pipelineState); -} - -uint QSGD3D12Engine::genBuffer() -{ - return d->genBuffer(); -} - -void QSGD3D12Engine::releaseBuffer(uint id) -{ - d->releaseBuffer(id); -} - -void QSGD3D12Engine::resetBuffer(uint id, const quint8 *data, int size) -{ - d->resetBuffer(id, data, size); -} - -void QSGD3D12Engine::markBufferDirty(uint id, int offset, int size) -{ - d->markBufferDirty(id, offset, size); -} - -void QSGD3D12Engine::queueViewport(const QRect &rect) -{ - d->queueViewport(rect); -} - -void QSGD3D12Engine::queueScissor(const QRect &rect) -{ - d->queueScissor(rect); -} - -void QSGD3D12Engine::queueSetRenderTarget(uint id) -{ - d->queueSetRenderTarget(id); -} - -void QSGD3D12Engine::queueClearRenderTarget(const QColor &color) -{ - d->queueClearRenderTarget(color); -} - -void QSGD3D12Engine::queueClearDepthStencil(float depthValue, quint8 stencilValue, ClearFlags which) -{ - d->queueClearDepthStencil(depthValue, stencilValue, which); -} - -void QSGD3D12Engine::queueSetBlendFactor(const QVector4D &factor) -{ - d->queueSetBlendFactor(factor); -} - -void QSGD3D12Engine::queueSetStencilRef(quint32 ref) -{ - d->queueSetStencilRef(ref); -} - -void QSGD3D12Engine::queueDraw(const DrawParams ¶ms) -{ - d->queueDraw(params); -} - -void QSGD3D12Engine::present() -{ - d->present(); -} - -void QSGD3D12Engine::waitGPU() -{ - d->waitGPU(); -} - -uint QSGD3D12Engine::genTexture() -{ - return d->genTexture(); -} - -void QSGD3D12Engine::createTexture(uint id, const QSize &size, QImage::Format format, TextureCreateFlags flags) -{ - d->createTexture(id, size, format, flags); -} - -void QSGD3D12Engine::queueTextureResize(uint id, const QSize &size) -{ - d->queueTextureResize(id, size); -} - -void QSGD3D12Engine::queueTextureUpload(uint id, const QImage &image, const QPoint &dstPos, TextureUploadFlags flags) -{ - d->queueTextureUpload(id, QVector<QImage>() << image, QVector<QPoint>() << dstPos, flags); -} - -void QSGD3D12Engine::queueTextureUpload(uint id, const QVector<QImage> &images, const QVector<QPoint> &dstPos, - TextureUploadFlags flags) -{ - d->queueTextureUpload(id, images, dstPos, flags); -} - -void QSGD3D12Engine::releaseTexture(uint id) -{ - d->releaseTexture(id); -} - -void QSGD3D12Engine::useTexture(uint id) -{ - d->useTexture(id); -} - -uint QSGD3D12Engine::genRenderTarget() -{ - return d->genRenderTarget(); -} - -void QSGD3D12Engine::createRenderTarget(uint id, const QSize &size, const QVector4D &clearColor, uint samples) -{ - d->createRenderTarget(id, size, clearColor, samples); -} - -void QSGD3D12Engine::releaseRenderTarget(uint id) -{ - d->releaseRenderTarget(id); -} - -void QSGD3D12Engine::useRenderTargetAsTexture(uint id) -{ - d->useRenderTargetAsTexture(id); -} - -uint QSGD3D12Engine::activeRenderTarget() const -{ - return d->activeRenderTarget(); -} - -QImage QSGD3D12Engine::executeAndWaitReadbackRenderTarget(uint id) -{ - return d->executeAndWaitReadbackRenderTarget(id); -} - -void QSGD3D12Engine::simulateDeviceLoss() -{ - d->simulateDeviceLoss(); -} - -void *QSGD3D12Engine::getResource(QQuickWindow *, QSGRendererInterface::Resource resource) const -{ - return d->getResource(resource); -} - -static inline quint32 alignedSize(quint32 size, quint32 byteAlign) -{ - return (size + byteAlign - 1) & ~(byteAlign - 1); -} - -quint32 QSGD3D12Engine::alignedConstantBufferSize(quint32 size) -{ - return alignedSize(size, D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT); -} - -QSGD3D12Format QSGD3D12Engine::toDXGIFormat(QSGGeometry::Type sgtype, int tupleSize, int *size) -{ - QSGD3D12Format format = FmtUnknown; - - static const QSGD3D12Format formatMap_ub[] = { FmtUnknown, - FmtUNormByte, - FmtUNormByte2, - FmtUnknown, - FmtUNormByte4 }; - - static const QSGD3D12Format formatMap_f[] = { FmtUnknown, - FmtFloat, - FmtFloat2, - FmtFloat3, - FmtFloat4 }; - - switch (sgtype) { - case QSGGeometry::UnsignedByteType: - format = formatMap_ub[tupleSize]; - if (size) - *size = tupleSize; - break; - case QSGGeometry::FloatType: - format = formatMap_f[tupleSize]; - if (size) - *size = sizeof(float) * tupleSize; - break; - - case QSGGeometry::UnsignedShortType: - format = FmtUnsignedShort; - if (size) - *size = sizeof(ushort) * tupleSize; - break; - case QSGGeometry::UnsignedIntType: - format = FmtUnsignedInt; - if (size) - *size = sizeof(uint) * tupleSize; - break; - - case QSGGeometry::ByteType: - case QSGGeometry::IntType: - case QSGGeometry::ShortType: - qWarning("no mapping for GL type 0x%x", sgtype); - break; - - default: - qWarning("unknown GL type 0x%x", sgtype); - break; - } - - return format; -} - -int QSGD3D12Engine::mipMapLevels(const QSize &size) -{ - return ceil(log2(qMax(size.width(), size.height()))) + 1; -} - -inline static bool isPowerOfTwo(int x) -{ - // Assumption: x >= 1 - return x == (x & -x); -} - -QSize QSGD3D12Engine::mipMapAdjustedSourceSize(const QSize &size) -{ - if (size.isEmpty()) - return size; - - QSize adjustedSize = size; - - // ### for now only power-of-two sizes are mipmap-capable - if (!isPowerOfTwo(size.width())) - adjustedSize.setWidth(qNextPowerOfTwo(size.width())); - if (!isPowerOfTwo(size.height())) - adjustedSize.setHeight(qNextPowerOfTwo(size.height())); - - return adjustedSize; -} - -void QSGD3D12EnginePrivate::releaseResources() -{ - if (!initialized) - return; - - mipmapper.releaseResources(); - devLossTest.releaseResources(); - - frameCommandList = nullptr; - copyCommandList = nullptr; - - copyCommandAllocator = nullptr; - for (int i = 0; i < frameInFlightCount; ++i) { - frameCommandAllocator[i] = nullptr; - pframeData[i].gpuCbvSrvUavHeap = nullptr; - delete frameFence[i]; - } - - defaultDS = nullptr; - for (int i = 0; i < swapChainBufferCount; ++i) { - backBufferRT[i] = nullptr; - defaultRT[i] = nullptr; - } - - psoCache.clear(); - rootSigCache.clear(); - buffers.clear(); - textures.clear(); - renderTargets.clear(); - - cpuDescHeapManager.releaseResources(); - - commandQueue = nullptr; - copyCommandQueue = nullptr; - -#ifndef Q_OS_WINRT - dcompTarget = nullptr; - dcompVisual = nullptr; - dcompDevice = nullptr; -#endif - - swapChain = nullptr; - - delete presentFence; - textureUploadFence = nullptr; - - deviceManager()->unref(); - - initialized = false; - - // 'window' must be kept, may just be a device loss -} - -void QSGD3D12EnginePrivate::initialize(WId w, const QSize &size, float dpr, int surfaceFormatSamples, bool alpha) -{ - if (initialized) - return; - - window = w; - windowSize = size; - windowDpr = dpr; - windowSamples = qMax(1, surfaceFormatSamples); // may be -1 or 0, whereas windowSamples is uint and >= 1 - windowAlpha = alpha; - - swapChainBufferCount = qMin(qEnvironmentVariableIntValue("QT_D3D_BUFFER_COUNT"), MAX_SWAP_CHAIN_BUFFER_COUNT); - if (swapChainBufferCount < 2) - swapChainBufferCount = DEFAULT_SWAP_CHAIN_BUFFER_COUNT; - - frameInFlightCount = qMin(qEnvironmentVariableIntValue("QT_D3D_FRAME_COUNT"), MAX_FRAME_IN_FLIGHT_COUNT); - if (frameInFlightCount < 1) - frameInFlightCount = DEFAULT_FRAME_IN_FLIGHT_COUNT; - - static const char *latReqEnvVar = "QT_D3D_WAITABLE_SWAP_CHAIN_MAX_LATENCY"; - if (!qEnvironmentVariableIsSet(latReqEnvVar)) - waitableSwapChainMaxLatency = DEFAULT_WAITABLE_SWAP_CHAIN_MAX_LATENCY; - else - waitableSwapChainMaxLatency = qBound(0, qEnvironmentVariableIntValue(latReqEnvVar), 16); - - if (qEnvironmentVariableIsSet("QSG_INFO")) - const_cast<QLoggingCategory &>(QSG_LOG_INFO_GENERAL()).setEnabled(QtDebugMsg, true); - - qCDebug(QSG_LOG_INFO_GENERAL, "d3d12 engine init. swap chain buffer count %d, max frames prepared without blocking %d", - swapChainBufferCount, frameInFlightCount); - if (waitableSwapChainMaxLatency) - qCDebug(QSG_LOG_INFO_GENERAL, "Swap chain frame latency waitable object enabled. Frame latency is %d", waitableSwapChainMaxLatency); - - const bool debugLayer = qEnvironmentVariableIntValue("QT_D3D_DEBUG") != 0; - if (debugLayer) { - qCDebug(QSG_LOG_INFO_GENERAL, "Enabling debug layer"); -#if !defined(Q_OS_WINRT) || !defined(NDEBUG) - ComPtr<ID3D12Debug> debugController; - if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)))) - debugController->EnableDebugLayer(); -#else - qCDebug(QSG_LOG_INFO_GENERAL, "Using DebugInterface will not allow certification to pass"); -#endif - } - - QSGD3D12DeviceManager *dev = deviceManager(); - device = dev->ref(); - dev->registerDeviceLossObserver(this); - - if (debugLayer) { - ComPtr<ID3D12InfoQueue> infoQueue; - if (SUCCEEDED(device->QueryInterface(IID_PPV_ARGS(&infoQueue)))) { - infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_CORRUPTION, true); - infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_ERROR, true); - const bool breakOnWarning = qEnvironmentVariableIntValue("QT_D3D_DEBUG_BREAK_ON_WARNING") != 0; - infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_WARNING, breakOnWarning); - D3D12_INFO_QUEUE_FILTER filter = {}; - D3D12_MESSAGE_ID suppressedMessages[] = { - // When using a render target other than the default one we - // have no way to know the custom clear color, if there is one. - D3D12_MESSAGE_ID_CLEARRENDERTARGETVIEW_MISMATCHINGCLEARVALUE - }; - filter.DenyList.NumIDs = _countof(suppressedMessages); - filter.DenyList.pIDList = suppressedMessages; - // setting the filter would enable Info messages which we don't need - D3D12_MESSAGE_SEVERITY infoSev = D3D12_MESSAGE_SEVERITY_INFO; - filter.DenyList.NumSeverities = 1; - filter.DenyList.pSeverityList = &infoSev; - infoQueue->PushStorageFilter(&filter); - } - } - - D3D12_COMMAND_QUEUE_DESC queueDesc = {}; - queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; - if (FAILED(device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&commandQueue)))) { - qWarning("Failed to create command queue"); - return; - } - - queueDesc.Type = D3D12_COMMAND_LIST_TYPE_COPY; - if (FAILED(device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(©CommandQueue)))) { - qWarning("Failed to create copy command queue"); - return; - } - -#ifndef Q_OS_WINRT - HWND hwnd = reinterpret_cast<HWND>(w); - - if (windowAlpha) { - // Go through DirectComposition for semi-transparent windows since the - // traditional approaches won't fly with flip model swapchains. - HRESULT hr = DCompositionCreateDevice(nullptr, IID_PPV_ARGS(&dcompDevice)); - if (SUCCEEDED(hr)) { - hr = dcompDevice->CreateTargetForHwnd(hwnd, true, &dcompTarget); - if (SUCCEEDED(hr)) { - hr = dcompDevice->CreateVisual(&dcompVisual); - if (FAILED(hr)) { - qWarning("Failed to create DirectComposition visual: %s", - qPrintable(comErrorMessage(hr))); - windowAlpha = false; - } - } else { - qWarning("Failed to create DirectComposition target: %s", - qPrintable(comErrorMessage(hr))); - windowAlpha = false; - } - } else { - qWarning("Failed to create DirectComposition device: %s", - qPrintable(comErrorMessage(hr))); - windowAlpha = false; - } - } - - if (windowAlpha) { - DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; - swapChainDesc.Width = windowSize.width() * windowDpr; - swapChainDesc.Height = windowSize.height() * windowDpr; - swapChainDesc.Format = RT_COLOR_FORMAT; - swapChainDesc.SampleDesc.Count = 1; - swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapChainDesc.BufferCount = swapChainBufferCount; - swapChainDesc.Scaling = DXGI_SCALING_STRETCH; - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED; - if (waitableSwapChainMaxLatency) - swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT; - - ComPtr<IDXGISwapChain1> baseSwapChain; - HRESULT hr = dev->dxgi()->CreateSwapChainForComposition(commandQueue.Get(), &swapChainDesc, nullptr, &baseSwapChain); - if (SUCCEEDED(hr)) { - if (SUCCEEDED(baseSwapChain.As(&swapChain))) { - hr = dcompVisual->SetContent(swapChain.Get()); - if (SUCCEEDED(hr)) { - hr = dcompTarget->SetRoot(dcompVisual.Get()); - if (FAILED(hr)) { - qWarning("SetRoot failed for DirectComposition target: %s", - qPrintable(comErrorMessage(hr))); - windowAlpha = false; - } - } else { - qWarning("SetContent failed for DirectComposition visual: %s", - qPrintable(comErrorMessage(hr))); - windowAlpha = false; - } - } else { - qWarning("Failed to cast swap chain"); - windowAlpha = false; - } - } else { - qWarning("Failed to create swap chain for composition: 0x%x", hr); - windowAlpha = false; - } - } - - if (!windowAlpha) { - DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; - swapChainDesc.BufferCount = swapChainBufferCount; - swapChainDesc.BufferDesc.Width = windowSize.width() * windowDpr; - swapChainDesc.BufferDesc.Height = windowSize.height() * windowDpr; - swapChainDesc.BufferDesc.Format = RT_COLOR_FORMAT; - swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; // D3D12 requires the flip model - swapChainDesc.OutputWindow = hwnd; - swapChainDesc.SampleDesc.Count = 1; // Flip does not support MSAA so no choice here - swapChainDesc.Windowed = TRUE; - if (waitableSwapChainMaxLatency) - swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT; - - ComPtr<IDXGISwapChain> baseSwapChain; - HRESULT hr = dev->dxgi()->CreateSwapChain(commandQueue.Get(), &swapChainDesc, &baseSwapChain); - if (FAILED(hr)) { - qWarning("Failed to create swap chain: %s", qPrintable(comErrorMessage(hr))); - return; - } - hr = baseSwapChain.As(&swapChain); - if (FAILED(hr)) { - qWarning("Failed to cast swap chain: %s", qPrintable(comErrorMessage(hr))); - return; - } - } - - dev->dxgi()->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER); -#else - DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; - swapChainDesc.Width = windowSize.width() * windowDpr; - swapChainDesc.Height = windowSize.height() * windowDpr; - swapChainDesc.Format = RT_COLOR_FORMAT; - swapChainDesc.SampleDesc.Count = 1; - swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapChainDesc.BufferCount = swapChainBufferCount; - swapChainDesc.Scaling = DXGI_SCALING_STRETCH; - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED; - if (waitableSwapChainMaxLatency) - swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT; - - ComPtr<IDXGISwapChain1> baseSwapChain; - HRESULT hr = dev->dxgi()->CreateSwapChainForComposition(commandQueue.Get(), &swapChainDesc, nullptr, &baseSwapChain); - if (FAILED(hr)) { - qWarning("Failed to create swap chain for composition: 0x%x", hr); - return; - } - if (FAILED(baseSwapChain.As(&swapChain))) { - qWarning("Failed to cast swap chain"); - return; - } - - // The winrt platform plugin returns an ISwapChainPanel* from winId(). - ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> swapChainPanel - = reinterpret_cast<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel *>(window); - ComPtr<ISwapChainPanelNative> swapChainPanelNative; - if (FAILED(swapChainPanel.As(&swapChainPanelNative))) { - qWarning("Failed to cast swap chain panel to native"); - return; - } - hr = QEventDispatcherWinRT::runOnXamlThread([this, &swapChainPanelNative]() { - return swapChainPanelNative->SetSwapChain(swapChain.Get()); - }); - if (FAILED(hr)) { - qWarning("Failed to set swap chain on panel: 0x%x", hr); - return; - } -#endif - - if (waitableSwapChainMaxLatency) { - if (FAILED(swapChain->SetMaximumFrameLatency(waitableSwapChainMaxLatency))) - qWarning("Failed to set maximum frame latency to %d", waitableSwapChainMaxLatency); - swapEvent = swapChain->GetFrameLatencyWaitableObject(); - } - - for (int i = 0; i < frameInFlightCount; ++i) { - if (FAILED(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&frameCommandAllocator[i])))) { - qWarning("Failed to create command allocator"); - return; - } - } - - if (FAILED(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_COPY, IID_PPV_ARGS(©CommandAllocator)))) { - qWarning("Failed to create copy command allocator"); - return; - } - - for (int i = 0; i < frameInFlightCount; ++i) { - if (!createCbvSrvUavHeap(i, GPU_CBVSRVUAV_DESCRIPTORS)) - return; - } - - cpuDescHeapManager.initialize(device); - - setupDefaultRenderTargets(); - - if (FAILED(device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, frameCommandAllocator[0].Get(), - nullptr, IID_PPV_ARGS(&frameCommandList)))) { - qWarning("Failed to create command list"); - return; - } - // created in recording state, close it for now - frameCommandList->Close(); - - if (FAILED(device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_COPY, copyCommandAllocator.Get(), - nullptr, IID_PPV_ARGS(©CommandList)))) { - qWarning("Failed to create copy command list"); - return; - } - copyCommandList->Close(); - - frameIndex = 0; - - presentFence = createCPUWaitableFence(); - for (int i = 0; i < frameInFlightCount; ++i) - frameFence[i] = createCPUWaitableFence(); - - if (FAILED(device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&textureUploadFence)))) { - qWarning("Failed to create fence"); - return; - } - - psoCache.setMaxCost(MAX_CACHED_PSO); - rootSigCache.setMaxCost(MAX_CACHED_ROOTSIG); - - if (!mipmapper.initialize(this)) - return; - - if (!devLossTest.initialize(this)) - return; - - currentRenderTarget = 0; - - initialized = true; -} - -bool QSGD3D12EnginePrivate::createCbvSrvUavHeap(int pframeIndex, int descriptorCount) -{ - D3D12_DESCRIPTOR_HEAP_DESC gpuDescHeapDesc = {}; - gpuDescHeapDesc.NumDescriptors = descriptorCount; - gpuDescHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; - gpuDescHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; - - if (FAILED(device->CreateDescriptorHeap(&gpuDescHeapDesc, IID_PPV_ARGS(&pframeData[pframeIndex].gpuCbvSrvUavHeap)))) { - qWarning("Failed to create shader-visible CBV-SRV-UAV heap"); - return false; - } - - pframeData[pframeIndex].gpuCbvSrvUavHeapSize = descriptorCount; - - return true; -} - -DXGI_SAMPLE_DESC QSGD3D12EnginePrivate::makeSampleDesc(DXGI_FORMAT format, uint samples) -{ - DXGI_SAMPLE_DESC sampleDesc; - sampleDesc.Count = 1; - sampleDesc.Quality = 0; - - if (samples > 1) { - D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS msaaInfo = {}; - msaaInfo.Format = format; - msaaInfo.SampleCount = samples; - if (SUCCEEDED(device->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, &msaaInfo, sizeof(msaaInfo)))) { - if (msaaInfo.NumQualityLevels > 0) { - sampleDesc.Count = samples; - sampleDesc.Quality = msaaInfo.NumQualityLevels - 1; - } else { - qWarning("No quality levels for multisampling with sample count %d", samples); - } - } else { - qWarning("Failed to query multisample quality levels for sample count %d", samples); - } - } - - return sampleDesc; -} - -ID3D12Resource *QSGD3D12EnginePrivate::createColorBuffer(D3D12_CPU_DESCRIPTOR_HANDLE viewHandle, const QSize &size, - const QVector4D &clearColor, uint samples) -{ - D3D12_CLEAR_VALUE clearValue = {}; - clearValue.Format = RT_COLOR_FORMAT; - clearValue.Color[0] = clearColor.x(); - clearValue.Color[1] = clearColor.y(); - clearValue.Color[2] = clearColor.z(); - clearValue.Color[3] = clearColor.w(); - - D3D12_HEAP_PROPERTIES heapProp = {}; - heapProp.Type = D3D12_HEAP_TYPE_DEFAULT; - - D3D12_RESOURCE_DESC rtDesc = {}; - rtDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; - rtDesc.Width = size.width(); - rtDesc.Height = size.height(); - rtDesc.DepthOrArraySize = 1; - rtDesc.MipLevels = 1; - rtDesc.Format = RT_COLOR_FORMAT; - rtDesc.SampleDesc = makeSampleDesc(rtDesc.Format, samples); - rtDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; - - ID3D12Resource *resource = nullptr; - const D3D12_RESOURCE_STATES initialState = samples <= 1 - ? D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE - : D3D12_RESOURCE_STATE_RENDER_TARGET; - if (FAILED(device->CreateCommittedResource(&heapProp, D3D12_HEAP_FLAG_NONE, &rtDesc, - initialState, &clearValue, IID_PPV_ARGS(&resource)))) { - qWarning("Failed to create offscreen render target of size %dx%d", size.width(), size.height()); - return nullptr; - } - - device->CreateRenderTargetView(resource, nullptr, viewHandle); - - return resource; -} - -ID3D12Resource *QSGD3D12EnginePrivate::createDepthStencil(D3D12_CPU_DESCRIPTOR_HANDLE viewHandle, const QSize &size, uint samples) -{ - D3D12_CLEAR_VALUE depthClearValue = {}; - depthClearValue.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; - depthClearValue.DepthStencil.Depth = 1.0f; - depthClearValue.DepthStencil.Stencil = 0; - - D3D12_HEAP_PROPERTIES heapProp = {}; - heapProp.Type = D3D12_HEAP_TYPE_DEFAULT; - - D3D12_RESOURCE_DESC bufDesc = {}; - bufDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; - bufDesc.Width = size.width(); - bufDesc.Height = size.height(); - bufDesc.DepthOrArraySize = 1; - bufDesc.MipLevels = 1; - bufDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; - bufDesc.SampleDesc = makeSampleDesc(bufDesc.Format, samples); - bufDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; - bufDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; - - ID3D12Resource *resource = nullptr; - if (FAILED(device->CreateCommittedResource(&heapProp, D3D12_HEAP_FLAG_NONE, &bufDesc, - D3D12_RESOURCE_STATE_DEPTH_WRITE, &depthClearValue, IID_PPV_ARGS(&resource)))) { - qWarning("Failed to create depth-stencil buffer of size %dx%d", size.width(), size.height()); - return nullptr; - } - - D3D12_DEPTH_STENCIL_VIEW_DESC depthStencilDesc = {}; - depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; - depthStencilDesc.ViewDimension = bufDesc.SampleDesc.Count <= 1 ? D3D12_DSV_DIMENSION_TEXTURE2D : D3D12_DSV_DIMENSION_TEXTURE2DMS; - - device->CreateDepthStencilView(resource, &depthStencilDesc, viewHandle); - - return resource; -} - -void QSGD3D12EnginePrivate::setupDefaultRenderTargets() -{ - for (int i = 0; i < swapChainBufferCount; ++i) { - if (FAILED(swapChain->GetBuffer(i, IID_PPV_ARGS(&backBufferRT[i])))) { - qWarning("Failed to get buffer %d from swap chain", i); - return; - } - defaultRTV[i] = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); - if (windowSamples == 1) { - defaultRT[i] = backBufferRT[i]; - device->CreateRenderTargetView(defaultRT[i].Get(), nullptr, defaultRTV[i]); - } else { - const QSize size(windowSize.width() * windowDpr, windowSize.height() * windowDpr); - // Not optimal if the user called setClearColor, but there's so - // much we can do. The debug layer warning is suppressed so we're good to go. - const QColor cc(Qt::white); - const QVector4D clearColor(cc.redF(), cc.greenF(), cc.blueF(), cc.alphaF()); - ID3D12Resource *msaaRT = createColorBuffer(defaultRTV[i], size, clearColor, windowSamples); - if (msaaRT) - defaultRT[i].Attach(msaaRT); - } - } - - defaultDSV = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_DSV); - const QSize size(windowSize.width() * windowDpr, windowSize.height() * windowDpr); - ID3D12Resource *ds = createDepthStencil(defaultDSV, size, windowSamples); - if (ds) - defaultDS.Attach(ds); - - presentFrameIndex = 0; -} - -void QSGD3D12EnginePrivate::setWindowSize(const QSize &size, float dpr) -{ - if (!initialized || (windowSize == size && windowDpr == dpr)) - return; - - waitGPU(); - - windowSize = size; - windowDpr = dpr; - - if (Q_UNLIKELY(debug_render())) - qDebug() << "resize" << size << dpr; - - // Clear these, otherwise resizing will fail. - defaultDS = nullptr; - cpuDescHeapManager.release(defaultDSV, D3D12_DESCRIPTOR_HEAP_TYPE_DSV); - for (int i = 0; i < swapChainBufferCount; ++i) { - backBufferRT[i] = nullptr; - defaultRT[i] = nullptr; - cpuDescHeapManager.release(defaultRTV[i], D3D12_DESCRIPTOR_HEAP_TYPE_RTV); - } - - const int w = windowSize.width() * windowDpr; - const int h = windowSize.height() * windowDpr; - HRESULT hr = swapChain->ResizeBuffers(swapChainBufferCount, w, h, RT_COLOR_FORMAT, - waitableSwapChainMaxLatency ? DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT : 0); - if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) { - deviceManager()->deviceLossDetected(); - return; - } else if (FAILED(hr)) { - qWarning("Failed to resize buffers: %s", qPrintable(comErrorMessage(hr))); - return; - } - - setupDefaultRenderTargets(); -} - -void QSGD3D12EnginePrivate::deviceLost() -{ - qWarning("D3D device lost, will attempt to reinitialize"); - - // Release all resources. This is important because otherwise reinitialization may fail. - releaseResources(); - - // Now in uninitialized state (but 'window' is still valid). Will recreate - // all the resources on the next beginFrame(). -} - -QSGD3D12CPUWaitableFence *QSGD3D12EnginePrivate::createCPUWaitableFence() const -{ - QSGD3D12CPUWaitableFence *f = new QSGD3D12CPUWaitableFence; - HRESULT hr = device->CreateFence(f->value, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&f->fence)); - if (FAILED(hr)) { - qWarning("Failed to create fence: %s", qPrintable(comErrorMessage(hr))); - return f; - } - f->event = CreateEvent(nullptr, FALSE, FALSE, nullptr); - return f; -} - -void QSGD3D12EnginePrivate::waitForGPU(QSGD3D12CPUWaitableFence *f) const -{ - const UINT64 newValue = f->value.fetchAndAddAcquire(1) + 1; - commandQueue->Signal(f->fence.Get(), newValue); - if (f->fence->GetCompletedValue() < newValue) { - HRESULT hr = f->fence->SetEventOnCompletion(newValue, f->event); - if (FAILED(hr)) { - qWarning("SetEventOnCompletion failed: %s", qPrintable(comErrorMessage(hr))); - return; - } - WaitForSingleObject(f->event, INFINITE); - } -} - -void QSGD3D12EnginePrivate::transitionResource(ID3D12Resource *resource, ID3D12GraphicsCommandList *commandList, - D3D12_RESOURCE_STATES before, D3D12_RESOURCE_STATES after) const -{ - D3D12_RESOURCE_BARRIER barrier; - barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - barrier.Transition.pResource = resource; - barrier.Transition.StateBefore = before; - barrier.Transition.StateAfter = after; - barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - - commandList->ResourceBarrier(1, &barrier); -} - -void QSGD3D12EnginePrivate::resolveMultisampledTarget(ID3D12Resource *msaa, - ID3D12Resource *resolve, - D3D12_RESOURCE_STATES resolveUsage, - ID3D12GraphicsCommandList *commandList) const -{ - D3D12_RESOURCE_BARRIER barriers[2]; - for (int i = 0; i < _countof(barriers); ++i) { - barriers[i].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - barriers[i].Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - barriers[i].Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - } - - barriers[0].Transition.pResource = msaa; - barriers[0].Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET; - barriers[0].Transition.StateAfter = D3D12_RESOURCE_STATE_RESOLVE_SOURCE; - barriers[1].Transition.pResource = resolve; - barriers[1].Transition.StateBefore = resolveUsage; - barriers[1].Transition.StateAfter = D3D12_RESOURCE_STATE_RESOLVE_DEST; - commandList->ResourceBarrier(2, barriers); - - commandList->ResolveSubresource(resolve, 0, msaa, 0, RT_COLOR_FORMAT); - - barriers[0].Transition.pResource = msaa; - barriers[0].Transition.StateBefore = D3D12_RESOURCE_STATE_RESOLVE_SOURCE; - barriers[0].Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; - barriers[1].Transition.pResource = resolve; - barriers[1].Transition.StateBefore = D3D12_RESOURCE_STATE_RESOLVE_DEST; - barriers[1].Transition.StateAfter = resolveUsage; - commandList->ResourceBarrier(2, barriers); -} - -void QSGD3D12EnginePrivate::uavBarrier(ID3D12Resource *resource, ID3D12GraphicsCommandList *commandList) const -{ - D3D12_RESOURCE_BARRIER barrier = {}; - barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; - barrier.UAV.pResource = resource; - - commandList->ResourceBarrier(1, &barrier); -} - -ID3D12Resource *QSGD3D12EnginePrivate::createBuffer(int size) -{ - ID3D12Resource *buf; - - D3D12_HEAP_PROPERTIES uploadHeapProp = {}; - uploadHeapProp.Type = D3D12_HEAP_TYPE_UPLOAD; - - D3D12_RESOURCE_DESC bufDesc = {}; - bufDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - bufDesc.Width = size; - bufDesc.Height = 1; - bufDesc.DepthOrArraySize = 1; - bufDesc.MipLevels = 1; - bufDesc.Format = DXGI_FORMAT_UNKNOWN; - bufDesc.SampleDesc.Count = 1; - bufDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; - - HRESULT hr = device->CreateCommittedResource(&uploadHeapProp, D3D12_HEAP_FLAG_NONE, &bufDesc, - D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&buf)); - if (FAILED(hr)) - qWarning("Failed to create buffer resource: %s", qPrintable(comErrorMessage(hr))); - - return buf; -} - -void QSGD3D12EnginePrivate::ensureBuffer(Buffer *buf) -{ - Buffer::InFlightData &bfd(buf->d[currentPFrameIndex]); - // Only enlarge, never shrink - const bool newBufferNeeded = bfd.buffer ? (buf->cpuDataRef.size > bfd.resourceSize) : true; - if (newBufferNeeded) { - // Round it up and overallocate a little bit so that a subsequent - // buffer contents rebuild with a slightly larger total size does - // not lead to creating a new buffer. - const quint32 sz = alignedSize(buf->cpuDataRef.size, 4096); - if (Q_UNLIKELY(debug_buffer())) - qDebug("new buffer[pf=%d] of size %d (actual data size %d)", currentPFrameIndex, sz, buf->cpuDataRef.size); - bfd.buffer.Attach(createBuffer(sz)); - bfd.resourceSize = sz; - } - // Cache the actual data size in the per-in-flight-frame data as well. - bfd.dataSize = buf->cpuDataRef.size; -} - -void QSGD3D12EnginePrivate::updateBuffer(Buffer *buf) -{ - if (buf->cpuDataRef.dirty.isEmpty()) - return; - - Buffer::InFlightData &bfd(buf->d[currentPFrameIndex]); - quint8 *p = nullptr; - const D3D12_RANGE readRange = { 0, 0 }; - if (FAILED(bfd.buffer->Map(0, &readRange, reinterpret_cast<void **>(&p)))) { - qWarning("Map failed for buffer of size %d", buf->cpuDataRef.size); - return; - } - for (const auto &r : qAsConst(buf->cpuDataRef.dirty)) { - if (Q_UNLIKELY(debug_buffer())) - qDebug("%p o %d s %d", buf, r.first, r.second); - memcpy(p + r.first, buf->cpuDataRef.p + r.first, r.second); - } - bfd.buffer->Unmap(0, nullptr); - buf->cpuDataRef.dirty.clear(); -} - -void QSGD3D12EnginePrivate::ensureDevice() -{ - if (!initialized && window) - initialize(window, windowSize, windowDpr, windowSamples, windowAlpha); -} - -void QSGD3D12EnginePrivate::beginFrame() -{ - if (inFrame && !activeLayers) - qFatal("beginFrame called again without an endFrame, frame index was %d", frameIndex); - - if (Q_UNLIKELY(debug_render())) - qDebug() << "***** begin frame, logical" << frameIndex << "present" << presentFrameIndex << "layer" << activeLayers; - - if (inFrame && activeLayers) { - if (Q_UNLIKELY(debug_render())) - qDebug("frame %d already in progress", frameIndex); - if (!currentLayerDepth) { - // There are layers and the real frame preparation starts now. Prepare for present. - beginFrameDraw(); - } - return; - } - - inFrame = true; - - // The device may have been lost. This is the point to attempt to start - // again from scratch. Except when it is not. Operations that can happen - // out of frame (e.g. textures, render targets) may trigger reinit earlier - // than beginFrame. - ensureDevice(); - - // Wait for a buffer to be available for Present, if the waitable event is in use. - if (waitableSwapChainMaxLatency) - WaitForSingleObject(swapEvent, INFINITE); - - // Block if needed. With 2 frames in flight frame N waits for frame N - 2, but not N - 1, to finish. - currentPFrameIndex = frameIndex % frameInFlightCount; - if (frameIndex >= frameInFlightCount) { - ID3D12Fence *fence = frameFence[currentPFrameIndex]->fence.Get(); - HANDLE event = frameFence[currentPFrameIndex]->event; - // Frame fence values start from 1, hence the +1. - const quint64 inFlightFenceValue = frameIndex - frameInFlightCount + 1; - if (fence->GetCompletedValue() < inFlightFenceValue) { - fence->SetEventOnCompletion(inFlightFenceValue, event); - WaitForSingleObject(event, INFINITE); - } - frameCommandAllocator[currentPFrameIndex]->Reset(); - } - - PersistentFrameData &pfd(pframeData[currentPFrameIndex]); - pfd.cbvSrvUavNextFreeDescriptorIndex = 0; - - for (Buffer &b : buffers) { - if (b.entryInUse()) - b.d[currentPFrameIndex].dirty.clear(); - } - - if (frameIndex >= frameInFlightCount - 1) { - // Now sync the buffer changes from the previous, potentially still in - // flight, frames. This is done by taking the ranges dirtied in those - // frames and adding them to the global CPU-side buffer's dirty list, - // as if this frame changed those ranges. (however, dirty ranges - // inherited this way are not added to this frame's persistent - // per-frame dirty list because the next frame after this one should - // inherit this frame's genuine changes only, the rest will come from - // the earlier ones) - for (int delta = frameInFlightCount - 1; delta >= 1; --delta) { - const int prevPFrameIndex = (frameIndex - delta) % frameInFlightCount; - PersistentFrameData &prevFrameData(pframeData[prevPFrameIndex]); - for (uint id : qAsConst(prevFrameData.buffersUsedInFrame)) { - Buffer &b(buffers[id - 1]); - if (b.d[currentPFrameIndex].buffer && b.d[currentPFrameIndex].dataSize == b.cpuDataRef.size) { - if (Q_UNLIKELY(debug_buffer())) - qDebug() << "frame" << frameIndex << "takes dirty" << b.d[prevPFrameIndex].dirty - << "from frame" << frameIndex - delta << "for buffer" << id; - for (const auto &range : qAsConst(b.d[prevPFrameIndex].dirty)) - addDirtyRange(&b.cpuDataRef.dirty, range.first, range.second, b.cpuDataRef.size); - } else { - if (Q_UNLIKELY(debug_buffer())) - qDebug() << "frame" << frameIndex << "makes all dirty from frame" << frameIndex - delta - << "for buffer" << id; - addDirtyRange(&b.cpuDataRef.dirty, 0, b.cpuDataRef.size, b.cpuDataRef.size); - } - } - } - } - - if (frameIndex >= frameInFlightCount) { - // Do some texture upload bookkeeping. - const quint64 finishedFrameIndex = frameIndex - frameInFlightCount; // we know since we just blocked for this - // pfd conveniently refers to the same slot that was used by that frame - if (!pfd.pendingTextureUploads.isEmpty()) { - if (Q_UNLIKELY(debug_texture())) - qDebug("Removing texture upload data for frame %d", finishedFrameIndex); - for (uint id : qAsConst(pfd.pendingTextureUploads)) { - const int idx = id - 1; - Texture &t(textures[idx]); - // fenceValue is 0 when the previous frame cleared it, skip in - // this case. Skip also when fenceValue > the value it was when - // adding the last GPU wait - this is the case when more - // uploads were queued for the same texture in the meantime. - if (t.fenceValue && t.fenceValue == t.lastWaitFenceValue) { - t.fenceValue = 0; - t.lastWaitFenceValue = 0; - t.stagingBuffers.clear(); - t.stagingHeaps.clear(); - if (Q_UNLIKELY(debug_texture())) - qDebug("Cleaned staging data for texture %u", id); - } - } - pfd.pendingTextureUploads.clear(); - if (!pfd.pendingTextureMipMap.isEmpty()) { - if (Q_UNLIKELY(debug_texture())) - qDebug() << "cleaning mipmap generation data for " << pfd.pendingTextureMipMap; - // no special cleanup is needed as mipmap generation uses the frame's resources - pfd.pendingTextureMipMap.clear(); - } - bool hasPending = false; - for (int delta = 1; delta < frameInFlightCount; ++delta) { - const PersistentFrameData &prevFrameData(pframeData[(frameIndex - delta) % frameInFlightCount]); - if (!prevFrameData.pendingTextureUploads.isEmpty()) { - hasPending = true; - break; - } - } - if (!hasPending) { - if (Q_UNLIKELY(debug_texture())) - qDebug("no more pending textures"); - copyCommandAllocator->Reset(); - } - } - - // Do the deferred deletes. - if (!pfd.deleteQueue.isEmpty()) { - for (PersistentFrameData::DeleteQueueEntry &e : pfd.deleteQueue) { - e.res = nullptr; - e.descHeap = nullptr; - if (e.cpuDescriptorPtr) { - D3D12_CPU_DESCRIPTOR_HANDLE h = { e.cpuDescriptorPtr }; - cpuDescHeapManager.release(h, e.descHeapType); - } - } - pfd.deleteQueue.clear(); - } - // Deferred deletes issued outside a begin-endFrame go to the next - // frame's out-of-frame delete queue as these cannot be executed in the - // next beginFrame, only in next + frameInFlightCount. Move to the - // normal queue if this is the next beginFrame. - if (!pfd.outOfFrameDeleteQueue.isEmpty()) { - pfd.deleteQueue = pfd.outOfFrameDeleteQueue; - pfd.outOfFrameDeleteQueue.clear(); - } - - // Mark released texture, buffer, etc. slots free. - if (!pfd.pendingReleases.isEmpty()) { - for (const auto &pr : qAsConst(pfd.pendingReleases)) { - Q_ASSERT(pr.id); - if (pr.type == PersistentFrameData::PendingRelease::TypeTexture) { - Texture &t(textures[pr.id - 1]); - Q_ASSERT(t.entryInUse()); - t.flags &= ~RenderTarget::EntryInUse; // createTexture() can now reuse this entry - t.texture = nullptr; - } else if (pr.type == PersistentFrameData::PendingRelease::TypeBuffer) { - Buffer &b(buffers[pr.id - 1]); - Q_ASSERT(b.entryInUse()); - b.flags &= ~Buffer::EntryInUse; - for (int i = 0; i < frameInFlightCount; ++i) - b.d[i].buffer = nullptr; - } else { - qFatal("Corrupt pending release list, type %d", pr.type); - } - } - pfd.pendingReleases.clear(); - } - if (!pfd.outOfFramePendingReleases.isEmpty()) { - pfd.pendingReleases = pfd.outOfFramePendingReleases; - pfd.outOfFramePendingReleases.clear(); - } - } - - pfd.buffersUsedInFrame.clear(); - - beginDrawCalls(); - - // Prepare for present if this is a frame without layers. - if (!activeLayers) - beginFrameDraw(); -} - -void QSGD3D12EnginePrivate::beginDrawCalls() -{ - frameCommandList->Reset(frameCommandAllocator[frameIndex % frameInFlightCount].Get(), nullptr); - commandList = frameCommandList.Get(); - invalidateCachedFrameState(); -} - -void QSGD3D12EnginePrivate::invalidateCachedFrameState() -{ - tframeData.drawingMode = QSGGeometry::DrawingMode(-1); - tframeData.currentIndexBuffer = 0; - tframeData.activeTextureCount = 0; - tframeData.drawCount = 0; - tframeData.lastPso = nullptr; - tframeData.lastRootSig = nullptr; - tframeData.descHeapSet = false; -} - -void QSGD3D12EnginePrivate::restoreFrameState(bool minimal) -{ - queueSetRenderTarget(currentRenderTarget); - if (!minimal) { - queueViewport(tframeData.viewport); - queueScissor(tframeData.scissor); - queueSetBlendFactor(tframeData.blendFactor); - queueSetStencilRef(tframeData.stencilRef); - } - finalizePipeline(tframeData.pipelineState); -} - -void QSGD3D12EnginePrivate::beginFrameDraw() -{ - if (windowSamples == 1) - transitionResource(defaultRT[presentFrameIndex % swapChainBufferCount].Get(), commandList, - D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET); -} - -void QSGD3D12EnginePrivate::endFrame() -{ - if (!inFrame) - qFatal("endFrame called without beginFrame, frame index %d", frameIndex); - - if (Q_UNLIKELY(debug_render())) - qDebug("***** end frame"); - - endDrawCalls(true); - - commandQueue->Signal(frameFence[frameIndex % frameInFlightCount]->fence.Get(), frameIndex + 1); - ++frameIndex; - - inFrame = false; -} - -void QSGD3D12EnginePrivate::endDrawCalls(bool lastInFrame) -{ - PersistentFrameData &pfd(pframeData[currentPFrameIndex]); - - // Now is the time to sync all the changed areas in the buffers. - if (Q_UNLIKELY(debug_buffer())) - qDebug() << "buffers used in drawcall set" << pfd.buffersUsedInDrawCallSet; - for (uint id : qAsConst(pfd.buffersUsedInDrawCallSet)) - updateBuffer(&buffers[id - 1]); - - pfd.buffersUsedInFrame += pfd.buffersUsedInDrawCallSet; - pfd.buffersUsedInDrawCallSet.clear(); - - // Add a wait on the 3D queue for the relevant texture uploads on the copy queue. - if (!pfd.pendingTextureUploads.isEmpty()) { - quint64 topFenceValue = 0; - for (uint id : qAsConst(pfd.pendingTextureUploads)) { - const int idx = id - 1; - Texture &t(textures[idx]); - Q_ASSERT(t.fenceValue); - // skip if already added a Wait in the previous frame - if (t.lastWaitFenceValue == t.fenceValue) - continue; - t.lastWaitFenceValue = t.fenceValue; - if (t.fenceValue > topFenceValue) - topFenceValue = t.fenceValue; - if (t.mipmap()) - pfd.pendingTextureMipMap.insert(id); - } - if (topFenceValue) { - if (Q_UNLIKELY(debug_texture())) - qDebug("added wait for texture fence %llu", topFenceValue); - commandQueue->Wait(textureUploadFence.Get(), topFenceValue); - // Generate mipmaps after the wait, when necessary. - if (!pfd.pendingTextureMipMap.isEmpty()) { - if (Q_UNLIKELY(debug_texture())) - qDebug() << "starting mipmap generation for" << pfd.pendingTextureMipMap; - for (uint id : qAsConst(pfd.pendingTextureMipMap)) - mipmapper.queueGenerate(textures[id - 1]); - } - } - } - - if (lastInFrame) { - // Resolve and transition the backbuffer for present, if needed. - const int idx = presentFrameIndex % swapChainBufferCount; - if (windowSamples == 1) { - transitionResource(defaultRT[idx].Get(), commandList, - D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT); - } else { - if (Q_UNLIKELY(debug_render())) { - const D3D12_RESOURCE_DESC desc = defaultRT[idx]->GetDesc(); - qDebug("added resolve for multisampled render target (count %d, quality %d)", - desc.SampleDesc.Count, desc.SampleDesc.Quality); - } - resolveMultisampledTarget(defaultRT[idx].Get(), backBufferRT[idx].Get(), - D3D12_RESOURCE_STATE_PRESENT, commandList); - } - - if (activeLayers) { - if (Q_UNLIKELY(debug_render())) - qDebug("this frame had %d layers", activeLayers); - activeLayers = 0; - } - } - - // Go! - HRESULT hr = frameCommandList->Close(); - if (FAILED(hr)) { - qWarning("Failed to close command list: %s", qPrintable(comErrorMessage(hr))); - if (hr == E_INVALIDARG) - qWarning("Invalid arguments. Some of the commands in the list is invalid in some way."); - } - - ID3D12CommandList *commandLists[] = { frameCommandList.Get() }; - commandQueue->ExecuteCommandLists(_countof(commandLists), commandLists); - - commandList = nullptr; -} - -void QSGD3D12EnginePrivate::beginLayer() -{ - if (inFrame && !activeLayers) - qFatal("Layer rendering cannot be started while a frame is active"); - - if (Q_UNLIKELY(debug_render())) - qDebug("===== beginLayer active %d depth %d (inFrame=%d)", activeLayers, currentLayerDepth, inFrame); - - ++activeLayers; - ++currentLayerDepth; - - // Do an early beginFrame. With multiple layers this results in - // beginLayer - beginFrame - endLayer - beginLayer - beginFrame - endLayer - ... - (*) beginFrame - endFrame - // where (*) denotes the start of the preparation of the actual, non-layer frame. - - if (activeLayers == 1) - beginFrame(); -} - -void QSGD3D12EnginePrivate::endLayer() -{ - if (!inFrame || !activeLayers || !currentLayerDepth) - qFatal("Mismatched endLayer"); - - if (Q_UNLIKELY(debug_render())) - qDebug("===== endLayer active %d depth %d", activeLayers, currentLayerDepth); - - --currentLayerDepth; - - // Do not touch activeLayers. It remains valid until endFrame. -} - -// Root signature: -// [0] CBV - always present -// [1] table with one SRV per texture (must be a table since root descriptor SRVs cannot be textures) - optional -// one static sampler per texture - optional -// -// SRVs can be created freely via QSGD3D12CPUDescriptorHeapManager and stored -// in QSGD3D12TextureView. The engine will copy them onto a dedicated, -// shader-visible CBV-SRV-UAV heap in the correct order. - -void QSGD3D12EnginePrivate::finalizePipeline(const QSGD3D12PipelineState &pipelineState) -{ - if (!inFrame) { - qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__); - return; - } - - tframeData.pipelineState = pipelineState; - - RootSigCacheEntry *cachedRootSig = rootSigCache[pipelineState.shaders.rootSig]; - if (!cachedRootSig) { - if (Q_UNLIKELY(debug_render())) - qDebug("NEW ROOTSIG"); - - cachedRootSig = new RootSigCacheEntry; - - D3D12_ROOT_PARAMETER rootParams[4]; - int rootParamCount = 0; - - rootParams[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; - rootParams[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; - rootParams[0].Descriptor.ShaderRegister = 0; // b0 - rootParams[0].Descriptor.RegisterSpace = 0; - ++rootParamCount; - - D3D12_DESCRIPTOR_RANGE tvDescRange; - if (pipelineState.shaders.rootSig.textureViewCount > 0) { - rootParams[rootParamCount].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; - rootParams[rootParamCount].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; - rootParams[rootParamCount].DescriptorTable.NumDescriptorRanges = 1; - tvDescRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; - tvDescRange.NumDescriptors = pipelineState.shaders.rootSig.textureViewCount; - tvDescRange.BaseShaderRegister = 0; // t0, t1, ... - tvDescRange.RegisterSpace = 0; - tvDescRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; - rootParams[rootParamCount].DescriptorTable.pDescriptorRanges = &tvDescRange; - ++rootParamCount; - } - - Q_ASSERT(rootParamCount <= _countof(rootParams)); - D3D12_ROOT_SIGNATURE_DESC desc; - desc.NumParameters = rootParamCount; - desc.pParameters = rootParams; - // Mixing up samplers and resource views in QSGD3D12TextureView means - // that the number of static samplers has to match the number of - // textures. This is not really ideal in general but works for Quick's use cases. - // The shaders can still choose to declare and use fewer samplers, if they want to. - desc.NumStaticSamplers = pipelineState.shaders.rootSig.textureViewCount; - D3D12_STATIC_SAMPLER_DESC staticSamplers[8]; - int sdIdx = 0; - Q_ASSERT(pipelineState.shaders.rootSig.textureViewCount <= _countof(staticSamplers)); - for (int i = 0; i < pipelineState.shaders.rootSig.textureViewCount; ++i) { - const QSGD3D12TextureView &tv(pipelineState.shaders.rootSig.textureViews[i]); - D3D12_STATIC_SAMPLER_DESC sd = {}; - sd.Filter = D3D12_FILTER(tv.filter); - sd.AddressU = D3D12_TEXTURE_ADDRESS_MODE(tv.addressModeHoriz); - sd.AddressV = D3D12_TEXTURE_ADDRESS_MODE(tv.addressModeVert); - sd.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; - sd.MinLOD = 0.0f; - sd.MaxLOD = D3D12_FLOAT32_MAX; - sd.ShaderRegister = sdIdx; // t0, t1, ... - sd.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; - staticSamplers[sdIdx++] = sd; - } - desc.pStaticSamplers = staticSamplers; - desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; - - ComPtr<ID3DBlob> signature; - ComPtr<ID3DBlob> error; - if (FAILED(D3D12SerializeRootSignature(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error))) { - QByteArray msg(static_cast<const char *>(error->GetBufferPointer()), error->GetBufferSize()); - qWarning("Failed to serialize root signature: %s", qPrintable(msg)); - return; - } - if (FAILED(device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), - IID_PPV_ARGS(&cachedRootSig->rootSig)))) { - qWarning("Failed to create root signature"); - return; - } - - rootSigCache.insert(pipelineState.shaders.rootSig, cachedRootSig); - } - - PSOCacheEntry *cachedPso = psoCache[pipelineState]; - if (!cachedPso) { - if (Q_UNLIKELY(debug_render())) - qDebug("NEW PSO"); - - cachedPso = new PSOCacheEntry; - - D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; - - D3D12_INPUT_ELEMENT_DESC inputElements[QSGD3D12_MAX_INPUT_ELEMENTS]; - int ieIdx = 0; - for (int i = 0; i < pipelineState.inputElementCount; ++i) { - const QSGD3D12InputElement &ie(pipelineState.inputElements[i]); - D3D12_INPUT_ELEMENT_DESC ieDesc = {}; - ieDesc.SemanticName = ie.semanticName; - ieDesc.SemanticIndex = ie.semanticIndex; - ieDesc.Format = DXGI_FORMAT(ie.format); - ieDesc.InputSlot = ie.slot; - ieDesc.AlignedByteOffset = ie.offset; - ieDesc.InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA; - if (Q_UNLIKELY(debug_render())) - qDebug("input [%d]: %s %d 0x%x %d", ieIdx, ie.semanticName, ie.offset, ie.format, ie.slot); - inputElements[ieIdx++] = ieDesc; - } - - psoDesc.InputLayout = { inputElements, UINT(ieIdx) }; - - psoDesc.pRootSignature = cachedRootSig->rootSig.Get(); - - D3D12_SHADER_BYTECODE vshader; - vshader.pShaderBytecode = pipelineState.shaders.vs; - vshader.BytecodeLength = pipelineState.shaders.vsSize; - D3D12_SHADER_BYTECODE pshader; - pshader.pShaderBytecode = pipelineState.shaders.ps; - pshader.BytecodeLength = pipelineState.shaders.psSize; - - psoDesc.VS = vshader; - psoDesc.PS = pshader; - - D3D12_RASTERIZER_DESC rastDesc = {}; - rastDesc.FillMode = D3D12_FILL_MODE_SOLID; - rastDesc.CullMode = D3D12_CULL_MODE(pipelineState.cullMode); - rastDesc.FrontCounterClockwise = pipelineState.frontCCW; - rastDesc.DepthBias = D3D12_DEFAULT_DEPTH_BIAS; - rastDesc.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP; - rastDesc.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; - rastDesc.DepthClipEnable = TRUE; - - psoDesc.RasterizerState = rastDesc; - - D3D12_BLEND_DESC blendDesc = {}; - if (pipelineState.blend == QSGD3D12PipelineState::BlendNone) { - D3D12_RENDER_TARGET_BLEND_DESC noBlendDesc = {}; - noBlendDesc.RenderTargetWriteMask = pipelineState.colorWrite ? D3D12_COLOR_WRITE_ENABLE_ALL : 0; - blendDesc.RenderTarget[0] = noBlendDesc; - } else if (pipelineState.blend == QSGD3D12PipelineState::BlendPremul) { - const D3D12_RENDER_TARGET_BLEND_DESC premulBlendDesc = { - TRUE, FALSE, - D3D12_BLEND_ONE, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD, - D3D12_BLEND_ONE, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD, - D3D12_LOGIC_OP_NOOP, - UINT8(pipelineState.colorWrite ? D3D12_COLOR_WRITE_ENABLE_ALL : 0) - }; - blendDesc.RenderTarget[0] = premulBlendDesc; - } else if (pipelineState.blend == QSGD3D12PipelineState::BlendColor) { - const D3D12_RENDER_TARGET_BLEND_DESC colorBlendDesc = { - TRUE, FALSE, - D3D12_BLEND_BLEND_FACTOR, D3D12_BLEND_INV_SRC_COLOR, D3D12_BLEND_OP_ADD, - D3D12_BLEND_BLEND_FACTOR, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD, - D3D12_LOGIC_OP_NOOP, - UINT8(pipelineState.colorWrite ? D3D12_COLOR_WRITE_ENABLE_ALL : 0) - }; - blendDesc.RenderTarget[0] = colorBlendDesc; - } - psoDesc.BlendState = blendDesc; - - psoDesc.DepthStencilState.DepthEnable = pipelineState.depthEnable; - psoDesc.DepthStencilState.DepthWriteMask = pipelineState.depthWrite ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO; - psoDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC(pipelineState.depthFunc); - - psoDesc.DepthStencilState.StencilEnable = pipelineState.stencilEnable; - psoDesc.DepthStencilState.StencilReadMask = psoDesc.DepthStencilState.StencilWriteMask = 0xFF; - D3D12_DEPTH_STENCILOP_DESC stencilOpDesc = { - D3D12_STENCIL_OP(pipelineState.stencilFailOp), - D3D12_STENCIL_OP(pipelineState.stencilDepthFailOp), - D3D12_STENCIL_OP(pipelineState.stencilPassOp), - D3D12_COMPARISON_FUNC(pipelineState.stencilFunc) - }; - psoDesc.DepthStencilState.FrontFace = psoDesc.DepthStencilState.BackFace = stencilOpDesc; - - psoDesc.SampleMask = UINT_MAX; - psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE(pipelineState.topologyType); - psoDesc.NumRenderTargets = 1; - psoDesc.RTVFormats[0] = RT_COLOR_FORMAT; - psoDesc.DSVFormat = DXGI_FORMAT_D24_UNORM_S8_UINT; - psoDesc.SampleDesc = defaultRT[0]->GetDesc().SampleDesc; - - HRESULT hr = device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&cachedPso->pso)); - if (FAILED(hr)) { - qWarning("Failed to create graphics pipeline state: %s", - qPrintable(comErrorMessage(hr))); - return; - } - - psoCache.insert(pipelineState, cachedPso); - } - - if (cachedPso->pso.Get() != tframeData.lastPso) { - tframeData.lastPso = cachedPso->pso.Get(); - commandList->SetPipelineState(tframeData.lastPso); - } - - if (cachedRootSig->rootSig.Get() != tframeData.lastRootSig) { - tframeData.lastRootSig = cachedRootSig->rootSig.Get(); - commandList->SetGraphicsRootSignature(tframeData.lastRootSig); - } - - if (pipelineState.shaders.rootSig.textureViewCount > 0) - setDescriptorHeaps(); -} - -void QSGD3D12EnginePrivate::setDescriptorHeaps(bool force) -{ - if (force || !tframeData.descHeapSet) { - tframeData.descHeapSet = true; - ID3D12DescriptorHeap *heaps[] = { pframeData[currentPFrameIndex].gpuCbvSrvUavHeap.Get() }; - commandList->SetDescriptorHeaps(_countof(heaps), heaps); - } -} - -void QSGD3D12EnginePrivate::queueViewport(const QRect &rect) -{ - if (!inFrame) { - qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__); - return; - } - - tframeData.viewport = rect; - const D3D12_VIEWPORT viewport = { float(rect.x()), float(rect.y()), float(rect.width()), float(rect.height()), 0, 1 }; - commandList->RSSetViewports(1, &viewport); -} - -void QSGD3D12EnginePrivate::queueScissor(const QRect &rect) -{ - if (!inFrame) { - qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__); - return; - } - - tframeData.scissor = rect; - const D3D12_RECT scissorRect = { rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height() }; - commandList->RSSetScissorRects(1, &scissorRect); -} - -void QSGD3D12EnginePrivate::queueSetRenderTarget(uint id) -{ - if (!inFrame) { - qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__); - return; - } - - D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle; - D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle; - - if (!id) { - rtvHandle = defaultRTV[presentFrameIndex % swapChainBufferCount]; - dsvHandle = defaultDSV; - } else { - const int idx = id - 1; - Q_ASSERT(idx < renderTargets.count() && renderTargets[idx].entryInUse()); - RenderTarget &rt(renderTargets[idx]); - rtvHandle = rt.rtv; - dsvHandle = rt.dsv; - if (!(rt.flags & RenderTarget::NeedsReadBarrier)) { - rt.flags |= RenderTarget::NeedsReadBarrier; - if (!(rt.flags & RenderTarget::Multisample)) - transitionResource(rt.color.Get(), commandList, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, - D3D12_RESOURCE_STATE_RENDER_TARGET); - } - } - - commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, &dsvHandle); - - currentRenderTarget = id; -} - -void QSGD3D12EnginePrivate::queueClearRenderTarget(const QColor &color) -{ - if (!inFrame) { - qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__); - return; - } - - const float clearColor[] = { float(color.redF()), float(color.blueF()), float(color.greenF()), float(color.alphaF()) }; - D3D12_CPU_DESCRIPTOR_HANDLE rtv = !currentRenderTarget - ? defaultRTV[presentFrameIndex % swapChainBufferCount] - : renderTargets[currentRenderTarget - 1].rtv; - commandList->ClearRenderTargetView(rtv, clearColor, 0, nullptr); -} - -void QSGD3D12EnginePrivate::queueClearDepthStencil(float depthValue, quint8 stencilValue, QSGD3D12Engine::ClearFlags which) -{ - if (!inFrame) { - qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__); - return; - } - - D3D12_CPU_DESCRIPTOR_HANDLE dsv = !currentRenderTarget - ? defaultDSV - : renderTargets[currentRenderTarget - 1].dsv; - commandList->ClearDepthStencilView(dsv, D3D12_CLEAR_FLAGS(int(which)), depthValue, stencilValue, 0, nullptr); -} - -void QSGD3D12EnginePrivate::queueSetBlendFactor(const QVector4D &factor) -{ - if (!inFrame) { - qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__); - return; - } - - tframeData.blendFactor = factor; - const float f[4] = { factor.x(), factor.y(), factor.z(), factor.w() }; - commandList->OMSetBlendFactor(f); -} - -void QSGD3D12EnginePrivate::queueSetStencilRef(quint32 ref) -{ - if (!inFrame) { - qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__); - return; - } - - tframeData.stencilRef = ref; - commandList->OMSetStencilRef(ref); -} - -void QSGD3D12EnginePrivate::queueDraw(const QSGD3D12Engine::DrawParams ¶ms) -{ - if (!inFrame) { - qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__); - return; - } - - const bool skip = tframeData.scissor.isEmpty(); - - PersistentFrameData &pfd(pframeData[currentPFrameIndex]); - - pfd.buffersUsedInDrawCallSet.insert(params.vertexBuf); - const int vertexBufIdx = params.vertexBuf - 1; - Q_ASSERT(params.vertexBuf && vertexBufIdx < buffers.count() && buffers[vertexBufIdx].entryInUse()); - pfd.buffersUsedInDrawCallSet.insert(params.constantBuf); - const int constantBufIdx = params.constantBuf - 1; - Q_ASSERT(params.constantBuf && constantBufIdx < buffers.count() && buffers[constantBufIdx].entryInUse()); - int indexBufIdx = -1; - if (params.indexBuf) { - pfd.buffersUsedInDrawCallSet.insert(params.indexBuf); - indexBufIdx = params.indexBuf - 1; - Q_ASSERT(indexBufIdx < buffers.count() && buffers[indexBufIdx].entryInUse()); - } - - // Ensure buffers are created but do not copy the data here, leave that to endDrawCalls(). - ensureBuffer(&buffers[vertexBufIdx]); - ensureBuffer(&buffers[constantBufIdx]); - if (indexBufIdx >= 0) - ensureBuffer(&buffers[indexBufIdx]); - - // Set the CBV. - if (!skip && params.cboOffset >= 0) { - ID3D12Resource *cbuf = buffers[constantBufIdx].d[currentPFrameIndex].buffer.Get(); - if (cbuf) - commandList->SetGraphicsRootConstantBufferView(0, cbuf->GetGPUVirtualAddress() + params.cboOffset); - } - - // Set up vertex and index buffers. - ID3D12Resource *vbuf = buffers[vertexBufIdx].d[currentPFrameIndex].buffer.Get(); - ID3D12Resource *ibuf = indexBufIdx >= 0 && params.startIndexIndex >= 0 - ? buffers[indexBufIdx].d[currentPFrameIndex].buffer.Get() : nullptr; - - if (!skip && params.mode != tframeData.drawingMode) { - D3D_PRIMITIVE_TOPOLOGY topology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; - switch (params.mode) { - case QSGGeometry::DrawPoints: - topology = D3D_PRIMITIVE_TOPOLOGY_POINTLIST; - break; - case QSGGeometry::DrawLines: - topology = D3D_PRIMITIVE_TOPOLOGY_LINELIST; - break; - case QSGGeometry::DrawLineStrip: - topology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; - break; - case QSGGeometry::DrawTriangles: - topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; - break; - case QSGGeometry::DrawTriangleStrip: - topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; - break; - default: - qFatal("Unsupported drawing mode 0x%x", params.mode); - break; - } - commandList->IASetPrimitiveTopology(topology); - tframeData.drawingMode = params.mode; - } - - if (!skip) { - D3D12_VERTEX_BUFFER_VIEW vbv; - vbv.BufferLocation = vbuf->GetGPUVirtualAddress() + params.vboOffset; - vbv.SizeInBytes = params.vboSize; - vbv.StrideInBytes = params.vboStride; - - // must be set after the topology - commandList->IASetVertexBuffers(0, 1, &vbv); - } - - if (!skip && params.startIndexIndex >= 0 && ibuf && tframeData.currentIndexBuffer != params.indexBuf) { - tframeData.currentIndexBuffer = params.indexBuf; - D3D12_INDEX_BUFFER_VIEW ibv; - ibv.BufferLocation = ibuf->GetGPUVirtualAddress(); - ibv.SizeInBytes = buffers[indexBufIdx].cpuDataRef.size; - ibv.Format = DXGI_FORMAT(params.indexFormat); - commandList->IASetIndexBuffer(&ibv); - } - - // Copy the SRVs to a drawcall-dedicated area of the shader-visible descriptor heap. - Q_ASSERT(tframeData.activeTextureCount == tframeData.pipelineState.shaders.rootSig.textureViewCount); - if (tframeData.activeTextureCount > 0) { - if (!skip) { - ensureGPUDescriptorHeap(tframeData.activeTextureCount); - const uint stride = cpuDescHeapManager.handleSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - D3D12_CPU_DESCRIPTOR_HANDLE dst = pfd.gpuCbvSrvUavHeap->GetCPUDescriptorHandleForHeapStart(); - dst.ptr += pfd.cbvSrvUavNextFreeDescriptorIndex * stride; - for (int i = 0; i < tframeData.activeTextureCount; ++i) { - const TransientFrameData::ActiveTexture &t(tframeData.activeTextures[i]); - Q_ASSERT(t.id); - const int idx = t.id - 1; - const bool isTex = t.type == TransientFrameData::ActiveTexture::TypeTexture; - device->CopyDescriptorsSimple(1, dst, isTex ? textures[idx].srv : renderTargets[idx].srv, - D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - dst.ptr += stride; - } - - D3D12_GPU_DESCRIPTOR_HANDLE gpuAddr = pfd.gpuCbvSrvUavHeap->GetGPUDescriptorHandleForHeapStart(); - gpuAddr.ptr += pfd.cbvSrvUavNextFreeDescriptorIndex * stride; - commandList->SetGraphicsRootDescriptorTable(1, gpuAddr); - - pfd.cbvSrvUavNextFreeDescriptorIndex += tframeData.activeTextureCount; - } - tframeData.activeTextureCount = 0; - } - - // Add the draw call. - if (!skip) { - ++tframeData.drawCount; - if (params.startIndexIndex >= 0) - commandList->DrawIndexedInstanced(params.count, 1, params.startIndexIndex, 0, 0); - else - commandList->DrawInstanced(params.count, 1, 0, 0); - } - - if (tframeData.drawCount == MAX_DRAW_CALLS_PER_LIST) { - if (Q_UNLIKELY(debug_render())) - qDebug("Limit of %d draw calls reached, executing command list", MAX_DRAW_CALLS_PER_LIST); - // submit the command list - endDrawCalls(); - // start a new one - beginDrawCalls(); - // prepare for the upcoming drawcalls - restoreFrameState(); - } -} - -void QSGD3D12EnginePrivate::ensureGPUDescriptorHeap(int cbvSrvUavDescriptorCount) -{ - PersistentFrameData &pfd(pframeData[currentPFrameIndex]); - int newSize = pfd.gpuCbvSrvUavHeapSize; - while (pfd.cbvSrvUavNextFreeDescriptorIndex + cbvSrvUavDescriptorCount > newSize) - newSize *= 2; - if (newSize != pfd.gpuCbvSrvUavHeapSize) { - if (Q_UNLIKELY(debug_descheap())) - qDebug("Out of space for SRVs, creating new CBV-SRV-UAV descriptor heap with descriptor count %d", newSize); - deferredDelete(pfd.gpuCbvSrvUavHeap); - createCbvSrvUavHeap(currentPFrameIndex, newSize); - setDescriptorHeaps(true); - pfd.cbvSrvUavNextFreeDescriptorIndex = 0; - } -} - -void QSGD3D12EnginePrivate::present() -{ - if (!initialized) - return; - - if (Q_UNLIKELY(debug_render())) - qDebug("--- present with vsync ---"); - - // This call will not block the CPU unless at least 3 buffers are queued, - // unless the waitable frame latency event is enabled. Then the latency of - // 3 is changed to whatever value desired, and blocking happens in - // beginFrame. If none of these hold, the fence-based wait in beginFrame - // throttles. Vsync (interval 1) is always enabled. - HRESULT hr = swapChain->Present(1, 0); - if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) { - deviceManager()->deviceLossDetected(); - return; - } else if (FAILED(hr)) { - qWarning("Present failed: %s", qPrintable(comErrorMessage(hr))); - return; - } - -#ifndef Q_OS_WINRT - if (dcompDevice) - dcompDevice->Commit(); -#endif - - ++presentFrameIndex; -} - -void QSGD3D12EnginePrivate::waitGPU() -{ - if (!initialized) - return; - - if (Q_UNLIKELY(debug_render())) - qDebug("--- blocking wait for GPU ---"); - - waitForGPU(presentFence); -} - -template<class T> uint newId(T *tbl) -{ - uint id = 0; - for (int i = 0; i < tbl->count(); ++i) { - if (!(*tbl)[i].entryInUse()) { - id = i + 1; - break; - } - } - - if (!id) { - tbl->resize(tbl->size() + 1); - id = tbl->count(); - } - - (*tbl)[id - 1].flags = 0x01; // reset flags and set EntryInUse - - return id; -} - -template<class T> void syncEntryFlags(T *e, int flag, bool b) -{ - if (b) - e->flags |= flag; - else - e->flags &= ~flag; -} - -uint QSGD3D12EnginePrivate::genBuffer() -{ - return newId(&buffers); -} - -void QSGD3D12EnginePrivate::releaseBuffer(uint id) -{ - if (!id || !initialized) - return; - - const int idx = id - 1; - Q_ASSERT(idx < buffers.count()); - - if (Q_UNLIKELY(debug_buffer())) - qDebug("releasing buffer %u", id); - - Buffer &b(buffers[idx]); - if (!b.entryInUse()) - return; - - // Do not null out and do not mark the entry reusable yet. - // Do that only when the frames potentially in flight have finished for sure. - - for (int i = 0; i < frameInFlightCount; ++i) { - if (b.d[i].buffer) - deferredDelete(b.d[i].buffer); - } - - QSet<PersistentFrameData::PendingRelease> *pendingReleasesSet = inFrame - ? &pframeData[currentPFrameIndex].pendingReleases - : &pframeData[(currentPFrameIndex + 1) % frameInFlightCount].outOfFramePendingReleases; - - pendingReleasesSet->insert(PersistentFrameData::PendingRelease(PersistentFrameData::PendingRelease::TypeBuffer, id)); -} - -void QSGD3D12EnginePrivate::resetBuffer(uint id, const quint8 *data, int size) -{ - if (!inFrame) { - qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__); - return; - } - - Q_ASSERT(id); - const int idx = id - 1; - Q_ASSERT(idx < buffers.count() && buffers[idx].entryInUse()); - Buffer &b(buffers[idx]); - - if (Q_UNLIKELY(debug_buffer())) - qDebug("reset buffer %u, size %d", id, size); - - b.cpuDataRef.p = data; - b.cpuDataRef.size = size; - - b.cpuDataRef.dirty.clear(); - b.d[currentPFrameIndex].dirty.clear(); - - if (size > 0) { - const QPair<int, int> range = qMakePair(0, size); - b.cpuDataRef.dirty.append(range); - b.d[currentPFrameIndex].dirty.append(range); - } -} - -void QSGD3D12EnginePrivate::addDirtyRange(DirtyList *dirty, int offset, int size, int bufferSize) -{ - // Bail out when the dirty list already spans the entire buffer. - if (!dirty->isEmpty()) { - if (dirty->at(0).first == 0 && dirty->at(0).second == bufferSize) - return; - } - - const QPair<int, int> range = qMakePair(offset, size); - if (!dirty->contains(range)) - dirty->append(range); -} - -void QSGD3D12EnginePrivate::markBufferDirty(uint id, int offset, int size) -{ - if (!inFrame) { - qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__); - return; - } - - Q_ASSERT(id); - const int idx = id - 1; - Q_ASSERT(idx < buffers.count() && buffers[idx].entryInUse()); - Buffer &b(buffers[idx]); - - addDirtyRange(&b.cpuDataRef.dirty, offset, size, b.cpuDataRef.size); - addDirtyRange(&b.d[currentPFrameIndex].dirty, offset, size, b.cpuDataRef.size); -} - -uint QSGD3D12EnginePrivate::genTexture() -{ - const uint id = newId(&textures); - textures[id - 1].fenceValue = 0; - return id; -} - -static inline DXGI_FORMAT textureFormat(QImage::Format format, bool wantsAlpha, bool mipmap, bool force32bit, - QImage::Format *imageFormat, int *bytesPerPixel) -{ - DXGI_FORMAT f = DXGI_FORMAT_R8G8B8A8_UNORM; - QImage::Format convFormat = format; - int bpp = 4; - - if (!mipmap) { - switch (format) { - case QImage::Format_Grayscale8: - case QImage::Format_Indexed8: - case QImage::Format_Alpha8: - if (!force32bit) { - f = DXGI_FORMAT_R8_UNORM; - bpp = 1; - } else { - convFormat = QImage::Format_RGBA8888; - } - break; - case QImage::Format_RGB32: - f = DXGI_FORMAT_B8G8R8A8_UNORM; - break; - case QImage::Format_ARGB32: - f = DXGI_FORMAT_B8G8R8A8_UNORM; - convFormat = wantsAlpha ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; - break; - case QImage::Format_ARGB32_Premultiplied: - f = DXGI_FORMAT_B8G8R8A8_UNORM; - convFormat = wantsAlpha ? format : QImage::Format_RGB32; - break; - default: - convFormat = wantsAlpha ? QImage::Format_RGBA8888_Premultiplied : QImage::Format_RGBX8888; - break; - } - } else { - // Mipmap generation needs unordered access and BGRA is not an option for that. Stick to RGBA. - convFormat = wantsAlpha ? QImage::Format_RGBA8888_Premultiplied : QImage::Format_RGBX8888; - } - - if (imageFormat) - *imageFormat = convFormat; - - if (bytesPerPixel) - *bytesPerPixel = bpp; - - return f; -} - -static inline QImage::Format imageFormatForTexture(DXGI_FORMAT format) -{ - QImage::Format f = QImage::Format_Invalid; - - switch (format) { - case DXGI_FORMAT_R8G8B8A8_UNORM: - f = QImage::Format_RGBA8888_Premultiplied; - break; - case DXGI_FORMAT_B8G8R8A8_UNORM: - f = QImage::Format_ARGB32_Premultiplied; - break; - case DXGI_FORMAT_R8_UNORM: - f = QImage::Format_Grayscale8; - break; - default: - break; - } - - return f; -} - -void QSGD3D12EnginePrivate::createTexture(uint id, const QSize &size, QImage::Format format, - QSGD3D12Engine::TextureCreateFlags createFlags) -{ - ensureDevice(); - - Q_ASSERT(id); - const int idx = id - 1; - Q_ASSERT(idx < textures.count() && textures[idx].entryInUse()); - Texture &t(textures[idx]); - - syncEntryFlags(&t, Texture::Alpha, createFlags & QSGD3D12Engine::TextureWithAlpha); - syncEntryFlags(&t, Texture::MipMap, createFlags & QSGD3D12Engine::TextureWithMipMaps); - - const QSize adjustedSize = !t.mipmap() ? size : QSGD3D12Engine::mipMapAdjustedSourceSize(size); - - D3D12_HEAP_PROPERTIES defaultHeapProp = {}; - defaultHeapProp.Type = D3D12_HEAP_TYPE_DEFAULT; - - D3D12_RESOURCE_DESC textureDesc = {}; - textureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; - textureDesc.Width = adjustedSize.width(); - textureDesc.Height = adjustedSize.height(); - textureDesc.DepthOrArraySize = 1; - textureDesc.MipLevels = !t.mipmap() ? 1 : QSGD3D12Engine::mipMapLevels(adjustedSize); - textureDesc.Format = textureFormat(format, t.alpha(), t.mipmap(), - createFlags.testFlag(QSGD3D12Engine::TextureAlways32Bit), - nullptr, nullptr); - textureDesc.SampleDesc.Count = 1; - textureDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; - if (t.mipmap()) - textureDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; - - HRESULT hr = device->CreateCommittedResource(&defaultHeapProp, D3D12_HEAP_FLAG_NONE, &textureDesc, - D3D12_RESOURCE_STATE_COMMON, nullptr, IID_PPV_ARGS(&t.texture)); - if (FAILED(hr)) { - qWarning("Failed to create texture resource: %s", qPrintable(comErrorMessage(hr))); - return; - } - - t.srv = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - - D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; - srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; - srvDesc.Format = textureDesc.Format; - srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; - srvDesc.Texture2D.MipLevels = textureDesc.MipLevels; - - device->CreateShaderResourceView(t.texture.Get(), &srvDesc, t.srv); - - if (t.mipmap()) { - // Mipmap generation will need an UAV for each level that needs to be generated. - t.mipUAVs.clear(); - for (int level = 1; level < textureDesc.MipLevels; ++level) { - D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {}; - uavDesc.Format = textureDesc.Format; - uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D; - uavDesc.Texture2D.MipSlice = level; - D3D12_CPU_DESCRIPTOR_HANDLE h = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - device->CreateUnorderedAccessView(t.texture.Get(), nullptr, &uavDesc, h); - t.mipUAVs.append(h); - } - } - - if (Q_UNLIKELY(debug_texture())) - qDebug("created texture %u, size %dx%d, miplevels %d", id, adjustedSize.width(), adjustedSize.height(), textureDesc.MipLevels); -} - -void QSGD3D12EnginePrivate::queueTextureResize(uint id, const QSize &size) -{ - Q_ASSERT(id); - const int idx = id - 1; - Q_ASSERT(idx < textures.count() && textures[idx].entryInUse()); - Texture &t(textures[idx]); - - if (!t.texture) { - qWarning("Cannot resize non-created texture %u", id); - return; - } - - if (t.mipmap()) { - qWarning("Cannot resize mipmapped texture %u", id); - return; - } - - if (Q_UNLIKELY(debug_texture())) - qDebug("resizing texture %u, size %dx%d", id, size.width(), size.height()); - - D3D12_RESOURCE_DESC textureDesc = t.texture->GetDesc(); - textureDesc.Width = size.width(); - textureDesc.Height = size.height(); - - D3D12_HEAP_PROPERTIES defaultHeapProp = {}; - defaultHeapProp.Type = D3D12_HEAP_TYPE_DEFAULT; - - ComPtr<ID3D12Resource> oldTexture = t.texture; - deferredDelete(t.texture); - - HRESULT hr = device->CreateCommittedResource(&defaultHeapProp, D3D12_HEAP_FLAG_NONE, &textureDesc, - D3D12_RESOURCE_STATE_COMMON, nullptr, IID_PPV_ARGS(&t.texture)); - if (FAILED(hr)) { - qWarning("Failed to create resized texture resource: %s", - qPrintable(comErrorMessage(hr))); - return; - } - - deferredDelete(t.srv, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - t.srv = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - - D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; - srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; - srvDesc.Format = textureDesc.Format; - srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; - srvDesc.Texture2D.MipLevels = textureDesc.MipLevels; - - device->CreateShaderResourceView(t.texture.Get(), &srvDesc, t.srv); - - D3D12_TEXTURE_COPY_LOCATION dstLoc; - dstLoc.pResource = t.texture.Get(); - dstLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - dstLoc.SubresourceIndex = 0; - - D3D12_TEXTURE_COPY_LOCATION srcLoc; - srcLoc.pResource = oldTexture.Get(); - srcLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - srcLoc.SubresourceIndex = 0; - - copyCommandList->Reset(copyCommandAllocator.Get(), nullptr); - - copyCommandList->CopyTextureRegion(&dstLoc, 0, 0, 0, &srcLoc, nullptr); - - copyCommandList->Close(); - ID3D12CommandList *commandLists[] = { copyCommandList.Get() }; - copyCommandQueue->ExecuteCommandLists(_countof(commandLists), commandLists); - - t.fenceValue = nextTextureUploadFenceValue.fetchAndAddAcquire(1) + 1; - copyCommandQueue->Signal(textureUploadFence.Get(), t.fenceValue); - - if (Q_UNLIKELY(debug_texture())) - qDebug("submitted old content copy for texture %u on the copy queue, fence %llu", id, t.fenceValue); -} - -void QSGD3D12EnginePrivate::queueTextureUpload(uint id, const QVector<QImage> &images, const QVector<QPoint> &dstPos, - QSGD3D12Engine::TextureUploadFlags flags) -{ - Q_ASSERT(id); - Q_ASSERT(images.count() == dstPos.count()); - if (images.isEmpty()) - return; - - const int idx = id - 1; - Q_ASSERT(idx < textures.count() && textures[idx].entryInUse()); - Texture &t(textures[idx]); - Q_ASSERT(t.texture); - - // When mipmapping is not in use, image can be smaller than the size passed - // to createTexture() and dstPos can specify a non-zero destination position. - - if (t.mipmap() && (images.count() != 1 || dstPos.count() != 1 || !dstPos[0].isNull())) { - qWarning("Mipmapped textures (%u) do not support partial uploads", id); - return; - } - - // Make life simpler by disallowing queuing a new mipmapped upload before the previous one finishes. - if (t.mipmap() && t.fenceValue) { - qWarning("Attempted to queue mipmapped texture upload (%u) while a previous upload is still in progress", id); - return; - } - - t.fenceValue = nextTextureUploadFenceValue.fetchAndAddAcquire(1) + 1; - - if (Q_UNLIKELY(debug_texture())) - qDebug("adding upload for texture %u on the copy queue, fence %llu", id, t.fenceValue); - - D3D12_RESOURCE_DESC textureDesc = t.texture->GetDesc(); - const QSize adjustedTextureSize(textureDesc.Width, textureDesc.Height); - - int totalSize = 0; - for (const QImage &image : images) { - int bytesPerPixel; - textureFormat(image.format(), t.alpha(), t.mipmap(), - flags.testFlag(QSGD3D12Engine::TextureUploadAlways32Bit), - nullptr, &bytesPerPixel); - const int w = !t.mipmap() ? image.width() : adjustedTextureSize.width(); - const int h = !t.mipmap() ? image.height() : adjustedTextureSize.height(); - const int stride = alignedSize(w * bytesPerPixel, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); - totalSize += alignedSize(h * stride, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT); - } - - if (Q_UNLIKELY(debug_texture())) - qDebug("%d sub-uploads, heap size %d bytes", images.count(), totalSize); - - // Instead of individual committed resources for each upload buffer, - // allocate only once and use placed resources. - D3D12_HEAP_PROPERTIES uploadHeapProp = {}; - uploadHeapProp.Type = D3D12_HEAP_TYPE_UPLOAD; - D3D12_HEAP_DESC uploadHeapDesc = {}; - uploadHeapDesc.SizeInBytes = totalSize; - uploadHeapDesc.Properties = uploadHeapProp; - uploadHeapDesc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS; - - Texture::StagingHeap sheap; - if (FAILED(device->CreateHeap(&uploadHeapDesc, IID_PPV_ARGS(&sheap.heap)))) { - qWarning("Failed to create texture upload heap of size %d", totalSize); - return; - } - t.stagingHeaps.append(sheap); - - copyCommandList->Reset(copyCommandAllocator.Get(), nullptr); - - int placedOffset = 0; - for (int i = 0; i < images.count(); ++i) { - QImage::Format convFormat; - int bytesPerPixel; - textureFormat(images[i].format(), t.alpha(), t.mipmap(), - flags.testFlag(QSGD3D12Engine::TextureUploadAlways32Bit), - &convFormat, &bytesPerPixel); - if (Q_UNLIKELY(debug_texture() && i == 0)) - qDebug("source image format %d, target format %d, bpp %d", images[i].format(), convFormat, bytesPerPixel); - - QImage convImage = images[i].format() == convFormat ? images[i] : images[i].convertToFormat(convFormat); - - if (t.mipmap() && adjustedTextureSize != convImage.size()) - convImage = convImage.scaled(adjustedTextureSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - - const int stride = alignedSize(convImage.width() * bytesPerPixel, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); - - D3D12_RESOURCE_DESC bufDesc = {}; - bufDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - bufDesc.Width = stride * convImage.height(); - bufDesc.Height = 1; - bufDesc.DepthOrArraySize = 1; - bufDesc.MipLevels = 1; - bufDesc.Format = DXGI_FORMAT_UNKNOWN; - bufDesc.SampleDesc.Count = 1; - bufDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; - - Texture::StagingBuffer sbuf; - if (FAILED(device->CreatePlacedResource(sheap.heap.Get(), placedOffset, - &bufDesc, D3D12_RESOURCE_STATE_GENERIC_READ, - nullptr, IID_PPV_ARGS(&sbuf.buffer)))) { - qWarning("Failed to create texture upload buffer"); - return; - } - - quint8 *p = nullptr; - const D3D12_RANGE readRange = { 0, 0 }; - if (FAILED(sbuf.buffer->Map(0, &readRange, reinterpret_cast<void **>(&p)))) { - qWarning("Map failed (texture upload buffer)"); - return; - } - for (int y = 0, ye = convImage.height(); y < ye; ++y) { - memcpy(p, convImage.constScanLine(y), convImage.width() * bytesPerPixel); - p += stride; - } - sbuf.buffer->Unmap(0, nullptr); - - D3D12_TEXTURE_COPY_LOCATION dstLoc; - dstLoc.pResource = t.texture.Get(); - dstLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - dstLoc.SubresourceIndex = 0; - - D3D12_TEXTURE_COPY_LOCATION srcLoc; - srcLoc.pResource = sbuf.buffer.Get(); - srcLoc.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; - srcLoc.PlacedFootprint.Offset = 0; - srcLoc.PlacedFootprint.Footprint.Format = textureDesc.Format; - srcLoc.PlacedFootprint.Footprint.Width = convImage.width(); - srcLoc.PlacedFootprint.Footprint.Height = convImage.height(); - srcLoc.PlacedFootprint.Footprint.Depth = 1; - srcLoc.PlacedFootprint.Footprint.RowPitch = stride; - - copyCommandList->CopyTextureRegion(&dstLoc, dstPos[i].x(), dstPos[i].y(), 0, &srcLoc, nullptr); - - t.stagingBuffers.append(sbuf); - placedOffset += alignedSize(bufDesc.Width, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT); - } - - copyCommandList->Close(); - ID3D12CommandList *commandLists[] = { copyCommandList.Get() }; - copyCommandQueue->ExecuteCommandLists(_countof(commandLists), commandLists); - copyCommandQueue->Signal(textureUploadFence.Get(), t.fenceValue); -} - -void QSGD3D12EnginePrivate::releaseTexture(uint id) -{ - if (!id || !initialized) - return; - - const int idx = id - 1; - Q_ASSERT(idx < textures.count()); - - if (Q_UNLIKELY(debug_texture())) - qDebug("releasing texture %d", id); - - Texture &t(textures[idx]); - if (!t.entryInUse()) - return; - - if (t.texture) { - deferredDelete(t.texture); - deferredDelete(t.srv, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - for (D3D12_CPU_DESCRIPTOR_HANDLE h : t.mipUAVs) - deferredDelete(h, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - } - - QSet<PersistentFrameData::PendingRelease> *pendingReleasesSet = inFrame - ? &pframeData[currentPFrameIndex].pendingReleases - : &pframeData[(currentPFrameIndex + 1) % frameInFlightCount].outOfFramePendingReleases; - - pendingReleasesSet->insert(PersistentFrameData::PendingRelease(PersistentFrameData::PendingRelease::TypeTexture, id)); -} - -void QSGD3D12EnginePrivate::useTexture(uint id) -{ - if (!inFrame) { - qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__); - return; - } - - Q_ASSERT(id); - const int idx = id - 1; - Q_ASSERT(idx < textures.count() && textures[idx].entryInUse()); - - // Within one frame the order of calling this function determines the - // texture register (0, 1, ...) so fill up activeTextures accordingly. - tframeData.activeTextures[tframeData.activeTextureCount++] - = TransientFrameData::ActiveTexture(TransientFrameData::ActiveTexture::TypeTexture, id); - - if (textures[idx].fenceValue) - pframeData[currentPFrameIndex].pendingTextureUploads.insert(id); -} - -bool QSGD3D12EnginePrivate::MipMapGen::initialize(QSGD3D12EnginePrivate *enginePriv) -{ - engine = enginePriv; - - D3D12_STATIC_SAMPLER_DESC sampler = {}; - sampler.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR; - sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; - sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; - sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; - sampler.MinLOD = 0.0f; - sampler.MaxLOD = D3D12_FLOAT32_MAX; - - D3D12_DESCRIPTOR_RANGE descRange[2]; - descRange[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; - descRange[0].NumDescriptors = 1; - descRange[0].BaseShaderRegister = 0; // t0 - descRange[0].RegisterSpace = 0; - descRange[0].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; - descRange[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; - descRange[1].NumDescriptors = 4; - descRange[1].BaseShaderRegister = 0; // u0..u3 - descRange[1].RegisterSpace = 0; - descRange[1].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; - - // Split into two to allow switching between the first and second set of UAVs later. - D3D12_ROOT_PARAMETER rootParameters[3]; - rootParameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; - rootParameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; - rootParameters[0].DescriptorTable.NumDescriptorRanges = 1; - rootParameters[0].DescriptorTable.pDescriptorRanges = &descRange[0]; - - rootParameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; - rootParameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; - rootParameters[1].DescriptorTable.NumDescriptorRanges = 1; - rootParameters[1].DescriptorTable.pDescriptorRanges = &descRange[1]; - - rootParameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; - rootParameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; - rootParameters[2].Constants.Num32BitValues = 4; // uint2 mip1Size, uint sampleLevel, uint totalMips - rootParameters[2].Constants.ShaderRegister = 0; // b0 - rootParameters[2].Constants.RegisterSpace = 0; - - D3D12_ROOT_SIGNATURE_DESC desc = {}; - desc.NumParameters = 3; - desc.pParameters = rootParameters; - desc.NumStaticSamplers = 1; - desc.pStaticSamplers = &sampler; - - ComPtr<ID3DBlob> signature; - ComPtr<ID3DBlob> error; - if (FAILED(D3D12SerializeRootSignature(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error))) { - QByteArray msg(static_cast<const char *>(error->GetBufferPointer()), error->GetBufferSize()); - qWarning("Failed to serialize compute root signature: %s", qPrintable(msg)); - return false; - } - if (FAILED(engine->device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), - IID_PPV_ARGS(&rootSig)))) { - qWarning("Failed to create compute root signature"); - return false; - } - - D3D12_COMPUTE_PIPELINE_STATE_DESC psoDesc = {}; - psoDesc.pRootSignature = rootSig.Get(); - psoDesc.CS.pShaderBytecode = g_CS_Generate4MipMaps; - psoDesc.CS.BytecodeLength = sizeof(g_CS_Generate4MipMaps); - - if (FAILED(engine->device->CreateComputePipelineState(&psoDesc, IID_PPV_ARGS(&pipelineState)))) { - qWarning("Failed to create compute pipeline state"); - return false; - } - - return true; -} - -void QSGD3D12EnginePrivate::MipMapGen::releaseResources() -{ - pipelineState = nullptr; - rootSig = nullptr; -} - -// The mipmap generator is used to insert commands on the main 3D queue. It is -// guaranteed that the queue has a wait for the base texture level upload -// before invoking queueGenerate(). There can be any number of invocations -// without waiting for earlier ones to finish. finished() is invoked when it is -// known for sure that frame containing the upload and mipmap generation has -// finished on the GPU. - -void QSGD3D12EnginePrivate::MipMapGen::queueGenerate(const Texture &t) -{ - D3D12_RESOURCE_DESC textureDesc = t.texture->GetDesc(); - - engine->commandList->SetPipelineState(pipelineState.Get()); - engine->commandList->SetComputeRootSignature(rootSig.Get()); - - // 1 SRV + (miplevels - 1) UAVs - const int descriptorCount = 1 + (textureDesc.MipLevels - 1); - - engine->ensureGPUDescriptorHeap(descriptorCount); - - // The descriptor heap is set on the command list either because the - // ensure() call above resized, or, typically, due to a texture-dependent - // draw call earlier. - - engine->transitionResource(t.texture.Get(), engine->commandList, - D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - - QSGD3D12EnginePrivate::PersistentFrameData &pfd(engine->pframeData[engine->currentPFrameIndex]); - - const uint stride = engine->cpuDescHeapManager.handleSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - D3D12_CPU_DESCRIPTOR_HANDLE h = pfd.gpuCbvSrvUavHeap->GetCPUDescriptorHandleForHeapStart(); - h.ptr += pfd.cbvSrvUavNextFreeDescriptorIndex * stride; - - engine->device->CopyDescriptorsSimple(1, h, t.srv, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - h.ptr += stride; - - for (int level = 1; level < textureDesc.MipLevels; ++level, h.ptr += stride) - engine->device->CopyDescriptorsSimple(1, h, t.mipUAVs[level - 1], D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - - D3D12_GPU_DESCRIPTOR_HANDLE gpuAddr = pfd.gpuCbvSrvUavHeap->GetGPUDescriptorHandleForHeapStart(); - gpuAddr.ptr += pfd.cbvSrvUavNextFreeDescriptorIndex * stride; - - engine->commandList->SetComputeRootDescriptorTable(0, gpuAddr); - gpuAddr.ptr += stride; // now points to the first UAV - - for (int level = 1; level < textureDesc.MipLevels; level += 4, gpuAddr.ptr += stride * 4) { - engine->commandList->SetComputeRootDescriptorTable(1, gpuAddr); - - QSize sz(textureDesc.Width, textureDesc.Height); - sz.setWidth(qMax(1, sz.width() >> level)); - sz.setHeight(qMax(1, sz.height() >> level)); - - const quint32 constants[4] = { quint32(sz.width()), quint32(sz.height()), - quint32(level - 1), - quint32(textureDesc.MipLevels - 1) }; - - engine->commandList->SetComputeRoot32BitConstants(2, 4, constants, 0); - engine->commandList->Dispatch(sz.width(), sz.height(), 1); - engine->uavBarrier(t.texture.Get(), engine->commandList); - } - - engine->transitionResource(t.texture.Get(), engine->commandList, - D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); - - pfd.cbvSrvUavNextFreeDescriptorIndex += descriptorCount; -} - -void QSGD3D12EnginePrivate::deferredDelete(ComPtr<ID3D12Resource> res) -{ - PersistentFrameData::DeleteQueueEntry e; - e.res = res; - QVector<PersistentFrameData::DeleteQueueEntry> *dq = inFrame - ? &pframeData[currentPFrameIndex].deleteQueue - : &pframeData[(currentPFrameIndex + 1) % frameInFlightCount].outOfFrameDeleteQueue; - (*dq) << e; -} - -void QSGD3D12EnginePrivate::deferredDelete(ComPtr<ID3D12DescriptorHeap> dh) -{ - PersistentFrameData::DeleteQueueEntry e; - e.descHeap = dh; - QVector<PersistentFrameData::DeleteQueueEntry> *dq = inFrame - ? &pframeData[currentPFrameIndex].deleteQueue - : &pframeData[(currentPFrameIndex + 1) % frameInFlightCount].outOfFrameDeleteQueue; - (*dq) << e; -} - -void QSGD3D12EnginePrivate::deferredDelete(D3D12_CPU_DESCRIPTOR_HANDLE h, D3D12_DESCRIPTOR_HEAP_TYPE type) -{ - PersistentFrameData::DeleteQueueEntry e; - e.cpuDescriptorPtr = h.ptr; - e.descHeapType = type; - QVector<PersistentFrameData::DeleteQueueEntry> *dq = inFrame - ? &pframeData[currentPFrameIndex].deleteQueue - : &pframeData[(currentPFrameIndex + 1) % frameInFlightCount].outOfFrameDeleteQueue; - (*dq) << e; -} - -uint QSGD3D12EnginePrivate::genRenderTarget() -{ - return newId(&renderTargets); -} - -void QSGD3D12EnginePrivate::createRenderTarget(uint id, const QSize &size, const QVector4D &clearColor, uint samples) -{ - ensureDevice(); - - Q_ASSERT(id); - const int idx = id - 1; - Q_ASSERT(idx < renderTargets.count() && renderTargets[idx].entryInUse()); - RenderTarget &rt(renderTargets[idx]); - - rt.rtv = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); - rt.dsv = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_DSV); - rt.srv = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - - ID3D12Resource *res = createColorBuffer(rt.rtv, size, clearColor, samples); - if (res) - rt.color.Attach(res); - - ID3D12Resource *dsres = createDepthStencil(rt.dsv, size, samples); - if (dsres) - rt.ds.Attach(dsres); - - const bool multisample = rt.color->GetDesc().SampleDesc.Count > 1; - syncEntryFlags(&rt, RenderTarget::Multisample, multisample); - - if (!multisample) { - device->CreateShaderResourceView(rt.color.Get(), nullptr, rt.srv); - } else { - D3D12_HEAP_PROPERTIES defaultHeapProp = {}; - defaultHeapProp.Type = D3D12_HEAP_TYPE_DEFAULT; - - D3D12_RESOURCE_DESC textureDesc = {}; - textureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; - textureDesc.Width = size.width(); - textureDesc.Height = size.height(); - textureDesc.DepthOrArraySize = 1; - textureDesc.MipLevels = 1; - textureDesc.Format = RT_COLOR_FORMAT; - textureDesc.SampleDesc.Count = 1; - textureDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; - - HRESULT hr = device->CreateCommittedResource(&defaultHeapProp, D3D12_HEAP_FLAG_NONE, &textureDesc, - D3D12_RESOURCE_STATE_COMMON, nullptr, IID_PPV_ARGS(&rt.colorResolve)); - if (FAILED(hr)) { - qWarning("Failed to create resolve buffer: %s", - qPrintable(comErrorMessage(hr))); - return; - } - - device->CreateShaderResourceView(rt.colorResolve.Get(), nullptr, rt.srv); - } - - if (Q_UNLIKELY(debug_render())) - qDebug("created new render target %u, size %dx%d, samples %d", id, size.width(), size.height(), samples); -} - -void QSGD3D12EnginePrivate::releaseRenderTarget(uint id) -{ - if (!id || !initialized) - return; - - const int idx = id - 1; - Q_ASSERT(idx < renderTargets.count()); - RenderTarget &rt(renderTargets[idx]); - if (!rt.entryInUse()) - return; - - if (Q_UNLIKELY(debug_render())) - qDebug("releasing render target %u", id); - - if (rt.colorResolve) { - deferredDelete(rt.colorResolve); - rt.colorResolve = nullptr; - } - if (rt.color) { - deferredDelete(rt.color); - rt.color = nullptr; - deferredDelete(rt.rtv, D3D12_DESCRIPTOR_HEAP_TYPE_RTV); - deferredDelete(rt.srv, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - } - if (rt.ds) { - deferredDelete(rt.ds); - rt.ds = nullptr; - deferredDelete(rt.dsv, D3D12_DESCRIPTOR_HEAP_TYPE_DSV); - } - - rt.flags &= ~RenderTarget::EntryInUse; -} - -void QSGD3D12EnginePrivate::useRenderTargetAsTexture(uint id) -{ - if (!inFrame) { - qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__); - return; - } - - Q_ASSERT(id); - const int idx = id - 1; - Q_ASSERT(idx < renderTargets.count()); - RenderTarget &rt(renderTargets[idx]); - Q_ASSERT(rt.entryInUse() && rt.color); - - if (rt.flags & RenderTarget::NeedsReadBarrier) { - rt.flags &= ~RenderTarget::NeedsReadBarrier; - if (rt.flags & RenderTarget::Multisample) - resolveMultisampledTarget(rt.color.Get(), rt.colorResolve.Get(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, commandList); - else - transitionResource(rt.color.Get(), commandList, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); - } - - tframeData.activeTextures[tframeData.activeTextureCount++] = - TransientFrameData::ActiveTexture(TransientFrameData::ActiveTexture::TypeRenderTarget, id); -} - -QImage QSGD3D12EnginePrivate::executeAndWaitReadbackRenderTarget(uint id) -{ - // Readback due to QQuickWindow::grabWindow() happens outside - // begin-endFrame, but QQuickItemGrabResult leads to rendering a layer - // without a real frame afterwards and triggering readback. This has to be - // supported as well. - if (inFrame && (!activeLayers || currentLayerDepth)) { - qWarning("%s: Cannot be called while frame preparation is active", __FUNCTION__); - return QImage(); - } - - // Due to the above we insert a fake "real" frame when a layer was just rendered into. - if (inFrame) { - beginFrame(); - endFrame(); - } - - frameCommandList->Reset(frameCommandAllocator[frameIndex % frameInFlightCount].Get(), nullptr); - - D3D12_RESOURCE_STATES bstate; - bool needsBarrier = false; - ID3D12Resource *rtRes; - if (id == 0) { - const int idx = presentFrameIndex % swapChainBufferCount; - if (windowSamples > 1) { - resolveMultisampledTarget(defaultRT[idx].Get(), backBufferRT[idx].Get(), - D3D12_RESOURCE_STATE_COPY_SOURCE, frameCommandList.Get()); - } else { - bstate = D3D12_RESOURCE_STATE_PRESENT; - needsBarrier = true; - } - rtRes = backBufferRT[idx].Get(); - } else { - const int idx = id - 1; - Q_ASSERT(idx < renderTargets.count()); - RenderTarget &rt(renderTargets[idx]); - Q_ASSERT(rt.entryInUse() && rt.color); - - if (rt.flags & RenderTarget::Multisample) { - resolveMultisampledTarget(rt.color.Get(), rt.colorResolve.Get(), - D3D12_RESOURCE_STATE_COPY_SOURCE, frameCommandList.Get()); - rtRes = rt.colorResolve.Get(); - } else { - rtRes = rt.color.Get(); - bstate = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; - needsBarrier = true; - } - } - - ComPtr<ID3D12Resource> readbackBuf; - - D3D12_RESOURCE_DESC rtDesc = rtRes->GetDesc(); - UINT64 textureByteSize = 0; - D3D12_PLACED_SUBRESOURCE_FOOTPRINT textureLayout = {}; - device->GetCopyableFootprints(&rtDesc, 0, 1, 0, &textureLayout, nullptr, nullptr, &textureByteSize); - - D3D12_HEAP_PROPERTIES heapProp = {}; - heapProp.Type = D3D12_HEAP_TYPE_READBACK; - - D3D12_RESOURCE_DESC bufDesc = {}; - bufDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - bufDesc.Width = textureByteSize; - bufDesc.Height = 1; - bufDesc.DepthOrArraySize = 1; - bufDesc.MipLevels = 1; - bufDesc.Format = DXGI_FORMAT_UNKNOWN; - bufDesc.SampleDesc.Count = 1; - bufDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; - - if (FAILED(device->CreateCommittedResource(&heapProp, D3D12_HEAP_FLAG_NONE, &bufDesc, - D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&readbackBuf)))) { - qWarning("Failed to create committed resource (readback buffer)"); - return QImage(); - } - - D3D12_TEXTURE_COPY_LOCATION dstLoc; - dstLoc.pResource = readbackBuf.Get(); - dstLoc.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; - dstLoc.PlacedFootprint = textureLayout; - D3D12_TEXTURE_COPY_LOCATION srcLoc; - srcLoc.pResource = rtRes; - srcLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - srcLoc.SubresourceIndex = 0; - - ID3D12GraphicsCommandList *cl = frameCommandList.Get(); - if (needsBarrier) - transitionResource(rtRes, cl, bstate, D3D12_RESOURCE_STATE_COPY_SOURCE); - cl->CopyTextureRegion(&dstLoc, 0, 0, 0, &srcLoc, nullptr); - if (needsBarrier) - transitionResource(rtRes, cl, D3D12_RESOURCE_STATE_COPY_SOURCE, bstate); - - cl->Close(); - ID3D12CommandList *commandLists[] = { cl }; - commandQueue->ExecuteCommandLists(_countof(commandLists), commandLists); - - QScopedPointer<QSGD3D12CPUWaitableFence> f(createCPUWaitableFence()); - waitForGPU(f.data()); // uh oh - - QImage::Format fmt = imageFormatForTexture(rtDesc.Format); - if (fmt == QImage::Format_Invalid) { - qWarning("Could not map render target format %d to a QImage format", rtDesc.Format); - return QImage(); - } - QImage img(rtDesc.Width, rtDesc.Height, fmt); - quint8 *p = nullptr; - const D3D12_RANGE readRange = { 0, 0 }; - if (FAILED(readbackBuf->Map(0, &readRange, reinterpret_cast<void **>(&p)))) { - qWarning("Mapping the readback buffer failed"); - return QImage(); - } - const int bpp = 4; // ### - if (id == 0) { - for (UINT y = 0; y < rtDesc.Height; ++y) { - quint8 *dst = img.scanLine(y); - memcpy(dst, p, rtDesc.Width * bpp); - p += textureLayout.Footprint.RowPitch; - } - } else { - for (int y = rtDesc.Height - 1; y >= 0; --y) { - quint8 *dst = img.scanLine(y); - memcpy(dst, p, rtDesc.Width * bpp); - p += textureLayout.Footprint.RowPitch; - } - } - readbackBuf->Unmap(0, nullptr); - - return img; -} - -void QSGD3D12EnginePrivate::simulateDeviceLoss() -{ - qWarning("QSGD3D12Engine: Triggering device loss via TDR"); - devLossTest.killDevice(); -} - -bool QSGD3D12EnginePrivate::DeviceLossTester::initialize(QSGD3D12EnginePrivate *enginePriv) -{ - engine = enginePriv; - -#ifdef DEVLOSS_TEST - D3D12_DESCRIPTOR_RANGE descRange[2]; - descRange[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV; - descRange[0].NumDescriptors = 1; - descRange[0].BaseShaderRegister = 0; - descRange[0].RegisterSpace = 0; - descRange[0].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; - descRange[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; - descRange[1].NumDescriptors = 1; - descRange[1].BaseShaderRegister = 0; - descRange[1].RegisterSpace = 0; - descRange[1].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; - - D3D12_ROOT_PARAMETER param; - param.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; - param.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; - param.DescriptorTable.NumDescriptorRanges = 2; - param.DescriptorTable.pDescriptorRanges = descRange; - - D3D12_ROOT_SIGNATURE_DESC desc = {}; - desc.NumParameters = 1; - desc.pParameters = ¶m; - - ComPtr<ID3DBlob> signature; - ComPtr<ID3DBlob> error; - if (FAILED(D3D12SerializeRootSignature(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error))) { - QByteArray msg(static_cast<const char *>(error->GetBufferPointer()), error->GetBufferSize()); - qWarning("Failed to serialize compute root signature: %s", qPrintable(msg)); - return false; - } - if (FAILED(engine->device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), - IID_PPV_ARGS(&computeRootSignature)))) { - qWarning("Failed to create compute root signature"); - return false; - } - - D3D12_COMPUTE_PIPELINE_STATE_DESC psoDesc = {}; - psoDesc.pRootSignature = computeRootSignature.Get(); - psoDesc.CS.pShaderBytecode = g_timeout; - psoDesc.CS.BytecodeLength = sizeof(g_timeout); - - if (FAILED(engine->device->CreateComputePipelineState(&psoDesc, IID_PPV_ARGS(&computeState)))) { - qWarning("Failed to create compute pipeline state"); - return false; - } -#endif - - return true; -} - -void QSGD3D12EnginePrivate::DeviceLossTester::releaseResources() -{ - computeState = nullptr; - computeRootSignature = nullptr; -} - -void QSGD3D12EnginePrivate::DeviceLossTester::killDevice() -{ -#ifdef DEVLOSS_TEST - ID3D12CommandAllocator *ca = engine->frameCommandAllocator[engine->frameIndex % engine->frameInFlightCount].Get(); - ID3D12GraphicsCommandList *cl = engine->frameCommandList.Get(); - cl->Reset(ca, computeState.Get()); - - cl->SetComputeRootSignature(computeRootSignature.Get()); - cl->Dispatch(256, 1, 1); - - cl->Close(); - ID3D12CommandList *commandLists[] = { cl }; - engine->commandQueue->ExecuteCommandLists(_countof(commandLists), commandLists); - - engine->waitGPU(); -#endif -} - -void *QSGD3D12EnginePrivate::getResource(QSGRendererInterface::Resource resource) const -{ - switch (resource) { - case QSGRendererInterface::DeviceResource: - return device; - case QSGRendererInterface::CommandQueueResource: - return commandQueue.Get(); - case QSGRendererInterface::CommandListResource: - return commandList; - default: - break; - } - return nullptr; -} - -QT_END_NAMESPACE diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12engine_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12engine_p.h deleted file mode 100644 index b80de28bed..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12engine_p.h +++ /dev/null @@ -1,394 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSGD3D12ENGINE_P_H -#define QSGD3D12ENGINE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QWindow> -#include <QImage> -#include <QVector4D> -#include <qsggeometry.h> -#include <qsgrendererinterface.h> -#include <qt_windows.h> - -QT_BEGIN_NAMESPACE - -// No D3D or COM headers must be pulled in here. All that has to be isolated -// to engine_p_p.h and engine.cpp. - -class QSGD3D12EnginePrivate; - -// Shader bytecode and other strings are expected to be static so that a -// different pointer means a different shader. - -enum QSGD3D12Format { - FmtUnknown = 0, - - FmtFloat4 = 2, // DXGI_FORMAT_R32G32B32A32_FLOAT - FmtFloat3 = 6, // DXGI_FORMAT_R32G32B32_FLOAT - FmtFloat2 = 16, // DXGI_FORMAT_R32G32_FLOAT - FmtFloat = 41, // DXGI_FORMAT_R32_FLOAT - - // glVertexAttribPointer with GL_UNSIGNED_BYTE and normalized == true maps to the UNORM formats below - FmtUNormByte4 = 28, // DXGI_FORMAT_R8G8B8A8_UNORM - FmtUNormByte2 = 49, // DXGI_FORMAT_R8G8_UNORM - FmtUNormByte = 61, // DXGI_FORMAT_R8_UNORM - - // Index data types - FmtUnsignedShort = 57, // DXGI_FORMAT_R16_UINT - FmtUnsignedInt = 42 // DXGI_FORMAT_R32_UINT -}; - -struct QSGD3D12InputElement -{ - const char *semanticName = nullptr; - int semanticIndex = 0; - QSGD3D12Format format = FmtFloat4; - quint32 slot = 0; - quint32 offset = 0; - - bool operator==(const QSGD3D12InputElement &other) const { - return semanticName == other.semanticName && semanticIndex == other.semanticIndex - && format == other.format && slot == other.slot && offset == other.offset; - } -}; - -inline uint qHash(const QSGD3D12InputElement &key, uint seed = 0) -{ - return qHash(key.semanticName, seed) + key.semanticIndex + key.format + key.offset; -} - -struct QSGD3D12TextureView -{ - enum Filter { - FilterNearest = 0, - FilterLinear = 0x15, - FilterMinMagNearestMipLinear = 0x1, - FilterMinMagLinearMipNearest = 0x14 - }; - - enum AddressMode { - AddressWrap = 1, - AddressClamp = 3 - }; - - Filter filter = FilterLinear; - AddressMode addressModeHoriz = AddressClamp; - AddressMode addressModeVert = AddressClamp; - - bool operator==(const QSGD3D12TextureView &other) const { - return filter == other.filter - && addressModeHoriz == other.addressModeHoriz - && addressModeVert == other.addressModeVert; - } -}; - -inline uint qHash(const QSGD3D12TextureView &key, uint seed = 0) -{ - Q_UNUSED(seed); - return key.filter + key.addressModeHoriz + key.addressModeVert; -} - -const int QSGD3D12_MAX_TEXTURE_VIEWS = 8; - -struct QSGD3D12RootSignature -{ - int textureViewCount = 0; - QSGD3D12TextureView textureViews[QSGD3D12_MAX_TEXTURE_VIEWS]; - - bool operator==(const QSGD3D12RootSignature &other) const { - if (textureViewCount != other.textureViewCount) - return false; - for (int i = 0; i < textureViewCount; ++i) - if (!(textureViews[i] == other.textureViews[i])) - return false; - return true; - } -}; - -inline uint qHash(const QSGD3D12RootSignature &key, uint seed = 0) -{ - return key.textureViewCount + (key.textureViewCount > 0 ? qHash(key.textureViews[0], seed) : 0); -} - -// Shader bytecode blobs and root signature-related data. -struct QSGD3D12ShaderState -{ - const quint8 *vs = nullptr; - quint32 vsSize = 0; - const quint8 *ps = nullptr; - quint32 psSize = 0; - - QSGD3D12RootSignature rootSig; - - bool operator==(const QSGD3D12ShaderState &other) const { - return vs == other.vs && vsSize == other.vsSize - && ps == other.ps && psSize == other.psSize - && rootSig == other.rootSig; - } -}; - -inline uint qHash(const QSGD3D12ShaderState &key, uint seed = 0) -{ - return qHash(key.vs, seed) + key.vsSize + qHash(key.ps, seed) + key.psSize + qHash(key.rootSig, seed); -} - -const int QSGD3D12_MAX_INPUT_ELEMENTS = 8; - -struct QSGD3D12PipelineState -{ - enum CullMode { - CullNone = 1, - CullFront, - CullBack - }; - - enum CompareFunc { - CompareNever = 1, - CompareLess, - CompareEqual, - CompareLessEqual, - CompareGreater, - CompareNotEqual, - CompareGreaterEqual, - CompareAlways - }; - - enum StencilOp { - StencilKeep = 1, - StencilZero, - StencilReplace, - StencilIncrSat, - StencilDecrSat, - StencilInvert, - StencilIncr, - StencilDescr - }; - - enum TopologyType { - TopologyTypePoint = 1, - TopologyTypeLine, - TopologyTypeTriangle - }; - - enum BlendType { - BlendNone, - BlendPremul, // == GL_ONE, GL_ONE_MINUS_SRC_ALPHA - BlendColor // == GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR - }; - - QSGD3D12ShaderState shaders; - - int inputElementCount = 0; - QSGD3D12InputElement inputElements[QSGD3D12_MAX_INPUT_ELEMENTS]; - - CullMode cullMode = CullNone; - bool frontCCW = true; - bool colorWrite = true; - BlendType blend = BlendNone; - bool depthEnable = true; - CompareFunc depthFunc = CompareLess; - bool depthWrite = true; - bool stencilEnable = false; - CompareFunc stencilFunc = CompareEqual; - StencilOp stencilFailOp = StencilKeep; - StencilOp stencilDepthFailOp = StencilKeep; - StencilOp stencilPassOp = StencilKeep; - TopologyType topologyType = TopologyTypeTriangle; - - bool operator==(const QSGD3D12PipelineState &other) const { - bool eq = shaders == other.shaders - && inputElementCount == other.inputElementCount - && cullMode == other.cullMode - && frontCCW == other.frontCCW - && colorWrite == other.colorWrite - && blend == other.blend - && depthEnable == other.depthEnable - && (!depthEnable || depthFunc == other.depthFunc) - && depthWrite == other.depthWrite - && stencilEnable == other.stencilEnable - && (!stencilEnable || stencilFunc == other.stencilFunc) - && (!stencilEnable || stencilFailOp == other.stencilFailOp) - && (!stencilEnable || stencilDepthFailOp == other.stencilDepthFailOp) - && (!stencilEnable || stencilPassOp == other.stencilPassOp) - && topologyType == other.topologyType; - if (eq) { - for (int i = 0; i < inputElementCount; ++i) { - if (!(inputElements[i] == other.inputElements[i])) { - eq = false; - break; - } - } - } - return eq; - } -}; - -inline uint qHash(const QSGD3D12PipelineState &key, uint seed = 0) -{ - return qHash(key.shaders, seed) + key.inputElementCount - + key.cullMode + key.frontCCW - + key.colorWrite + key.blend - + key.depthEnable + key.depthWrite - + key.stencilEnable - + key.topologyType; -} - -class QSGD3D12Engine -{ -public: - QSGD3D12Engine(); - ~QSGD3D12Engine(); - - bool attachToWindow(WId window, const QSize &size, float dpr, int surfaceFormatSamples, bool alpha); - void releaseResources(); - bool hasResources() const; - void setWindowSize(const QSize &size, float dpr); - WId window() const; - QSize windowSize() const; - float windowDevicePixelRatio() const; - uint windowSamples() const; - - void beginFrame(); - void endFrame(); - void beginLayer(); - void endLayer(); - void invalidateCachedFrameState(); - void restoreFrameState(bool minimal = false); - - uint genBuffer(); - void releaseBuffer(uint id); - void resetBuffer(uint id, const quint8 *data, int size); - void markBufferDirty(uint id, int offset, int size); - - enum ClearFlag { - ClearDepth = 0x1, - ClearStencil = 0x2 - }; - Q_DECLARE_FLAGS(ClearFlags, ClearFlag) - - void queueViewport(const QRect &rect); - void queueScissor(const QRect &rect); - void queueSetRenderTarget(uint id = 0); - void queueClearRenderTarget(const QColor &color); - void queueClearDepthStencil(float depthValue, quint8 stencilValue, ClearFlags which); - void queueSetBlendFactor(const QVector4D &factor); - void queueSetStencilRef(quint32 ref); - - void finalizePipeline(const QSGD3D12PipelineState &pipelineState); - - struct DrawParams { - QSGGeometry::DrawingMode mode = QSGGeometry::DrawTriangles; - int count = 0; - uint vertexBuf = 0; - uint indexBuf = 0; - uint constantBuf = 0; - int vboOffset = 0; - int vboSize = 0; - int vboStride = 0; - int cboOffset = 0; - int startIndexIndex = -1; - QSGD3D12Format indexFormat = FmtUnsignedShort; - }; - - void queueDraw(const DrawParams ¶ms); - - void present(); - void waitGPU(); - - static quint32 alignedConstantBufferSize(quint32 size); - static QSGD3D12Format toDXGIFormat(QSGGeometry::Type sgtype, int tupleSize = 1, int *size = nullptr); - static int mipMapLevels(const QSize &size); - static QSize mipMapAdjustedSourceSize(const QSize &size); - - enum TextureCreateFlag { - TextureWithAlpha = 0x01, - TextureWithMipMaps = 0x02, - TextureAlways32Bit = 0x04 - }; - Q_DECLARE_FLAGS(TextureCreateFlags, TextureCreateFlag) - - enum TextureUploadFlag { - TextureUploadAlways32Bit = 0x01 - }; - Q_DECLARE_FLAGS(TextureUploadFlags, TextureUploadFlag) - - uint genTexture(); - void createTexture(uint id, const QSize &size, QImage::Format format, TextureCreateFlags flags); - void queueTextureResize(uint id, const QSize &size); - void queueTextureUpload(uint id, const QImage &image, const QPoint &dstPos = QPoint(), TextureUploadFlags flags = { }); - void queueTextureUpload(uint id, const QVector<QImage> &images, const QVector<QPoint> &dstPos, TextureUploadFlags flags = { }); - void releaseTexture(uint id); - void useTexture(uint id); - - uint genRenderTarget(); - void createRenderTarget(uint id, const QSize &size, const QVector4D &clearColor, uint samples); - void releaseRenderTarget(uint id); - void useRenderTargetAsTexture(uint id); - uint activeRenderTarget() const; - - QImage executeAndWaitReadbackRenderTarget(uint id = 0); - - void simulateDeviceLoss(); - - void *getResource(QQuickWindow *window, QSGRendererInterface::Resource resource) const; - -private: - QSGD3D12EnginePrivate *d; - Q_DISABLE_COPY(QSGD3D12Engine) -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(QSGD3D12Engine::ClearFlags) -Q_DECLARE_OPERATORS_FOR_FLAGS(QSGD3D12Engine::TextureCreateFlags) -Q_DECLARE_OPERATORS_FOR_FLAGS(QSGD3D12Engine::TextureUploadFlags) - -QT_END_NAMESPACE - -#endif // QSGD3D12ENGINE_P_H diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12engine_p_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12engine_p_p.h deleted file mode 100644 index a95cbb1cbb..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12engine_p_p.h +++ /dev/null @@ -1,455 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSGD3D12ENGINE_P_P_H -#define QSGD3D12ENGINE_P_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qsgd3d12engine_p.h" -#include <QCache> - -#include <d3d12.h> -#include <dxgi1_4.h> -#include <dcomp.h> -#include <wrl/client.h> - -using namespace Microsoft::WRL; - -// No moc-related features (Q_OBJECT, signals, etc.) can be used here to due -// moc-generated code failing to compile when combined with COM stuff. - -// Recommended reading before moving further: https://github.com/Microsoft/DirectXTK/wiki/ComPtr -// Note esp. operator= vs. Attach and operator& vs. GetAddressOf - -// ID3D12* is never passed to Qt containers directly. Always use ComPtr and put it into a struct. - -QT_BEGIN_NAMESPACE - -class QSGD3D12CPUDescriptorHeapManager -{ -public: - void initialize(ID3D12Device *device); - - void releaseResources(); - - D3D12_CPU_DESCRIPTOR_HANDLE allocate(D3D12_DESCRIPTOR_HEAP_TYPE type); - void release(D3D12_CPU_DESCRIPTOR_HANDLE handle, D3D12_DESCRIPTOR_HEAP_TYPE type); - quint32 handleSize(D3D12_DESCRIPTOR_HEAP_TYPE type) const { return m_handleSizes[type]; } - -private: - ID3D12Device *m_device = nullptr; - struct Heap { - D3D12_DESCRIPTOR_HEAP_TYPE type; - ComPtr<ID3D12DescriptorHeap> heap; - D3D12_CPU_DESCRIPTOR_HANDLE start; - quint32 handleSize; - quint32 freeMap[8]; - }; - QVector<Heap> m_heaps; - quint32 m_handleSizes[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES]; -}; - -class QSGD3D12DeviceManager -{ -public: - ID3D12Device *ref(); - void unref(); - void deviceLossDetected(); - IDXGIFactory4 *dxgi(); - - struct DeviceLossObserver { - virtual void deviceLost() = 0; - virtual ~DeviceLossObserver() = default; - }; - void registerDeviceLossObserver(DeviceLossObserver *observer); - -private: - void ensureCreated(); - - ComPtr<ID3D12Device> m_device; - ComPtr<IDXGIFactory4> m_factory; - QAtomicInt m_ref; - QVector<DeviceLossObserver *> m_observers; -}; - -struct QSGD3D12CPUWaitableFence -{ - ~QSGD3D12CPUWaitableFence() { - if (event) - CloseHandle(event); - } - ComPtr<ID3D12Fence> fence; - HANDLE event = nullptr; - QAtomicInt value; -}; - -class QSGD3D12EnginePrivate : public QSGD3D12DeviceManager::DeviceLossObserver -{ -public: - void initialize(WId w, const QSize &size, float dpr, int surfaceFormatSamples, bool alpha); - bool isInitialized() const { return initialized; } - void releaseResources(); - void setWindowSize(const QSize &size, float dpr); - WId currentWindow() const { return window; } - QSize currentWindowSize() const { return windowSize; } - float currentWindowDpr() const { return windowDpr; } - uint currentWindowSamples() const { return windowSamples; } - - void beginFrame(); - void endFrame(); - void beginLayer(); - void endLayer(); - void invalidateCachedFrameState(); - void restoreFrameState(bool minimal = false); - - uint genBuffer(); - void releaseBuffer(uint id); - void resetBuffer(uint id, const quint8 *data, int size); - void markBufferDirty(uint id, int offset, int size); - - void queueViewport(const QRect &rect); - void queueScissor(const QRect &rect); - void queueSetRenderTarget(uint id); - void queueClearRenderTarget(const QColor &color); - void queueClearDepthStencil(float depthValue, quint8 stencilValue, QSGD3D12Engine::ClearFlags which); - void queueSetBlendFactor(const QVector4D &factor); - void queueSetStencilRef(quint32 ref); - - void finalizePipeline(const QSGD3D12PipelineState &pipelineState); - - void queueDraw(const QSGD3D12Engine::DrawParams ¶ms); - - void present(); - void waitGPU(); - - uint genTexture(); - void createTexture(uint id, const QSize &size, QImage::Format format, QSGD3D12Engine::TextureCreateFlags flags); - void queueTextureResize(uint id, const QSize &size); - void queueTextureUpload(uint id, const QVector<QImage> &images, const QVector<QPoint> &dstPos, - QSGD3D12Engine::TextureUploadFlags flags); - void releaseTexture(uint id); - void useTexture(uint id); - - uint genRenderTarget(); - void createRenderTarget(uint id, const QSize &size, const QVector4D &clearColor, uint samples); - void releaseRenderTarget(uint id); - void useRenderTargetAsTexture(uint id); - uint activeRenderTarget() const { return currentRenderTarget; } - - QImage executeAndWaitReadbackRenderTarget(uint id); - - void simulateDeviceLoss(); - - void *getResource(QSGRendererInterface::Resource resource) const; - - // the device is intentionally hidden here. all resources have to go - // through the engine and, unlike with GL, cannot just be created in random - // places due to the need for proper tracking, managing and releasing. -private: - void ensureDevice(); - void setupDefaultRenderTargets(); - void deviceLost() override; - - bool createCbvSrvUavHeap(int pframeIndex, int descriptorCount); - void setDescriptorHeaps(bool force = false); - void ensureGPUDescriptorHeap(int cbvSrvUavDescriptorCount); - - DXGI_SAMPLE_DESC makeSampleDesc(DXGI_FORMAT format, uint samples); - ID3D12Resource *createColorBuffer(D3D12_CPU_DESCRIPTOR_HANDLE viewHandle, const QSize &size, - const QVector4D &clearColor, uint samples); - ID3D12Resource *createDepthStencil(D3D12_CPU_DESCRIPTOR_HANDLE viewHandle, const QSize &size, uint samples); - - QSGD3D12CPUWaitableFence *createCPUWaitableFence() const; - void waitForGPU(QSGD3D12CPUWaitableFence *f) const; - - void transitionResource(ID3D12Resource *resource, ID3D12GraphicsCommandList *commandList, - D3D12_RESOURCE_STATES before, D3D12_RESOURCE_STATES after) const; - void resolveMultisampledTarget(ID3D12Resource *msaa, ID3D12Resource *resolve, D3D12_RESOURCE_STATES resolveUsage, - ID3D12GraphicsCommandList *commandList) const; - void uavBarrier(ID3D12Resource *resource, ID3D12GraphicsCommandList *commandList) const; - - ID3D12Resource *createBuffer(int size); - - typedef QVector<QPair<int, int> > DirtyList; - void addDirtyRange(DirtyList *dirty, int offset, int size, int bufferSize); - - struct PersistentFrameData { - ComPtr<ID3D12DescriptorHeap> gpuCbvSrvUavHeap; - int gpuCbvSrvUavHeapSize; - int cbvSrvUavNextFreeDescriptorIndex; - QSet<uint> pendingTextureUploads; - QSet<uint> pendingTextureMipMap; - struct DeleteQueueEntry { - ComPtr<ID3D12Resource> res; - ComPtr<ID3D12DescriptorHeap> descHeap; - SIZE_T cpuDescriptorPtr = 0; - D3D12_DESCRIPTOR_HEAP_TYPE descHeapType = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; - }; - QVector<DeleteQueueEntry> deleteQueue; - QVector<DeleteQueueEntry> outOfFrameDeleteQueue; - QSet<uint> buffersUsedInDrawCallSet; - QSet<uint> buffersUsedInFrame; - struct PendingRelease { - enum Type { - TypeTexture, - TypeBuffer - }; - Type type = TypeTexture; - uint id = 0; - PendingRelease(Type type, uint id) : type(type), id(id) { } - PendingRelease() { } - bool operator==(const PendingRelease &other) const { return type == other.type && id == other.id; } - }; - QSet<PendingRelease> pendingReleases; - QSet<PendingRelease> outOfFramePendingReleases; - }; - friend uint qHash(const PersistentFrameData::PendingRelease &pr, uint seed); - - void deferredDelete(ComPtr<ID3D12Resource> res); - void deferredDelete(ComPtr<ID3D12DescriptorHeap> dh); - void deferredDelete(D3D12_CPU_DESCRIPTOR_HANDLE h, D3D12_DESCRIPTOR_HEAP_TYPE type); - - struct Buffer; - void ensureBuffer(Buffer *buf); - void updateBuffer(Buffer *buf); - - void beginDrawCalls(); - void beginFrameDraw(); - void endDrawCalls(bool lastInFrame = false); - - static const int MAX_SWAP_CHAIN_BUFFER_COUNT = 4; - static const int MAX_FRAME_IN_FLIGHT_COUNT = 4; - - bool initialized = false; - bool inFrame = false; - WId window = 0; - QSize windowSize; - float windowDpr; - uint windowSamples; - bool windowAlpha; - int swapChainBufferCount; - int frameInFlightCount; - int waitableSwapChainMaxLatency; - ID3D12Device *device; - ComPtr<ID3D12CommandQueue> commandQueue; - ComPtr<ID3D12CommandQueue> copyCommandQueue; - ComPtr<IDXGISwapChain3> swapChain; - HANDLE swapEvent; - ComPtr<ID3D12Resource> backBufferRT[MAX_SWAP_CHAIN_BUFFER_COUNT]; - ComPtr<ID3D12Resource> defaultRT[MAX_SWAP_CHAIN_BUFFER_COUNT]; - D3D12_CPU_DESCRIPTOR_HANDLE defaultRTV[MAX_SWAP_CHAIN_BUFFER_COUNT]; - ComPtr<ID3D12Resource> defaultDS; - D3D12_CPU_DESCRIPTOR_HANDLE defaultDSV; - ComPtr<ID3D12CommandAllocator> frameCommandAllocator[MAX_FRAME_IN_FLIGHT_COUNT]; - ComPtr<ID3D12CommandAllocator> copyCommandAllocator; - ComPtr<ID3D12GraphicsCommandList> frameCommandList; - ComPtr<ID3D12GraphicsCommandList> copyCommandList; - QSGD3D12CPUDescriptorHeapManager cpuDescHeapManager; - quint64 presentFrameIndex; - quint64 frameIndex; - QSGD3D12CPUWaitableFence *presentFence = nullptr; - QSGD3D12CPUWaitableFence *frameFence[MAX_FRAME_IN_FLIGHT_COUNT]; - - PersistentFrameData pframeData[MAX_FRAME_IN_FLIGHT_COUNT]; - int currentPFrameIndex; - ID3D12GraphicsCommandList *commandList = nullptr; - int activeLayers = 0; - int currentLayerDepth = 0; - - struct PSOCacheEntry { - ComPtr<ID3D12PipelineState> pso; - }; - QCache<QSGD3D12PipelineState, PSOCacheEntry> psoCache; - struct RootSigCacheEntry { - ComPtr<ID3D12RootSignature> rootSig; - }; - QCache<QSGD3D12RootSignature, RootSigCacheEntry> rootSigCache; - - struct Texture { - enum Flag { - EntryInUse = 0x01, - Alpha = 0x02, - MipMap = 0x04 - }; - int flags = 0; - bool entryInUse() const { return flags & EntryInUse; } - bool alpha() const { return flags & Alpha; } - bool mipmap() const { return flags & MipMap; } - ComPtr<ID3D12Resource> texture; - D3D12_CPU_DESCRIPTOR_HANDLE srv; - quint64 fenceValue = 0; - quint64 lastWaitFenceValue = 0; - struct StagingHeap { - ComPtr<ID3D12Heap> heap; - }; - QVector<StagingHeap> stagingHeaps; - struct StagingBuffer { - ComPtr<ID3D12Resource> buffer; - }; - QVector<StagingBuffer> stagingBuffers; - QVector<D3D12_CPU_DESCRIPTOR_HANDLE> mipUAVs; - }; - - QVector<Texture> textures; - ComPtr<ID3D12Fence> textureUploadFence; - QAtomicInt nextTextureUploadFenceValue; - - struct TransientFrameData { - QSGGeometry::DrawingMode drawingMode; - uint currentIndexBuffer; - struct ActiveTexture { - enum Type { - TypeTexture, - TypeRenderTarget - }; - Type type = TypeTexture; - uint id = 0; - ActiveTexture(Type type, uint id) : type(type), id(id) { } - ActiveTexture() { } - }; - int activeTextureCount; - ActiveTexture activeTextures[QSGD3D12_MAX_TEXTURE_VIEWS]; - int drawCount; - ID3D12PipelineState *lastPso; - ID3D12RootSignature *lastRootSig; - bool descHeapSet; - - QRect viewport; - QRect scissor; - QVector4D blendFactor = QVector4D(1, 1, 1, 1); - quint32 stencilRef = 1; - QSGD3D12PipelineState pipelineState; - }; - TransientFrameData tframeData; - - struct MipMapGen { - bool initialize(QSGD3D12EnginePrivate *enginePriv); - void releaseResources(); - void queueGenerate(const Texture &t); - - QSGD3D12EnginePrivate *engine; - ComPtr<ID3D12RootSignature> rootSig; - ComPtr<ID3D12PipelineState> pipelineState; - }; - - MipMapGen mipmapper; - - struct RenderTarget { - enum Flag { - EntryInUse = 0x01, - NeedsReadBarrier = 0x02, - Multisample = 0x04 - }; - int flags = 0; - bool entryInUse() const { return flags & EntryInUse; } - ComPtr<ID3D12Resource> color; - ComPtr<ID3D12Resource> colorResolve; - D3D12_CPU_DESCRIPTOR_HANDLE rtv; - ComPtr<ID3D12Resource> ds; - D3D12_CPU_DESCRIPTOR_HANDLE dsv; - D3D12_CPU_DESCRIPTOR_HANDLE srv; - }; - - QVector<RenderTarget> renderTargets; - uint currentRenderTarget; - - struct CPUBufferRef { - const quint8 *p = nullptr; - quint32 size = 0; - DirtyList dirty; - CPUBufferRef() { dirty.reserve(16); } - }; - - struct Buffer { - enum Flag { - EntryInUse = 0x01 - }; - int flags = 0; - bool entryInUse() const { return flags & EntryInUse; } - struct InFlightData { - ComPtr<ID3D12Resource> buffer; - DirtyList dirty; - quint32 dataSize = 0; - quint32 resourceSize = 0; - InFlightData() { dirty.reserve(16); } - }; - InFlightData d[MAX_FRAME_IN_FLIGHT_COUNT]; - CPUBufferRef cpuDataRef; - }; - - QVector<Buffer> buffers; - - struct DeviceLossTester { - bool initialize(QSGD3D12EnginePrivate *enginePriv); - void releaseResources(); - void killDevice(); - - QSGD3D12EnginePrivate *engine; - ComPtr<ID3D12PipelineState> computeState; - ComPtr<ID3D12RootSignature> computeRootSignature; - }; - - DeviceLossTester devLossTest; - -#ifndef Q_OS_WINRT - ComPtr<IDCompositionDevice> dcompDevice; - ComPtr<IDCompositionTarget> dcompTarget; - ComPtr<IDCompositionVisual> dcompVisual; -#endif -}; - -inline uint qHash(const QSGD3D12EnginePrivate::PersistentFrameData::PendingRelease &pr, uint seed = 0) -{ - Q_UNUSED(seed); - return pr.id + pr.type; -} - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12glyphcache.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12glyphcache.cpp deleted file mode 100644 index 915917c3d5..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12glyphcache.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsgd3d12glyphcache_p.h" -#include "qsgd3d12engine_p.h" - -QT_BEGIN_NAMESPACE - -// Convert A8 glyphs to 32-bit in the engine. This is here to work around -// QTBUG-55330 for AMD cards. -// If removing, textmask.hlsl must be adjusted! (.a -> .r) -#define ALWAYS_32BIT - -// NOTE: Avoid categorized logging. It is slow. - -#define DECLARE_DEBUG_VAR(variable) \ - static bool debug_ ## variable() \ - { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; } - -DECLARE_DEBUG_VAR(render) - -QSGD3D12GlyphCache::QSGD3D12GlyphCache(QSGD3D12Engine *engine, QFontEngine::GlyphFormat format, const QTransform &matrix) - : QTextureGlyphCache(format, matrix), - m_engine(engine) -{ -} - -QSGD3D12GlyphCache::~QSGD3D12GlyphCache() -{ - if (m_id) - m_engine->releaseTexture(m_id); -} - -void QSGD3D12GlyphCache::createTextureData(int width, int height) -{ - width = qMax(128, width); - height = qMax(32, height); - - m_id = m_engine->genTexture(); - Q_ASSERT(m_id); - - if (Q_UNLIKELY(debug_render())) - qDebug("new glyph cache texture %u of size %dx%d, fontengine format %d", m_id, width, height, m_format); - - m_size = QSize(width, height); - - const QImage::Format imageFormat = - m_format == QFontEngine::Format_A8 ? QImage::Format_Alpha8 : QImage::Format_ARGB32_Premultiplied; - m_engine->createTexture(m_id, m_size, imageFormat, QSGD3D12Engine::TextureWithAlpha -#ifdef ALWAYS_32BIT - | QSGD3D12Engine::TextureAlways32Bit -#endif - ); -} - -void QSGD3D12GlyphCache::resizeTextureData(int width, int height) -{ - width = qMax(128, width); - height = qMax(32, height); - - if (m_size.width() >= width && m_size.height() >= height) - return; - - if (Q_UNLIKELY(debug_render())) - qDebug("glyph cache texture %u resize to %dx%d", m_id, width, height); - - m_size = QSize(width, height); - - m_engine->queueTextureResize(m_id, m_size); -} - -void QSGD3D12GlyphCache::beginFillTexture() -{ - Q_ASSERT(m_glyphImages.isEmpty() && m_glyphPos.isEmpty()); -} - -void QSGD3D12GlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition) -{ - QImage mask = textureMapForGlyph(glyph, subPixelPosition); - const int maskWidth = mask.width(); - const int maskHeight = mask.height(); - - if (mask.format() == QImage::Format_Mono) { - mask = mask.convertToFormat(QImage::Format_Indexed8); - for (int y = 0; y < maskHeight; ++y) { - uchar *src = mask.scanLine(y); - for (int x = 0; x < maskWidth; ++x) - src[x] = -src[x]; // convert 0 and 1 into 0 and 255 - } - } else if (mask.depth() == 32) { - if (mask.format() == QImage::Format_RGB32) { - // We need to make the alpha component equal to the average of the RGB values. - // This is needed when drawing sub-pixel antialiased text on translucent targets. - for (int y = 0; y < maskHeight; ++y) { - QRgb *src = reinterpret_cast<QRgb *>(mask.scanLine(y)); - for (int x = 0; x < maskWidth; ++x) { - const int r = qRed(src[x]); - const int g = qGreen(src[x]); - const int b = qBlue(src[x]); - int avg; - if (mask.format() == QImage::Format_RGB32) - avg = (r + g + b + 1) / 3; // "+1" for rounding. - else // Format_ARGB32_Premultiplied - avg = qAlpha(src[x]); - src[x] = qRgba(r, g, b, avg); - } - } - } - } - - m_glyphImages.append(mask); - m_glyphPos.append(QPoint(c.x, c.y)); -} - -void QSGD3D12GlyphCache::endFillTexture() -{ - if (m_glyphImages.isEmpty()) - return; - - Q_ASSERT(m_id); - - m_engine->queueTextureUpload(m_id, m_glyphImages, m_glyphPos -#ifdef ALWAYS_32BIT - , QSGD3D12Engine::TextureUploadAlways32Bit -#endif - ); - - // Nothing else left to do, it is up to the text material to call - // useTexture() which will then add the texture dependency to the frame. - - m_glyphImages.clear(); - m_glyphPos.clear(); -} - -int QSGD3D12GlyphCache::glyphPadding() const -{ - return 1; -} - -int QSGD3D12GlyphCache::maxTextureWidth() const -{ - return 16384; -} - -int QSGD3D12GlyphCache::maxTextureHeight() const -{ - return 16384; -} - -void QSGD3D12GlyphCache::useTexture() -{ - if (m_id) - m_engine->useTexture(m_id); -} - -QSize QSGD3D12GlyphCache::currentSize() const -{ - return m_size; -} - -QT_END_NAMESPACE diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12glyphcache_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12glyphcache_p.h deleted file mode 100644 index 88d3d36f33..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12glyphcache_p.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSGD3D12GLYPHCACHE_P_H -#define QSGD3D12GLYPHCACHE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtGui/private/qtextureglyphcache_p.h> - -QT_BEGIN_NAMESPACE - -class QSGD3D12Engine; - -class QSGD3D12GlyphCache : public QTextureGlyphCache -{ -public: - QSGD3D12GlyphCache(QSGD3D12Engine *engine, QFontEngine::GlyphFormat format, const QTransform &matrix); - ~QSGD3D12GlyphCache(); - - void createTextureData(int width, int height) override; - void resizeTextureData(int width, int height) override; - void beginFillTexture() override; - void fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition) override; - void endFillTexture() override; - int glyphPadding() const override; - int maxTextureWidth() const override; - int maxTextureHeight() const override; - - void useTexture(); - QSize currentSize() const; - -private: - QSGD3D12Engine *m_engine; - uint m_id = 0; - QVector<QImage> m_glyphImages; - QVector<QPoint> m_glyphPos; - QSize m_size; -}; - -QT_END_NAMESPACE - -#endif // QSGD3D12GLYPHCACHE_P_H diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12glyphnode.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12glyphnode.cpp deleted file mode 100644 index e559739018..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12glyphnode.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsgd3d12glyphnode_p.h" -#include "qsgd3d12builtinmaterials_p.h" - -QT_BEGIN_NAMESPACE - -void QSGD3D12GlyphNode::setMaterialColor(const QColor &color) -{ - static_cast<QSGD3D12TextMaterial *>(m_material)->setColor(color); -} - -void QSGD3D12GlyphNode::update() -{ - QRawFont font = m_glyphs.rawFont(); - QMargins margins(0, 0, 0, 0); - - if (m_style == QQuickText::Normal) { - // QSGBasicGlyphNode dtor will delete - m_material = new QSGD3D12TextMaterial(QSGD3D12TextMaterial::Normal, m_rc, font); - } else if (m_style == QQuickText::Outline) { - QSGD3D12TextMaterial *material = new QSGD3D12TextMaterial(QSGD3D12TextMaterial::Outlined, - m_rc, font, QFontEngine::Format_A8); - material->setStyleColor(m_styleColor); - m_material = material; - margins = QMargins(1, 1, 1, 1); - } else { - QSGD3D12TextMaterial *material = new QSGD3D12TextMaterial(QSGD3D12TextMaterial::Styled, - m_rc, font, QFontEngine::Format_A8); - if (m_style == QQuickText::Sunken) { - material->setStyleShift(QVector2D(0, -1)); - margins.setTop(1); - } else if (m_style == QQuickText::Raised) { - material->setStyleShift(QVector2D(0, 1)); - margins.setBottom(1); - } - material->setStyleColor(m_styleColor); - m_material = material; - } - - QSGD3D12TextMaterial *textMaterial = static_cast<QSGD3D12TextMaterial *>(m_material); - textMaterial->setColor(m_color); - - QRectF boundingRect; - textMaterial->populate(m_position, m_glyphs.glyphIndexes(), m_glyphs.positions(), geometry(), - &boundingRect, &m_baseLine, margins); - setBoundingRect(boundingRect); - - setMaterial(m_material); - markDirty(DirtyGeometry); -} - -QT_END_NAMESPACE diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12glyphnode_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12glyphnode_p.h deleted file mode 100644 index d04a8e8777..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12glyphnode_p.h +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSGD3D12GLYPHNODE_P_H -#define QSGD3D12GLYPHNODE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qsgbasicglyphnode_p.h> - -QT_BEGIN_NAMESPACE - -class QSGD3D12RenderContext; - -class QSGD3D12GlyphNode : public QSGBasicGlyphNode -{ -public: - QSGD3D12GlyphNode(QSGD3D12RenderContext *rc) : m_rc(rc) { } - - void setMaterialColor(const QColor &color) override; - void update() override; - -private: - QSGD3D12RenderContext *m_rc; -}; - -QT_END_NAMESPACE - -#endif // QSGD3D12GLYPHNODE_P_H diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12internalimagenode.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12internalimagenode.cpp deleted file mode 100644 index aa163cacbf..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12internalimagenode.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsgd3d12internalimagenode_p.h" - -QT_BEGIN_NAMESPACE - -QSGD3D12InternalImageNode::QSGD3D12InternalImageNode() -{ - setMaterial(&m_material); -} - -void QSGD3D12InternalImageNode::setFiltering(QSGTexture::Filtering filtering) -{ - if (m_material.filtering() == filtering) - return; - - m_material.setFiltering(filtering); - m_smoothMaterial.setFiltering(filtering); - markDirty(DirtyMaterial); -} - -void QSGD3D12InternalImageNode::setMipmapFiltering(QSGTexture::Filtering filtering) -{ - if (m_material.mipmapFiltering() == filtering) - return; - - m_material.setMipmapFiltering(filtering); - m_smoothMaterial.setMipmapFiltering(filtering); - markDirty(DirtyMaterial); -} - -void QSGD3D12InternalImageNode::setVerticalWrapMode(QSGTexture::WrapMode wrapMode) -{ - if (m_material.verticalWrapMode() == wrapMode) - return; - - m_material.setVerticalWrapMode(wrapMode); - m_smoothMaterial.setVerticalWrapMode(wrapMode); - markDirty(DirtyMaterial); -} - -void QSGD3D12InternalImageNode::setHorizontalWrapMode(QSGTexture::WrapMode wrapMode) -{ - if (m_material.horizontalWrapMode() == wrapMode) - return; - - m_material.setHorizontalWrapMode(wrapMode); - m_smoothMaterial.setHorizontalWrapMode(wrapMode); - markDirty(DirtyMaterial); -} - -void QSGD3D12InternalImageNode::updateMaterialAntialiasing() -{ - if (m_antialiasing) - setMaterial(&m_smoothMaterial); - else - setMaterial(&m_material); -} - -void QSGD3D12InternalImageNode::setMaterialTexture(QSGTexture *texture) -{ - m_material.setTexture(texture); - m_smoothMaterial.setTexture(texture); -} - -QSGTexture *QSGD3D12InternalImageNode::materialTexture() const -{ - return m_material.texture(); -} - -bool QSGD3D12InternalImageNode::updateMaterialBlending() -{ - const bool alpha = m_material.flags() & QSGMaterial::Blending; - if (materialTexture() && alpha != materialTexture()->hasAlphaChannel()) { - m_material.setFlag(QSGMaterial::Blending, !alpha); - return true; - } - return false; -} - -bool QSGD3D12InternalImageNode::supportsWrap(const QSize &) const -{ - return true; -} - -QT_END_NAMESPACE diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12internalimagenode_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12internalimagenode_p.h deleted file mode 100644 index 26284740ee..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12internalimagenode_p.h +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSGD3D12INTERNALIMAGENODE_P_H -#define QSGD3D12INTERNALIMAGENODE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qsgbasicinternalimagenode_p.h> -#include "qsgd3d12builtinmaterials_p.h" - -QT_BEGIN_NAMESPACE - -class QSGD3D12InternalImageNode : public QSGBasicInternalImageNode -{ -public: - QSGD3D12InternalImageNode(); - - void setMipmapFiltering(QSGTexture::Filtering filtering) override; - void setFiltering(QSGTexture::Filtering filtering) override; - void setHorizontalWrapMode(QSGTexture::WrapMode wrapMode) override; - void setVerticalWrapMode(QSGTexture::WrapMode wrapMode) override; - - void updateMaterialAntialiasing() override; - void setMaterialTexture(QSGTexture *texture) override; - QSGTexture *materialTexture() const override; - bool updateMaterialBlending() override; - bool supportsWrap(const QSize &size) const override; - -private: - QSGD3D12TextureMaterial m_material; - QSGD3D12SmoothTextureMaterial m_smoothMaterial; -}; - -QT_END_NAMESPACE - -#endif // QSGD3D12INTERNALIMAGENODE_P_H diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12internalrectanglenode.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12internalrectanglenode.cpp deleted file mode 100644 index 2d9c5b55d1..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12internalrectanglenode.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsgd3d12internalrectanglenode_p.h" - -QT_BEGIN_NAMESPACE - -QSGD3D12InternalRectangleNode::QSGD3D12InternalRectangleNode() -{ - setMaterial(&m_material); -} - -void QSGD3D12InternalRectangleNode::updateMaterialAntialiasing() -{ - if (m_antialiasing) - setMaterial(&m_smoothMaterial); - else - setMaterial(&m_material); -} - -void QSGD3D12InternalRectangleNode::updateMaterialBlending(QSGNode::DirtyState *state) -{ - // smoothed material is always blended, so no change in material state - if (material() == &m_material) { - bool wasBlending = (m_material.flags() & QSGMaterial::Blending); - bool isBlending = (m_gradient_stops.size() > 0 && !m_gradient_is_opaque) - || (m_color.alpha() < 255 && m_color.alpha() != 0) - || (m_pen_width > 0 && m_border_color.alpha() < 255); - if (wasBlending != isBlending) { - m_material.setFlag(QSGMaterial::Blending, isBlending); - *state |= QSGNode::DirtyMaterial; - } - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12internalrectanglenode_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12internalrectanglenode_p.h deleted file mode 100644 index 2fc3c69285..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12internalrectanglenode_p.h +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSGD3D12INTERNALRECTANGLENODE_P_H -#define QSGD3D12INTERNALRECTANGLENODE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qsgbasicinternalrectanglenode_p.h> -#include "qsgd3d12builtinmaterials_p.h" - -QT_BEGIN_NAMESPACE - -class QSGD3D12InternalRectangleNode : public QSGBasicInternalRectangleNode -{ -public: - QSGD3D12InternalRectangleNode(); - -private: - void updateMaterialAntialiasing() override; - void updateMaterialBlending(QSGNode::DirtyState *state) override; - - QSGD3D12VertexColorMaterial m_material; - QSGD3D12SmoothColorMaterial m_smoothMaterial; -}; - -QT_END_NAMESPACE - -#endif // QSGD3D12INTERNALRECTANGLENODE_P_H diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12layer.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12layer.cpp deleted file mode 100644 index b9d3a180cf..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12layer.cpp +++ /dev/null @@ -1,370 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsgd3d12layer_p.h" -#include "qsgd3d12rendercontext_p.h" -#include "qsgd3d12engine_p.h" -#include "qsgd3d12renderer_p.h" - -QT_BEGIN_NAMESPACE - -// NOTE: Avoid categorized logging. It is slow. - -#define DECLARE_DEBUG_VAR(variable) \ - static bool debug_ ## variable() \ - { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; } - -DECLARE_DEBUG_VAR(render) - -QSGD3D12Layer::QSGD3D12Layer(QSGD3D12RenderContext *rc) - : QSGLayer(*(new QSGD3D12LayerPrivate)), - m_rc(rc) -{ - if (Q_UNLIKELY(debug_render())) - qDebug("new layer %p", this); -} - -QSGD3D12Layer::~QSGD3D12Layer() -{ - if (Q_UNLIKELY(debug_render())) - qDebug("destroying layer %p", this); - - cleanup(); -} - -// QSGTexture - -int QSGD3D12Layer::textureId() const -{ - return m_rt; // not a texture id per se but will do -} - -int QSGD3D12LayerPrivate::comparisonKey() const -{ - Q_Q(const QSGD3D12Layer); - return q->m_rt; -} - -QSize QSGD3D12Layer::textureSize() const -{ - return m_size; -} - -bool QSGD3D12Layer::hasAlphaChannel() const -{ - return true; -} - -bool QSGD3D12Layer::hasMipmaps() const -{ - // mipmapped layers are not supported for now - return false; -} - -QRectF QSGD3D12Layer::normalizedTextureSubRect() const -{ - return QRectF(m_mirrorHorizontal ? 1 : 0, - m_mirrorVertical ? 0 : 1, - m_mirrorHorizontal ? -1 : 1, - m_mirrorVertical ? 1 : -1); -} - -void QSGD3D12Layer::bind() -{ - if (Q_UNLIKELY(debug_render())) - qDebug("layer %p bind rt=%u", this, m_rt); - - QSGD3D12Engine *engine = m_rc->engine(); - Q_ASSERT(m_rt); - -#ifndef QT_NO_DEBUG - // Should not use the color buffer as a texture while it is the current render target. - if (!m_recursive && engine->activeRenderTarget() == m_rt && engine->windowSamples() == 1) - qWarning("ShaderEffectSource: \'recursive\' must be set to true when rendering recursively."); -#endif - - engine->useRenderTargetAsTexture(m_rt); -} - -// QSGDynamicTexture - -bool QSGD3D12Layer::updateTexture() -{ - if (Q_UNLIKELY(debug_render())) - qDebug("layer %p updateTexture", this); - - const bool doUpdate = (m_live || m_updateContentPending) && m_dirtyTexture; - - if (doUpdate) - updateContent(); - - if (m_updateContentPending) { - m_updateContentPending = false; - emit scheduledUpdateCompleted(); - } - - return doUpdate; -} - -// QSGLayer - -void QSGD3D12Layer::setItem(QSGNode *item) -{ - if (m_item == item) - return; - - if (m_live && !item) - resetRenderTarget(); - - m_item = item; - markDirtyTexture(); -} - -void QSGD3D12Layer::setRect(const QRectF &rect) -{ - if (m_rect == rect) - return; - - m_rect = rect; - markDirtyTexture(); -} - -void QSGD3D12Layer::setSize(const QSize &size) -{ - if (m_size == size) - return; - - if (m_live && size.isNull()) - resetRenderTarget(); - - m_size = size; - markDirtyTexture(); -} - -void QSGD3D12Layer::scheduleUpdate() -{ - if (m_updateContentPending) - return; - - if (Q_UNLIKELY(debug_render())) - qDebug("layer %p scheduleUpdate", this); - - m_updateContentPending = true; - - if (m_dirtyTexture) - emit updateRequested(); -} - -QImage QSGD3D12Layer::toImage() const -{ - return m_rc->engine()->executeAndWaitReadbackRenderTarget(m_rt); -} - -void QSGD3D12Layer::setLive(bool live) -{ - if (m_live == live) - return; - - if (live && (!m_item || m_size.isNull())) - resetRenderTarget(); - - m_live = live; - markDirtyTexture(); -} - -void QSGD3D12Layer::setRecursive(bool recursive) -{ - m_recursive = recursive; -} - -void QSGD3D12Layer::setFormat(uint format) -{ - Q_UNUSED(format); -} - -void QSGD3D12Layer::setHasMipmaps(bool mipmap) -{ - // mipmapped layers are not supported for now - Q_UNUSED(mipmap); -} - -void QSGD3D12Layer::setDevicePixelRatio(qreal ratio) -{ - m_dpr = ratio; -} - -void QSGD3D12Layer::setMirrorHorizontal(bool mirror) -{ - m_mirrorHorizontal = mirror; -} - -void QSGD3D12Layer::setMirrorVertical(bool mirror) -{ - m_mirrorVertical = mirror; -} - -void QSGD3D12Layer::markDirtyTexture() -{ - if (Q_UNLIKELY(debug_render())) - qDebug("layer %p markDirtyTexture", this); - - m_dirtyTexture = true; - - if (m_live || m_updateContentPending) - emit updateRequested(); -} - -void QSGD3D12Layer::invalidated() -{ - cleanup(); -} - -void QSGD3D12Layer::cleanup() -{ - if (!m_renderer && !m_rt) - return; - - if (Q_UNLIKELY(debug_render())) - qDebug("layer %p cleanup renderer=%p rt=%u", this, m_renderer, m_rt); - - delete m_renderer; - m_renderer = nullptr; - - resetRenderTarget(); -} - -void QSGD3D12Layer::resetRenderTarget() -{ - if (!m_rt) - return; - - if (Q_UNLIKELY(debug_render())) - qDebug("layer %p resetRenderTarget rt=%u", this, m_rt); - - m_rc->engine()->releaseRenderTarget(m_rt); - m_rt = 0; - - if (m_secondaryRT) { - m_rc->engine()->releaseRenderTarget(m_secondaryRT); - m_secondaryRT = 0; - } -} - -void QSGD3D12Layer::updateContent() -{ - if (Q_UNLIKELY(debug_render())) - qDebug("layer %p updateContent", this); - - if (!m_item || m_size.isNull()) { - resetRenderTarget(); - m_dirtyTexture = false; - return; - } - - QSGNode *root = m_item; - while (root->firstChild() && root->type() != QSGNode::RootNodeType) - root = root->firstChild(); - - if (root->type() != QSGNode::RootNodeType) - return; - - if (!m_renderer) { - m_renderer = m_rc->createRenderer(); - static_cast<QSGD3D12Renderer *>(m_renderer)->turnToLayerRenderer(); - connect(m_renderer, &QSGRenderer::sceneGraphChanged, this, &QSGD3D12Layer::markDirtyTexture); - } - - m_renderer->setDevicePixelRatio(m_dpr); - m_renderer->setRootNode(static_cast<QSGRootNode *>(root)); - - QSGD3D12Engine *engine = m_rc->engine(); - const uint sampleCount = engine->windowSamples(); - const QVector4D clearColor; - - if (!m_rt || m_rtSize != m_size) { - if (m_rt) - resetRenderTarget(); - - m_rt = engine->genRenderTarget(); - m_rtSize = m_size; - - if (Q_UNLIKELY(debug_render())) - qDebug("new render target for layer %p, size=%dx%d, samples=%d", - this, m_size.width(), m_size.height(), sampleCount); - - engine->createRenderTarget(m_rt, m_rtSize, clearColor, sampleCount); - - // For multisampling the resolving via an extra non-ms color buffer is - // handled internally in the engine, no need to worry about it here. - } - - if (m_recursive && !m_secondaryRT && sampleCount == 1) { - m_secondaryRT = engine->genRenderTarget(); - engine->createRenderTarget(m_secondaryRT, m_rtSize, clearColor, sampleCount); - } - - m_dirtyTexture = false; - - m_renderer->setDeviceRect(m_size); - m_renderer->setViewportRect(m_size); - - // Note that the handling of vertical mirroring differs from OpenGL here - // due to y running top-bottom with D3D as opposed to bottom-top with GL. - // The common parts of Quick follow OpenGL so vertical mirroring is - // typically enabled. - QRectF mirrored(m_mirrorHorizontal ? m_rect.right() : m_rect.left(), - m_mirrorVertical ? m_rect.top() : m_rect.bottom(), - m_mirrorHorizontal ? -m_rect.width() : m_rect.width(), - m_mirrorVertical ? m_rect.height() : -m_rect.height()); - - m_renderer->setProjectionMatrixToRect(mirrored); - m_renderer->setClearColor(Qt::transparent); - - if (!m_recursive || sampleCount > 1) { - m_renderer->renderScene(m_rt); - } else { - m_renderer->renderScene(m_secondaryRT); - qSwap(m_rt, m_secondaryRT); - } - - if (m_recursive) - markDirtyTexture(); // Continuously update if 'live' and 'recursive'. -} - -QT_END_NAMESPACE diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12layer_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12layer_p.h deleted file mode 100644 index 42a56877cf..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12layer_p.h +++ /dev/null @@ -1,129 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSGD3D12LAYER_P_H -#define QSGD3D12LAYER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qsgadaptationlayer_p.h> -#include <private/qsgtexture_p.h> - -QT_BEGIN_NAMESPACE - -class QSGD3D12RenderContext; -class QSGD3D12LayerPrivate; - -class QSGD3D12Layer : public QSGLayer -{ - Q_DECLARE_PRIVATE(QSGD3D12Layer) - Q_OBJECT - -public: - QSGD3D12Layer(QSGD3D12RenderContext *rc); - ~QSGD3D12Layer(); - - int textureId() const override; - QSize textureSize() const override; - bool hasAlphaChannel() const override; - bool hasMipmaps() const override; - QRectF normalizedTextureSubRect() const override; - void bind() override; - - bool updateTexture() override; - - void setItem(QSGNode *item) override; - void setRect(const QRectF &rect) override; - void setSize(const QSize &size) override; - void scheduleUpdate() override; - QImage toImage() const override; - void setLive(bool live) override; - void setRecursive(bool recursive) override; - void setFormat(uint format) override; - void setHasMipmaps(bool mipmap) override; - void setDevicePixelRatio(qreal ratio) override; - void setMirrorHorizontal(bool mirror) override; - void setMirrorVertical(bool mirror) override; - void setSamples(int) override { } - -public Q_SLOTS: - void markDirtyTexture() override; - void invalidated() override; - -private: - void cleanup(); - void resetRenderTarget(); - void updateContent(); - - QSGD3D12RenderContext *m_rc; - uint m_rt = 0; - uint m_secondaryRT = 0; - QSize m_rtSize; - QSize m_size; - QRectF m_rect; - QSGNode *m_item = nullptr; - QSGRenderer *m_renderer = nullptr; - float m_dpr = 1; - bool m_mirrorHorizontal = false; - bool m_mirrorVertical = true; - bool m_live = true; - bool m_recursive = false; - bool m_dirtyTexture = true; - bool m_updateContentPending = false; -}; - -class QSGD3D12LayerPrivate : public QSGTexturePrivate -{ - Q_DECLARE_PUBLIC(QSGD3D12Layer) -public: - int comparisonKey() const override; -}; - -QT_END_NAMESPACE - -#endif // QSGD3D12LAYER_P_H diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12material.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12material.cpp deleted file mode 100644 index 1b638106ee..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12material.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsgd3d12material_p.h" - -QT_BEGIN_NAMESPACE - -QSGMaterialShader *QSGD3D12Material::createShader() const -{ - return nullptr; -} - -QT_END_NAMESPACE diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12material_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12material_p.h deleted file mode 100644 index 65d53600c3..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12material_p.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSGD3D12MATERIAL_P_H -#define QSGD3D12MATERIAL_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtQuick/qsgmaterial.h> -#include "qsgd3d12engine_p.h" - -QT_BEGIN_NAMESPACE - -class QSGRenderer; - -// The D3D renderer works with QSGD3D12Material as the "base" class since -// QSGMaterial and its GL program related bits are not suitable. Also, there is -// no split like with QSGMaterialShader. - -typedef QSGMaterialShader::RenderState QSGD3D12MaterialRenderState; - -class QSGD3D12Material : public QSGMaterial -{ -public: - struct ExtraState { - QVector4D blendFactor; - }; - - enum UpdateResult { - UpdatedShaders = 0x0001, - UpdatedConstantBuffer = 0x0002, - UpdatedBlendFactor = 0x0004 - }; - Q_DECLARE_FLAGS(UpdateResults, UpdateResult) - - virtual int constantBufferSize() const = 0; - virtual void preparePipeline(QSGD3D12PipelineState *pipelineState) = 0; - virtual UpdateResults updatePipeline(const QSGD3D12MaterialRenderState &state, - QSGD3D12PipelineState *pipelineState, - ExtraState *extraState, - quint8 *constantBuffer) = 0; - -private: - QSGMaterialShader *createShader() const override; // dummy, QSGMaterialShader is too GL dependent -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(QSGD3D12Material::UpdateResults) - -QT_END_NAMESPACE - -#endif // QSGD3D12MATERIAL_P_H diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12painternode.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12painternode.cpp deleted file mode 100644 index b22c42f2e5..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12painternode.cpp +++ /dev/null @@ -1,255 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsgd3d12painternode_p.h" -#include "qsgd3d12rendercontext_p.h" -#include "qsgd3d12engine_p.h" -#include <private/qquickitem_p.h> -#include <qmath.h> - -QT_BEGIN_NAMESPACE - -QSGD3D12PainterTexture::QSGD3D12PainterTexture(QSGD3D12Engine *engine) - : QSGD3D12Texture(engine) -{ -} - -void QSGD3D12PainterTexture::bind() -{ - if (m_image.isNull()) { - if (!m_id) { - m_id = m_engine->genTexture(); - m_engine->createTexture(m_id, QSize(16, 16), QImage::Format_RGB32, 0); - } - } else if (m_image.size() != lastSize) { - lastSize = m_image.size(); - if (m_id) - m_engine->releaseTexture(m_id); - m_id = m_engine->genTexture(); - m_engine->createTexture(m_id, m_image.size(), m_image.format(), QSGD3D12Engine::TextureWithAlpha); - m_engine->queueTextureUpload(m_id, m_image); - } else if (!dirty.isEmpty()) { - const int bpl = m_image.bytesPerLine(); - const uchar *p = m_image.constBits() + dirty.y() * bpl + dirty.x() * 4; - QImage subImg(p, dirty.width(), dirty.height(), bpl, QImage::Format_ARGB32_Premultiplied); - m_engine->queueTextureUpload(m_id, subImg, dirty.topLeft()); - } - - dirty = QRect(); - - m_engine->useTexture(m_id); -} - -QSGD3D12PainterNode::QSGD3D12PainterNode(QQuickPaintedItem *item) - : m_item(item), - m_engine(static_cast<QSGD3D12RenderContext *>(QQuickItemPrivate::get(item)->sceneGraphRenderContext())->engine()), - m_texture(new QSGD3D12PainterTexture(m_engine)), - m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4), - m_dirtyGeometry(false), - m_dirtyContents(false) -{ - setGeometry(&m_geometry); - m_material.setTexture(m_texture); - setMaterial(&m_material); -} - -QSGD3D12PainterNode::~QSGD3D12PainterNode() -{ - delete m_texture; -} - -void QSGD3D12PainterNode::setPreferredRenderTarget(QQuickPaintedItem::RenderTarget) -{ - // always QImage-based -} - -void QSGD3D12PainterNode::setSize(const QSize &size) -{ - if (m_size == size) - return; - - m_size = size; - m_dirtyGeometry = true; -} - -void QSGD3D12PainterNode::setDirty(const QRect &dirtyRect) -{ - m_dirtyRect = dirtyRect; - m_dirtyContents = true; - markDirty(DirtyMaterial); -} - -void QSGD3D12PainterNode::setOpaquePainting(bool) -{ - // ignored -} - -void QSGD3D12PainterNode::setLinearFiltering(bool linearFiltering) -{ - m_material.setFiltering(linearFiltering ? QSGTexture::Linear : QSGTexture::Nearest); - markDirty(DirtyMaterial); -} - -void QSGD3D12PainterNode::setMipmapping(bool) -{ - // ### not yet -} - -void QSGD3D12PainterNode::setSmoothPainting(bool s) -{ - if (m_smoothPainting == s) - return; - - m_smoothPainting = s; - m_dirtyContents = true; - markDirty(DirtyMaterial); -} - -void QSGD3D12PainterNode::setFillColor(const QColor &c) -{ - if (m_fillColor == c) - return; - - m_fillColor = c; - m_dirtyContents = true; - markDirty(DirtyMaterial); -} - -void QSGD3D12PainterNode::setContentsScale(qreal s) -{ - if (m_contentsScale == s) - return; - - m_contentsScale = s; - m_dirtyContents = true; - markDirty(DirtyMaterial); -} - -void QSGD3D12PainterNode::setFastFBOResizing(bool) -{ - // nope -} - -void QSGD3D12PainterNode::setTextureSize(const QSize &size) -{ - if (m_textureSize == size) - return; - - m_textureSize = size; - m_dirtyGeometry = true; -} - -QImage QSGD3D12PainterNode::toImage() const -{ - return *m_texture->image(); -} - -void QSGD3D12PainterNode::update() -{ - if (m_dirtyGeometry) { - m_dirtyGeometry = false; - QRectF src(0, 0, 1, 1); - QRectF dst(QPointF(0, 0), m_size); - QSGGeometry::updateTexturedRectGeometry(&m_geometry, dst, src); - markDirty(DirtyGeometry); - } - - QImage *img = m_texture->image(); - if (img->size() != m_textureSize) { - *img = QImage(m_textureSize, QImage::Format_ARGB32_Premultiplied); - img->fill(Qt::transparent); - m_dirtyContents = true; - } - - if (m_dirtyContents) { - m_dirtyContents = false; - if (!img->isNull()) { - QRect dirtyRect = m_dirtyRect.isNull() ? QRect(QPoint(0, 0), m_size) : m_dirtyRect; - QPainter painter; - painter.begin(img); - if (m_smoothPainting) - painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform); - - QRect clipRect; - QRect dirtyTextureRect; - - if (m_contentsScale == 1) { - float scaleX = m_textureSize.width() / (float) m_size.width(); - float scaleY = m_textureSize.height() / (float) m_size.height(); - painter.scale(scaleX, scaleY); - clipRect = dirtyRect; - dirtyTextureRect = QRectF(dirtyRect.x() * scaleX, - dirtyRect.y() * scaleY, - dirtyRect.width() * scaleX, - dirtyRect.height() * scaleY).toAlignedRect(); - } else { - painter.scale(m_contentsScale, m_contentsScale); - QRect sclip(qFloor(dirtyRect.x() / m_contentsScale), - qFloor(dirtyRect.y() / m_contentsScale), - qCeil(dirtyRect.width() / m_contentsScale + dirtyRect.x() / m_contentsScale - - qFloor(dirtyRect.x() / m_contentsScale)), - qCeil(dirtyRect.height() / m_contentsScale + dirtyRect.y() / m_contentsScale - - qFloor(dirtyRect.y() / m_contentsScale))); - clipRect = sclip; - dirtyTextureRect = dirtyRect; - } - - // only clip if we were originally updating only a subrect - if (!m_dirtyRect.isNull()) - painter.setClipRect(clipRect); - - painter.setCompositionMode(QPainter::CompositionMode_Source); - painter.fillRect(clipRect, m_fillColor); - painter.setCompositionMode(QPainter::CompositionMode_SourceOver); - - m_item->paint(&painter); - painter.end(); - - m_texture->dirty = dirtyTextureRect; - } - m_dirtyRect = QRect(); - } -} - -QSGTexture *QSGD3D12PainterNode::texture() const -{ - return m_texture; -} - -QT_END_NAMESPACE diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12painternode_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12painternode_p.h deleted file mode 100644 index 7f4842b3a6..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12painternode_p.h +++ /dev/null @@ -1,120 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSGD3D12PAINTERNODE_P_H -#define QSGD3D12PAINTERNODE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qsgadaptationlayer_p.h> -#include "qsgd3d12texture_p.h" -#include "qsgd3d12builtinmaterials_p.h" - -QT_BEGIN_NAMESPACE - -class QSGD3D12Engine; - -class QSGD3D12PainterTexture : public QSGD3D12Texture -{ -public: - QSGD3D12PainterTexture(QSGD3D12Engine *engine); - - void bind() override; - bool hasAlphaChannel() const override { return true; } - - QImage *image() { return &m_image; } - - QRect dirty; - -private: - QSize lastSize; -}; - -class QSGD3D12PainterNode : public QSGPainterNode -{ -public: - QSGD3D12PainterNode(QQuickPaintedItem *item); - ~QSGD3D12PainterNode(); - - void setPreferredRenderTarget(QQuickPaintedItem::RenderTarget target) override; - void setSize(const QSize &size) override; - void setDirty(const QRect &dirtyRect = QRect()) override; - void setOpaquePainting(bool opaque) override; - void setLinearFiltering(bool linearFiltering) override; - void setMipmapping(bool mipmapping) override; - void setSmoothPainting(bool s) override; - void setFillColor(const QColor &c) override; - void setContentsScale(qreal s) override; - void setFastFBOResizing(bool dynamic) override; - void setTextureSize(const QSize &size) override; - - QImage toImage() const override; - void update() override; - QSGTexture *texture() const override; - -private: - QQuickPaintedItem *m_item; - QSGD3D12Engine *m_engine; - QSGD3D12PainterTexture *m_texture; - QSize m_size; - QSize m_textureSize; - float m_contentsScale = 1; - bool m_smoothPainting = false; - QColor m_fillColor = Qt::transparent; - QRect m_dirtyRect; - - QSGGeometry m_geometry; - QSGD3D12TextureMaterial m_material; - - uint m_dirtyGeometry : 1; - uint m_dirtyContents : 1; -}; - -QT_END_NAMESPACE - -#endif // QSGD3D12PAINTERNODE_P_H diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12publicnodes.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12publicnodes.cpp deleted file mode 100644 index 1f01c440e5..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12publicnodes.cpp +++ /dev/null @@ -1,250 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsgd3d12publicnodes_p.h" - -QT_BEGIN_NAMESPACE - -QSGD3D12RectangleNode::QSGD3D12RectangleNode() - : m_geometry(QSGGeometry::defaultAttributes_Point2D(), 4) -{ - QSGGeometry::updateRectGeometry(&m_geometry, QRectF()); - setMaterial(&m_material); - setGeometry(&m_geometry); -#ifdef QSG_RUNTIME_DESCRIPTION - qsgnode_set_description(this, QLatin1String("rectangle")); -#endif -} - -void QSGD3D12RectangleNode::setRect(const QRectF &rect) -{ - QSGGeometry::updateRectGeometry(&m_geometry, rect); - markDirty(QSGNode::DirtyGeometry); -} - -QRectF QSGD3D12RectangleNode::rect() const -{ - const QSGGeometry::Point2D *pts = m_geometry.vertexDataAsPoint2D(); - return QRectF(pts[0].x, - pts[0].y, - pts[3].x - pts[0].x, - pts[3].y - pts[0].y); -} - -void QSGD3D12RectangleNode::setColor(const QColor &color) -{ - if (color != m_material.color()) { - m_material.setColor(color); - markDirty(QSGNode::DirtyMaterial); - } -} - -QColor QSGD3D12RectangleNode::color() const -{ - return m_material.color(); -} - -QSGD3D12ImageNode::QSGD3D12ImageNode() - : m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4), - m_texCoordMode(QSGD3D12ImageNode::NoTransform), - m_isAtlasTexture(false), - m_ownsTexture(false) -{ - setGeometry(&m_geometry); - setMaterial(&m_material); - m_material.setMipmapFiltering(QSGTexture::None); -#ifdef QSG_RUNTIME_DESCRIPTION - qsgnode_set_description(this, QLatin1String("image")); -#endif -} - -QSGD3D12ImageNode::~QSGD3D12ImageNode() -{ - if (m_ownsTexture) - delete m_material.texture(); -} - -void QSGD3D12ImageNode::setFiltering(QSGTexture::Filtering filtering) -{ - if (m_material.filtering() == filtering) - return; - - m_material.setFiltering(filtering); - markDirty(DirtyMaterial); -} - -QSGTexture::Filtering QSGD3D12ImageNode::filtering() const -{ - return m_material.filtering(); -} - -void QSGD3D12ImageNode::setMipmapFiltering(QSGTexture::Filtering filtering) -{ - if (m_material.mipmapFiltering() == filtering) - return; - - m_material.setMipmapFiltering(filtering); - markDirty(DirtyMaterial); -} - -QSGTexture::Filtering QSGD3D12ImageNode::mipmapFiltering() const -{ - return m_material.mipmapFiltering(); -} - -void QSGD3D12ImageNode::setRect(const QRectF &r) -{ - if (m_rect == r) - return; - - m_rect = r; - QSGImageNode::rebuildGeometry(&m_geometry, texture(), m_rect, m_sourceRect, m_texCoordMode); - markDirty(DirtyGeometry); -} - -QRectF QSGD3D12ImageNode::rect() const -{ - return m_rect; -} - -void QSGD3D12ImageNode::setSourceRect(const QRectF &r) -{ - if (m_sourceRect == r) - return; - - m_sourceRect = r; - QSGImageNode::rebuildGeometry(&m_geometry, texture(), m_rect, m_sourceRect, m_texCoordMode); - markDirty(DirtyGeometry); -} - -QRectF QSGD3D12ImageNode::sourceRect() const -{ - return m_sourceRect; -} - -void QSGD3D12ImageNode::setTexture(QSGTexture *texture) -{ - Q_ASSERT(texture); - - if (m_ownsTexture) - delete m_material.texture(); - - m_material.setTexture(texture); - QSGImageNode::rebuildGeometry(&m_geometry, texture, m_rect, m_sourceRect, m_texCoordMode); - - DirtyState dirty = DirtyMaterial; - const bool wasAtlas = m_isAtlasTexture; - m_isAtlasTexture = texture->isAtlasTexture(); - if (wasAtlas || m_isAtlasTexture) - dirty |= DirtyGeometry; - - markDirty(dirty); -} - -QSGTexture *QSGD3D12ImageNode::texture() const -{ - return m_material.texture(); -} - -void QSGD3D12ImageNode::setTextureCoordinatesTransform(TextureCoordinatesTransformMode mode) -{ - if (m_texCoordMode == mode) - return; - - m_texCoordMode = mode; - QSGImageNode::rebuildGeometry(&m_geometry, texture(), m_rect, m_sourceRect, m_texCoordMode); - markDirty(DirtyMaterial); -} - -QSGD3D12ImageNode::TextureCoordinatesTransformMode QSGD3D12ImageNode::textureCoordinatesTransform() const -{ - return m_texCoordMode; -} - -void QSGD3D12ImageNode::setOwnsTexture(bool owns) -{ - m_ownsTexture = owns; -} - -bool QSGD3D12ImageNode::ownsTexture() const -{ - return m_ownsTexture; -} - -QSGD3D12NinePatchNode::QSGD3D12NinePatchNode() - : m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4) -{ - m_geometry.setDrawingMode(QSGGeometry::DrawTriangleStrip); - setGeometry(&m_geometry); - setMaterial(&m_material); -} - -QSGD3D12NinePatchNode::~QSGD3D12NinePatchNode() -{ - delete m_material.texture(); -} - -void QSGD3D12NinePatchNode::setTexture(QSGTexture *texture) -{ - delete m_material.texture(); - m_material.setTexture(texture); -} - -void QSGD3D12NinePatchNode::setBounds(const QRectF &bounds) -{ - m_bounds = bounds; -} - -void QSGD3D12NinePatchNode::setDevicePixelRatio(qreal ratio) -{ - m_devicePixelRatio = ratio; -} - -void QSGD3D12NinePatchNode::setPadding(qreal left, qreal top, qreal right, qreal bottom) -{ - m_padding = QVector4D(left, top, right, bottom); -} - -void QSGD3D12NinePatchNode::update() -{ - QSGNinePatchNode::rebuildGeometry(m_material.texture(), &m_geometry, m_padding, m_bounds, m_devicePixelRatio); - markDirty(QSGNode::DirtyGeometry | QSGNode::DirtyMaterial); -} - -QT_END_NAMESPACE diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12publicnodes_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12publicnodes_p.h deleted file mode 100644 index 6150083aaf..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12publicnodes_p.h +++ /dev/null @@ -1,136 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSGD3D12PUBLICNODES_P_H -#define QSGD3D12PUBLICNODES_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtQuick/qsgrectanglenode.h> -#include <QtQuick/qsgimagenode.h> -#include <QtQuick/qsgninepatchnode.h> -#include "qsgd3d12builtinmaterials_p.h" - -QT_BEGIN_NAMESPACE - -class QSGD3D12RectangleNode : public QSGRectangleNode -{ -public: - QSGD3D12RectangleNode(); - - void setRect(const QRectF &rect) override; - QRectF rect() const override; - - void setColor(const QColor &color) override; - QColor color() const override; - -private: - QSGGeometry m_geometry; - QSGD3D12FlatColorMaterial m_material; -}; - -class QSGD3D12ImageNode : public QSGImageNode -{ -public: - QSGD3D12ImageNode(); - ~QSGD3D12ImageNode(); - - void setRect(const QRectF &rect) override; - QRectF rect() const override; - - void setSourceRect(const QRectF &r) override; - QRectF sourceRect() const override; - - void setTexture(QSGTexture *texture) override; - QSGTexture *texture() const override; - - void setFiltering(QSGTexture::Filtering filtering) override; - QSGTexture::Filtering filtering() const override; - - void setMipmapFiltering(QSGTexture::Filtering filtering) override; - QSGTexture::Filtering mipmapFiltering() const override; - - void setTextureCoordinatesTransform(TextureCoordinatesTransformMode mode) override; - TextureCoordinatesTransformMode textureCoordinatesTransform() const override; - - void setOwnsTexture(bool owns) override; - bool ownsTexture() const override; - -private: - QSGGeometry m_geometry; - QSGD3D12TextureMaterial m_material; - QRectF m_rect; - QRectF m_sourceRect; - TextureCoordinatesTransformMode m_texCoordMode; - uint m_isAtlasTexture : 1; - uint m_ownsTexture : 1; -}; - -class QSGD3D12NinePatchNode : public QSGNinePatchNode -{ -public: - QSGD3D12NinePatchNode(); - ~QSGD3D12NinePatchNode(); - - void setTexture(QSGTexture *texture) override; - void setBounds(const QRectF &bounds) override; - void setDevicePixelRatio(qreal ratio) override; - void setPadding(qreal left, qreal top, qreal right, qreal bottom) override; - void update() override; - -private: - QSGGeometry m_geometry; - QSGD3D12TextureMaterial m_material; - QRectF m_bounds; - qreal m_devicePixelRatio; - QVector4D m_padding; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12rendercontext.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12rendercontext.cpp deleted file mode 100644 index 48693207c6..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12rendercontext.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsgd3d12rendercontext_p.h" -#include "qsgd3d12renderer_p.h" -#include "qsgd3d12texture_p.h" - -QT_BEGIN_NAMESPACE - -// NOTE: Avoid categorized logging. It is slow. - -#define DECLARE_DEBUG_VAR(variable) \ - static bool debug_ ## variable() \ - { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; } - -DECLARE_DEBUG_VAR(render) - -QSGD3D12RenderContext::QSGD3D12RenderContext(QSGContext *ctx) - : QSGRenderContext(ctx) -{ -} - -bool QSGD3D12RenderContext::isValid() const -{ - // The render thread sets an engine when it starts up and resets when it - // quits. The rc is initialized and functional between those two points, - // regardless of any calls to invalidate(). See setEngine(). - return m_engine != nullptr; -} - -void QSGD3D12RenderContext::initialize(const InitParams *) -{ - if (m_initialized) - return; - - m_initialized = true; - emit initialized(); -} - -void QSGD3D12RenderContext::invalidate() -{ - if (!m_initialized) - return; - - m_initialized = false; - - if (Q_UNLIKELY(debug_render())) - qDebug("rendercontext invalidate engine %p, %d/%d/%d", m_engine, - m_texturesToDelete.count(), m_textures.count(), m_fontEnginesToClean.count()); - - qDeleteAll(m_texturesToDelete); - m_texturesToDelete.clear(); - - qDeleteAll(m_textures); - m_textures.clear(); - - for (QSet<QFontEngine *>::const_iterator it = m_fontEnginesToClean.constBegin(), - end = m_fontEnginesToClean.constEnd(); it != end; ++it) { - (*it)->clearGlyphCache(m_engine); - if (!(*it)->ref.deref()) - delete *it; - } - m_fontEnginesToClean.clear(); - - m_sg->renderContextInvalidated(this); - emit invalidated(); -} - -QSGTexture *QSGD3D12RenderContext::createTexture(const QImage &image, uint flags) const -{ - Q_ASSERT(m_engine); - QSGD3D12Texture *t = new QSGD3D12Texture(m_engine); - t->create(image, flags); - return t; -} - -QSGRenderer *QSGD3D12RenderContext::createRenderer() -{ - return new QSGD3D12Renderer(this); -} - -int QSGD3D12RenderContext::maxTextureSize() const -{ - return 16384; // D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION -} - -void QSGD3D12RenderContext::renderNextFrame(QSGRenderer *renderer, uint fbo) -{ - static_cast<QSGD3D12Renderer *>(renderer)->renderScene(fbo); -} - -void QSGD3D12RenderContext::setEngine(QSGD3D12Engine *engine) -{ - if (m_engine == engine) - return; - - m_engine = engine; - - if (m_engine) - initialize(nullptr); -} - -QSGRendererInterface::GraphicsApi QSGD3D12RenderContext::graphicsApi() const -{ - return Direct3D12; -} - -void *QSGD3D12RenderContext::getResource(QQuickWindow *window, Resource resource) const -{ - if (!m_engine) { - qWarning("getResource: No D3D12 engine available yet (window not exposed?)"); - return nullptr; - } - // window can be ignored since the rendercontext and engine are both per window - return m_engine->getResource(window, resource); -} - -QSGRendererInterface::ShaderType QSGD3D12RenderContext::shaderType() const -{ - return HLSL; -} - -QSGRendererInterface::ShaderCompilationTypes QSGD3D12RenderContext::shaderCompilationType() const -{ - return RuntimeCompilation | OfflineCompilation; -} - -QSGRendererInterface::ShaderSourceTypes QSGD3D12RenderContext::shaderSourceType() const -{ - return ShaderSourceString | ShaderSourceFile | ShaderByteCode; -} - -QT_END_NAMESPACE diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12rendercontext_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12rendercontext_p.h deleted file mode 100644 index c555c0808e..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12rendercontext_p.h +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSGD3D12RENDERCONTEXT_P_H -#define QSGD3D12RENDERCONTEXT_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qsgcontext_p.h> -#include <qsgrendererinterface.h> - -QT_BEGIN_NAMESPACE - -class QSGD3D12Engine; - -class QSGD3D12RenderContext : public QSGRenderContext, public QSGRendererInterface -{ -public: - QSGD3D12RenderContext(QSGContext *ctx); - bool isValid() const override; - void initialize(const InitParams *params) override; - void invalidate() override; - void renderNextFrame(QSGRenderer *renderer, uint fbo) override; - QSGTexture *createTexture(const QImage &image, uint flags) const override; - QSGRenderer *createRenderer() override; - int maxTextureSize() const override; - - void setEngine(QSGD3D12Engine *engine); - QSGD3D12Engine *engine() { return m_engine; } - - // QSGRendererInterface - GraphicsApi graphicsApi() const override; - void *getResource(QQuickWindow *window, Resource resource) const override; - ShaderType shaderType() const override; - ShaderCompilationTypes shaderCompilationType() const override; - ShaderSourceTypes shaderSourceType() const override; - -private: - QSGD3D12Engine *m_engine = nullptr; - bool m_initialized = false; -}; - -QT_END_NAMESPACE - -#endif // QSGD3D12RENDERCONTEXT_P_H diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12renderer.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12renderer.cpp deleted file mode 100644 index c38c616ae6..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12renderer.cpp +++ /dev/null @@ -1,785 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsgd3d12renderer_p.h" -#include "qsgd3d12rendercontext_p.h" -#include <private/qsgnodeupdater_p.h> -#include <private/qsgrendernode_p.h> - -#include "vs_stencilclip.hlslh" -#include "ps_stencilclip.hlslh" - -//#define I_LIKE_STENCIL - -QT_BEGIN_NAMESPACE - -#define QSGNODE_TRAVERSE(NODE) for (QSGNode *child = NODE->firstChild(); child; child = child->nextSibling()) - -// NOTE: Avoid categorized logging. It is slow. - -#define DECLARE_DEBUG_VAR(variable) \ - static bool debug_ ## variable() \ - { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; } - -DECLARE_DEBUG_VAR(build) -DECLARE_DEBUG_VAR(change) -DECLARE_DEBUG_VAR(render) - -class DummyUpdater : public QSGNodeUpdater -{ -public: - void updateState(QSGNode *) { }; -}; - -QSGD3D12Renderer::QSGD3D12Renderer(QSGRenderContext *context) - : QSGRenderer(context), - m_vboData(1024), - m_iboData(256), - m_cboData(4096), - m_renderList(16) -{ - setNodeUpdater(new DummyUpdater); -} - -QSGD3D12Renderer::~QSGD3D12Renderer() -{ - if (m_engine) { - m_engine->releaseBuffer(m_vertexBuf); - m_engine->releaseBuffer(m_indexBuf); - m_engine->releaseBuffer(m_constantBuf); - } -} - -void QSGD3D12Renderer::renderScene(GLuint fboId) -{ - m_renderTarget = fboId; - - struct DummyBindable : public QSGBindable { - void bind() const { } - } bindable; - - QSGRenderer::renderScene(bindable); // calls back render() -} - -// Search through the node set and remove nodes that are descendants of other -// nodes in the same set. -static QSet<QSGNode *> qsg_removeDescendants(const QSet<QSGNode *> &nodes, QSGRootNode *root) -{ - QSet<QSGNode *> result = nodes; - for (QSGNode *node : nodes) { - QSGNode *n = node; - while (n != root) { - if (n != node && result.contains(n)) { - result.remove(node); - break; - } - n = n->parent(); - } - } - return result; -} - -void QSGD3D12Renderer::updateMatrices(QSGNode *node, QSGTransformNode *xform) -{ - if (node->isSubtreeBlocked()) - return; - - if (node->type() == QSGNode::TransformNodeType) { - QSGTransformNode *tn = static_cast<QSGTransformNode *>(node); - if (xform) - tn->setCombinedMatrix(xform->combinedMatrix() * tn->matrix()); - else - tn->setCombinedMatrix(tn->matrix()); - QSGNODE_TRAVERSE(node) - updateMatrices(child, tn); - } else { - if (node->type() == QSGNode::GeometryNodeType || node->type() == QSGNode::ClipNodeType) { - m_nodeDirtyMap[node] |= QSGD3D12MaterialRenderState::DirtyMatrix; - QSGBasicGeometryNode *gnode = static_cast<QSGBasicGeometryNode *>(node); - const QMatrix4x4 *newMatrix = xform ? &xform->combinedMatrix() : nullptr; - // NB the newMatrix ptr is usually the same as before as it just - // references the transform node's own matrix. - gnode->setRendererMatrix(newMatrix); - } - QSGNODE_TRAVERSE(node) - updateMatrices(child, xform); - } -} - -void QSGD3D12Renderer::updateOpacities(QSGNode *node, float inheritedOpacity) -{ - if (node->isSubtreeBlocked()) - return; - - if (node->type() == QSGNode::OpacityNodeType) { - QSGOpacityNode *on = static_cast<QSGOpacityNode *>(node); - float combined = inheritedOpacity * on->opacity(); - on->setCombinedOpacity(combined); - QSGNODE_TRAVERSE(node) - updateOpacities(child, combined); - } else { - if (node->type() == QSGNode::GeometryNodeType) { - m_nodeDirtyMap[node] |= QSGD3D12MaterialRenderState::DirtyOpacity; - QSGGeometryNode *gn = static_cast<QSGGeometryNode *>(node); - gn->setInheritedOpacity(inheritedOpacity); - } - QSGNODE_TRAVERSE(node) - updateOpacities(child, inheritedOpacity); - } -} - -void QSGD3D12Renderer::buildRenderList(QSGNode *node, QSGClipNode *clip) -{ - if (node->isSubtreeBlocked()) - return; - - if (node->type() == QSGNode::GeometryNodeType || node->type() == QSGNode::ClipNodeType) { - QSGBasicGeometryNode *gn = static_cast<QSGBasicGeometryNode *>(node); - QSGGeometry *g = gn->geometry(); - - Element e; - e.node = gn; - - if (g->vertexCount() > 0) { - e.vboOffset = m_vboData.size(); - const int vertexSize = g->sizeOfVertex() * g->vertexCount(); - m_vboData.resize(m_vboData.size() + vertexSize); - memcpy(m_vboData.data() + e.vboOffset, g->vertexData(), vertexSize); - } - - if (g->indexCount() > 0) { - e.iboOffset = m_iboData.size(); - e.iboStride = g->sizeOfIndex(); - const int indexSize = e.iboStride * g->indexCount(); - m_iboData.resize(m_iboData.size() + indexSize); - memcpy(m_iboData.data() + e.iboOffset, g->indexData(), indexSize); - } - - e.cboOffset = m_cboData.size(); - if (node->type() == QSGNode::GeometryNodeType) { - QSGD3D12Material *m = static_cast<QSGD3D12Material *>(static_cast<QSGGeometryNode *>(node)->activeMaterial()); - e.cboSize = m->constantBufferSize(); - } else { - // Stencil-based clipping needs a 4x4 matrix. - e.cboSize = QSGD3D12Engine::alignedConstantBufferSize(16 * sizeof(float)); - } - m_cboData.resize(m_cboData.size() + e.cboSize); - - m_renderList.add(e); - - gn->setRendererClipList(clip); - if (node->type() == QSGNode::ClipNodeType) - clip = static_cast<QSGClipNode *>(node); - } else if (node->type() == QSGNode::RenderNodeType) { - QSGRenderNode *rn = static_cast<QSGRenderNode *>(node); - Element e; - e.node = rn; - m_renderList.add(e); - } - - QSGNODE_TRAVERSE(node) - buildRenderList(child, clip); -} - -void QSGD3D12Renderer::render() -{ - QSGD3D12RenderContext *rc = static_cast<QSGD3D12RenderContext *>(context()); - m_engine = rc->engine(); - if (!m_layerRenderer) - m_engine->beginFrame(); - else - m_engine->beginLayer(); - - m_activeScissorRect = QRect(); - - if (m_rebuild) { - m_rebuild = false; - - m_dirtyTransformNodes.clear(); - m_dirtyTransformNodes.insert(rootNode()); - m_dirtyOpacityNodes.clear(); - m_dirtyOpacityNodes.insert(rootNode()); - - m_renderList.reset(); - m_vboData.reset(); - m_iboData.reset(); - m_cboData.reset(); - - buildRenderList(rootNode(), nullptr); - - if (!m_vertexBuf) - m_vertexBuf = m_engine->genBuffer(); - m_engine->resetBuffer(m_vertexBuf, m_vboData.data(), m_vboData.size()); - - if (!m_constantBuf) - m_constantBuf = m_engine->genBuffer(); - m_engine->resetBuffer(m_constantBuf, m_cboData.data(), m_cboData.size()); - - if (m_iboData.size()) { - if (!m_indexBuf) - m_indexBuf = m_engine->genBuffer(); - m_engine->resetBuffer(m_indexBuf, m_iboData.data(), m_iboData.size()); - } else if (m_indexBuf) { - m_engine->releaseBuffer(m_indexBuf); - m_indexBuf = 0; - } - - if (Q_UNLIKELY(debug_build())) { - qDebug("renderList: %d elements in total", m_renderList.size()); - for (int i = 0; i < m_renderList.size(); ++i) { - const Element &e = m_renderList.at(i); - qDebug() << " - " << e.vboOffset << e.iboOffset << e.cboOffset << e.cboSize << e.node; - } - } - } - - const QRect devRect = deviceRect(); - m_projectionChangedDueToDeviceSize = devRect != m_lastDeviceRect; - if (m_projectionChangedDueToDeviceSize) - m_lastDeviceRect = devRect; - - if (m_dirtyTransformNodes.size()) { - const QSet<QSGNode *> subTreeRoots = qsg_removeDescendants(m_dirtyTransformNodes, rootNode()); - for (QSGNode *node : subTreeRoots) { - // First find the parent transform so we have the accumulated - // matrix up until this point. - QSGTransformNode *xform = 0; - QSGNode *n = node; - if (n->type() == QSGNode::TransformNodeType) - n = node->parent(); - while (n != rootNode() && n->type() != QSGNode::TransformNodeType) - n = n->parent(); - if (n != rootNode()) - xform = static_cast<QSGTransformNode *>(n); - - // Then update in the subtree - updateMatrices(node, xform); - } - } - - if (m_dirtyOpacityNodes.size()) { - const QSet<QSGNode *> subTreeRoots = qsg_removeDescendants(m_dirtyOpacityNodes, rootNode()); - for (QSGNode *node : subTreeRoots) { - float opacity = 1.0f; - QSGNode *n = node; - if (n->type() == QSGNode::OpacityNodeType) - n = node->parent(); - while (n != rootNode() && n->type() != QSGNode::OpacityNodeType) - n = n->parent(); - if (n != rootNode()) - opacity = static_cast<QSGOpacityNode *>(n)->combinedOpacity(); - - updateOpacities(node, opacity); - } - m_dirtyOpaqueElements = true; - } - - if (m_dirtyOpaqueElements) { - m_dirtyOpaqueElements = false; - m_opaqueElements.clear(); - m_opaqueElements.resize(m_renderList.size()); - for (int i = 0; i < m_renderList.size(); ++i) { - const Element &e = m_renderList.at(i); - if (e.node->type() == QSGNode::GeometryNodeType) { - const QSGGeometryNode *gn = static_cast<QSGGeometryNode *>(e.node); - if (gn->inheritedOpacity() > 0.999f && ((gn->activeMaterial()->flags() & QSGMaterial::Blending) == 0)) - m_opaqueElements.setBit(i); - } - // QSGRenderNodes are always treated as non-opaque - } - } - - // Build pipeline state and draw calls. - renderElements(); - - m_dirtyTransformNodes.clear(); - m_dirtyOpacityNodes.clear(); - m_dirtyOpaqueElements = false; - m_nodeDirtyMap.clear(); - - // Finalize buffers and execute commands. - if (!m_layerRenderer) - m_engine->endFrame(); - else - m_engine->endLayer(); -} - -void QSGD3D12Renderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state) -{ - // note that with DirtyNodeRemoved the window and all the graphics engine may already be gone - - if (Q_UNLIKELY(debug_change())) { - QDebug debug = qDebug(); - debug << "dirty:"; - if (state & QSGNode::DirtyGeometry) - debug << "Geometry"; - if (state & QSGNode::DirtyMaterial) - debug << "Material"; - if (state & QSGNode::DirtyMatrix) - debug << "Matrix"; - if (state & QSGNode::DirtyNodeAdded) - debug << "Added"; - if (state & QSGNode::DirtyNodeRemoved) - debug << "Removed"; - if (state & QSGNode::DirtyOpacity) - debug << "Opacity"; - if (state & QSGNode::DirtySubtreeBlocked) - debug << "SubtreeBlocked"; - if (state & QSGNode::DirtyForceUpdate) - debug << "ForceUpdate"; - - // when removed, some parts of the node could already have been destroyed - // so don't debug it out. - if (state & QSGNode::DirtyNodeRemoved) - debug << (void *) node << node->type(); - else - debug << node; - } - - if (state & (QSGNode::DirtyNodeAdded - | QSGNode::DirtyNodeRemoved - | QSGNode::DirtySubtreeBlocked - | QSGNode::DirtyGeometry - | QSGNode::DirtyForceUpdate)) - m_rebuild = true; - - if (state & QSGNode::DirtyMatrix) - m_dirtyTransformNodes << node; - - if (state & QSGNode::DirtyOpacity) - m_dirtyOpacityNodes << node; - - if (state & QSGNode::DirtyMaterial) - m_dirtyOpaqueElements = true; - - QSGRenderer::nodeChanged(node, state); -} - -void QSGD3D12Renderer::renderElements() -{ - m_engine->queueSetRenderTarget(m_renderTarget); - m_engine->queueViewport(viewportRect()); - m_engine->queueClearRenderTarget(clearColor()); - m_engine->queueClearDepthStencil(1, 0, QSGD3D12Engine::ClearDepth | QSGD3D12Engine::ClearStencil); - - m_pipelineState.blend = m_freshPipelineState.blend = QSGD3D12PipelineState::BlendNone; - m_pipelineState.depthEnable = m_freshPipelineState.depthEnable = true; - m_pipelineState.depthWrite = m_freshPipelineState.depthWrite = true; - - // First do opaque... - // The algorithm is quite simple. We traverse the list back-to-front, and - // for every item we start a second traversal and draw all elements which - // have identical material. Then we clear the bit for this in the rendered - // list so we don't draw it again when we come to that index. - QBitArray rendered = m_opaqueElements; - for (int i = m_renderList.size() - 1; i >= 0; --i) { - if (rendered.testBit(i)) { - renderElement(i); - for (int j = i - 1; j >= 0; --j) { - if (rendered.testBit(j)) { - const QSGGeometryNode *gni = static_cast<QSGGeometryNode *>(m_renderList.at(i).node); - const QSGGeometryNode *gnj = static_cast<QSGGeometryNode *>(m_renderList.at(j).node); - if (gni->clipList() == gnj->clipList() - && gni->inheritedOpacity() == gnj->inheritedOpacity() - && gni->geometry()->drawingMode() == gnj->geometry()->drawingMode() - && gni->geometry()->attributes() == gnj->geometry()->attributes()) { - const QSGMaterial *ami = gni->activeMaterial(); - const QSGMaterial *amj = gnj->activeMaterial(); - if (ami->type() == amj->type() - && ami->flags() == amj->flags() - && ami->compare(amj) == 0) { - renderElement(j); - rendered.clearBit(j); - } - } - } - } - } - } - - m_pipelineState.blend = m_freshPipelineState.blend = QSGD3D12PipelineState::BlendPremul; - m_pipelineState.depthWrite = m_freshPipelineState.depthWrite = false; - - // ...then the alpha ones - for (int i = 0; i < m_renderList.size(); ++i) { - if ((m_renderList.at(i).node->type() == QSGNode::GeometryNodeType && !m_opaqueElements.testBit(i)) - || m_renderList.at(i).node->type() == QSGNode::RenderNodeType) - renderElement(i); - } -} - -struct RenderNodeState : public QSGRenderNode::RenderState -{ - const QMatrix4x4 *projectionMatrix() const override { return m_projectionMatrix; } - QRect scissorRect() const override { return m_scissorRect; } - bool scissorEnabled() const override { return m_scissorEnabled; } - int stencilValue() const override { return m_stencilValue; } - bool stencilEnabled() const override { return m_stencilEnabled; } - const QRegion *clipRegion() const override { return nullptr; } - - const QMatrix4x4 *m_projectionMatrix; - QRect m_scissorRect; - bool m_scissorEnabled; - int m_stencilValue; - bool m_stencilEnabled; -}; - -void QSGD3D12Renderer::renderElement(int elementIndex) -{ - Element &e = m_renderList.at(elementIndex); - Q_ASSERT(e.node->type() == QSGNode::GeometryNodeType || e.node->type() == QSGNode::RenderNodeType); - - if (e.node->type() == QSGNode::RenderNodeType) { - renderRenderNode(static_cast<QSGRenderNode *>(e.node), elementIndex); - return; - } - - if (e.vboOffset < 0) - return; - - Q_ASSERT(e.cboOffset >= 0); - - const QSGGeometryNode *gn = static_cast<QSGGeometryNode *>(e.node); - if (Q_UNLIKELY(debug_render())) - qDebug() << "renderElement:" << elementIndex << gn << e.vboOffset << e.iboOffset << gn->inheritedOpacity() << gn->clipList(); - - if (gn->inheritedOpacity() < 0.001f) // pretty much invisible, don't draw it - return; - - // Update the QSGRenderer members which the materials will access. - m_current_projection_matrix = projectionMatrix(); - const float scale = 1.0 / m_renderList.size(); - m_current_projection_matrix(2, 2) = scale; - m_current_projection_matrix(2, 3) = 1.0f - (elementIndex + 1) * scale; - m_current_model_view_matrix = gn->matrix() ? *gn->matrix() : QMatrix4x4(); - m_current_determinant = m_current_model_view_matrix.determinant(); - m_current_opacity = gn->inheritedOpacity(); - - const QSGGeometry *g = gn->geometry(); - QSGD3D12Material *m = static_cast<QSGD3D12Material *>(gn->activeMaterial()); - - if (m->type() != m_lastMaterialType) { - m_pipelineState = m_freshPipelineState; - m->preparePipeline(&m_pipelineState); - } - - QSGD3D12MaterialRenderState::DirtyStates dirtyState = m_nodeDirtyMap.value(e.node); - - // After a rebuild everything in the cbuffer has to be updated. - if (!e.cboPrepared) { - e.cboPrepared = true; - dirtyState = QSGD3D12MaterialRenderState::DirtyAll; - } - - // DirtyMatrix does not include projection matrix changes that can arise - // due to changing the render target's size (and there is no rebuild). - // Accommodate for this. - if (m_projectionChangedDueToDeviceSize) - dirtyState |= QSGD3D12MaterialRenderState::DirtyMatrix; - - quint8 *cboPtr = nullptr; - if (e.cboSize > 0) - cboPtr = m_cboData.data() + e.cboOffset; - - if (Q_UNLIKELY(debug_render())) - qDebug() << "dirty state for" << e.node << "is" << dirtyState; - - QSGD3D12Material::ExtraState extraState; - QSGD3D12Material::UpdateResults updRes = m->updatePipeline(state(dirtyState), - &m_pipelineState, - &extraState, - cboPtr); - - if (updRes.testFlag(QSGD3D12Material::UpdatedConstantBuffer)) - m_engine->markBufferDirty(m_constantBuf, e.cboOffset, e.cboSize); - - if (updRes.testFlag(QSGD3D12Material::UpdatedBlendFactor)) - m_engine->queueSetBlendFactor(extraState.blendFactor); - - setInputLayout(g, &m_pipelineState); - - m_lastMaterialType = m->type(); - - setupClipping(gn->clipList(), elementIndex); - - // ### Lines and points with sizes other than 1 have to be implemented in some other way. Just ignore for now. - if (g->drawingMode() == QSGGeometry::DrawLineStrip || g->drawingMode() == QSGGeometry::DrawLines) { - if (g->lineWidth() != 1.0f) - qWarning("QSGD3D12Renderer: Line widths other than 1 are not supported by this renderer"); - } else if (g->drawingMode() == QSGGeometry::DrawPoints) { - if (g->lineWidth() != 1.0f) - qWarning("QSGD3D12Renderer: Point sprites are not supported by this renderer"); - } - - m_engine->finalizePipeline(m_pipelineState); - - queueDrawCall(g, e); -} - -void QSGD3D12Renderer::setInputLayout(const QSGGeometry *g, QSGD3D12PipelineState *pipelineState) -{ - pipelineState->inputElementCount = g->attributeCount(); - const QSGGeometry::Attribute *attrs = g->attributes(); - quint32 offset = 0; - for (int i = 0; i < g->attributeCount(); ++i) { - QSGD3D12InputElement &ie(pipelineState->inputElements[i]); - static const char *semanticNames[] = { "UNKNOWN", "POSITION", "COLOR", "TEXCOORD", "TEXCOORD", "TEXCOORD" }; - static const int semanticIndices[] = { 0, 0, 0, 0, 1, 2 }; - const int semantic = attrs[i].attributeType; - Q_ASSERT(semantic >= 1 && semantic < _countof(semanticNames)); - const int tupleSize = attrs[i].tupleSize; - ie.semanticName = semanticNames[semantic]; - ie.semanticIndex = semanticIndices[semantic]; - ie.offset = offset; - int bytesPerTuple = 0; - ie.format = QSGD3D12Engine::toDXGIFormat(QSGGeometry::Type(attrs[i].type), tupleSize, &bytesPerTuple); - if (ie.format == FmtUnknown) - qFatal("QSGD3D12Renderer: unsupported tuple size for attribute type 0x%x", attrs[i].type); - offset += bytesPerTuple; - // There is one buffer with interleaved data so the slot is always 0. - ie.slot = 0; - } -} - -void QSGD3D12Renderer::queueDrawCall(const QSGGeometry *g, const QSGD3D12Renderer::Element &e) -{ - QSGD3D12Engine::DrawParams dp; - dp.mode = QSGGeometry::DrawingMode(g->drawingMode()); - dp.vertexBuf = m_vertexBuf; - dp.constantBuf = m_constantBuf; - dp.vboOffset = e.vboOffset; - dp.vboSize = g->vertexCount() * g->sizeOfVertex(); - dp.vboStride = g->sizeOfVertex(); - dp.cboOffset = e.cboOffset; - - if (e.iboOffset >= 0) { - const QSGGeometry::Type indexType = QSGGeometry::Type(g->indexType()); - const QSGD3D12Format indexFormat = QSGD3D12Engine::toDXGIFormat(indexType); - if (indexFormat == FmtUnknown) - qFatal("QSGD3D12Renderer: unsupported index type 0x%x", indexType); - dp.count = g->indexCount(); - dp.indexBuf = m_indexBuf; - dp.startIndexIndex = e.iboOffset / e.iboStride; - dp.indexFormat = indexFormat; - } else { - dp.count = g->vertexCount(); - } - - m_engine->queueDraw(dp); -} - -void QSGD3D12Renderer::setupClipping(const QSGClipNode *clip, int elementIndex) -{ - const QRect devRect = deviceRect(); - QRect scissorRect; - int clipTypes = 0; - quint32 stencilValue = 0; - - while (clip) { - QMatrix4x4 m = projectionMatrix(); - if (clip->matrix()) - m *= *clip->matrix(); - -#ifndef I_LIKE_STENCIL - const bool isRectangleWithNoPerspective = clip->isRectangular() - && qFuzzyIsNull(m(3, 0)) && qFuzzyIsNull(m(3, 1)); - const bool noRotate = qFuzzyIsNull(m(0, 1)) && qFuzzyIsNull(m(1, 0)); - const bool isRotate90 = qFuzzyIsNull(m(0, 0)) && qFuzzyIsNull(m(1, 1)); - - if (isRectangleWithNoPerspective && (noRotate || isRotate90)) { - QRectF bbox = clip->clipRect(); - float invW = 1.0f / m(3, 3); - float fx1, fy1, fx2, fy2; - if (noRotate) { - fx1 = (bbox.left() * m(0, 0) + m(0, 3)) * invW; - fy1 = (bbox.bottom() * m(1, 1) + m(1, 3)) * invW; - fx2 = (bbox.right() * m(0, 0) + m(0, 3)) * invW; - fy2 = (bbox.top() * m(1, 1) + m(1, 3)) * invW; - } else { - Q_ASSERT(isRotate90); - fx1 = (bbox.bottom() * m(0, 1) + m(0, 3)) * invW; - fy1 = (bbox.left() * m(1, 0) + m(1, 3)) * invW; - fx2 = (bbox.top() * m(0, 1) + m(0, 3)) * invW; - fy2 = (bbox.right() * m(1, 0) + m(1, 3)) * invW; - } - - if (fx1 > fx2) - qSwap(fx1, fx2); - if (fy1 > fy2) - qSwap(fy1, fy2); - - int ix1 = qRound((fx1 + 1) * devRect.width() * 0.5f); - int iy1 = qRound((fy1 + 1) * devRect.height() * 0.5f); - int ix2 = qRound((fx2 + 1) * devRect.width() * 0.5f); - int iy2 = qRound((fy2 + 1) * devRect.height() * 0.5f); - - if (!(clipTypes & ClipScissor)) { - scissorRect = QRect(ix1, devRect.height() - iy2, ix2 - ix1, iy2 - iy1); - clipTypes |= ClipScissor; - } else { - scissorRect &= QRect(ix1, devRect.height() - iy2, ix2 - ix1, iy2 - iy1); - } - } else -#endif - { - clipTypes |= ClipStencil; - renderStencilClip(clip, elementIndex, m, stencilValue); - } - - clip = clip->clipList(); - } - - setScissor((clipTypes & ClipScissor) ? scissorRect : viewportRect()); - - if (clipTypes & ClipStencil) { - m_pipelineState.stencilEnable = true; - m_engine->queueSetStencilRef(stencilValue); - m_currentStencilValue = stencilValue; - } else { - m_pipelineState.stencilEnable = false; - m_currentStencilValue = 0; - } - - m_currentClipTypes = clipTypes; -} - -void QSGD3D12Renderer::setScissor(const QRect &r) -{ - if (m_activeScissorRect == r) - return; - - m_activeScissorRect = r; - m_engine->queueScissor(r); -} - -void QSGD3D12Renderer::renderStencilClip(const QSGClipNode *clip, int elementIndex, - const QMatrix4x4 &m, quint32 &stencilValue) -{ - QSGD3D12PipelineState sps; - sps.shaders.vs = g_VS_StencilClip; - sps.shaders.vsSize = sizeof(g_VS_StencilClip); - sps.shaders.ps = g_PS_StencilClip; - sps.shaders.psSize = sizeof(g_PS_StencilClip); - - m_engine->queueClearDepthStencil(1, 0, QSGD3D12Engine::ClearStencil); - sps.stencilEnable = true; - sps.colorWrite = false; - sps.depthWrite = false; - - sps.stencilFunc = QSGD3D12PipelineState::CompareEqual; - sps.stencilFailOp = QSGD3D12PipelineState::StencilKeep; - sps.stencilDepthFailOp = QSGD3D12PipelineState::StencilKeep; - sps.stencilPassOp = QSGD3D12PipelineState::StencilIncr; - - m_engine->queueSetStencilRef(stencilValue); - - int clipIndex = elementIndex; - while (m_renderList.at(--clipIndex).node != clip) { - Q_ASSERT(clipIndex >= 0); - } - const Element &ce = m_renderList.at(clipIndex); - Q_ASSERT(ce.node == clip); - - const QSGGeometry *g = clip->geometry(); - Q_ASSERT(g->attributeCount() == 1); - Q_ASSERT(g->attributes()[0].tupleSize == 2); - Q_ASSERT(g->attributes()[0].type == QSGGeometry::FloatType); - - setInputLayout(g, &sps); - m_engine->finalizePipeline(sps); - - Q_ASSERT(ce.cboSize > 0); - quint8 *p = m_cboData.data() + ce.cboOffset; - memcpy(p, m.constData(), 16 * sizeof(float)); - m_engine->markBufferDirty(m_constantBuf, ce.cboOffset, ce.cboSize); - - queueDrawCall(g, ce); - - ++stencilValue; -} - -void QSGD3D12Renderer::renderRenderNode(QSGRenderNode *node, int elementIndex) -{ - QSGRenderNodePrivate *rd = QSGRenderNodePrivate::get(node); - RenderNodeState state; - - setupClipping(rd->m_clip_list, elementIndex); - - QMatrix4x4 pm = projectionMatrix(); - state.m_projectionMatrix = ± - state.m_scissorEnabled = m_currentClipTypes & ClipScissor; - state.m_stencilEnabled = m_currentClipTypes & ClipStencil; - state.m_scissorRect = m_activeScissorRect; - state.m_stencilValue = m_currentStencilValue; - - // ### rendernodes do not have the QSGBasicGeometryNode infrastructure - // for storing combined matrices, opacity and such, but perhaps they should. - QSGNode *xform = node->parent(); - QSGNode *root = rootNode(); - QMatrix4x4 modelview; - while (xform != root) { - if (xform->type() == QSGNode::TransformNodeType) { - modelview *= static_cast<QSGTransformNode *>(xform)->combinedMatrix(); - break; - } - xform = xform->parent(); - } - rd->m_matrix = &modelview; - - QSGNode *opacity = node->parent(); - rd->m_opacity = 1.0; - while (opacity != rootNode()) { - if (opacity->type() == QSGNode::OpacityNodeType) { - rd->m_opacity = static_cast<QSGOpacityNode *>(opacity)->combinedOpacity(); - break; - } - opacity = opacity->parent(); - } - - node->render(&state); - - m_engine->invalidateCachedFrameState(); - // For simplicity, reset viewport, scissor, blend factor, stencil ref when - // any of them got changed. This will likely be rare so skip these otherwise. - // Render target, pipeline state, draw call related stuff will be reset always. - const bool restoreMinimal = node->changedStates() == 0; - m_engine->restoreFrameState(restoreMinimal); -} - -QT_END_NAMESPACE diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12renderer_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12renderer_p.h deleted file mode 100644 index df30a49f0d..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12renderer_p.h +++ /dev/null @@ -1,137 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSGD3D12RENDERER_P_H -#define QSGD3D12RENDERER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qsgrenderer_p.h> -#include <QtGui/private/qdatabuffer_p.h> -#include <QtCore/qbitarray.h> -#include "qsgd3d12engine_p.h" -#include "qsgd3d12material_p.h" - -QT_BEGIN_NAMESPACE - -class QSGRenderNode; - -class QSGD3D12Renderer : public QSGRenderer -{ -public: - QSGD3D12Renderer(QSGRenderContext *context); - ~QSGD3D12Renderer(); - - void renderScene(GLuint fboId) override; - void render() override; - void nodeChanged(QSGNode *node, QSGNode::DirtyState state) override; - - void turnToLayerRenderer() { m_layerRenderer = true; } - -private: - void updateMatrices(QSGNode *node, QSGTransformNode *xform); - void updateOpacities(QSGNode *node, float inheritedOpacity); - void buildRenderList(QSGNode *node, QSGClipNode *clip); - void renderElements(); - void renderElement(int elementIndex); - void setInputLayout(const QSGGeometry *g, QSGD3D12PipelineState *pipelineState); - void setupClipping(const QSGClipNode *clip, int elementIndex); - void setScissor(const QRect &r); - void renderStencilClip(const QSGClipNode *clip, int elementIndex, const QMatrix4x4 &m, quint32 &stencilValue); - void renderRenderNode(QSGRenderNode *node, int elementIndex); - - struct Element { - QSGNode *node = nullptr; - qint32 vboOffset = -1; - qint32 iboOffset = -1; - quint32 iboStride = 0; - qint32 cboOffset = -1; - quint32 cboSize = 0; - bool cboPrepared = false; - }; - - void queueDrawCall(const QSGGeometry *g, const Element &e); - - bool m_layerRenderer = false; - QSet<QSGNode *> m_dirtyTransformNodes; - QSet<QSGNode *> m_dirtyOpacityNodes; - QBitArray m_opaqueElements; - bool m_rebuild = true; - bool m_dirtyOpaqueElements = true; - QDataBuffer<quint8> m_vboData; - QDataBuffer<quint8> m_iboData; - QDataBuffer<quint8> m_cboData; - QDataBuffer<Element> m_renderList; - uint m_vertexBuf = 0; - uint m_indexBuf = 0; - uint m_constantBuf = 0; - QSGD3D12Engine *m_engine = nullptr; - - QSGMaterialType *m_lastMaterialType = nullptr; - QSGD3D12PipelineState m_pipelineState; - QSGD3D12PipelineState m_freshPipelineState; - - typedef QHash<QSGNode *, QSGD3D12MaterialRenderState::DirtyStates> NodeDirtyMap; - NodeDirtyMap m_nodeDirtyMap; - - QRect m_activeScissorRect; - QRect m_lastDeviceRect; - bool m_projectionChangedDueToDeviceSize; - - uint m_renderTarget = 0; - quint32 m_currentStencilValue; - enum ClipType { - ClipScissor = 0x1, - ClipStencil = 0x2 - }; - int m_currentClipTypes; -}; - -QT_END_NAMESPACE - -#endif // QSGD3D12RENDERER_P_H diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12renderloop.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12renderloop.cpp deleted file mode 100644 index 79ffee7689..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12renderloop.cpp +++ /dev/null @@ -1,548 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsgd3d12renderloop_p.h" -#include "qsgd3d12engine_p.h" -#include "qsgd3d12context_p.h" -#include "qsgd3d12rendercontext_p.h" -#include "qsgd3d12shadereffectnode_p.h" -#include <private/qquickwindow_p.h> -#include <private/qquickprofiler_p.h> -#include <private/qquickanimatorcontroller_p.h> -#include <QElapsedTimer> -#include <QGuiApplication> -#include <QScreen> - -#include <qtquick_tracepoints_p.h> - -QT_BEGIN_NAMESPACE - -// NOTE: Avoid categorized logging. It is slow. - -#define DECLARE_DEBUG_VAR(variable) \ - static bool debug_ ## variable() \ - { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; } - -DECLARE_DEBUG_VAR(loop) -DECLARE_DEBUG_VAR(time) - - -// This render loop operates on the gui (main) thread. -// Conceptually it matches the OpenGL 'windows' render loop. - -static inline int qsgrl_animation_interval() -{ - const qreal refreshRate = QGuiApplication::primaryScreen() ? QGuiApplication::primaryScreen()->refreshRate() : 0; - return refreshRate < 1 ? 16 : int(1000 / refreshRate); -} - -QSGD3D12RenderLoop::QSGD3D12RenderLoop() -{ - if (Q_UNLIKELY(debug_loop())) - qDebug("new d3d12 render loop"); - - sg = new QSGD3D12Context; - - m_anims = sg->createAnimationDriver(this); - connect(m_anims, &QAnimationDriver::started, this, &QSGD3D12RenderLoop::onAnimationStarted); - connect(m_anims, &QAnimationDriver::stopped, this, &QSGD3D12RenderLoop::onAnimationStopped); - m_anims->install(); - - m_vsyncDelta = qsgrl_animation_interval(); -} - -QSGD3D12RenderLoop::~QSGD3D12RenderLoop() -{ - delete sg; -} - -void QSGD3D12RenderLoop::show(QQuickWindow *window) -{ - if (Q_UNLIKELY(debug_loop())) - qDebug() << "show" << window; -} - -void QSGD3D12RenderLoop::hide(QQuickWindow *window) -{ - if (Q_UNLIKELY(debug_loop())) - qDebug() << "hide" << window; -} - -void QSGD3D12RenderLoop::resize(QQuickWindow *window) -{ - if (!m_windows.contains(window) || window->size().isEmpty()) - return; - - if (Q_UNLIKELY(debug_loop())) - qDebug() << "resize" << window; - - const WindowData &data(m_windows[window]); - - if (!data.exposed) - return; - - if (data.engine) - data.engine->setWindowSize(window->size(), window->effectiveDevicePixelRatio()); -} - -void QSGD3D12RenderLoop::windowDestroyed(QQuickWindow *window) -{ - if (Q_UNLIKELY(debug_loop())) - qDebug() << "window destroyed" << window; - - if (!m_windows.contains(window)) - return; - - QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window); - wd->fireAboutToStop(); - - WindowData &data(m_windows[window]); - QSGD3D12Engine *engine = data.engine; - QSGD3D12RenderContext *rc = data.rc; - m_windows.remove(window); - - // QSGNode destruction may release graphics resources in use so wait first. - engine->waitGPU(); - - // Bye bye nodes... - wd->cleanupNodesOnShutdown(); - - QSGD3D12ShaderEffectNode::cleanupMaterialTypeCache(); - - rc->invalidate(); - - delete rc; - delete engine; - - wd->animationController.reset(); -} - -void QSGD3D12RenderLoop::exposeWindow(QQuickWindow *window) -{ - WindowData data; - data.exposed = true; - data.engine = new QSGD3D12Engine; - data.rc = static_cast<QSGD3D12RenderContext *>(QQuickWindowPrivate::get(window)->context); - data.rc->setEngine(data.engine); - m_windows[window] = data; - - const int samples = window->format().samples(); - const bool alpha = window->format().alphaBufferSize() > 0; - const qreal dpr = window->effectiveDevicePixelRatio(); - - if (Q_UNLIKELY(debug_loop())) - qDebug() << "initializing D3D12 engine" << window << window->size() << dpr << samples << alpha; - - data.engine->attachToWindow(window->winId(), window->size(), dpr, samples, alpha); -} - -void QSGD3D12RenderLoop::obscureWindow(QQuickWindow *window) -{ - m_windows[window].exposed = false; - QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window); - wd->fireAboutToStop(); -} - -void QSGD3D12RenderLoop::exposureChanged(QQuickWindow *window) -{ - if (Q_UNLIKELY(debug_loop())) - qDebug() << "exposure changed" << window << window->isExposed(); - - if (window->isExposed()) { - if (!m_windows.contains(window)) - exposeWindow(window); - - // Stop non-visual animation timer as we now have a window rendering. - if (m_animationTimer && somethingVisible()) { - killTimer(m_animationTimer); - m_animationTimer = 0; - } - // If we have a pending timer and we get an expose, we need to stop it. - // Otherwise we get two frames and two animation ticks in the same time interval. - if (m_updateTimer) { - killTimer(m_updateTimer); - m_updateTimer = 0; - } - - WindowData &data(m_windows[window]); - data.exposed = true; - data.updatePending = true; - - render(); - - } else if (m_windows.contains(window)) { - obscureWindow(window); - - // Potentially start the non-visual animation timer if nobody is rendering. - if (m_anims->isRunning() && !somethingVisible() && !m_animationTimer) - m_animationTimer = startTimer(m_vsyncDelta); - } -} - -QImage QSGD3D12RenderLoop::grab(QQuickWindow *window) -{ - const bool tempExpose = !m_windows.contains(window); - if (tempExpose) - exposeWindow(window); - - m_windows[window].grabOnly = true; - - renderWindow(window); - - QImage grabbed = m_grabContent; - m_grabContent = QImage(); - - if (tempExpose) - obscureWindow(window); - - return grabbed; -} - -bool QSGD3D12RenderLoop::somethingVisible() const -{ - for (auto it = m_windows.constBegin(), itEnd = m_windows.constEnd(); it != itEnd; ++it) { - if (it.key()->isVisible() && it.key()->isExposed()) - return true; - } - return false; -} - -void QSGD3D12RenderLoop::maybePostUpdateTimer() -{ - if (!m_updateTimer) { - if (Q_UNLIKELY(debug_loop())) - qDebug("starting update timer"); - m_updateTimer = startTimer(m_vsyncDelta / 3); - } -} - -void QSGD3D12RenderLoop::update(QQuickWindow *window) -{ - maybeUpdate(window); -} - -void QSGD3D12RenderLoop::maybeUpdate(QQuickWindow *window) -{ - if (!m_windows.contains(window) || !somethingVisible()) - return; - - m_windows[window].updatePending = true; - maybePostUpdateTimer(); -} - -QAnimationDriver *QSGD3D12RenderLoop::animationDriver() const -{ - return m_anims; -} - -QSGContext *QSGD3D12RenderLoop::sceneGraphContext() const -{ - return sg; -} - -QSGRenderContext *QSGD3D12RenderLoop::createRenderContext(QSGContext *) const -{ - // The rendercontext and engine are per-window, like with the threaded - // loop, but unlike the non-threaded OpenGL variants. - return sg->createRenderContext(); -} - -void QSGD3D12RenderLoop::releaseResources(QQuickWindow *window) -{ - if (Q_UNLIKELY(debug_loop())) - qDebug() << "releaseResources" << window; -} - -void QSGD3D12RenderLoop::postJob(QQuickWindow *window, QRunnable *job) -{ - Q_UNUSED(window); - Q_ASSERT(job); - Q_ASSERT(window); - job->run(); - delete job; -} - -QSurface::SurfaceType QSGD3D12RenderLoop::windowSurfaceType() const -{ - return QSurface::OpenGLSurface; -} - -bool QSGD3D12RenderLoop::interleaveIncubation() const -{ - return m_anims->isRunning() && somethingVisible(); -} - -void QSGD3D12RenderLoop::onAnimationStarted() -{ - if (!somethingVisible()) { - if (!m_animationTimer) { - if (Q_UNLIKELY(debug_loop())) - qDebug("starting non-visual animation timer"); - m_animationTimer = startTimer(m_vsyncDelta); - } - } else { - maybePostUpdateTimer(); - } -} - -void QSGD3D12RenderLoop::onAnimationStopped() -{ - if (m_animationTimer) { - if (Q_UNLIKELY(debug_loop())) - qDebug("stopping non-visual animation timer"); - killTimer(m_animationTimer); - m_animationTimer = 0; - } -} - -bool QSGD3D12RenderLoop::event(QEvent *event) -{ - switch (event->type()) { - case QEvent::Timer: - { - QTimerEvent *te = static_cast<QTimerEvent *>(event); - if (te->timerId() == m_animationTimer) { - if (Q_UNLIKELY(debug_loop())) - qDebug("animation tick while no windows exposed"); - m_anims->advance(); - } else if (te->timerId() == m_updateTimer) { - if (Q_UNLIKELY(debug_loop())) - qDebug("update timeout - rendering"); - killTimer(m_updateTimer); - m_updateTimer = 0; - render(); - } - return true; - } - default: - break; - } - - return QObject::event(event); -} - -void QSGD3D12RenderLoop::render() -{ - bool rendered = false; - for (auto it = m_windows.begin(), itEnd = m_windows.end(); it != itEnd; ++it) { - if (it->updatePending) { - it->updatePending = false; - renderWindow(it.key()); - rendered = true; - } - } - - if (!rendered) { - if (Q_UNLIKELY(debug_loop())) - qDebug("render - no changes, sleep"); - QThread::msleep(m_vsyncDelta); - } - - if (m_anims->isRunning()) { - if (Q_UNLIKELY(debug_loop())) - qDebug("render - advancing animations"); - - m_anims->advance(); - - // It is not given that animations triggered another maybeUpdate() - // and thus another render pass, so to keep things running, - // make sure there is another frame pending. - maybePostUpdateTimer(); - - emit timeToIncubate(); - } -} - -void QSGD3D12RenderLoop::renderWindow(QQuickWindow *window) -{ - if (Q_UNLIKELY(debug_loop())) - qDebug() << "renderWindow" << window; - - QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window); - if (!m_windows.contains(window) || !window->geometry().isValid()) - return; - - WindowData &data(m_windows[window]); - if (!data.exposed) { // not the same as window->isExposed(), when grabbing invisible windows for instance - if (Q_UNLIKELY(debug_loop())) - qDebug("renderWindow - not exposed, abort"); - return; - } - - Q_TRACE_SCOPE(QSG_renderWindow); - - if (!data.grabOnly) - wd->flushFrameSynchronousEvents(); - - QElapsedTimer renderTimer; - qint64 renderTime = 0, syncTime = 0, polishTime = 0; - const bool profileFrames = debug_time(); - if (profileFrames) - renderTimer.start(); - Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishFrame); - Q_TRACE(QSG_polishItems_entry); - - wd->polishItems(); - - if (profileFrames) - polishTime = renderTimer.nsecsElapsed(); - Q_TRACE(QSG_polishItems_exit); - Q_QUICK_SG_PROFILE_SWITCH(QQuickProfiler::SceneGraphPolishFrame, - QQuickProfiler::SceneGraphRenderLoopFrame, - QQuickProfiler::SceneGraphPolishPolish); - Q_TRACE(QSG_sync_entry); - - emit window->afterAnimating(); - - // The native window may change in some (quite artificial) cases, e.g. due - // to a hide - destroy - show on the QWindow. - bool needsWindow = !data.engine->window(); - if (data.engine->window() && data.engine->window() != window->winId()) { - if (Q_UNLIKELY(debug_loop())) - qDebug("sync - native window handle changes for active engine"); - data.engine->waitGPU(); - wd->cleanupNodesOnShutdown(); - QSGD3D12ShaderEffectNode::cleanupMaterialTypeCache(); - data.rc->invalidate(); - data.engine->releaseResources(); - needsWindow = true; - } - if (needsWindow) { - // Must only ever get here when there is no window or releaseResources() has been called. - const int samples = window->format().samples(); - const bool alpha = window->format().alphaBufferSize() > 0; - const qreal dpr = window->effectiveDevicePixelRatio(); - if (Q_UNLIKELY(debug_loop())) - qDebug() << "sync - reinitializing D3D12 engine" << window << window->size() << dpr << samples << alpha; - data.engine->attachToWindow(window->winId(), window->size(), dpr, samples, alpha); - } - - // Recover from device loss. - if (!data.engine->hasResources()) { - if (Q_UNLIKELY(debug_loop())) - qDebug("sync - device was lost, resetting scenegraph"); - wd->cleanupNodesOnShutdown(); - QSGD3D12ShaderEffectNode::cleanupMaterialTypeCache(); - data.rc->invalidate(); - } - - data.rc->initialize(nullptr); - - wd->syncSceneGraph(); - data.rc->endSync(); - - if (profileFrames) - syncTime = renderTimer.nsecsElapsed(); - Q_TRACE(QSG_sync_exit); - Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame, - QQuickProfiler::SceneGraphRenderLoopSync); - Q_TRACE(QSG_render_entry); - - wd->renderSceneGraph(window->size()); - - if (profileFrames) - renderTime = renderTimer.nsecsElapsed(); - Q_TRACE(QSG_render_exit); - Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame, - QQuickProfiler::SceneGraphRenderLoopRender); - Q_TRACE(QSG_swap_entry); - - if (!data.grabOnly) { - // The engine is able to have multiple frames in flight. This in effect is - // similar to BufferQueueingOpenGL. Provide an env var to force the - // traditional blocking swap behavior, just in case. - static bool blockOnEachFrame = qEnvironmentVariableIntValue("QT_D3D_BLOCKING_PRESENT") != 0; - - if (window->isVisible()) { - data.engine->present(); - if (blockOnEachFrame) - data.engine->waitGPU(); - // The concept of "frame swaps" is quite misleading by default, when - // blockOnEachFrame is not used, but emit it for compatibility. - wd->fireFrameSwapped(); - } else { - if (blockOnEachFrame) - data.engine->waitGPU(); - } - } else { - m_grabContent = data.engine->executeAndWaitReadbackRenderTarget(); - data.grabOnly = false; - } - - qint64 swapTime = 0; - if (profileFrames) - swapTime = renderTimer.nsecsElapsed(); - Q_TRACE(QSG_swap_exit); - Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame, - QQuickProfiler::SceneGraphRenderLoopSwap); - - if (Q_UNLIKELY(debug_time())) { - static QTime lastFrameTime = QTime::currentTime(); - qDebug("Frame rendered with 'd3d12' renderloop in %dms, polish=%d, sync=%d, render=%d, swap=%d, frameDelta=%d", - int(swapTime / 1000000), - int(polishTime / 1000000), - int((syncTime - polishTime) / 1000000), - int((renderTime - syncTime) / 1000000), - int((swapTime - renderTime) / 10000000), - int(lastFrameTime.msecsTo(QTime::currentTime()))); - lastFrameTime = QTime::currentTime(); - } - - // Simulate device loss if requested. - static int devLossTest = qEnvironmentVariableIntValue("QT_D3D_TEST_DEVICE_LOSS"); - if (devLossTest > 0) { - static QElapsedTimer kt; - static bool timerRunning = false; - if (!timerRunning) { - kt.start(); - timerRunning = true; - } else if (kt.elapsed() > 5000) { - --devLossTest; - kt.restart(); - data.engine->simulateDeviceLoss(); - } - } -} - -int QSGD3D12RenderLoop::flags() const -{ - return SupportsGrabWithoutExpose; -} - -QT_END_NAMESPACE diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12renderloop_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12renderloop_p.h deleted file mode 100644 index c0333ffad0..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12renderloop_p.h +++ /dev/null @@ -1,130 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSGD3D12RENDERLOOP_P_H -#define QSGD3D12RENDERLOOP_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qsgrenderloop_p.h> - -QT_BEGIN_NAMESPACE - -class QSGD3D12Engine; -class QSGD3D12Context; -class QSGD3D12RenderContext; - -class QSGD3D12RenderLoop : public QSGRenderLoop -{ - Q_OBJECT - -public: - QSGD3D12RenderLoop(); - ~QSGD3D12RenderLoop(); - - void show(QQuickWindow *window) override; - void hide(QQuickWindow *window) override; - void resize(QQuickWindow *window) override; - - void windowDestroyed(QQuickWindow *window) override; - - void exposureChanged(QQuickWindow *window) override; - - QImage grab(QQuickWindow *window) override; - - void update(QQuickWindow *window) override; - void maybeUpdate(QQuickWindow *window) override; - - QAnimationDriver *animationDriver() const override; - - QSGContext *sceneGraphContext() const override; - QSGRenderContext *createRenderContext(QSGContext *) const override; - - void releaseResources(QQuickWindow *window) override; - void postJob(QQuickWindow *window, QRunnable *job) override; - - QSurface::SurfaceType windowSurfaceType() const override; - bool interleaveIncubation() const override; - int flags() const override; - - bool event(QEvent *event) override; - -public Q_SLOTS: - void onAnimationStarted(); - void onAnimationStopped(); - -private: - void exposeWindow(QQuickWindow *window); - void obscureWindow(QQuickWindow *window); - void renderWindow(QQuickWindow *window); - void render(); - void maybePostUpdateTimer(); - bool somethingVisible() const; - - QSGD3D12Context *sg; - QAnimationDriver *m_anims; - int m_vsyncDelta; - int m_updateTimer = 0; - int m_animationTimer = 0; - - struct WindowData { - QSGD3D12RenderContext *rc = nullptr; - QSGD3D12Engine *engine = nullptr; - bool updatePending = false; - bool grabOnly = false; - bool exposed = false; - }; - - QHash<QQuickWindow *, WindowData> m_windows; - - QImage m_grabContent; -}; - -QT_END_NAMESPACE - -#endif // QSGD3D12RENDERLOOP_P_H diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp deleted file mode 100644 index 1f574a9802..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp +++ /dev/null @@ -1,995 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsgd3d12shadereffectnode_p.h" -#include "qsgd3d12rendercontext_p.h" -#include "qsgd3d12texture_p.h" -#include "qsgd3d12engine_p.h" -#include <QtCore/qthreadpool.h> -#include <QtCore/qfile.h> -#include <QtCore/qfileselector.h> -#include <QtQml/qqmlfile.h> -#include <qsgtextureprovider.h> - -#include <d3d12shader.h> -#include <d3dcompiler.h> - -#include "vs_shadereffectdefault.hlslh" -#include "ps_shadereffectdefault.hlslh" - -QT_BEGIN_NAMESPACE - -// NOTE: Avoid categorized logging. It is slow. - -#define DECLARE_DEBUG_VAR(variable) \ - static bool debug_ ## variable() \ - { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; } - -DECLARE_DEBUG_VAR(shader) - -void QSGD3D12ShaderLinker::reset(const QByteArray &vertBlob, const QByteArray &fragBlob) -{ - Q_ASSERT(!vertBlob.isEmpty() && !fragBlob.isEmpty()); - vs = vertBlob; - fs = fragBlob; - - error = false; - - constantBufferSize = 0; - constants.clear(); - samplers.clear(); - textures.clear(); - textureNameMap.clear(); -} - -void QSGD3D12ShaderLinker::feedConstants(const QSGShaderEffectNode::ShaderData &shader, const QSet<int> *dirtyIndices) -{ - Q_ASSERT(shader.shaderInfo.variables.count() == shader.varData.count()); - if (!dirtyIndices) { - constantBufferSize = qMax(constantBufferSize, shader.shaderInfo.constantDataSize); - for (int i = 0; i < shader.shaderInfo.variables.count(); ++i) { - const auto &var(shader.shaderInfo.variables.at(i)); - if (var.type == QSGGuiThreadShaderEffectManager::ShaderInfo::Constant) { - const auto &vd(shader.varData.at(i)); - Constant c; - c.size = var.size; - c.specialType = vd.specialType; - if (c.specialType != QSGShaderEffectNode::VariableData::SubRect) { - c.value = vd.value; - } else { - Q_ASSERT(var.name.startsWith(QByteArrayLiteral("qt_SubRect_"))); - c.value = var.name.mid(11); - } - constants[var.offset] = c; - } - } - } else { - for (int idx : *dirtyIndices) - constants[shader.shaderInfo.variables.at(idx).offset].value = shader.varData.at(idx).value; - } -} - -void QSGD3D12ShaderLinker::feedSamplers(const QSGShaderEffectNode::ShaderData &shader) -{ - for (int i = 0; i < shader.shaderInfo.variables.count(); ++i) { - const auto &var(shader.shaderInfo.variables.at(i)); - if (var.type == QSGGuiThreadShaderEffectManager::ShaderInfo::Sampler) { - Q_ASSERT(shader.varData.at(i).specialType == QSGShaderEffectNode::VariableData::Unused); - samplers.insert(var.bindPoint); - } - } -} - -void QSGD3D12ShaderLinker::feedTextures(const QSGShaderEffectNode::ShaderData &shader, const QSet<int> *dirtyIndices) -{ - if (!dirtyIndices) { - for (int i = 0; i < shader.shaderInfo.variables.count(); ++i) { - const auto &var(shader.shaderInfo.variables.at(i)); - const auto &vd(shader.varData.at(i)); - if (var.type == QSGGuiThreadShaderEffectManager::ShaderInfo::Texture) { - Q_ASSERT(vd.specialType == QSGShaderEffectNode::VariableData::Source); - textures.insert(var.bindPoint, vd.value); - textureNameMap.insert(var.name, var.bindPoint); - } - } - } else { - for (int idx : *dirtyIndices) { - const auto &var(shader.shaderInfo.variables.at(idx)); - const auto &vd(shader.varData.at(idx)); - textures.insert(var.bindPoint, vd.value); - textureNameMap.insert(var.name, var.bindPoint); - } - } -} - -void QSGD3D12ShaderLinker::linkTextureSubRects() -{ - // feedConstants stores <name> in Constant::value for subrect entries. Now - // that both constants and textures are known, replace the name with the - // texture bind point. - for (Constant &c : constants) { - if (c.specialType == QSGShaderEffectNode::VariableData::SubRect) { - if (c.value.type() == QVariant::ByteArray) { - const QByteArray name = c.value.toByteArray(); - if (!textureNameMap.contains(name)) - qWarning("ShaderEffect: qt_SubRect_%s refers to unknown source texture", qPrintable(name)); - c.value = textureNameMap[name]; - } - } - } -} - -void QSGD3D12ShaderLinker::dump() -{ - if (error) { - qDebug() << "Failed to generate program data"; - return; - } - qDebug() << "Combined shader data" << vs.size() << fs.size() << "cbuffer size" << constantBufferSize; - qDebug() << " - constants" << constants; - qDebug() << " - samplers" << samplers; - qDebug() << " - textures" << textures; -} - -QDebug operator<<(QDebug debug, const QSGD3D12ShaderLinker::Constant &c) -{ - QDebugStateSaver saver(debug); - debug.space(); - debug << "size" << c.size; - if (c.specialType != QSGShaderEffectNode::VariableData::None) - debug << "special" << c.specialType; - else - debug << "value" << c.value; - return debug; -} - -QSGD3D12ShaderEffectMaterial::QSGD3D12ShaderEffectMaterial(QSGD3D12ShaderEffectNode *node) - : node(node) -{ - setFlag(Blending | RequiresFullMatrix, true); // may be changed in sync() -} - -QSGD3D12ShaderEffectMaterial::~QSGD3D12ShaderEffectMaterial() -{ - delete dummy; -} - -struct QSGD3D12ShaderMaterialTypeCache -{ - QSGMaterialType *get(const QByteArray &vs, const QByteArray &fs); - void reset() { qDeleteAll(m_types); m_types.clear(); } - - struct Key { - QByteArray blob[2]; - Key() { } - Key(const QByteArray &vs, const QByteArray &fs) { blob[0] = vs; blob[1] = fs; } - bool operator==(const Key &other) const { - return blob[0] == other.blob[0] && blob[1] == other.blob[1]; - } - }; - QHash<Key, QSGMaterialType *> m_types; -}; - -uint qHash(const QSGD3D12ShaderMaterialTypeCache::Key &key, uint seed = 0) -{ - uint hash = seed; - for (int i = 0; i < 2; ++i) - hash = hash * 31337 + qHash(key.blob[i]); - return hash; -} - -QSGMaterialType *QSGD3D12ShaderMaterialTypeCache::get(const QByteArray &vs, const QByteArray &fs) -{ - const Key k(vs, fs); - if (m_types.contains(k)) - return m_types.value(k); - - QSGMaterialType *t = new QSGMaterialType; - m_types.insert(k, t); - return t; -} - -Q_GLOBAL_STATIC(QSGD3D12ShaderMaterialTypeCache, shaderMaterialTypeCache) - -void QSGD3D12ShaderEffectNode::cleanupMaterialTypeCache() -{ - shaderMaterialTypeCache()->reset(); -} - -QSGMaterialType *QSGD3D12ShaderEffectMaterial::type() const -{ - return mtype; -} - -static bool hasAtlasTexture(const QVector<QSGTextureProvider *> &textureProviders) -{ - for (int i = 0; i < textureProviders.count(); ++i) { - QSGTextureProvider *t = textureProviders.at(i); - if (t && t->texture() && t->texture()->isAtlasTexture()) - return true; - } - return false; -} - -int QSGD3D12ShaderEffectMaterial::compare(const QSGMaterial *other) const -{ - Q_ASSERT(other && type() == other->type()); - const QSGD3D12ShaderEffectMaterial *o = static_cast<const QSGD3D12ShaderEffectMaterial *>(other); - - if (int diff = cullMode - o->cullMode) - return diff; - - if (int diff = textureProviders.count() - o->textureProviders.count()) - return diff; - - if (linker.constants != o->linker.constants) - return 1; - - if ((hasAtlasTexture(textureProviders) && !geometryUsesTextureSubRect) - || (hasAtlasTexture(o->textureProviders) && !o->geometryUsesTextureSubRect)) - return 1; - - for (int i = 0; i < textureProviders.count(); ++i) { - QSGTextureProvider *tp1 = textureProviders.at(i); - QSGTextureProvider *tp2 = o->textureProviders.at(i); - if (!tp1 || !tp2) - return tp1 == tp2 ? 0 : 1; - QSGTexture *t1 = tp1->texture(); - QSGTexture *t2 = tp2->texture(); - if (!t1 || !t2) - return t1 == t2 ? 0 : 1; - if (int diff = t1->textureId() - t2->textureId()) - return diff; - } - - return 0; -} - -int QSGD3D12ShaderEffectMaterial::constantBufferSize() const -{ - return QSGD3D12Engine::alignedConstantBufferSize(linker.constantBufferSize); -} - -void QSGD3D12ShaderEffectMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState) -{ - pipelineState->shaders.vs = reinterpret_cast<const quint8 *>(linker.vs.constData()); - pipelineState->shaders.vsSize = linker.vs.size(); - pipelineState->shaders.ps = reinterpret_cast<const quint8 *>(linker.fs.constData()); - pipelineState->shaders.psSize = linker.fs.size(); - - pipelineState->shaders.rootSig.textureViewCount = textureProviders.count(); -} - -static inline QColor qsg_premultiply_color(const QColor &c) -{ - return QColor::fromRgbF(c.redF() * c.alphaF(), c.greenF() * c.alphaF(), c.blueF() * c.alphaF(), c.alphaF()); -} - -QSGD3D12Material::UpdateResults QSGD3D12ShaderEffectMaterial::updatePipeline(const QSGD3D12MaterialRenderState &state, - QSGD3D12PipelineState *pipelineState, - ExtraState *, - quint8 *constantBuffer) -{ - QSGD3D12Material::UpdateResults r = 0; - quint8 *p = constantBuffer; - - for (auto it = linker.constants.constBegin(), itEnd = linker.constants.constEnd(); it != itEnd; ++it) { - quint8 *dst = p + it.key(); - const QSGD3D12ShaderLinker::Constant &c(it.value()); - if (c.specialType == QSGShaderEffectNode::VariableData::Opacity) { - if (state.isOpacityDirty()) { - const float f = state.opacity(); - Q_ASSERT(sizeof(f) == c.size); - memcpy(dst, &f, sizeof(f)); - r |= UpdatedConstantBuffer; - } - } else if (c.specialType == QSGShaderEffectNode::VariableData::Matrix) { - if (state.isMatrixDirty()) { - const int sz = 16 * sizeof(float); - Q_ASSERT(sz == c.size); - memcpy(dst, state.combinedMatrix().constData(), sz); - r |= UpdatedConstantBuffer; - } - } else if (c.specialType == QSGShaderEffectNode::VariableData::SubRect) { - // float4 - QRectF subRect(0, 0, 1, 1); - int srcBindPoint = c.value.toInt(); // filled in by linkTextureSubRects - if (QSGTexture *t = textureProviders.at(srcBindPoint)->texture()) - subRect = t->normalizedTextureSubRect(); - const float f[4] = { float(subRect.x()), float(subRect.y()), - float(subRect.width()), float(subRect.height()) }; - Q_ASSERT(sizeof(f) == c.size); - memcpy(dst, f, sizeof(f)); - } else if (c.specialType == QSGShaderEffectNode::VariableData::None) { - r |= UpdatedConstantBuffer; - switch (c.value.type()) { - case QMetaType::QColor: { - const QColor v = qsg_premultiply_color(qvariant_cast<QColor>(c.value)); - const float f[4] = { float(v.redF()), float(v.greenF()), float(v.blueF()), float(v.alphaF()) }; - Q_ASSERT(sizeof(f) == c.size); - memcpy(dst, f, sizeof(f)); - break; - } - case QMetaType::Float: { - const float f = qvariant_cast<float>(c.value); - Q_ASSERT(sizeof(f) == c.size); - memcpy(dst, &f, sizeof(f)); - break; - } - case QMetaType::Double: { - const float f = float(qvariant_cast<double>(c.value)); - Q_ASSERT(sizeof(f) == c.size); - memcpy(dst, &f, sizeof(f)); - break; - } - case QMetaType::Int: { - const int i = c.value.toInt(); - Q_ASSERT(sizeof(i) == c.size); - memcpy(dst, &i, sizeof(i)); - break; - } - case QMetaType::Bool: { - const bool b = c.value.toBool(); - Q_ASSERT(sizeof(b) == c.size); - memcpy(dst, &b, sizeof(b)); - break; - } - case QMetaType::QTransform: { // float3x3 - const QTransform v = qvariant_cast<QTransform>(c.value); - const float m[3][3] = { - { float(v.m11()), float(v.m12()), float(v.m13()) }, - { float(v.m21()), float(v.m22()), float(v.m23()) }, - { float(v.m31()), float(v.m32()), float(v.m33()) } - }; - Q_ASSERT(sizeof(m) == c.size); - memcpy(dst, m[0], sizeof(m)); - break; - } - case QMetaType::QSize: - case QMetaType::QSizeF: { // float2 - const QSizeF v = c.value.toSizeF(); - const float f[2] = { float(v.width()), float(v.height()) }; - Q_ASSERT(sizeof(f) == c.size); - memcpy(dst, f, sizeof(f)); - break; - } - case QMetaType::QPoint: - case QMetaType::QPointF: { // float2 - const QPointF v = c.value.toPointF(); - const float f[2] = { float(v.x()), float(v.y()) }; - Q_ASSERT(sizeof(f) == c.size); - memcpy(dst, f, sizeof(f)); - break; - } - case QMetaType::QRect: - case QMetaType::QRectF: { // float4 - const QRectF v = c.value.toRectF(); - const float f[4] = { float(v.x()), float(v.y()), float(v.width()), float(v.height()) }; - Q_ASSERT(sizeof(f) == c.size); - memcpy(dst, f, sizeof(f)); - break; - } - case QMetaType::QVector2D: { // float2 - const QVector2D v = qvariant_cast<QVector2D>(c.value); - const float f[2] = { float(v.x()), float(v.y()) }; - Q_ASSERT(sizeof(f) == c.size); - memcpy(dst, f, sizeof(f)); - break; - } - case QMetaType::QVector3D: { // float3 - const QVector3D v = qvariant_cast<QVector3D>(c.value); - const float f[3] = { float(v.x()), float(v.y()), float(v.z()) }; - Q_ASSERT(sizeof(f) == c.size); - memcpy(dst, f, sizeof(f)); - break; - } - case QMetaType::QVector4D: { // float4 - const QVector4D v = qvariant_cast<QVector4D>(c.value); - const float f[4] = { float(v.x()), float(v.y()), float(v.z()), float(v.w()) }; - Q_ASSERT(sizeof(f) == c.size); - memcpy(dst, f, sizeof(f)); - break; - } - case QMetaType::QQuaternion: { // float4 - const QQuaternion v = qvariant_cast<QQuaternion>(c.value); - const float f[4] = { float(v.x()), float(v.y()), float(v.z()), float(v.scalar()) }; - Q_ASSERT(sizeof(f) == c.size); - memcpy(dst, f, sizeof(f)); - break; - } - case QMetaType::QMatrix4x4: { // float4x4 - const QMatrix4x4 v = qvariant_cast<QMatrix4x4>(c.value); - const int sz = 16 * sizeof(float); - Q_ASSERT(sz == c.size); - memcpy(dst, v.constData(), sz); - break; - } - default: - break; - } - } - } - - for (int i = 0; i < textureProviders.count(); ++i) { - QSGTextureProvider *tp = textureProviders[i]; - QSGD3D12TextureView &tv(pipelineState->shaders.rootSig.textureViews[i]); - if (tp) { - if (QSGTexture *t = tp->texture()) { - if (t->isAtlasTexture() && !geometryUsesTextureSubRect) { - QSGTexture *newTexture = t->removedFromAtlas(); - if (newTexture) - t = newTexture; - } - tv.filter = t->filtering() == QSGTexture::Linear - ? QSGD3D12TextureView::FilterLinear : QSGD3D12TextureView::FilterNearest; - tv.addressModeHoriz = t->horizontalWrapMode() == QSGTexture::ClampToEdge - ? QSGD3D12TextureView::AddressClamp : QSGD3D12TextureView::AddressWrap; - tv.addressModeVert = t->verticalWrapMode() == QSGTexture::ClampToEdge - ? QSGD3D12TextureView::AddressClamp : QSGD3D12TextureView::AddressWrap; - t->bind(); - continue; - } - } - if (!dummy) { - dummy = new QSGD3D12Texture(node->renderContext()->engine()); - QImage img(128, 128, QImage::Format_ARGB32_Premultiplied); - img.fill(0); - dummy->create(img, QSGRenderContext::CreateTexture_Alpha); - } - tv.filter = QSGD3D12TextureView::FilterNearest; - tv.addressModeHoriz = QSGD3D12TextureView::AddressWrap; - tv.addressModeVert = QSGD3D12TextureView::AddressWrap; - dummy->bind(); - } - - switch (cullMode) { - case QSGShaderEffectNode::FrontFaceCulling: - pipelineState->cullMode = QSGD3D12PipelineState::CullFront; - break; - case QSGShaderEffectNode::BackFaceCulling: - pipelineState->cullMode = QSGD3D12PipelineState::CullBack; - break; - default: - pipelineState->cullMode = QSGD3D12PipelineState::CullNone; - break; - } - - return r; -} - -void QSGD3D12ShaderEffectMaterial::updateTextureProviders(bool layoutChange) -{ - if (layoutChange) { - for (QSGTextureProvider *tp : textureProviders) { - if (tp) { - QObject::disconnect(tp, SIGNAL(textureChanged()), node, - SLOT(handleTextureChange())); - QObject::disconnect(tp, SIGNAL(destroyed(QObject*)), node, - SLOT(handleTextureProviderDestroyed(QObject*))); - } - } - - textureProviders.fill(nullptr, linker.textures.count()); - } - - for (auto it = linker.textures.constBegin(), itEnd = linker.textures.constEnd(); it != itEnd; ++it) { - const int bindPoint = it.key(); - // Now that the linker has merged the textures, we can switch over to a - // simple vector indexed by the binding point for textureProviders. - Q_ASSERT(bindPoint >= 0 && bindPoint < textureProviders.count()); - QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(it.value())); - QSGTextureProvider *newProvider = source && source->isTextureProvider() ? source->textureProvider() : nullptr; - QSGTextureProvider *&activeProvider(textureProviders[bindPoint]); - if (newProvider != activeProvider) { - if (activeProvider) { - QObject::disconnect(activeProvider, SIGNAL(textureChanged()), node, - SLOT(handleTextureChange())); - QObject::disconnect(activeProvider, SIGNAL(destroyed(QObject*)), node, - SLOT(handleTextureProviderDestroyed(QObject*))); - } - if (newProvider) { - Q_ASSERT_X(newProvider->thread() == QThread::currentThread(), - "QSGD3D12ShaderEffectMaterial::updateTextureProviders", - "Texture provider must belong to the rendering thread"); - QObject::connect(newProvider, SIGNAL(textureChanged()), node, SLOT(handleTextureChange())); - QObject::connect(newProvider, SIGNAL(destroyed(QObject*)), node, - SLOT(handleTextureProviderDestroyed(QObject*))); - } else { - const char *typeName = source ? source->metaObject()->className() : it.value().typeName(); - qWarning("ShaderEffect: Texture t%d is not assigned a valid texture provider (%s).", - bindPoint, typeName); - } - activeProvider = newProvider; - } - } -} - -QSGD3D12ShaderEffectNode::QSGD3D12ShaderEffectNode(QSGD3D12RenderContext *rc, QSGD3D12GuiThreadShaderEffectManager *mgr) - : QSGShaderEffectNode(mgr), - m_rc(rc), - m_mgr(mgr), - m_material(this) -{ - setFlag(UsePreprocess, true); - setMaterial(&m_material); -} - -QRectF QSGD3D12ShaderEffectNode::updateNormalizedTextureSubRect(bool supportsAtlasTextures) -{ - QRectF srcRect(0, 0, 1, 1); - bool geometryUsesTextureSubRect = false; - if (supportsAtlasTextures && m_material.textureProviders.count() == 1) { - QSGTextureProvider *provider = m_material.textureProviders.at(0); - if (provider->texture()) { - srcRect = provider->texture()->normalizedTextureSubRect(); - geometryUsesTextureSubRect = true; - } - } - - if (m_material.geometryUsesTextureSubRect != geometryUsesTextureSubRect) { - m_material.geometryUsesTextureSubRect = geometryUsesTextureSubRect; - markDirty(QSGNode::DirtyMaterial); - } - - return srcRect; -} - -void QSGD3D12ShaderEffectNode::syncMaterial(SyncData *syncData) -{ - if (Q_UNLIKELY(debug_shader())) - qDebug() << "shadereffect node sync" << syncData->dirty; - - if (bool(m_material.flags() & QSGMaterial::Blending) != syncData->blending) { - m_material.setFlag(QSGMaterial::Blending, syncData->blending); - markDirty(QSGNode::DirtyMaterial); - } - - if (m_material.cullMode != syncData->cullMode) { - m_material.cullMode = syncData->cullMode; - markDirty(QSGNode::DirtyMaterial); - } - - if (syncData->dirty & QSGShaderEffectNode::DirtyShaders) { - QByteArray vertBlob, fragBlob; - - m_material.hasCustomVertexShader = syncData->vertex.shader->hasShaderCode; - if (m_material.hasCustomVertexShader) { - vertBlob = syncData->vertex.shader->shaderInfo.blob; - } else { - vertBlob = QByteArray::fromRawData(reinterpret_cast<const char *>(g_VS_DefaultShaderEffect), - sizeof(g_VS_DefaultShaderEffect)); - } - - m_material.hasCustomFragmentShader = syncData->fragment.shader->hasShaderCode; - if (m_material.hasCustomFragmentShader) { - fragBlob = syncData->fragment.shader->shaderInfo.blob; - } else { - fragBlob = QByteArray::fromRawData(reinterpret_cast<const char *>(g_PS_DefaultShaderEffect), - sizeof(g_PS_DefaultShaderEffect)); - } - - m_material.mtype = shaderMaterialTypeCache()->get(vertBlob, fragBlob); - m_material.linker.reset(vertBlob, fragBlob); - - if (m_material.hasCustomVertexShader) { - m_material.linker.feedConstants(*syncData->vertex.shader); - } else { - QSGShaderEffectNode::ShaderData defaultSD; - defaultSD.shaderInfo.blob = vertBlob; - defaultSD.shaderInfo.type = QSGGuiThreadShaderEffectManager::ShaderInfo::TypeVertex; - - // { float4x4 qt_Matrix; float qt_Opacity; } where only the matrix is used - QSGGuiThreadShaderEffectManager::ShaderInfo::Variable v; - v.name = QByteArrayLiteral("qt_Matrix"); - v.offset = 0; - v.size = 16 * sizeof(float); - defaultSD.shaderInfo.variables.append(v); - QSGShaderEffectNode::VariableData vd; - vd.specialType = QSGShaderEffectNode::VariableData::Matrix; - defaultSD.varData.append(vd); - defaultSD.shaderInfo.constantDataSize = (16 + 1) * sizeof(float); - m_material.linker.feedConstants(defaultSD); - } - - m_material.linker.feedSamplers(*syncData->vertex.shader); - m_material.linker.feedTextures(*syncData->vertex.shader); - - if (m_material.hasCustomFragmentShader) { - m_material.linker.feedConstants(*syncData->fragment.shader); - } else { - QSGShaderEffectNode::ShaderData defaultSD; - defaultSD.shaderInfo.blob = fragBlob; - defaultSD.shaderInfo.type = QSGGuiThreadShaderEffectManager::ShaderInfo::TypeFragment; - - // { float4x4 qt_Matrix; float qt_Opacity; } where only the opacity is used - QSGGuiThreadShaderEffectManager::ShaderInfo::Variable v; - v.name = QByteArrayLiteral("qt_Opacity"); - v.offset = 16 * sizeof(float); - v.size = sizeof(float); - defaultSD.shaderInfo.variables.append(v); - QSGShaderEffectNode::VariableData vd; - vd.specialType = QSGShaderEffectNode::VariableData::Opacity; - defaultSD.varData.append(vd); - - v.name = QByteArrayLiteral("source"); - v.bindPoint = 0; - v.type = QSGGuiThreadShaderEffectManager::ShaderInfo::Texture; - defaultSD.shaderInfo.variables.append(v); - vd.specialType = QSGShaderEffectNode::VariableData::Source; - defaultSD.varData.append(vd); - - v.name = QByteArrayLiteral("sourceSampler"); - v.bindPoint = 0; - v.type = QSGGuiThreadShaderEffectManager::ShaderInfo::Sampler; - defaultSD.shaderInfo.variables.append(v); - vd.specialType = QSGShaderEffectNode::VariableData::Unused; - defaultSD.varData.append(vd); - - defaultSD.shaderInfo.constantDataSize = (16 + 1) * sizeof(float); - - m_material.linker.feedConstants(defaultSD); - m_material.linker.feedSamplers(defaultSD); - m_material.linker.feedTextures(defaultSD); - } - - // While this may seem unnecessary for the built-in shaders, the value - // of 'source' is still in there and we have to process it. - m_material.linker.feedSamplers(*syncData->fragment.shader); - m_material.linker.feedTextures(*syncData->fragment.shader); - - m_material.linker.linkTextureSubRects(); - - m_material.updateTextureProviders(true); - - markDirty(QSGNode::DirtyMaterial); - - if (Q_UNLIKELY(debug_shader())) - m_material.linker.dump(); - } else { - if (syncData->dirty & QSGShaderEffectNode::DirtyShaderConstant) { - if (!syncData->vertex.dirtyConstants->isEmpty()) - m_material.linker.feedConstants(*syncData->vertex.shader, syncData->vertex.dirtyConstants); - if (!syncData->fragment.dirtyConstants->isEmpty()) - m_material.linker.feedConstants(*syncData->fragment.shader, syncData->fragment.dirtyConstants); - markDirty(QSGNode::DirtyMaterial); - if (Q_UNLIKELY(debug_shader())) - m_material.linker.dump(); - } - - if (syncData->dirty & QSGShaderEffectNode::DirtyShaderTexture) { - if (!syncData->vertex.dirtyTextures->isEmpty()) - m_material.linker.feedTextures(*syncData->vertex.shader, syncData->vertex.dirtyTextures); - if (!syncData->fragment.dirtyTextures->isEmpty()) - m_material.linker.feedTextures(*syncData->fragment.shader, syncData->fragment.dirtyTextures); - m_material.linker.linkTextureSubRects(); - m_material.updateTextureProviders(false); - markDirty(QSGNode::DirtyMaterial); - if (Q_UNLIKELY(debug_shader())) - m_material.linker.dump(); - } - } - - if (bool(m_material.flags() & QSGMaterial::RequiresFullMatrix) != m_material.hasCustomVertexShader) { - m_material.setFlag(QSGMaterial::RequiresFullMatrix, m_material.hasCustomVertexShader); - markDirty(QSGNode::DirtyMaterial); - } -} - -void QSGD3D12ShaderEffectNode::handleTextureChange() -{ - markDirty(QSGNode::DirtyMaterial); - emit m_mgr->textureChanged(); -} - -void QSGD3D12ShaderEffectNode::handleTextureProviderDestroyed(QObject *object) -{ - for (QSGTextureProvider *&tp : m_material.textureProviders) { - if (tp == object) - tp = nullptr; - } -} - -void QSGD3D12ShaderEffectNode::preprocess() -{ - for (QSGTextureProvider *tp : m_material.textureProviders) { - if (tp) { - if (QSGDynamicTexture *texture = qobject_cast<QSGDynamicTexture *>(tp->texture())) - texture->updateTexture(); - } - } -} - -bool QSGD3D12GuiThreadShaderEffectManager::hasSeparateSamplerAndTextureObjects() const -{ - return true; -} - -QString QSGD3D12GuiThreadShaderEffectManager::log() const -{ - return m_log; -} - -QSGGuiThreadShaderEffectManager::Status QSGD3D12GuiThreadShaderEffectManager::status() const -{ - return m_status; -} - -struct RefGuard { - RefGuard(IUnknown *p) : p(p) { } - ~RefGuard() { p->Release(); } - IUnknown *p; -}; - -class QSGD3D12ShaderCompileTask : public QRunnable -{ -public: - QSGD3D12ShaderCompileTask(QSGD3D12GuiThreadShaderEffectManager *mgr, - QSGD3D12GuiThreadShaderEffectManager::ShaderInfo::Type typeHint, - const QByteArray &src, - QSGD3D12GuiThreadShaderEffectManager::ShaderInfo *result) - : mgr(mgr), typeHint(typeHint), src(src), result(result) { } - - void run() override; - -private: - QSGD3D12GuiThreadShaderEffectManager *mgr; - QSGD3D12GuiThreadShaderEffectManager::ShaderInfo::Type typeHint; - QByteArray src; - QSGD3D12GuiThreadShaderEffectManager::ShaderInfo *result; -}; - -void QSGD3D12ShaderCompileTask::run() -{ - const char *target = typeHint == QSGD3D12GuiThreadShaderEffectManager::ShaderInfo::TypeVertex ? "vs_5_0" : "ps_5_0"; - ID3DBlob *bytecode = nullptr; - ID3DBlob *errors = nullptr; - HRESULT hr = D3DCompile(src.constData(), src.size(), nullptr, nullptr, nullptr, - "main", target, 0, 0, &bytecode, &errors); - if (FAILED(hr) || !bytecode) { - qWarning("HLSL shader compilation failed: 0x%x", hr); - if (errors) { - mgr->m_log += QString::fromUtf8(static_cast<const char *>(errors->GetBufferPointer()), errors->GetBufferSize()); - errors->Release(); - } - mgr->m_status = QSGGuiThreadShaderEffectManager::Error; - emit mgr->shaderCodePrepared(false, typeHint, src, result); - emit mgr->logAndStatusChanged(); - return; - } - - result->blob.resize(bytecode->GetBufferSize()); - memcpy(result->blob.data(), bytecode->GetBufferPointer(), result->blob.size()); - bytecode->Release(); - - const bool ok = mgr->reflect(result); - mgr->m_status = ok ? QSGGuiThreadShaderEffectManager::Compiled : QSGGuiThreadShaderEffectManager::Error; - emit mgr->shaderCodePrepared(ok, typeHint, src, result); - emit mgr->logAndStatusChanged(); -} - -static const int BYTECODE_MAGIC = 0x43425844; // 'DXBC' - -void QSGD3D12GuiThreadShaderEffectManager::prepareShaderCode(ShaderInfo::Type typeHint, const QByteArray &src, ShaderInfo *result) -{ - // The D3D12 backend's ShaderEffect implementation supports both HLSL - // source strings and bytecode or source in files as input. Bytecode is - // strongly recommended, but in order to make ShaderEffect users' (and - // anything that stiches shader strings together dynamically, e.g. - // qtgraphicaleffects) life easier, and since we link to d3dcompiler - // anyways, compiling from source is also supported. - - QByteArray shaderSourceCode = src; - QUrl srcUrl(QString::fromUtf8(src)); - if (!srcUrl.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) || srcUrl.isLocalFile()) { - if (!m_fileSelector) { - m_fileSelector = new QFileSelector(this); - m_fileSelector->setExtraSelectors(QStringList() << QStringLiteral("hlsl")); - } - const QString fn = m_fileSelector->select(QQmlFile::urlToLocalFileOrQrc(srcUrl)); - QFile f(fn); - if (!f.open(QIODevice::ReadOnly)) { - qWarning("ShaderEffect: Failed to read %s", qPrintable(fn)); - emit shaderCodePrepared(false, typeHint, src, result); - return; - } - QByteArray blob = f.readAll(); - f.close(); - if (blob.size() > 4) { - const quint32 *p = reinterpret_cast<const quint32 *>(blob.constData()); - if (*p == BYTECODE_MAGIC) { - // already compiled D3D bytecode, skip straight to reflection - result->blob = blob; - const bool ok = reflect(result); - m_status = ok ? Compiled : Error; - emit shaderCodePrepared(ok, typeHint, src, result); - emit logAndStatusChanged(); - return; - } - // assume the file contained HLSL source code - shaderSourceCode = blob; - } - } - - QThreadPool::globalInstance()->start(new QSGD3D12ShaderCompileTask(this, typeHint, shaderSourceCode, result)); -} - -bool QSGD3D12GuiThreadShaderEffectManager::reflect(ShaderInfo *result) -{ - ID3D12ShaderReflection *reflector; - HRESULT hr = D3DReflect(result->blob.constData(), result->blob.size(), IID_PPV_ARGS(&reflector)); - if (FAILED(hr)) { - qWarning("D3D shader reflection failed: 0x%x", hr); - return false; - } - RefGuard rg(reflector); - - D3D12_SHADER_DESC shaderDesc; - reflector->GetDesc(&shaderDesc); - - const uint progType = (shaderDesc.Version & 0xFFFF0000) >> 16; - const uint major = (shaderDesc.Version & 0x000000F0) >> 4; - const uint minor = (shaderDesc.Version & 0x0000000F); - - switch (progType) { - case D3D12_SHVER_VERTEX_SHADER: - result->type = ShaderInfo::TypeVertex; - break; - case D3D12_SHVER_PIXEL_SHADER: - result->type = ShaderInfo::TypeFragment; - break; - default: - result->type = ShaderInfo::TypeOther; - qWarning("D3D shader is of unknown type 0x%x", shaderDesc.Version); - return false; - } - - if (major < 5) { - qWarning("D3D shader model version %u.%u is too low", major, minor); - return false; - } - - const int ieCount = shaderDesc.InputParameters; - const int cbufferCount = shaderDesc.ConstantBuffers; - const int boundResCount = shaderDesc.BoundResources; - - result->constantDataSize = 0; - - if (ieCount < 1) { - qWarning("Invalid shader: Not enough input parameters (%d)", ieCount); - return false; - } - if (cbufferCount < 1) { - qWarning("Invalid shader: Shader has no constant buffers"); - return false; - } - if (boundResCount < 1) { - qWarning("Invalid shader: No resources bound. Expected to have at least a constant buffer bound."); - return false; - } - - if (Q_UNLIKELY(debug_shader())) - qDebug("Shader reflection size %d type %d v%u.%u input elems %d cbuffers %d boundres %d", - result->blob.size(), result->type, major, minor, ieCount, cbufferCount, boundResCount); - - for (int i = 0; i < boundResCount; ++i) { - D3D12_SHADER_INPUT_BIND_DESC desc; - if (FAILED(reflector->GetResourceBindingDesc(i, &desc))) { - qWarning("D3D reflection: Failed to query resource binding %d", i); - continue; - } - bool gotCBuffer = false; - if (desc.Type == D3D_SIT_CBUFFER) { - ID3D12ShaderReflectionConstantBuffer *cbuf = reflector->GetConstantBufferByName(desc.Name); - D3D12_SHADER_BUFFER_DESC bufDesc; - if (FAILED(cbuf->GetDesc(&bufDesc))) { - qWarning("D3D reflection: Failed to query constant buffer description"); - continue; - } - if (gotCBuffer) { - qWarning("D3D reflection: Found more than one constant buffers. Only the first one is used."); - continue; - } - gotCBuffer = true; - result->constantDataSize = bufDesc.Size; - for (uint cbIdx = 0; cbIdx < bufDesc.Variables; ++cbIdx) { - ID3D12ShaderReflectionVariable *cvar = cbuf->GetVariableByIndex(cbIdx); - D3D12_SHADER_VARIABLE_DESC varDesc; - if (FAILED(cvar->GetDesc(&varDesc))) { - qWarning("D3D reflection: Failed to query constant buffer variable %d", cbIdx); - return false; - } - // we report the full size of the buffer but only return variables that are actually used by this shader - if (!(varDesc.uFlags & D3D_SVF_USED)) - continue; - ShaderInfo::Variable v; - v.type = ShaderInfo::Constant; - v.name = QByteArray(varDesc.Name); - v.offset = varDesc.StartOffset; - v.size = varDesc.Size; - result->variables.append(v); - } - } else if (desc.Type == D3D_SIT_TEXTURE) { - if (desc.Dimension != D3D_SRV_DIMENSION_TEXTURE2D) { - qWarning("D3D reflection: Texture %s is not a 2D texture, ignoring.", qPrintable(desc.Name)); - continue; - } - if (desc.NumSamples != (UINT) -1) { - qWarning("D3D reflection: Texture %s is multisample (%u), ignoring.", qPrintable(desc.Name), desc.NumSamples); - continue; - } - if (desc.BindCount != 1) { - qWarning("D3D reflection: Texture %s is an array, ignoring.", qPrintable(desc.Name)); - continue; - } - if (desc.Space != 0) { - qWarning("D3D reflection: Texture %s is not using register space 0, ignoring.", qPrintable(desc.Name)); - continue; - } - ShaderInfo::Variable v; - v.type = ShaderInfo::Texture; - v.name = QByteArray(desc.Name); - v.bindPoint = desc.BindPoint; - result->variables.append(v); - } else if (desc.Type == D3D_SIT_SAMPLER) { - if (desc.BindCount != 1) { - qWarning("D3D reflection: Sampler %s is an array, ignoring.", qPrintable(desc.Name)); - continue; - } - if (desc.Space != 0) { - qWarning("D3D reflection: Sampler %s is not using register space 0, ignoring.", qPrintable(desc.Name)); - continue; - } - ShaderInfo::Variable v; - v.type = ShaderInfo::Sampler; - v.name = QByteArray(desc.Name); - v.bindPoint = desc.BindPoint; - result->variables.append(v); - } else { - qWarning("D3D reflection: Resource binding %d has an unknown type of %d and will be ignored.", i, desc.Type); - continue; - } - } - - if (Q_UNLIKELY(debug_shader())) - qDebug() << "Variables:" << result->variables << "cbuffer size" << result->constantDataSize; - - return true; -} - -QT_END_NAMESPACE diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode_p.h deleted file mode 100644 index dec85fd782..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode_p.h +++ /dev/null @@ -1,176 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSGD3D12SHADEREFFECTNODE_P_H -#define QSGD3D12SHADEREFFECTNODE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qsgadaptationlayer_p.h> -#include "qsgd3d12material_p.h" - -QT_BEGIN_NAMESPACE - -class QSGD3D12RenderContext; -class QSGD3D12GuiThreadShaderEffectManager; -class QSGD3D12ShaderEffectNode; -class QSGD3D12Texture; -class QFileSelector; - -class QSGD3D12ShaderLinker -{ -public: - void reset(const QByteArray &vertBlob, const QByteArray &fragBlob); - - void feedConstants(const QSGShaderEffectNode::ShaderData &shader, const QSet<int> *dirtyIndices = nullptr); - void feedSamplers(const QSGShaderEffectNode::ShaderData &shader); - void feedTextures(const QSGShaderEffectNode::ShaderData &shader, const QSet<int> *dirtyIndices = nullptr); - void linkTextureSubRects(); - - void dump(); - - struct Constant { - uint size; - QSGShaderEffectNode::VariableData::SpecialType specialType; - QVariant value; - bool operator==(const Constant &other) const { - return size == other.size && specialType == other.specialType - && (specialType == QSGShaderEffectNode::VariableData::None ? value == other.value : true); - } - }; - - bool error; - QByteArray vs; - QByteArray fs; - uint constantBufferSize; - QHash<uint, Constant> constants; // offset -> Constant - QSet<int> samplers; // bindpoint - QHash<int, QVariant> textures; // bindpoint -> value (source ref) - QHash<QByteArray, int> textureNameMap; // name -> bindpoint -}; - -QDebug operator<<(QDebug debug, const QSGD3D12ShaderLinker::Constant &c); - -class QSGD3D12ShaderEffectMaterial : public QSGD3D12Material -{ -public: - QSGD3D12ShaderEffectMaterial(QSGD3D12ShaderEffectNode *node); - ~QSGD3D12ShaderEffectMaterial(); - - QSGMaterialType *type() const override; - int compare(const QSGMaterial *other) const override; - - int constantBufferSize() const override; - void preparePipeline(QSGD3D12PipelineState *pipelineState) override; - UpdateResults updatePipeline(const QSGD3D12MaterialRenderState &state, - QSGD3D12PipelineState *pipelineState, - ExtraState *extraState, - quint8 *constantBuffer) override; - - void updateTextureProviders(bool layoutChange); - - QSGD3D12ShaderEffectNode *node; - bool valid = false; - QSGShaderEffectNode::CullMode cullMode = QSGShaderEffectNode::NoCulling; - bool hasCustomVertexShader = false; - bool hasCustomFragmentShader = false; - QSGD3D12ShaderLinker linker; - QSGMaterialType *mtype = nullptr; - QVector<QSGTextureProvider *> textureProviders; - QSGD3D12Texture *dummy = nullptr; - bool geometryUsesTextureSubRect = false; -}; - -class QSGD3D12ShaderEffectNode : public QObject, public QSGShaderEffectNode -{ - Q_OBJECT - -public: - QSGD3D12ShaderEffectNode(QSGD3D12RenderContext *rc, QSGD3D12GuiThreadShaderEffectManager *mgr); - - QRectF updateNormalizedTextureSubRect(bool supportsAtlasTextures) override; - void syncMaterial(SyncData *syncData) override; - - static void cleanupMaterialTypeCache(); - - void preprocess() override; - - QSGD3D12RenderContext *renderContext() { return m_rc; } - -private Q_SLOTS: - void handleTextureChange(); - void handleTextureProviderDestroyed(QObject *object); - -private: - QSGD3D12RenderContext *m_rc; - QSGD3D12GuiThreadShaderEffectManager *m_mgr; - QSGD3D12ShaderEffectMaterial m_material; -}; - -class QSGD3D12GuiThreadShaderEffectManager : public QSGGuiThreadShaderEffectManager -{ -public: - bool hasSeparateSamplerAndTextureObjects() const override; - - QString log() const override; - Status status() const override; - - void prepareShaderCode(ShaderInfo::Type typeHint, const QByteArray &src, ShaderInfo *result) override; - -private: - bool reflect(ShaderInfo *result); - QString m_log; - Status m_status = Uncompiled; - QFileSelector *m_fileSelector = nullptr; - - friend class QSGD3D12ShaderCompileTask; -}; - -QT_END_NAMESPACE - -#endif // QSGD3D12SHADEREFFECTNODE_P_H diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12spritenode.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12spritenode.cpp deleted file mode 100644 index 807fbcdcec..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12spritenode.cpp +++ /dev/null @@ -1,314 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsgd3d12spritenode_p.h" -#include "qsgd3d12material_p.h" - -#include "vs_sprite.hlslh" -#include "ps_sprite.hlslh" - -QT_BEGIN_NAMESPACE - -struct SpriteVertex -{ - float x; - float y; - float tx; - float ty; -}; - -struct SpriteVertices -{ - SpriteVertex v1; - SpriteVertex v2; - SpriteVertex v3; - SpriteVertex v4; -}; - -class QSGD3D12SpriteMaterial : public QSGD3D12Material -{ -public: - QSGD3D12SpriteMaterial(); - ~QSGD3D12SpriteMaterial(); - - QSGMaterialType *type() const override { static QSGMaterialType type; return &type; } - - int compare(const QSGMaterial *other) const override - { - return this - static_cast<const QSGD3D12SpriteMaterial *>(other); - } - - int constantBufferSize() const override; - void preparePipeline(QSGD3D12PipelineState *pipelineState) override; - UpdateResults updatePipeline(const QSGD3D12MaterialRenderState &state, - QSGD3D12PipelineState *pipelineState, - ExtraState *extraState, - quint8 *constantBuffer) override; - - QSGTexture *texture; - - float animT; - float animX1; - float animY1; - float animX2; - float animY2; - float animW; - float animH; -}; - -QSGD3D12SpriteMaterial::QSGD3D12SpriteMaterial() - : texture(nullptr), - animT(0.0f), - animX1(0.0f), - animY1(0.0f), - animX2(0.0f), - animY2(0.0f), - animW(1.0f), - animH(1.0f) -{ - setFlag(Blending, true); -} - -QSGD3D12SpriteMaterial::~QSGD3D12SpriteMaterial() -{ - delete texture; -} - -static const int SPRITE_CB_SIZE_0 = 16 * sizeof(float); // float4x4 -static const int SPRITE_CB_SIZE_1 = 4 * sizeof(float); // float4 -static const int SPRITE_CB_SIZE_2 = 3 * sizeof(float); // float3 -static const int SPRITE_CB_SIZE_3 = sizeof(float); // float -static const int SPRITE_CB_SIZE = SPRITE_CB_SIZE_0 + SPRITE_CB_SIZE_1 + SPRITE_CB_SIZE_2 + SPRITE_CB_SIZE_3; - -int QSGD3D12SpriteMaterial::constantBufferSize() const -{ - return QSGD3D12Engine::alignedConstantBufferSize(SPRITE_CB_SIZE); -} - -void QSGD3D12SpriteMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState) -{ - pipelineState->shaders.vs = g_VS_Sprite; - pipelineState->shaders.vsSize = sizeof(g_VS_Sprite); - pipelineState->shaders.ps = g_PS_Sprite; - pipelineState->shaders.psSize = sizeof(g_PS_Sprite); - - pipelineState->shaders.rootSig.textureViewCount = 1; -} - -QSGD3D12Material::UpdateResults QSGD3D12SpriteMaterial::updatePipeline(const QSGD3D12MaterialRenderState &state, - QSGD3D12PipelineState *, - ExtraState *, - quint8 *constantBuffer) -{ - QSGD3D12Material::UpdateResults r = UpdatedConstantBuffer; - quint8 *p = constantBuffer; - - if (state.isMatrixDirty()) - memcpy(p, state.combinedMatrix().constData(), SPRITE_CB_SIZE_0); - p += SPRITE_CB_SIZE_0; - - { - const float v[] = { animX1, animY1, animX2, animY2 }; - memcpy(p, v, SPRITE_CB_SIZE_1); - } - p += SPRITE_CB_SIZE_1; - - { - const float v[] = { animW, animH, animT }; - memcpy(p, v, SPRITE_CB_SIZE_2); - } - p += SPRITE_CB_SIZE_2; - - if (state.isOpacityDirty()) { - const float opacity = state.opacity(); - memcpy(p, &opacity, SPRITE_CB_SIZE_3); - } - - texture->bind(); - - return r; -} - -static QSGGeometry::Attribute Sprite_Attributes[] = { - QSGGeometry::Attribute::createWithAttributeType(0, 2, QSGGeometry::FloatType, QSGGeometry::PositionAttribute), - QSGGeometry::Attribute::createWithAttributeType(1, 2, QSGGeometry::FloatType, QSGGeometry::TexCoordAttribute), -}; - -static QSGGeometry::AttributeSet Sprite_AttributeSet = { 2, 4 * sizeof(float), Sprite_Attributes }; - -QSGD3D12SpriteNode::QSGD3D12SpriteNode() - : m_material(new QSGD3D12SpriteMaterial) - , m_geometryDirty(true) - , m_sheetSize(QSize(64, 64)) -{ - m_geometry = new QSGGeometry(Sprite_AttributeSet, 4, 6); - m_geometry->setDrawingMode(QSGGeometry::DrawTriangles); - - quint16 *indices = m_geometry->indexDataAsUShort(); - indices[0] = 0; - indices[1] = 1; - indices[2] = 2; - indices[3] = 1; - indices[4] = 3; - indices[5] = 2; - - setGeometry(m_geometry); - setMaterial(m_material); - setFlag(OwnsGeometry, true); - setFlag(OwnsMaterial, true); -} - -void QSGD3D12SpriteNode::setTexture(QSGTexture *texture) -{ - m_material->texture = texture; - m_geometryDirty = true; - markDirty(DirtyMaterial); -} - -void QSGD3D12SpriteNode::setTime(float time) -{ - m_material->animT = time; - markDirty(DirtyMaterial); -} - -void QSGD3D12SpriteNode::setSourceA(const QPoint &source) -{ - if (m_sourceA != source) { - m_sourceA = source; - m_material->animX1 = static_cast<float>(source.x()) / m_sheetSize.width(); - m_material->animY1 = static_cast<float>(source.y()) / m_sheetSize.height(); - markDirty(DirtyMaterial); - } -} - -void QSGD3D12SpriteNode::setSourceB(const QPoint &source) -{ - if (m_sourceB != source) { - m_sourceB = source; - m_material->animX2 = static_cast<float>(source.x()) / m_sheetSize.width(); - m_material->animY2 = static_cast<float>(source.y()) / m_sheetSize.height(); - markDirty(DirtyMaterial); - } -} - -void QSGD3D12SpriteNode::setSpriteSize(const QSize &size) -{ - if (m_spriteSize != size) { - m_spriteSize = size; - m_material->animW = static_cast<float>(size.width()) / m_sheetSize.width(); - m_material->animH = static_cast<float>(size.height()) / m_sheetSize.height(); - markDirty(DirtyMaterial); - } -} - -void QSGD3D12SpriteNode::setSheetSize(const QSize &size) -{ - if (m_sheetSize != size) { - m_sheetSize = size; - - // Update all dependent properties - m_material->animX1 = static_cast<float>(m_sourceA.x()) / m_sheetSize.width(); - m_material->animY1 = static_cast<float>(m_sourceA.y()) / m_sheetSize.height(); - m_material->animX2 = static_cast<float>(m_sourceB.x()) / m_sheetSize.width(); - m_material->animY2 = static_cast<float>(m_sourceB.y()) / m_sheetSize.height(); - m_material->animW = static_cast<float>(m_spriteSize.width()) / m_sheetSize.width(); - m_material->animH = static_cast<float>(m_spriteSize.height()) / m_sheetSize.height(); - - markDirty(DirtyMaterial); - } -} - -void QSGD3D12SpriteNode::setSize(const QSizeF &size) -{ - if (m_size != size) { - m_size = size; - m_geometryDirty = true; - } -} - -void QSGD3D12SpriteNode::setFiltering(QSGTexture::Filtering filtering) -{ - m_material->texture->setFiltering(filtering); - markDirty(DirtyMaterial); -} - -void QSGD3D12SpriteNode::update() -{ - if (m_geometryDirty) { - m_geometryDirty = false; - updateGeometry(); - } -} - -void QSGD3D12SpriteNode::updateGeometry() -{ - if (!m_material->texture) - return; - - SpriteVertices *p = static_cast<SpriteVertices *>(m_geometry->vertexData()); - const QRectF texRect = m_material->texture->normalizedTextureSubRect(); - - p->v1.tx = texRect.topLeft().x(); - p->v1.ty = texRect.topLeft().y(); - - p->v2.tx = texRect.topRight().x(); - p->v2.ty = texRect.topRight().y(); - - p->v3.tx = texRect.bottomLeft().x(); - p->v3.ty = texRect.bottomLeft().y(); - - p->v4.tx = texRect.bottomRight().x(); - p->v4.ty = texRect.bottomRight().y(); - - p->v1.x = 0; - p->v1.y = 0; - - p->v2.x = m_size.width(); - p->v2.y = 0; - - p->v3.x = 0; - p->v3.y = m_size.height(); - - p->v4.x = m_size.width(); - p->v4.y = m_size.height(); - - markDirty(DirtyGeometry); -} - -QT_END_NAMESPACE diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12spritenode_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12spritenode_p.h deleted file mode 100644 index 265bec7c78..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12spritenode_p.h +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSGD3D12SPRITENODE_H -#define QSGD3D12SPRITENODE_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qsgadaptationlayer_p.h> - -QT_BEGIN_NAMESPACE - -class QSGD3D12SpriteMaterial; - -class QSGD3D12SpriteNode : public QSGSpriteNode -{ -public: - QSGD3D12SpriteNode(); - - void setTexture(QSGTexture *texture) override; - void setTime(float time) override; - void setSourceA(const QPoint &source) override; - void setSourceB(const QPoint &source) override; - void setSpriteSize(const QSize &size) override; - void setSheetSize(const QSize &size) override; - void setSize(const QSizeF &size) override; - void setFiltering(QSGTexture::Filtering filtering) override; - void update() override; - -private: - void updateGeometry(); - - QSGD3D12SpriteMaterial *m_material; - QSGGeometry *m_geometry; - bool m_geometryDirty; - QPoint m_sourceA; - QPoint m_sourceB; - QSize m_spriteSize; - QSize m_sheetSize; - QSizeF m_size; -}; - -QT_END_NAMESPACE - -#endif // QSGD3D12SPRITENODE_H diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12texture.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12texture.cpp deleted file mode 100644 index b49b851c23..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12texture.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsgd3d12texture_p.h" -#include "qsgd3d12engine_p.h" -#include <private/qsgcontext_p.h> - -QT_BEGIN_NAMESPACE - -#define RETAIN_IMAGE - -void QSGD3D12Texture::create(const QImage &image, uint flags) -{ - // ### atlas? - - const bool alphaRequest = flags & QSGRenderContext::CreateTexture_Alpha; - m_alphaWanted = alphaRequest && image.hasAlphaChannel(); - - // The engine maps 8-bit formats to R8. This is fine for glyphs and such - // but may not be what apps expect for ordinary image data. The OpenGL - // implementation maps these to ARGB32_Pre so let's follow suit. - if (image.depth() != 8) - m_image = image; - else - m_image = image.convertToFormat(m_alphaWanted ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32); - - m_id = m_engine->genTexture(); - Q_ASSERT(m_id); - - // We could kick off the texture creation and the async upload right here. - // Unfortunately we cannot tell at this stage if mipmaps will be enabled - // via an Image element's mipmap property...so defer to bind(). - m_createPending = true; -} - -QSGD3D12Texture::QSGD3D12Texture(QSGD3D12Engine *engine) - : QSGTexture(*(new QSGD3D12TexturePrivate)), - m_engine(engine) -{ -} - -QSGD3D12Texture::~QSGD3D12Texture() -{ - if (m_id) - m_engine->releaseTexture(m_id); -} - -int QSGD3D12Texture::textureId() const -{ - return m_id; -} - -int QSGD3D12TexturePrivate::comparisonKey() const -{ - Q_Q(const QSGD3D12Texture); - return q->m_id; -} - -QSize QSGD3D12Texture::textureSize() const -{ - return m_image.size(); -} - -bool QSGD3D12Texture::hasAlphaChannel() const -{ - return m_alphaWanted; -} - -bool QSGD3D12Texture::hasMipmaps() const -{ - return mipmapFiltering() != QSGTexture::None; -} - -QRectF QSGD3D12Texture::normalizedTextureSubRect() const -{ - return QRectF(0, 0, 1, 1); -} - -void QSGD3D12Texture::bind() -{ - // Called when the texture material updates the pipeline state. - - if (!m_createPending && hasMipmaps() != m_createdWithMipMaps) { -#ifdef RETAIN_IMAGE - m_engine->releaseTexture(m_id); - m_id = m_engine->genTexture(); - Q_ASSERT(m_id); - m_createPending = true; -#else - // ### this can be made working some day (something similar to - // queueTextureResize) but skip for now - qWarning("D3D12: mipmap property cannot be changed once the texture is created"); -#endif - } - - if (m_createPending) { - m_createPending = false; - - QSGD3D12Engine::TextureCreateFlags createFlags = 0; - if (m_alphaWanted) - createFlags |= QSGD3D12Engine::TextureWithAlpha; - - m_createdWithMipMaps = hasMipmaps(); - if (m_createdWithMipMaps) - createFlags |= QSGD3D12Engine::TextureWithMipMaps; - - m_engine->createTexture(m_id, m_image.size(), m_image.format(), createFlags); - m_engine->queueTextureUpload(m_id, m_image); - -#ifndef RETAIN_IMAGE - m_image = QImage(); -#endif - } - - // Here we know that the texture is going to be used in the current frame - // by the next draw call. Notify the engine so that it can wait for - // possible pending uploads and set up the pipeline accordingly. - m_engine->useTexture(m_id); -} - -QT_END_NAMESPACE diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12texture_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12texture_p.h deleted file mode 100644 index f6a5257773..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12texture_p.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSGD3D12TEXTURE_P_H -#define QSGD3D12TEXTURE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qsgtexture_p.h> -#include <basetsd.h> - -QT_BEGIN_NAMESPACE - -class QSGD3D12Engine; -class QSGD3D12TexturePrivate; - -class QSGD3D12Texture : public QSGTexture -{ - Q_DECLARE_PRIVATE(QSGD3D12Texture) -public: - QSGD3D12Texture(QSGD3D12Engine *engine); - ~QSGD3D12Texture(); - - void create(const QImage &image, uint flags); - - int textureId() const override; - QSize textureSize() const override; - bool hasAlphaChannel() const override; - bool hasMipmaps() const override; - QRectF normalizedTextureSubRect() const override; - void bind() override; - -protected: - QSGD3D12Engine *m_engine; - QImage m_image; - bool m_createPending = false; - bool m_createdWithMipMaps = false; - uint m_id = 0; - bool m_alphaWanted = false; -}; - -class QSGD3D12TexturePrivate : public QSGTexturePrivate -{ - Q_DECLARE_PUBLIC(QSGD3D12Texture) -public: - int comparisonKey() const override; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp deleted file mode 100644 index 91a35627ea..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp +++ /dev/null @@ -1,1208 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsgd3d12threadedrenderloop_p.h" -#include "qsgd3d12engine_p.h" -#include "qsgd3d12context_p.h" -#include "qsgd3d12rendercontext_p.h" -#include "qsgd3d12shadereffectnode_p.h" -#include <private/qsgrenderer_p.h> -#include <private/qquickwindow_p.h> -#include <private/qquickanimatorcontroller_p.h> -#include <private/qquickprofiler_p.h> -#include <private/qqmldebugserviceinterfaces_p.h> -#include <private/qqmldebugconnector_p.h> -#include <QElapsedTimer> -#include <QQueue> -#include <QGuiApplication> - -#include <qtquick_tracepoints_p.h> - -QT_BEGIN_NAMESPACE - -// NOTE: Avoid categorized logging. It is slow. - -#define DECLARE_DEBUG_VAR(variable) \ - static bool debug_ ## variable() \ - { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; } - -DECLARE_DEBUG_VAR(loop) -DECLARE_DEBUG_VAR(time) - - -// NOTE: The threaded renderloop is not currently safe to use in practice as it -// is prone to deadlocks, in particular when multiple windows are active. This -// is because DXGI's limitation of relying on the gui message pump in certain -// cases. See -// https://msdn.microsoft.com/en-us/library/windows/desktop/ee417025(v=vs.85).aspx#multithreading_and_dxgi -// -// This means that if swap chain functions like create, release, and -// potentially even Present, are called outside the gui thread, then the -// application must ensure the gui thread does not ever block and wait for the -// render thread - since on the render thread a DXGI call may be in turn -// waiting for the gui thread to deliver a window message... -// -// Ensuring this is impossible with the current design where the gui thread -// must block at certain points, waiting for the render thread. Qt moves out -// rendering from the main thread, in order to make application's life easier, -// whereas the typical DXGI-compatible model would require moving work, but not -// windowing and presenting, out to additional threads. - - -/* - The D3D render loop mostly mirrors the threaded OpenGL render loop. - - There are two classes here. QSGD3D12ThreadedRenderLoop and - QSGD3D12RenderThread. All communication between the two is based on event - passing and we have a number of custom events. - - Render loop is per process, render thread is per window. The - QSGD3D12RenderContext and QSGD3D12Engine are per window as well. The former - is created (but not owned) by QQuickWindow. The D3D device is per process. - - In this implementation, the render thread is never blocked and the GUI - thread will initiate a polishAndSync which will block and wait for the - render thread to pick it up and release the block only after the render - thread is done syncing. The reason for this is: - - 1. Clear blocking paradigm. We only have one real "block" point - (polishAndSync()) and all blocking is initiated by GUI and picked up by - Render at specific times based on events. This makes the execution - deterministic. - - 2. Render does not have to interact with GUI. This is done so that the - render thread can run its own animation system which stays alive even when - the GUI thread is blocked doing I/O, object instantiation, QPainter-painting - or any other non-trivial task. - - The render thread has affinity to the GUI thread until a window is shown. - From that moment and until the window is destroyed, it will have affinity to - the render thread. (moved back at the end of run for cleanup). - */ - -// Passed from the RL to the RT when a window is removed obscured and should be -// removed from the render loop. -const QEvent::Type WM_Obscure = QEvent::Type(QEvent::User + 1); - -// Passed from the RL to RT when GUI has been locked, waiting for sync. -const QEvent::Type WM_RequestSync = QEvent::Type(QEvent::User + 2); - -// Passed by the RL to the RT to maybe release resource if no windows are -// rendering. -const QEvent::Type WM_TryRelease = QEvent::Type(QEvent::User + 4); - -// Passed by the RL to the RT when a QQuickWindow::grabWindow() is called. -const QEvent::Type WM_Grab = QEvent::Type(QEvent::User + 5); - -// Passed by the window when there is a render job to run. -const QEvent::Type WM_PostJob = QEvent::Type(QEvent::User + 6); - -class QSGD3D12WindowEvent : public QEvent -{ -public: - QSGD3D12WindowEvent(QQuickWindow *c, QEvent::Type type) : QEvent(type), window(c) { } - QQuickWindow *window; -}; - -class QSGD3D12TryReleaseEvent : public QSGD3D12WindowEvent -{ -public: - QSGD3D12TryReleaseEvent(QQuickWindow *win, bool destroy) - : QSGD3D12WindowEvent(win, WM_TryRelease), destroying(destroy) { } - bool destroying; -}; - -class QSGD3D12SyncEvent : public QSGD3D12WindowEvent -{ -public: - QSGD3D12SyncEvent(QQuickWindow *c, bool inExpose, bool force) - : QSGD3D12WindowEvent(c, WM_RequestSync) - , size(c->size()) - , dpr(c->effectiveDevicePixelRatio()) - , syncInExpose(inExpose) - , forceRenderPass(force) { } - QSize size; - float dpr; - bool syncInExpose; - bool forceRenderPass; -}; - -class QSGD3D12GrabEvent : public QSGD3D12WindowEvent -{ -public: - QSGD3D12GrabEvent(QQuickWindow *c, QImage *result) - : QSGD3D12WindowEvent(c, WM_Grab), image(result) { } - QImage *image; -}; - -class QSGD3D12JobEvent : public QSGD3D12WindowEvent -{ -public: - QSGD3D12JobEvent(QQuickWindow *c, QRunnable *postedJob) - : QSGD3D12WindowEvent(c, WM_PostJob), job(postedJob) { } - ~QSGD3D12JobEvent() { delete job; } - QRunnable *job; -}; - -class QSGD3D12EventQueue : public QQueue<QEvent *> -{ -public: - void addEvent(QEvent *e) { - mutex.lock(); - enqueue(e); - if (waiting) - condition.wakeOne(); - mutex.unlock(); - } - - QEvent *takeEvent(bool wait) { - mutex.lock(); - if (isEmpty() && wait) { - waiting = true; - condition.wait(&mutex); - waiting = false; - } - QEvent *e = dequeue(); - mutex.unlock(); - return e; - } - - bool hasMoreEvents() { - mutex.lock(); - bool has = !isEmpty(); - mutex.unlock(); - return has; - } - -private: - QMutex mutex; - QWaitCondition condition; - bool waiting = false; -}; - -static inline int qsgrl_animation_interval() -{ - const qreal refreshRate = QGuiApplication::primaryScreen() ? QGuiApplication::primaryScreen()->refreshRate() : 0; - return refreshRate < 1 ? 16 : int(1000 / refreshRate); -} - -class QSGD3D12RenderThread : public QThread -{ - Q_OBJECT - -public: - QSGD3D12RenderThread(QSGD3D12ThreadedRenderLoop *rl, QSGRenderContext *renderContext) - : renderLoop(rl) - { - rc = static_cast<QSGD3D12RenderContext *>(renderContext); - vsyncDelta = qsgrl_animation_interval(); - } - - ~QSGD3D12RenderThread() - { - delete rc; - } - - bool event(QEvent *e); - void run(); - - void syncAndRender(); - void sync(bool inExpose); - - void requestRepaint() - { - if (sleeping) - stopEventProcessing = true; - if (exposedWindow) - pendingUpdate |= RepaintRequest; - } - - void processEventsAndWaitForMore(); - void processEvents(); - void postEvent(QEvent *e); - - enum UpdateRequest { - SyncRequest = 0x01, - RepaintRequest = 0x02, - ExposeRequest = 0x04 | RepaintRequest | SyncRequest - }; - - QSGD3D12Engine *engine = nullptr; - QSGD3D12ThreadedRenderLoop *renderLoop; - QSGD3D12RenderContext *rc; - QAnimationDriver *rtAnim = nullptr; - volatile bool active = false; - uint pendingUpdate = 0; - bool sleeping = false; - bool syncResultedInChanges = false; - float vsyncDelta; - QMutex mutex; - QWaitCondition waitCondition; - QQuickWindow *exposedWindow = nullptr; - bool stopEventProcessing = false; - QSGD3D12EventQueue eventQueue; - QElapsedTimer threadTimer; - qint64 syncTime; - qint64 renderTime; - qint64 sinceLastTime; - -public slots: - void onSceneGraphChanged() { - syncResultedInChanges = true; - } -}; - -bool QSGD3D12RenderThread::event(QEvent *e) -{ - switch (e->type()) { - - case WM_Obscure: - Q_ASSERT(!exposedWindow || exposedWindow == static_cast<QSGD3D12WindowEvent *>(e)->window); - if (Q_UNLIKELY(debug_loop())) - qDebug() << "RT - WM_Obscure" << exposedWindow; - mutex.lock(); - if (exposedWindow) { - QQuickWindowPrivate::get(exposedWindow)->fireAboutToStop(); - if (Q_UNLIKELY(debug_loop())) - qDebug("RT - WM_Obscure - window removed"); - exposedWindow = nullptr; - } - waitCondition.wakeOne(); - mutex.unlock(); - return true; - - case WM_RequestSync: { - QSGD3D12SyncEvent *wme = static_cast<QSGD3D12SyncEvent *>(e); - if (sleeping) - stopEventProcessing = true; - // One thread+engine for each window. However, the native window may - // change in some (quite artificial) cases, e.g. due to a hide - - // destroy - show on the QWindow. - bool needsWindow = !engine->window(); - if (engine->window() && engine->window() != wme->window->winId()) { - if (Q_UNLIKELY(debug_loop())) - qDebug("RT - WM_RequestSync - native window handle changes for active engine"); - engine->waitGPU(); - QQuickWindowPrivate::get(wme->window)->cleanupNodesOnShutdown(); - QSGD3D12ShaderEffectNode::cleanupMaterialTypeCache(); - rc->invalidate(); - engine->releaseResources(); - needsWindow = true; - } - if (needsWindow) { - // Must only ever get here when there is no window or releaseResources() has been called. - const int samples = wme->window->format().samples(); - const bool alpha = wme->window->format().alphaBufferSize() > 0; - if (Q_UNLIKELY(debug_loop())) - qDebug() << "RT - WM_RequestSync - initializing D3D12 engine" << wme->window - << wme->size << wme->dpr << samples << alpha; - engine->attachToWindow(wme->window->winId(), wme->size, wme->dpr, samples, alpha); - } - exposedWindow = wme->window; - engine->setWindowSize(wme->size, wme->dpr); - if (Q_UNLIKELY(debug_loop())) - qDebug() << "RT - WM_RequestSync" << exposedWindow; - pendingUpdate |= SyncRequest; - if (wme->syncInExpose) { - if (Q_UNLIKELY(debug_loop())) - qDebug("RT - WM_RequestSync - triggered from expose"); - pendingUpdate |= ExposeRequest; - } - if (wme->forceRenderPass) { - if (Q_UNLIKELY(debug_loop())) - qDebug("RT - WM_RequestSync - repaint regardless"); - pendingUpdate |= RepaintRequest; - } - return true; - } - - case WM_TryRelease: { - if (Q_UNLIKELY(debug_loop())) - qDebug("RT - WM_TryRelease"); - mutex.lock(); - renderLoop->lockedForSync = true; - QSGD3D12TryReleaseEvent *wme = static_cast<QSGD3D12TryReleaseEvent *>(e); - // Only when no windows are exposed anymore or we are shutting down. - if (!exposedWindow || wme->destroying) { - if (Q_UNLIKELY(debug_loop())) - qDebug("RT - WM_TryRelease - invalidating rc"); - if (wme->window) { - QQuickWindowPrivate *wd = QQuickWindowPrivate::get(wme->window); - if (wme->destroying) { - // QSGNode destruction may release graphics resources in use so wait first. - engine->waitGPU(); - // Bye bye nodes... - wd->cleanupNodesOnShutdown(); - QSGD3D12ShaderEffectNode::cleanupMaterialTypeCache(); - } - rc->invalidate(); - QCoreApplication::processEvents(); - QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); - if (wme->destroying) - wd->animationController.reset(); - } - if (wme->destroying) - active = false; - if (sleeping) - stopEventProcessing = true; - } else { - if (Q_UNLIKELY(debug_loop())) - qDebug("RT - WM_TryRelease - not releasing because window is still active"); - } - waitCondition.wakeOne(); - renderLoop->lockedForSync = false; - mutex.unlock(); - return true; - } - - case WM_Grab: { - if (Q_UNLIKELY(debug_loop())) - qDebug("RT - WM_Grab"); - QSGD3D12GrabEvent *wme = static_cast<QSGD3D12GrabEvent *>(e); - Q_ASSERT(wme->window); - Q_ASSERT(wme->window == exposedWindow || !exposedWindow); - mutex.lock(); - if (wme->window) { - // Grabbing is generally done by rendering a frame and reading the - // color buffer contents back, without presenting, and then - // creating a QImage from the returned data. It is terribly - // inefficient since it involves a full blocking wait for the GPU. - // However, our hands are tied by the existing, synchronous APIs of - // QQuickWindow and such. - QQuickWindowPrivate *wd = QQuickWindowPrivate::get(wme->window); - rc->initialize(nullptr); - wd->syncSceneGraph(); - rc->endSync(); - wd->renderSceneGraph(wme->window->size()); - *wme->image = engine->executeAndWaitReadbackRenderTarget(); - } - if (Q_UNLIKELY(debug_loop())) - qDebug("RT - WM_Grab - waking gui to handle result"); - waitCondition.wakeOne(); - mutex.unlock(); - return true; - } - - case WM_PostJob: { - if (Q_UNLIKELY(debug_loop())) - qDebug("RT - WM_PostJob"); - QSGD3D12JobEvent *wme = static_cast<QSGD3D12JobEvent *>(e); - Q_ASSERT(wme->window == exposedWindow); - if (exposedWindow) { - wme->job->run(); - delete wme->job; - wme->job = nullptr; - if (Q_UNLIKELY(debug_loop())) - qDebug("RT - WM_PostJob - job done"); - } - return true; - } - - default: - break; - } - - return QThread::event(e); -} - -void QSGD3D12RenderThread::postEvent(QEvent *e) -{ - eventQueue.addEvent(e); -} - -void QSGD3D12RenderThread::processEvents() -{ - while (eventQueue.hasMoreEvents()) { - QEvent *e = eventQueue.takeEvent(false); - event(e); - delete e; - } -} - -void QSGD3D12RenderThread::processEventsAndWaitForMore() -{ - stopEventProcessing = false; - while (!stopEventProcessing) { - QEvent *e = eventQueue.takeEvent(true); - event(e); - delete e; - } -} - -void QSGD3D12RenderThread::run() -{ - if (Q_UNLIKELY(debug_loop())) - qDebug("RT - run()"); - - engine = new QSGD3D12Engine; - rc->setEngine(engine); - - rtAnim = rc->sceneGraphContext()->createAnimationDriver(nullptr); - rtAnim->install(); - - if (QQmlDebugConnector::service<QQmlProfilerService>()) - QQuickProfiler::registerAnimationCallback(); - - while (active) { - if (exposedWindow) - syncAndRender(); - - processEvents(); - QCoreApplication::processEvents(); - - if (pendingUpdate == 0 || !exposedWindow) { - if (Q_UNLIKELY(debug_loop())) - qDebug("RT - done drawing, sleep"); - sleeping = true; - processEventsAndWaitForMore(); - sleeping = false; - } - } - - if (Q_UNLIKELY(debug_loop())) - qDebug("RT - run() exiting"); - - delete rtAnim; - rtAnim = nullptr; - - rc->moveToThread(renderLoop->thread()); - moveToThread(renderLoop->thread()); - - rc->setEngine(nullptr); - delete engine; - engine = nullptr; -} - -void QSGD3D12RenderThread::sync(bool inExpose) -{ - if (Q_UNLIKELY(debug_loop())) - qDebug("RT - sync"); - - mutex.lock(); - Q_ASSERT_X(renderLoop->lockedForSync, "QSGD3D12RenderThread::sync()", "sync triggered with gui not locked"); - - // Recover from device loss. - if (!engine->hasResources()) { - if (Q_UNLIKELY(debug_loop())) - qDebug("RT - sync - device was lost, resetting scenegraph"); - QQuickWindowPrivate::get(exposedWindow)->cleanupNodesOnShutdown(); - QSGD3D12ShaderEffectNode::cleanupMaterialTypeCache(); - rc->invalidate(); - } - - if (engine->window()) { - QQuickWindowPrivate *wd = QQuickWindowPrivate::get(exposedWindow); - bool hadRenderer = wd->renderer != nullptr; - // If the scene graph was touched since the last sync() make sure it sends the - // changed signal. - if (wd->renderer) - wd->renderer->clearChangedFlag(); - - rc->initialize(nullptr); - wd->syncSceneGraph(); - rc->endSync(); - - if (!hadRenderer && wd->renderer) { - if (Q_UNLIKELY(debug_loop())) - qDebug("RT - created renderer"); - syncResultedInChanges = true; - connect(wd->renderer, &QSGRenderer::sceneGraphChanged, this, - &QSGD3D12RenderThread::onSceneGraphChanged, Qt::DirectConnection); - } - - // Process deferred deletes now, directly after the sync as deleteLater - // on the GUI must now also have resulted in SG changes and the delete - // is a safe operation. - QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); - } - - if (!inExpose) { - if (Q_UNLIKELY(debug_loop())) - qDebug("RT - sync complete, waking gui"); - waitCondition.wakeOne(); - mutex.unlock(); - } -} - -void QSGD3D12RenderThread::syncAndRender() -{ - Q_TRACE_SCOPE(QSG_syncAndRender); - if (Q_UNLIKELY(debug_time())) { - sinceLastTime = threadTimer.nsecsElapsed(); - threadTimer.start(); - } - Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphRenderLoopFrame); - Q_TRACE(QSG_sync_entry); - - QElapsedTimer waitTimer; - waitTimer.start(); - - if (Q_UNLIKELY(debug_loop())) - qDebug("RT - syncAndRender()"); - - syncResultedInChanges = false; - QQuickWindowPrivate *wd = QQuickWindowPrivate::get(exposedWindow); - - const bool repaintRequested = (pendingUpdate & RepaintRequest) || wd->customRenderStage; - const bool syncRequested = pendingUpdate & SyncRequest; - const bool exposeRequested = (pendingUpdate & ExposeRequest) == ExposeRequest; - pendingUpdate = 0; - - if (syncRequested) - sync(exposeRequested); - -#ifndef QSG_NO_RENDER_TIMING - if (Q_UNLIKELY(debug_time())) - syncTime = threadTimer.nsecsElapsed(); -#endif - Q_TRACE(QSG_sync_exit); - Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame, - QQuickProfiler::SceneGraphRenderLoopSync); - - if (!syncResultedInChanges && !repaintRequested) { - if (Q_UNLIKELY(debug_loop())) - qDebug("RT - no changes, render aborted"); - int waitTime = vsyncDelta - (int) waitTimer.elapsed(); - if (waitTime > 0) - msleep(waitTime); - return; - } - Q_TRACE(QSG_render_entry); - - if (Q_UNLIKELY(debug_loop())) - qDebug("RT - rendering started"); - - if (rtAnim->isRunning()) { - wd->animationController->lock(); - rtAnim->advance(); - wd->animationController->unlock(); - } - - bool canRender = wd->renderer != nullptr; - // Recover from device loss. - if (!engine->hasResources()) { - if (Q_UNLIKELY(debug_loop())) - qDebug("RT - syncAndRender - device was lost, posting FullUpdateRequest"); - // Cannot do anything here because gui is not locked. Request a new - // sync+render round on the gui thread and let the sync handle it. - QCoreApplication::postEvent(exposedWindow, new QEvent(QEvent::Type(QQuickWindowPrivate::FullUpdateRequest))); - canRender = false; - } - - if (canRender) { - wd->renderSceneGraph(engine->windowSize()); - if (Q_UNLIKELY(debug_time())) - renderTime = threadTimer.nsecsElapsed(); - Q_TRACE(QSG_render_exit); - Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame, - QQuickProfiler::SceneGraphRenderLoopRender); - Q_TRACE(QSG_swap_entry); - - // The engine is able to have multiple frames in flight. This in effect is - // similar to BufferQueueingOpenGL. Provide an env var to force the - // traditional blocking swap behavior, just in case. - static bool blockOnEachFrame = qEnvironmentVariableIntValue("QT_D3D_BLOCKING_PRESENT") != 0; - - if (!wd->customRenderStage || !wd->customRenderStage->swap()) - engine->present(); - - if (blockOnEachFrame) - engine->waitGPU(); - - // The concept of "frame swaps" is quite misleading by default, when - // blockOnEachFrame is not used, but emit it for compatibility. - wd->fireFrameSwapped(); - } else { - Q_TRACE(QSG_render_exit); - Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphRenderLoopFrame, - QQuickProfiler::SceneGraphRenderLoopSync, 1); - Q_TRACE(QSG_swap_entry); - if (Q_UNLIKELY(debug_loop())) - qDebug("RT - window not ready, skipping render"); - } - - if (Q_UNLIKELY(debug_loop())) - qDebug("RT - rendering done"); - - if (exposeRequested) { - if (Q_UNLIKELY(debug_loop())) - qDebug("RT - wake gui after initial expose"); - waitCondition.wakeOne(); - mutex.unlock(); - } - - if (Q_UNLIKELY(debug_time())) - qDebug("Frame rendered with 'd3d12' renderloop in %dms, sync=%d, render=%d, swap=%d - (on render thread)", - int(threadTimer.elapsed()), - int((syncTime/1000000)), - int((renderTime - syncTime) / 1000000), - int(threadTimer.elapsed() - renderTime / 1000000)); - - Q_TRACE(QSG_swap_exit); - Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame, - QQuickProfiler::SceneGraphRenderLoopSwap); - - static int devLossTest = qEnvironmentVariableIntValue("QT_D3D_TEST_DEVICE_LOSS"); - if (devLossTest > 0) { - static QElapsedTimer kt; - static bool timerRunning = false; - if (!timerRunning) { - kt.start(); - timerRunning = true; - } else if (kt.elapsed() > 5000) { - --devLossTest; - kt.restart(); - engine->simulateDeviceLoss(); - } - } -} - -template<class T> T *windowFor(const QVector<T> &list, QQuickWindow *window) -{ - for (const T &t : list) { - if (t.window == window) - return const_cast<T *>(&t); - } - return nullptr; -} - -QSGD3D12ThreadedRenderLoop::QSGD3D12ThreadedRenderLoop() -{ - if (Q_UNLIKELY(debug_loop())) - qDebug("d3d12 THREADED render loop ctor"); - - sg = new QSGD3D12Context; - - anim = sg->createAnimationDriver(this); - connect(anim, &QAnimationDriver::started, this, &QSGD3D12ThreadedRenderLoop::onAnimationStarted); - connect(anim, &QAnimationDriver::stopped, this, &QSGD3D12ThreadedRenderLoop::onAnimationStopped); - anim->install(); -} - -QSGD3D12ThreadedRenderLoop::~QSGD3D12ThreadedRenderLoop() -{ - if (Q_UNLIKELY(debug_loop())) - qDebug("d3d12 THREADED render loop dtor"); - - delete sg; -} - -void QSGD3D12ThreadedRenderLoop::show(QQuickWindow *window) -{ - if (Q_UNLIKELY(debug_loop())) - qDebug() << "show" << window; -} - -void QSGD3D12ThreadedRenderLoop::hide(QQuickWindow *window) -{ - if (Q_UNLIKELY(debug_loop())) - qDebug() << "hide" << window; - - if (window->isExposed()) - handleObscurity(windowFor(windows, window)); - - releaseResources(window); -} - -void QSGD3D12ThreadedRenderLoop::resize(QQuickWindow *window) -{ - if (!window->isExposed() || window->size().isEmpty()) - return; - - if (Q_UNLIKELY(debug_loop())) - qDebug() << "resize" << window << window->size(); -} - -void QSGD3D12ThreadedRenderLoop::windowDestroyed(QQuickWindow *window) -{ - if (Q_UNLIKELY(debug_loop())) - qDebug() << "window destroyed" << window; - - WindowData *w = windowFor(windows, window); - if (!w) - return; - - handleObscurity(w); - handleResourceRelease(w, true); - - QSGD3D12RenderThread *thread = w->thread; - while (thread->isRunning()) - QThread::yieldCurrentThread(); - - Q_ASSERT(thread->thread() == QThread::currentThread()); - delete thread; - - for (int i = 0; i < windows.size(); ++i) { - if (windows.at(i).window == window) { - windows.removeAt(i); - break; - } - } - - // Now that we altered the window list, we may need to stop the animation - // timer even if we didn't via handleObscurity. This covers the case where - // we destroy a visible & exposed QQuickWindow. - startOrStopAnimationTimer(); -} - -void QSGD3D12ThreadedRenderLoop::exposureChanged(QQuickWindow *window) -{ - if (Q_UNLIKELY(debug_loop())) - qDebug() << "exposure changed" << window; - - if (window->isExposed()) { - handleExposure(window); - } else { - WindowData *w = windowFor(windows, window); - if (w) - handleObscurity(w); - } -} - -QImage QSGD3D12ThreadedRenderLoop::grab(QQuickWindow *window) -{ - if (Q_UNLIKELY(debug_loop())) - qDebug() << "grab" << window; - - WindowData *w = windowFor(windows, window); - // Have to support invisible (but created()'ed) windows as well. - // Unlike with GL, leaving that case for QQuickWindow to handle is not feasible. - const bool tempExpose = !w; - if (tempExpose) { - handleExposure(window); - w = windowFor(windows, window); - Q_ASSERT(w); - } - - if (!w->thread->isRunning()) - return QImage(); - - if (!window->handle()) - window->create(); - - QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window); - wd->polishItems(); - - QImage result; - w->thread->mutex.lock(); - lockedForSync = true; - w->thread->postEvent(new QSGD3D12GrabEvent(window, &result)); - w->thread->waitCondition.wait(&w->thread->mutex); - lockedForSync = false; - w->thread->mutex.unlock(); - - result.setDevicePixelRatio(window->effectiveDevicePixelRatio()); - - if (tempExpose) - handleObscurity(w); - - return result; -} - -void QSGD3D12ThreadedRenderLoop::update(QQuickWindow *window) -{ - WindowData *w = windowFor(windows, window); - if (!w) - return; - - if (w->thread == QThread::currentThread()) { - w->thread->requestRepaint(); - return; - } - - // We set forceRenderPass because we want to make sure the QQuickWindow - // actually does a full render pass after the next sync. - w->forceRenderPass = true; - scheduleUpdate(w); -} - -void QSGD3D12ThreadedRenderLoop::maybeUpdate(QQuickWindow *window) -{ - WindowData *w = windowFor(windows, window); - if (w) - scheduleUpdate(w); -} - -// called in response to window->requestUpdate() -void QSGD3D12ThreadedRenderLoop::handleUpdateRequest(QQuickWindow *window) -{ - if (Q_UNLIKELY(debug_loop())) - qDebug() << "handleUpdateRequest" << window; - - WindowData *w = windowFor(windows, window); - if (w) - polishAndSync(w, false); -} - -QAnimationDriver *QSGD3D12ThreadedRenderLoop::animationDriver() const -{ - return anim; -} - -QSGContext *QSGD3D12ThreadedRenderLoop::sceneGraphContext() const -{ - return sg; -} - -QSGRenderContext *QSGD3D12ThreadedRenderLoop::createRenderContext(QSGContext *) const -{ - return sg->createRenderContext(); -} - -void QSGD3D12ThreadedRenderLoop::releaseResources(QQuickWindow *window) -{ - if (Q_UNLIKELY(debug_loop())) - qDebug() << "releaseResources" << window; - - WindowData *w = windowFor(windows, window); - if (w) - handleResourceRelease(w, false); -} - -void QSGD3D12ThreadedRenderLoop::postJob(QQuickWindow *window, QRunnable *job) -{ - WindowData *w = windowFor(windows, window); - if (w && w->thread && w->thread->exposedWindow) - w->thread->postEvent(new QSGD3D12JobEvent(window, job)); - else - delete job; -} - -QSurface::SurfaceType QSGD3D12ThreadedRenderLoop::windowSurfaceType() const -{ - return QSurface::OpenGLSurface; -} - -bool QSGD3D12ThreadedRenderLoop::interleaveIncubation() const -{ - bool somethingVisible = false; - for (const WindowData &w : windows) { - if (w.window->isVisible() && w.window->isExposed()) { - somethingVisible = true; - break; - } - } - return somethingVisible && anim->isRunning(); -} - -int QSGD3D12ThreadedRenderLoop::flags() const -{ - return SupportsGrabWithoutExpose; -} - -bool QSGD3D12ThreadedRenderLoop::event(QEvent *e) -{ - if (e->type() == QEvent::Timer) { - QTimerEvent *te = static_cast<QTimerEvent *>(e); - if (te->timerId() == animationTimer) { - anim->advance(); - emit timeToIncubate(); - return true; - } - } - - return QObject::event(e); -} - -void QSGD3D12ThreadedRenderLoop::onAnimationStarted() -{ - startOrStopAnimationTimer(); - - for (const WindowData &w : qAsConst(windows)) - w.window->requestUpdate(); -} - -void QSGD3D12ThreadedRenderLoop::onAnimationStopped() -{ - startOrStopAnimationTimer(); -} - -void QSGD3D12ThreadedRenderLoop::startOrStopAnimationTimer() -{ - int exposedWindowCount = 0; - const WindowData *exposed = nullptr; - - for (int i = 0; i < windows.size(); ++i) { - const WindowData &w(windows[i]); - if (w.window->isVisible() && w.window->isExposed()) { - ++exposedWindowCount; - exposed = &w; - } - } - - if (animationTimer && (exposedWindowCount == 1 || !anim->isRunning())) { - killTimer(animationTimer); - animationTimer = 0; - // If animations are running, make sure we keep on animating - if (anim->isRunning()) - exposed->window->requestUpdate(); - } else if (!animationTimer && exposedWindowCount != 1 && anim->isRunning()) { - animationTimer = startTimer(qsgrl_animation_interval()); - } -} - -void QSGD3D12ThreadedRenderLoop::handleExposure(QQuickWindow *window) -{ - if (Q_UNLIKELY(debug_loop())) - qDebug() << "handleExposure" << window; - - WindowData *w = windowFor(windows, window); - if (!w) { - if (Q_UNLIKELY(debug_loop())) - qDebug("adding window to list"); - WindowData win; - win.window = window; - QSGRenderContext *rc = QQuickWindowPrivate::get(window)->context; // will transfer ownership - win.thread = new QSGD3D12RenderThread(this, rc); - win.updateDuringSync = false; - win.forceRenderPass = true; // also covered by polishAndSync(inExpose=true), but doesn't hurt - windows.append(win); - w = &windows.last(); - } - - // set this early as we'll be rendering shortly anyway and this avoids - // special casing exposure in polishAndSync. - w->thread->exposedWindow = window; - - if (w->window->size().isEmpty() - || (w->window->isTopLevel() && !w->window->geometry().intersects(w->window->screen()->availableGeometry()))) { -#ifndef QT_NO_DEBUG - qWarning().noquote().nospace() << "QSGD3D12ThreadedRenderLoop: expose event received for window " - << w->window << " with invalid geometry: " << w->window->geometry() - << " on " << w->window->screen(); -#endif - } - - if (!w->window->handle()) - w->window->create(); - - // Start render thread if it is not running - if (!w->thread->isRunning()) { - if (Q_UNLIKELY(debug_loop())) - qDebug("starting render thread"); - // Push a few things to the render thread. - QQuickAnimatorController *controller = QQuickWindowPrivate::get(w->window)->animationController.data(); - if (controller->thread() != w->thread) - controller->moveToThread(w->thread); - if (w->thread->thread() == QThread::currentThread()) { - w->thread->rc->moveToThread(w->thread); - w->thread->moveToThread(w->thread); - } - - w->thread->active = true; - w->thread->start(); - - if (!w->thread->isRunning()) - qFatal("Render thread failed to start, aborting application."); - } - - polishAndSync(w, true); - - startOrStopAnimationTimer(); -} - -void QSGD3D12ThreadedRenderLoop::handleObscurity(WindowData *w) -{ - if (Q_UNLIKELY(debug_loop())) - qDebug() << "handleObscurity" << w->window; - - if (w->thread->isRunning()) { - w->thread->mutex.lock(); - w->thread->postEvent(new QSGD3D12WindowEvent(w->window, WM_Obscure)); - w->thread->waitCondition.wait(&w->thread->mutex); - w->thread->mutex.unlock(); - } - - startOrStopAnimationTimer(); -} - -void QSGD3D12ThreadedRenderLoop::scheduleUpdate(WindowData *w) -{ - if (!QCoreApplication::instance()) - return; - - if (!w || !w->thread->isRunning()) - return; - - QThread *current = QThread::currentThread(); - if (current != QCoreApplication::instance()->thread() && (current != w->thread || !lockedForSync)) { - qWarning() << "Updates can only be scheduled from GUI thread or from QQuickItem::updatePaintNode()"; - return; - } - - if (current == w->thread) { - w->updateDuringSync = true; - return; - } - - w->window->requestUpdate(); -} - -void QSGD3D12ThreadedRenderLoop::handleResourceRelease(WindowData *w, bool destroying) -{ - if (Q_UNLIKELY(debug_loop())) - qDebug() << "handleResourceRelease" << (destroying ? "destroying" : "hide/releaseResources") << w->window; - - w->thread->mutex.lock(); - if (w->thread->isRunning() && w->thread->active) { - QQuickWindow *window = w->window; - - // Note that window->handle() is typically null by this time because - // the platform window is already destroyed. This should not be a - // problem for the D3D cleanup. - - w->thread->postEvent(new QSGD3D12TryReleaseEvent(window, destroying)); - w->thread->waitCondition.wait(&w->thread->mutex); - - // Avoid a shutdown race condition. - // If SG is invalidated and 'active' becomes false, the thread's run() - // method will exit. handleExposure() relies on QThread::isRunning() (because it - // potentially needs to start the thread again) and our mutex cannot be used to - // track the thread stopping, so we wait a few nanoseconds extra so the thread - // can exit properly. - if (!w->thread->active) - w->thread->wait(); - } - w->thread->mutex.unlock(); -} - -void QSGD3D12ThreadedRenderLoop::polishAndSync(WindowData *w, bool inExpose) -{ - if (Q_UNLIKELY(debug_loop())) - qDebug() << "polishAndSync" << (inExpose ? "(in expose)" : "(normal)") << w->window; - - QQuickWindow *window = w->window; - if (!w->thread || !w->thread->exposedWindow) { - if (Q_UNLIKELY(debug_loop())) - qDebug("polishAndSync - not exposed, abort"); - return; - } - - Q_TRACE_SCOPE(QSG_polishAndSync); - - // Flush pending touch events. - QQuickWindowPrivate::get(window)->flushFrameSynchronousEvents(); - // The delivery of the event might have caused the window to stop rendering - w = windowFor(windows, window); - if (!w || !w->thread || !w->thread->exposedWindow) { - if (Q_UNLIKELY(debug_loop())) - qDebug("polishAndSync - removed after touch event flushing, abort"); - return; - } - - QElapsedTimer timer; - qint64 polishTime = 0; - qint64 waitTime = 0; - qint64 syncTime = 0; - if (Q_UNLIKELY(debug_time())) - timer.start(); - Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishAndSync); - Q_TRACE(QSG_polishItems_entry); - - QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window); - wd->polishItems(); - - if (Q_UNLIKELY(debug_time())) - polishTime = timer.nsecsElapsed(); - Q_TRACE(QSG_polishItems_exit); - Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync, - QQuickProfiler::SceneGraphPolishAndSyncPolish); - Q_TRACE(QSG_wait_entry); - - w->updateDuringSync = false; - - emit window->afterAnimating(); - - if (Q_UNLIKELY(debug_loop())) - qDebug("polishAndSync - lock for sync"); - w->thread->mutex.lock(); - lockedForSync = true; - w->thread->postEvent(new QSGD3D12SyncEvent(window, inExpose, w->forceRenderPass)); - w->forceRenderPass = false; - - if (Q_UNLIKELY(debug_loop())) - qDebug("polishAndSync - wait for sync"); - if (Q_UNLIKELY(debug_time())) - waitTime = timer.nsecsElapsed(); - Q_TRACE(QSG_wait_exit); - Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync, - QQuickProfiler::SceneGraphPolishAndSyncWait); - Q_TRACE(QSG_sync_entry); - - w->thread->waitCondition.wait(&w->thread->mutex); - lockedForSync = false; - w->thread->mutex.unlock(); - if (Q_UNLIKELY(debug_loop())) - qDebug("polishAndSync - unlock after sync"); - - if (Q_UNLIKELY(debug_time())) - syncTime = timer.nsecsElapsed(); - Q_TRACE(QSG_sync_exit); - Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync, - QQuickProfiler::SceneGraphPolishAndSyncSync); - Q_TRACE(QSG_animations_entry); - - if (!animationTimer && anim->isRunning()) { - if (Q_UNLIKELY(debug_loop())) - qDebug("polishAndSync - advancing animations"); - anim->advance(); - // We need to trigger another sync to keep animations running... - w->window->requestUpdate(); - emit timeToIncubate(); - } else if (w->updateDuringSync) { - w->window->requestUpdate(); - } - - if (Q_UNLIKELY(debug_time())) - qDebug().nospace() - << "Frame prepared with 'd3d12' renderloop" - << ", polish=" << (polishTime / 1000000) - << ", lock=" << (waitTime - polishTime) / 1000000 - << ", blockedForSync=" << (syncTime - waitTime) / 1000000 - << ", animations=" << (timer.nsecsElapsed() - syncTime) / 1000000 - << " - (on gui thread) " << window; - - Q_TRACE(QSG_animations_exit); - Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphPolishAndSync, - QQuickProfiler::SceneGraphPolishAndSyncAnimations); -} - -#include "qsgd3d12threadedrenderloop.moc" - -QT_END_NAMESPACE diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop_p.h deleted file mode 100644 index 46f62948f1..0000000000 --- a/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop_p.h +++ /dev/null @@ -1,129 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSGD3D12THREADEDRENDERLOOP_P_H -#define QSGD3D12THREADEDRENDERLOOP_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qsgrenderloop_p.h> - -QT_BEGIN_NAMESPACE - -class QSGD3D12Engine; -class QSGD3D12Context; -class QSGD3D12RenderContext; -class QSGD3D12RenderThread; - -class QSGD3D12ThreadedRenderLoop : public QSGRenderLoop -{ - Q_OBJECT - -public: - QSGD3D12ThreadedRenderLoop(); - ~QSGD3D12ThreadedRenderLoop(); - - void show(QQuickWindow *window) override; - void hide(QQuickWindow *window) override; - void resize(QQuickWindow *window) override; - - void windowDestroyed(QQuickWindow *window) override; - - void exposureChanged(QQuickWindow *window) override; - - QImage grab(QQuickWindow *window) override; - - void update(QQuickWindow *window) override; - void maybeUpdate(QQuickWindow *window) override; - void handleUpdateRequest(QQuickWindow *window) override; - - QAnimationDriver *animationDriver() const override; - - QSGContext *sceneGraphContext() const override; - QSGRenderContext *createRenderContext(QSGContext *) const override; - - void releaseResources(QQuickWindow *window) override; - void postJob(QQuickWindow *window, QRunnable *job) override; - - QSurface::SurfaceType windowSurfaceType() const override; - bool interleaveIncubation() const override; - int flags() const override; - - bool event(QEvent *e) override; - -public Q_SLOTS: - void onAnimationStarted(); - void onAnimationStopped(); - -private: - struct WindowData { - QQuickWindow *window; - QSGD3D12RenderThread *thread; - uint updateDuringSync : 1; - uint forceRenderPass : 1; - }; - - void startOrStopAnimationTimer(); - void handleExposure(QQuickWindow *window); - void handleObscurity(WindowData *w); - void scheduleUpdate(WindowData *w); - void handleResourceRelease(WindowData *w, bool destroying); - void polishAndSync(WindowData *w, bool inExpose); - - QSGD3D12Context *sg; - QAnimationDriver *anim; - int animationTimer = 0; - bool lockedForSync = false; - QVector<WindowData> windows; - - friend class QSGD3D12RenderThread; -}; - -QT_END_NAMESPACE - -#endif // QSGD3D12THREADEDRENDERLOOP_P_H diff --git a/src/plugins/scenegraph/d3d12/shaders/flatcolor.hlsl b/src/plugins/scenegraph/d3d12/shaders/flatcolor.hlsl deleted file mode 100644 index 034b51435a..0000000000 --- a/src/plugins/scenegraph/d3d12/shaders/flatcolor.hlsl +++ /dev/null @@ -1,27 +0,0 @@ -struct VSInput -{ - float4 position : POSITION; -}; - -cbuffer ConstantBuffer : register(b0) -{ - float4x4 mvp; - float4 color; -}; - -struct PSInput -{ - float4 position : SV_POSITION; -}; - -PSInput VS_FlatColor(VSInput input) -{ - PSInput result; - result.position = mul(mvp, input.position); - return result; -} - -float4 PS_FlatColor(PSInput input) : SV_TARGET -{ - return color; -} diff --git a/src/plugins/scenegraph/d3d12/shaders/mipmapgen.hlsl b/src/plugins/scenegraph/d3d12/shaders/mipmapgen.hlsl deleted file mode 100644 index 6793b534b0..0000000000 --- a/src/plugins/scenegraph/d3d12/shaders/mipmapgen.hlsl +++ /dev/null @@ -1,60 +0,0 @@ -static const uint GROUP_DIM = 8; // 2 ^ (out_mip_count - 1) - -Texture2D tex : register(t0); -SamplerState samp : register(s0); - -cbuffer ConstantBuffer : register(b0) -{ - uint2 mip1Size; - uint sampleLevel; - uint totalMips; -} - -RWTexture2D<float4> mip1 : register(u0); -RWTexture2D<float4> mip2 : register(u1); -RWTexture2D<float4> mip3 : register(u2); -RWTexture2D<float4> mip4 : register(u3); - -groupshared float4 groupColor[GROUP_DIM][GROUP_DIM]; - -[numthreads(GROUP_DIM, GROUP_DIM, 1)] -void CS_Generate4MipMaps(uint3 localId: SV_GroupThreadId, uint3 globalId: SV_DispatchThreadID) -{ - const float2 coord = float2(1.0f / float(mip1Size.x), 1.0f / float(mip1Size.y)) * (globalId.xy + 0.5); - float4 c = tex.SampleLevel(samp, coord, sampleLevel); - - mip1[globalId.xy] = c; - groupColor[localId.y][localId.x] = c; - - if (sampleLevel + 1 >= totalMips) - return; - - GroupMemoryBarrierWithGroupSync(); - - if ((localId.x & 1) == 0 && (localId.y & 1) == 0) { - c = (c + groupColor[localId.y][localId.x + 1] + groupColor[localId.y + 1][localId.x] + groupColor[localId.y + 1][localId.x + 1]) / 4.0; - mip2[globalId.xy / 2] = c; - groupColor[localId.y][localId.x] = c; - } - - if (sampleLevel + 2 >= totalMips) - return; - - GroupMemoryBarrierWithGroupSync(); - - if ((localId.x & 3) == 0 && (localId.y & 3) == 0) { - c = (c + groupColor[localId.y][localId.x + 2] + groupColor[localId.y + 2][localId.x] + groupColor[localId.y + 2][localId.x + 2]) / 4.0; - mip3[globalId.xy / 4] = c; - groupColor[localId.y][localId.x] = c; - } - - if (sampleLevel + 3 >= totalMips) - return; - - GroupMemoryBarrierWithGroupSync(); - - if ((localId.x & 7) == 0 && (localId.y & 7) == 0) { - c = (c + groupColor[localId.y][localId.x + 3] + groupColor[localId.y + 3][localId.x] + groupColor[localId.y + 3][localId.x + 3]) / 4.0; - mip4[globalId.xy / 8] = c; - } -} diff --git a/src/plugins/scenegraph/d3d12/shaders/shadereffectdefault.hlsl b/src/plugins/scenegraph/d3d12/shaders/shadereffectdefault.hlsl deleted file mode 100644 index 94672d6267..0000000000 --- a/src/plugins/scenegraph/d3d12/shaders/shadereffectdefault.hlsl +++ /dev/null @@ -1,27 +0,0 @@ -cbuffer ConstantBuffer : register(b0) -{ - float4x4 qt_Matrix; - float qt_Opacity; -}; - -struct PSInput -{ - float4 position : SV_POSITION; - float2 coord : TEXCOORD0; -}; - -Texture2D source : register(t0); -SamplerState sourceSampler : register(s0); - -PSInput VS_DefaultShaderEffect(float4 position : POSITION, float2 coord : TEXCOORD0) -{ - PSInput result; - result.position = mul(qt_Matrix, position); - result.coord = coord; - return result; -} - -float4 PS_DefaultShaderEffect(PSInput input) : SV_TARGET -{ - return source.Sample(sourceSampler, input.coord) * qt_Opacity; -} diff --git a/src/plugins/scenegraph/d3d12/shaders/shaders.pri b/src/plugins/scenegraph/d3d12/shaders/shaders.pri deleted file mode 100644 index 963f4c5d8c..0000000000 --- a/src/plugins/scenegraph/d3d12/shaders/shaders.pri +++ /dev/null @@ -1,141 +0,0 @@ -vertexcolor_VSPS = $$PWD/vertexcolor.hlsl -vertexcolor_vshader.input = vertexcolor_VSPS -vertexcolor_vshader.header = vs_vertexcolor.hlslh -vertexcolor_vshader.entry = VS_VertexColor -vertexcolor_vshader.type = vs_5_0 -vertexcolor_pshader.input = vertexcolor_VSPS -vertexcolor_pshader.header = ps_vertexcolor.hlslh -vertexcolor_pshader.entry = PS_VertexColor -vertexcolor_pshader.type = ps_5_0 - -flatcolor_VSPS = $$PWD/flatcolor.hlsl -flatcolor_vshader.input = flatcolor_VSPS -flatcolor_vshader.header = vs_flatcolor.hlslh -flatcolor_vshader.entry = VS_FlatColor -flatcolor_vshader.type = vs_5_0 -flatcolor_pshader.input = flatcolor_VSPS -flatcolor_pshader.header = ps_flatcolor.hlslh -flatcolor_pshader.entry = PS_FlatColor -flatcolor_pshader.type = ps_5_0 - -stencilclip_VSPS = $$PWD/stencilclip.hlsl -stencilclip_vshader.input = stencilclip_VSPS -stencilclip_vshader.header = vs_stencilclip.hlslh -stencilclip_vshader.entry = VS_StencilClip -stencilclip_vshader.type = vs_5_0 -stencilclip_pshader.input = stencilclip_VSPS -stencilclip_pshader.header = ps_stencilclip.hlslh -stencilclip_pshader.entry = PS_StencilClip -stencilclip_pshader.type = ps_5_0 - -smoothcolor_VSPS = $$PWD/smoothcolor.hlsl -smoothcolor_vshader.input = smoothcolor_VSPS -smoothcolor_vshader.header = vs_smoothcolor.hlslh -smoothcolor_vshader.entry = VS_SmoothColor -smoothcolor_vshader.type = vs_5_0 -smoothcolor_pshader.input = smoothcolor_VSPS -smoothcolor_pshader.header = ps_smoothcolor.hlslh -smoothcolor_pshader.entry = PS_SmoothColor -smoothcolor_pshader.type = ps_5_0 - -texture_VSPS = $$PWD/texture.hlsl -texture_vshader.input = texture_VSPS -texture_vshader.header = vs_texture.hlslh -texture_vshader.entry = VS_Texture -texture_vshader.type = vs_5_0 -texture_pshader.input = texture_VSPS -texture_pshader.header = ps_texture.hlslh -texture_pshader.entry = PS_Texture -texture_pshader.type = ps_5_0 - -smoothtexture_VSPS = $$PWD/smoothtexture.hlsl -smoothtexture_vshader.input = smoothtexture_VSPS -smoothtexture_vshader.header = vs_smoothtexture.hlslh -smoothtexture_vshader.entry = VS_SmoothTexture -smoothtexture_vshader.type = vs_5_0 -smoothtexture_pshader.input = smoothtexture_VSPS -smoothtexture_pshader.header = ps_smoothtexture.hlslh -smoothtexture_pshader.entry = PS_SmoothTexture -smoothtexture_pshader.type = ps_5_0 - -mipmapgen_CS = $$PWD/mipmapgen.hlsl -mipmapgen_cshader.input = mipmapgen_CS -mipmapgen_cshader.header = cs_mipmapgen.hlslh -mipmapgen_cshader.entry = CS_Generate4MipMaps -mipmapgen_cshader.type = cs_5_0 - -textmask_VSPS = $$PWD/textmask.hlsl -textmask_vshader.input = textmask_VSPS -textmask_vshader.header = vs_textmask.hlslh -textmask_vshader.entry = VS_TextMask -textmask_vshader.type = vs_5_0 -textmask_pshader24.input = textmask_VSPS -textmask_pshader24.header = ps_textmask24.hlslh -textmask_pshader24.entry = PS_TextMask24 -textmask_pshader24.type = ps_5_0 -textmask_pshader32.input = textmask_VSPS -textmask_pshader32.header = ps_textmask32.hlslh -textmask_pshader32.entry = PS_TextMask32 -textmask_pshader32.type = ps_5_0 -textmask_pshader8.input = textmask_VSPS -textmask_pshader8.header = ps_textmask8.hlslh -textmask_pshader8.entry = PS_TextMask8 -textmask_pshader8.type = ps_5_0 -styledtext_vshader.input = textmask_VSPS -styledtext_vshader.header = vs_styledtext.hlslh -styledtext_vshader.entry = VS_StyledText -styledtext_vshader.type = vs_5_0 -styledtext_pshader.input = textmask_VSPS -styledtext_pshader.header = ps_styledtext.hlslh -styledtext_pshader.entry = PS_StyledText -styledtext_pshader.type = ps_5_0 -outlinedtext_vshader.input = textmask_VSPS -outlinedtext_vshader.header = vs_outlinedtext.hlslh -outlinedtext_vshader.entry = VS_OutlinedText -outlinedtext_vshader.type = vs_5_0 -outlinedtext_pshader.input = textmask_VSPS -outlinedtext_pshader.header = ps_outlinedtext.hlslh -outlinedtext_pshader.entry = PS_OutlinedText -outlinedtext_pshader.type = ps_5_0 - -shadereffectdefault_VSPS = $$PWD/shadereffectdefault.hlsl -shadereffectdefault_vshader.input = shadereffectdefault_VSPS -shadereffectdefault_vshader.header = vs_shadereffectdefault.hlslh -shadereffectdefault_vshader.entry = VS_DefaultShaderEffect -shadereffectdefault_vshader.type = vs_5_0 -shadereffectdefault_pshader.input = shadereffectdefault_VSPS -shadereffectdefault_pshader.header = ps_shadereffectdefault.hlslh -shadereffectdefault_pshader.entry = PS_DefaultShaderEffect -shadereffectdefault_pshader.type = ps_5_0 - -sprite_VSPS = $$PWD/sprite.hlsl -sprite_vshader.input = sprite_VSPS -sprite_vshader.header = vs_sprite.hlslh -sprite_vshader.entry = VS_Sprite -sprite_vshader.type = vs_5_0 -sprite_pshader.input = sprite_VSPS -sprite_pshader.header = ps_sprite.hlslh -sprite_pshader.entry = PS_Sprite -sprite_pshader.type = ps_5_0 - -tdr_CS = $$PWD/tdr.hlsl -tdr_cshader.input = tdr_CS -tdr_cshader.header = cs_tdr.hlslh -tdr_cshader.entry = timeout -tdr_cshader.type = cs_5_0 - -HLSL_SHADERS = \ - vertexcolor_vshader vertexcolor_pshader \ - flatcolor_vshader flatcolor_pshader \ - stencilclip_vshader stencilclip_pshader \ - smoothcolor_vshader smoothcolor_pshader \ - texture_vshader texture_pshader \ - smoothtexture_vshader smoothtexture_pshader \ - mipmapgen_cshader \ - textmask_vshader textmask_pshader24 textmask_pshader32 textmask_pshader8 \ - styledtext_vshader styledtext_pshader outlinedtext_vshader outlinedtext_pshader \ - shadereffectdefault_vshader shadereffectdefault_pshader \ - sprite_vshader sprite_pshader \ - tdr_cshader - -load(hlsl_bytecode_header) diff --git a/src/plugins/scenegraph/d3d12/shaders/smoothcolor.hlsl b/src/plugins/scenegraph/d3d12/shaders/smoothcolor.hlsl deleted file mode 100644 index 4f69eea60f..0000000000 --- a/src/plugins/scenegraph/d3d12/shaders/smoothcolor.hlsl +++ /dev/null @@ -1,64 +0,0 @@ -struct VSInput -{ - float4 position : POSITION; - float4 color : COLOR; - float2 offset : TEXCOORD0; -}; - -cbuffer ConstantBuffer : register(b0) -{ - float4x4 mvp; - float opacity; - float2 pixelSize; -}; - -struct PSInput -{ - float4 position : SV_POSITION; - float4 color : COLOR; -}; - -PSInput VS_SmoothColor(VSInput input) -{ - PSInput result; - - float4 pos = mul(mvp, input.position); - - if (input.offset.x != 0.0) { - // In HLSL matrix packing is column-major by default (which is good) but the math is row-major (unlike GLSL). - float4 delta = float4(mvp._11, mvp._21, mvp._31, mvp._41) * input.offset.x; - float2 dir = delta.xy * pos.w - pos.xy * delta.w; - float2 ndir = 0.5 * pixelSize * normalize(dir / pixelSize); - dir -= ndir * delta.w * pos.w; - float numerator = dot(dir, ndir * pos.w * pos.w); - float scale = 0.0; - if (numerator < 0.0) - scale = 1.0; - else - scale = min(1.0, numerator / dot(dir, dir)); - pos += scale * delta; - } - - if (input.offset.y != 0.0) { - float4 delta = float4(mvp._12, mvp._22, mvp._32, mvp._42) * input.offset.y; - float2 dir = delta.xy * pos.w - pos.xy * delta.w; - float2 ndir = 0.5 * pixelSize * normalize(dir / pixelSize); - dir -= ndir * delta.w * pos.w; - float numerator = dot(dir, ndir * pos.w * pos.w); - float scale = 0.0; - if (numerator < 0.0) - scale = 1.0; - else - scale = min(1.0, numerator / dot(dir, dir)); - pos += scale * delta; - } - - result.position = pos; - result.color = input.color * opacity; - return result; -} - -float4 PS_SmoothColor(PSInput input) : SV_TARGET -{ - return input.color; -} diff --git a/src/plugins/scenegraph/d3d12/shaders/smoothtexture.hlsl b/src/plugins/scenegraph/d3d12/shaders/smoothtexture.hlsl deleted file mode 100644 index 05b1c6e9d4..0000000000 --- a/src/plugins/scenegraph/d3d12/shaders/smoothtexture.hlsl +++ /dev/null @@ -1,77 +0,0 @@ -struct VSInput -{ - float4 position : POSITION; - float2 coord : TEXCOORD0; - float2 offset : TEXCOORD1; - float2 coordOffset : TEXCOORD2; -}; - -cbuffer ConstantBuffer : register(b0) -{ - float4x4 mvp; - float opacity; - float2 pixelSize; -}; - -struct PSInput -{ - float4 position : SV_POSITION; - float2 coord : TEXCOORD0; - float vertexOpacity : TEXCOORD3; -}; - -Texture2D tex : register(t0); -SamplerState samp : register(s0); - -PSInput VS_SmoothTexture(VSInput input) -{ - PSInput result; - - float4 pos = mul(mvp, input.position); - float2 coord = input.coord; - - if (input.offset.x != 0.0) { - // In HLSL matrix packing is column-major by default (which is good) but the math is row-major (unlike GLSL). - float4 delta = float4(mvp._11, mvp._21, mvp._31, mvp._41) * input.offset.x; - float2 dir = delta.xy * pos.w - pos.xy * delta.w; - float2 ndir = 0.5 * pixelSize * normalize(dir / pixelSize); - dir -= ndir * delta.w * pos.w; - float numerator = dot(dir, ndir * pos.w * pos.w); - float scale = 0.0; - if (numerator < 0.0) - scale = 1.0; - else - scale = min(1.0, numerator / dot(dir, dir)); - pos += scale * delta; - coord.x += scale * input.coordOffset.x; - } - - if (input.offset.y != 0.0) { - float4 delta = float4(mvp._12, mvp._22, mvp._32, mvp._42) * input.offset.y; - float2 dir = delta.xy * pos.w - pos.xy * delta.w; - float2 ndir = 0.5 * pixelSize * normalize(dir / pixelSize); - dir -= ndir * delta.w * pos.w; - float numerator = dot(dir, ndir * pos.w * pos.w); - float scale = 0.0; - if (numerator < 0.0) - scale = 1.0; - else - scale = min(1.0, numerator / dot(dir, dir)); - pos += scale * delta; - coord.y += scale * input.coordOffset.y; - } - - if ((input.offset.x != 0.0 || input.offset.y != 0.0) && (input.coordOffset.x == 0.0 && input.coordOffset.y == 0.0)) - result.vertexOpacity = 0.0; - else - result.vertexOpacity = opacity; - - result.position = pos; - result.coord = coord; - return result; -} - -float4 PS_SmoothTexture(PSInput input) : SV_TARGET -{ - return tex.Sample(samp, input.coord) * input.vertexOpacity; -} diff --git a/src/plugins/scenegraph/d3d12/shaders/sprite.hlsl b/src/plugins/scenegraph/d3d12/shaders/sprite.hlsl deleted file mode 100644 index d4e3b066ee..0000000000 --- a/src/plugins/scenegraph/d3d12/shaders/sprite.hlsl +++ /dev/null @@ -1,43 +0,0 @@ -struct VSInput -{ - float4 position : POSITION; - float2 coord : TEXCOORD0; -}; - -cbuffer ConstantBuffer : register(b0) -{ - float4x4 mvp; - float4 animPos; - float3 animData; - float opacity; -}; - -struct PSInput -{ - float4 position : SV_POSITION; - float4 fTexS : TEXCOORD0; - float progress : TEXCOORD1; -}; - -Texture2D tex : register(t0); -SamplerState samp : register(s0); - -PSInput VS_Sprite(VSInput input) -{ - PSInput result; - - result.position = mul(mvp, input.position); - result.progress = animData.z; - - // Calculate frame location in texture - result.fTexS.xy = animPos.xy + input.coord.xy * animData.xy; - // Next frame is also passed, for interpolation - result.fTexS.zw = animPos.zw + input.coord.xy * animData.xy; - - return result; -} - -float4 PS_Sprite(PSInput input) : SV_TARGET -{ - return lerp(tex.Sample(samp, input.fTexS.xy), tex.Sample(samp, input.fTexS.zw), input.progress) * opacity; -} diff --git a/src/plugins/scenegraph/d3d12/shaders/stencilclip.hlsl b/src/plugins/scenegraph/d3d12/shaders/stencilclip.hlsl deleted file mode 100644 index 9aff84d261..0000000000 --- a/src/plugins/scenegraph/d3d12/shaders/stencilclip.hlsl +++ /dev/null @@ -1,26 +0,0 @@ -struct VSInput -{ - float4 position : POSITION; -}; - -cbuffer ConstantBuffer : register(b0) -{ - float4x4 mvp; -}; - -struct PSInput -{ - float4 position : SV_POSITION; -}; - -PSInput VS_StencilClip(VSInput input) -{ - PSInput result; - result.position = mul(mvp, input.position); - return result; -} - -float4 PS_StencilClip(PSInput input) : SV_TARGET -{ - return float4(0.81, 0.83, 0.12, 1.0); // Trolltech green ftw! -} diff --git a/src/plugins/scenegraph/d3d12/shaders/tdr.hlsl b/src/plugins/scenegraph/d3d12/shaders/tdr.hlsl deleted file mode 100644 index f32d4fbace..0000000000 --- a/src/plugins/scenegraph/d3d12/shaders/tdr.hlsl +++ /dev/null @@ -1,11 +0,0 @@ -// http://gamedev.stackexchange.com/questions/108141/how-can-i-test-dxgi-error-device-removed-error-handling - -RWBuffer<uint> uav; -cbuffer ConstantBuffer { uint zero; } - -[numthreads(256, 1, 1)] -void timeout(uint3 id: SV_DispatchThreadID) -{ - while (zero == 0) - uav[id.x] = zero; -} diff --git a/src/plugins/scenegraph/d3d12/shaders/textmask.hlsl b/src/plugins/scenegraph/d3d12/shaders/textmask.hlsl deleted file mode 100644 index bb9381e7c0..0000000000 --- a/src/plugins/scenegraph/d3d12/shaders/textmask.hlsl +++ /dev/null @@ -1,104 +0,0 @@ -struct VSInput -{ - float4 position : POSITION; - float2 coord : TEXCOORD0; -}; - -cbuffer ConstantBuffer : register(b0) -{ - float4x4 mvp; - float2 textureScale; - float dpr; - float color; // for TextMask24 and 32 - float4 colorVec; // for TextMask8 and Styled and Outlined - float2 shift; // for Styled - float4 styleColor; // for Styled and Outlined -}; - -struct PSInput -{ - float4 position : SV_POSITION; - float2 coord : TEXCOORD0; -}; - -Texture2D tex : register(t0); -SamplerState samp : register(s0); - -PSInput VS_TextMask(VSInput input) -{ - PSInput result; - result.position = mul(mvp, floor(input.position * dpr + 0.5) / dpr); - result.coord = input.coord * textureScale; - return result; -} - -float4 PS_TextMask24(PSInput input) : SV_TARGET -{ - float4 glyph = tex.Sample(samp, input.coord); - return float4(glyph.rgb * color, glyph.a); -} - -float4 PS_TextMask32(PSInput input) : SV_TARGET -{ - return tex.Sample(samp, input.coord) * color; -} - -float4 PS_TextMask8(PSInput input) : SV_TARGET -{ - return colorVec * tex.Sample(samp, input.coord).a; -} - -struct StyledPSInput -{ - float4 position : SV_POSITION; - float2 coord : TEXCOORD0; - float2 shiftedCoord : TEXCOORD1; -}; - -StyledPSInput VS_StyledText(VSInput input) -{ - StyledPSInput result; - result.position = mul(mvp, floor(input.position * dpr + 0.5) / dpr); - result.coord = input.coord * textureScale; - result.shiftedCoord = (input.coord - shift) * textureScale; - return result; -} - -float4 PS_StyledText(StyledPSInput input) : SV_TARGET -{ - float glyph = tex.Sample(samp, input.coord).a; - float style = clamp(tex.Sample(samp, input.shiftedCoord).a - glyph, 0.0, 1.0); - return style * styleColor + glyph * colorVec; -} - -struct OutlinedPSInput -{ - float4 position : SV_POSITION; - float2 coord : TEXCOORD0; - float2 coordUp : TEXCOORD1; - float2 coordDown : TEXCOORD2; - float2 coordLeft : TEXCOORD3; - float2 coordRight : TEXCOORD4; -}; - -OutlinedPSInput VS_OutlinedText(VSInput input) -{ - OutlinedPSInput result; - result.position = mul(mvp, floor(input.position * dpr + 0.5) / dpr); - result.coord = input.coord * textureScale; - result.coordUp = (input.coord - float2(0.0, -1.0)) * textureScale; - result.coordDown = (input.coord - float2(0.0, 1.0)) * textureScale; - result.coordLeft = (input.coord - float2(-1.0, 0.0)) * textureScale; - result.coordRight = (input.coord - float2(1.0, 0.0)) * textureScale; - return result; -} - -float4 PS_OutlinedText(OutlinedPSInput input) : SV_TARGET -{ - float glyph = tex.Sample(samp, input.coord).a; - float outline = clamp(clamp(tex.Sample(samp, input.coordUp).a - + tex.Sample(samp, input.coordDown).a - + tex.Sample(samp, input.coordLeft).a - + tex.Sample(samp, input.coordRight).a, 0.0, 1.0) - glyph, 0.0, 1.0); - return outline * styleColor + glyph * colorVec; -} diff --git a/src/plugins/scenegraph/d3d12/shaders/texture.hlsl b/src/plugins/scenegraph/d3d12/shaders/texture.hlsl deleted file mode 100644 index 1ae6579e8d..0000000000 --- a/src/plugins/scenegraph/d3d12/shaders/texture.hlsl +++ /dev/null @@ -1,33 +0,0 @@ -struct VSInput -{ - float4 position : POSITION; - float2 coord : TEXCOORD0; -}; - -cbuffer ConstantBuffer : register(b0) -{ - float4x4 mvp; - float opacity; -}; - -struct PSInput -{ - float4 position : SV_POSITION; - float2 coord : TEXCOORD0; -}; - -Texture2D tex : register(t0); -SamplerState samp : register(s0); - -PSInput VS_Texture(VSInput input) -{ - PSInput result; - result.position = mul(mvp, input.position); - result.coord = input.coord; - return result; -} - -float4 PS_Texture(PSInput input) : SV_TARGET -{ - return tex.Sample(samp, input.coord) * opacity; -} diff --git a/src/plugins/scenegraph/d3d12/shaders/vertexcolor.hlsl b/src/plugins/scenegraph/d3d12/shaders/vertexcolor.hlsl deleted file mode 100644 index a0569bb5c1..0000000000 --- a/src/plugins/scenegraph/d3d12/shaders/vertexcolor.hlsl +++ /dev/null @@ -1,32 +0,0 @@ -struct VSInput -{ - float4 position : POSITION; - float4 color : COLOR; -}; - -cbuffer ConstantBuffer : register(b0) -{ - float4x4 mvp; - float opacity; -}; - -struct PSInput -{ - float4 position : SV_POSITION; - float4 color : COLOR; -}; - -PSInput VS_VertexColor(VSInput input) -{ - PSInput result; - - result.position = mul(mvp, input.position); - result.color = input.color * opacity; - - return result; -} - -float4 PS_VertexColor(PSInput input) : SV_TARGET -{ - return input.color; -} diff --git a/src/plugins/scenegraph/scenegraph.pro b/src/plugins/scenegraph/scenegraph.pro index 39c0c0815c..9cc521a191 100644 --- a/src/plugins/scenegraph/scenegraph.pro +++ b/src/plugins/scenegraph/scenegraph.pro @@ -1,5 +1,4 @@ TEMPLATE = subdirs QT_FOR_CONFIG += quick -qtConfig(d3d12): SUBDIRS += d3d12 qtConfig(openvg): SUBDIRS += openvg diff --git a/src/qml/common/qv4compileddata_p.h b/src/qml/common/qv4compileddata_p.h index a5a1cf8969..7d6ef14854 100644 --- a/src/qml/common/qv4compileddata_p.h +++ b/src/qml/common/qv4compileddata_p.h @@ -57,6 +57,7 @@ #include <QtCore/qvector.h> #include <QtCore/qstringlist.h> #include <QtCore/qhash.h> +#include <QtCore/qversionnumber.h> #if QT_CONFIG(temporaryfile) #include <QtCore/qsavefile.h> @@ -65,6 +66,7 @@ #include <private/qendian_p.h> #include <private/qv4staticvalue_p.h> #include <functional> +#include <limits.h> QT_BEGIN_NAMESPACE @@ -75,7 +77,7 @@ QT_BEGIN_NAMESPACE // Also change the comment behind the number to describe the latest change. This has the added // benefit that if another patch changes the version too, it will result in a merge conflict, and // not get removed silently. -#define QV4_DATA_STRUCTURE_VERSION 0x29// support additional required property features +#define QV4_DATA_STRUCTURE_VERSION 0x30// support additional required property features class QIODevice; class QQmlTypeNameCache; @@ -195,39 +197,14 @@ struct JSClass }; static_assert(sizeof(JSClass) == 4, "JSClass structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); -// This data structure is intended to be binary compatible with QStringData/QStaticStringData on -// 64-bit and 32-bit little-endian architectures, in all directions. So the same structure mapped -// from a file must be castable to a QStringData regardless of the pointer size. With the first -// few fields that's easy, they're always 32-bit. However the offset field of QArrayData is a -// ptrdiff_t and thus variable in size. -// On 64-bit systems compilers enforce an 8-byte alignment and thus place it at offset 16, while -// on 32-bit systems offset 12 is sufficient. Therefore the two values don't overlap and contain -// the same value. struct String { - qint32_le refcount; // -1 qint32_le size; - quint32_le allocAndCapacityReservedFlag; // 0 - quint32_le offsetOn32Bit; - quint64_le offsetOn64Bit; - // uint16 strdata[] static int calculateSize(const QString &str) { return (sizeof(String) + (str.length() + 1) * sizeof(quint16) + 7) & ~0x7; } }; -static_assert(sizeof(String) == 24, "String structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); - -// Ensure compatibility with QString -static_assert(offsetof(QArrayData, ref) == offsetof(String, refcount), "refcount must be at the same location"); -static_assert(offsetof(QArrayData, size) == offsetof(String, size), "size must be at the same location"); -static_assert(offsetof(String, offsetOn64Bit) == 16, "offset must be at 8-byte aligned location"); -static_assert(offsetof(String, offsetOn32Bit) == 12, "offset must be at 4-byte aligned location"); -#if QT_POINTER_SIZE == 8 -static_assert(offsetof(QArrayData, offset) == offsetof(String, offsetOn64Bit), "offset must be at the same location"); -#else -static_assert(offsetof(QArrayData, offset) == offsetof(String, offsetOn32Bit), "offset must be at the same location"); -#endif struct CodeOffsetToLine { quint32_le codeOffset; @@ -905,14 +882,16 @@ struct Import quint32_le uriIndex; quint32_le qualifierIndex; - qint32_le majorVersion; - qint32_le minorVersion; - Location location; + QTypeRevision version; + quint16_le reserved; - Import() { type = 0; uriIndex = 0; qualifierIndex = 0; majorVersion = 0; minorVersion = 0; } + Import() + { + type = 0; uriIndex = 0; qualifierIndex = 0; version = QTypeRevision::zero(); reserved = 0; + } }; -static_assert(sizeof(Import) == 24, "Import structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); +static_assert(sizeof(Import) == 20, "Import structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); struct QmlUnit { @@ -1016,14 +995,13 @@ struct Unit const quint32_le *offsetTable = reinterpret_cast<const quint32_le*>((reinterpret_cast<const char *>(this)) + offsetToStringTable); const quint32_le offset = offsetTable[idx]; const String *str = reinterpret_cast<const String*>(reinterpret_cast<const char *>(this) + offset); + Q_ASSERT(str->size >= 0); if (str->size == 0) return QString(); #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN - if (flags & StaticData) { - const QStringDataPtr holder = { const_cast<QStringData *>(reinterpret_cast<const QStringData*>(str)) }; - return QString(holder); - } const QChar *characters = reinterpret_cast<const QChar *>(str + 1); + if (flags & StaticData) + return QString::fromRawData(characters, str->size); return QString(characters, str->size); #else const quint16_le *characters = reinterpret_cast<const quint16_le *>(str + 1); diff --git a/src/qml/common/qv4stringtoarrayindex_p.h b/src/qml/common/qv4stringtoarrayindex_p.h index 61bd988d1e..d4b064f865 100644 --- a/src/qml/common/qv4stringtoarrayindex_p.h +++ b/src/qml/common/qv4stringtoarrayindex_p.h @@ -65,6 +65,8 @@ inline uint charToUInt(const char *ch) { return static_cast<unsigned char>(*ch); template <typename T> uint stringToArrayIndex(const T *ch, const T *end) { + if (ch == end) + return std::numeric_limits<uint>::max(); uint i = charToUInt(ch) - '0'; if (i > 9) return std::numeric_limits<uint>::max(); diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index a3ee431e90..4de7734ecf 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -407,11 +407,7 @@ void ScriptDirectivesCollector::importModule(const QString &uri, const QString & QV4::CompiledData::Import *import = engine->pool()->New<QV4::CompiledData::Import>(); import->type = QV4::CompiledData::Import::ImportLibrary; import->uriIndex = jsGenerator->registerString(uri); - int vmaj; - int vmin; - IRBuilder::extractVersion(QStringRef(&version), &vmaj, &vmin); - import->majorVersion = vmaj; - import->minorVersion = vmin; + import->version = IRBuilder::extractVersion(QStringRef(&version)); import->qualifierIndex = jsGenerator->registerString(module); import->location.line = lineNumber; import->location.column = column; @@ -752,16 +748,14 @@ bool IRBuilder::visit(QQmlJS::AST::UiImport *node) } if (node->version) { - import->majorVersion = node->version->majorVersion; - import->minorVersion = node->version->minorVersion; + import->version = node->version->version; } else if (import->type == QV4::CompiledData::Import::ImportLibrary) { recordError(node->importIdToken, QCoreApplication::translate("QQmlParser","Library import requires a version")); return false; } else { // For backward compatibility in how the imports are loaded we - // must otherwise initialize the major and minor version to -1. - import->majorVersion = -1; - import->minorVersion = -1; + // must otherwise initialize the major and minor version to invalid. + import->version = QTypeRevision(); } import->location.line = node->importToken.startLine; @@ -1055,22 +1049,15 @@ QStringRef IRBuilder::asStringRef(QQmlJS::AST::Node *node) return textRefAt(node->firstSourceLocation(), node->lastSourceLocation()); } -void IRBuilder::extractVersion(const QStringRef &string, int *maj, int *min) +QTypeRevision IRBuilder::extractVersion(const QStringRef &string) { - *maj = -1; *min = -1; + if (string.isEmpty()) + return QTypeRevision(); - if (!string.isEmpty()) { - - int dot = string.indexOf(QLatin1Char('.')); - - if (dot < 0) { - *maj = string.toInt(); - *min = 0; - } else { - *maj = string.left(dot).toInt(); - *min = string.mid(dot + 1).toInt(); - } - } + const int dot = string.indexOf(QLatin1Char('.')); + return (dot < 0) + ? QTypeRevision::fromVersion(string.toInt(), 0) + : QTypeRevision::fromVersion(string.left(dot).toInt(), string.mid(dot + 1).toInt()); } QStringRef IRBuilder::textRefAt(const QQmlJS::AST::SourceLocation &first, const QQmlJS::AST::SourceLocation &last) const diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h index 32921638af..ae74254a42 100644 --- a/src/qml/compiler/qqmlirbuilder_p.h +++ b/src/qml/compiler/qqmlirbuilder_p.h @@ -498,7 +498,7 @@ public: static QString asString(QQmlJS::AST::UiQualifiedId *node); QStringRef asStringRef(QQmlJS::AST::Node *node); - static void extractVersion(const QStringRef &string, int *maj, int *min); + static QTypeRevision extractVersion(const QStringRef &string); QStringRef textRefAt(const QQmlJS::AST::SourceLocation &loc) const { return QStringRef(&sourceCode, loc.offset, loc.length); } QStringRef textRefAt(const QQmlJS::AST::SourceLocation &first, diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp index acc4b02e96..0c0a005689 100644 --- a/src/qml/compiler/qv4compiler.cpp +++ b/src/qml/compiler/qv4compiler.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2018 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQml module of the Qt Toolkit. @@ -47,6 +48,7 @@ #include <private/qml_compile_hash_p.h> #include <private/qqmlirbuilder_p.h> #include <QCryptographicHash> +#include <QtEndian> // Efficient implementation that takes advantage of powers of two. static inline size_t roundUpToMultipleOf(size_t divisor, size_t x) @@ -108,19 +110,11 @@ void QV4::Compiler::StringTableGenerator::serialize(CompiledData::Unit *unit) QV4::CompiledData::String *s = reinterpret_cast<QV4::CompiledData::String *>(stringData); Q_ASSERT(reinterpret_cast<uintptr_t>(s) % alignof(QV4::CompiledData::String) == 0); - s->refcount = -1; + Q_ASSERT(qstr.length() >= 0); s->size = qstr.length(); - s->allocAndCapacityReservedFlag = 0; - s->offsetOn32Bit = sizeof(QV4::CompiledData::String); - s->offsetOn64Bit = sizeof(QV4::CompiledData::String); ushort *uc = reinterpret_cast<ushort *>(reinterpret_cast<char *>(s) + sizeof(*s)); -#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN - memcpy(uc, qstr.constData(), s->size * sizeof(ushort)); -#else - for (int i = 0; i < s->size; ++i) - uc[i] = qToLittleEndian<ushort>(qstr.at(i).unicode()); -#endif + qToLittleEndian<ushort>(qstr.constData(), s->size, uc); uc[s->size] = 0; stringData += QV4::CompiledData::String::calculateSize(qstr); diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h index c0dd696b8a..254e1c46e9 100644 --- a/src/qml/compiler/qv4instr_moth_p.h +++ b/src/qml/compiler/qv4instr_moth_p.h @@ -348,7 +348,7 @@ QT_BEGIN_NAMESPACE #endif #endif -#define MOTH_INSTR_ALIGN_MASK (Q_ALIGNOF(QV4::Moth::Instr) - 1) +#define MOTH_INSTR_ALIGN_MASK (alignof(QV4::Moth::Instr) - 1) #define MOTH_INSTR_ENUM(I) I, I##_Wide, #define MOTH_INSTR_SIZE(I) (sizeof(QV4::Moth::Instr::instr_##I)) diff --git a/src/qml/doc/src/cppintegration/data.qdoc b/src/qml/doc/src/cppintegration/data.qdoc index 7c2693508c..4095cd22ea 100644 --- a/src/qml/doc/src/cppintegration/data.qdoc +++ b/src/qml/doc/src/cppintegration/data.qdoc @@ -284,7 +284,7 @@ In particular, QML currently supports: \li \c {std::vector<bool>} \endlist -and all registered QList, QVector, QQueue, QStack, QSet, QLinkedList, std::list, +and all registered QList, QVector, QQueue, QStack, QSet, std::list, std::vector that contain a type marked with \l Q_DECLARE_METATYPE. These sequence types are implemented directly in terms of the underlying C++ diff --git a/src/qml/doc/src/external-resources.qdoc b/src/qml/doc/src/external-resources.qdoc index 68c5ab4664..17ac7693bc 100644 --- a/src/qml/doc/src/external-resources.qdoc +++ b/src/qml/doc/src/external-resources.qdoc @@ -45,7 +45,7 @@ \title Mozilla Developer Network Date Reference */ /*! - \externalpage hhttps://www.froglogic.com/squish/gui-testing + \externalpage https://www.froglogic.com/squish/gui-testing \title Squish */ /*! diff --git a/src/qml/jsapi/qjsengine_p.h b/src/qml/jsapi/qjsengine_p.h index 7866a5bdda..37376a1485 100644 --- a/src/qml/jsapi/qjsengine_p.h +++ b/src/qml/jsapi/qjsengine_p.h @@ -110,8 +110,8 @@ public: QString uiLanguage; // These methods may be called from the QML loader thread - inline QQmlPropertyCache *cache(QObject *obj, int minorVersion = -1); - inline QQmlPropertyCache *cache(const QMetaObject *, int minorVersion = -1); + inline QQmlPropertyCache *cache(QObject *obj, QTypeRevision version = QTypeRevision()); + inline QQmlPropertyCache *cache(const QMetaObject *obj, QTypeRevision version = QTypeRevision()); }; QJSEnginePrivate::Locker::Locker(const QJSEngine *e) @@ -161,14 +161,14 @@ and deleted before the loader thread has a chance to use or reference it. This can't currently happen as the cache holds a reference to the QQmlPropertyCache until the QQmlEngine is destroyed. */ -QQmlPropertyCache *QJSEnginePrivate::cache(QObject *obj, int minorVersion) +QQmlPropertyCache *QJSEnginePrivate::cache(QObject *obj, QTypeRevision version) { if (!obj || QObjectPrivate::get(obj)->metaObject || QObjectPrivate::get(obj)->wasDeleted) return nullptr; Locker locker(this); const QMetaObject *mo = obj->metaObject(); - return QQmlMetaType::propertyCache(mo, minorVersion); + return QQmlMetaType::propertyCache(mo, version); } /*! @@ -180,12 +180,12 @@ exist for the lifetime of the QQmlEngine. The returned cache is not referenced, so if it is to be stored, call addref(). */ -QQmlPropertyCache *QJSEnginePrivate::cache(const QMetaObject *metaObject, int minorVersion) +QQmlPropertyCache *QJSEnginePrivate::cache(const QMetaObject *metaObject, QTypeRevision version) { Q_ASSERT(metaObject); Locker locker(this); - return QQmlMetaType::propertyCache(metaObject, minorVersion); + return QQmlMetaType::propertyCache(metaObject, version); } diff --git a/src/qml/jsruntime/qv4arraybuffer.cpp b/src/qml/jsruntime/qv4arraybuffer.cpp index a99ec16943..a2fac21b29 100644 --- a/src/qml/jsruntime/qv4arraybuffer.cpp +++ b/src/qml/jsruntime/qv4arraybuffer.cpp @@ -127,13 +127,17 @@ ReturnedValue ArrayBufferCtor::method_isView(const FunctionObject *, const Value void Heap::SharedArrayBuffer::init(size_t length) { Object::init(); + QPair<QTypedArrayData<char> *, char *> pair; if (length < UINT_MAX) - data = QTypedArrayData<char>::allocate(length + 1); - if (!data) { + pair = QTypedArrayData<char>::allocate(length + 1); + if (!pair.first) { + new (&d) QArrayDataPointer<char>(); internalClass->engine->throwRangeError(QStringLiteral("ArrayBuffer: out of memory")); return; } - data->size = int(length); + auto data = new (&d) QArrayDataPointer<char>{ pair.first, pair.second, uint(length) }; + + // can't use appendInitialize() because we want to set the terminating '\0' memset(data->data(), 0, length + 1); isShared = true; } @@ -141,41 +145,24 @@ void Heap::SharedArrayBuffer::init(size_t length) void Heap::SharedArrayBuffer::init(const QByteArray& array) { Object::init(); - data = const_cast<QByteArray&>(array).data_ptr(); - data->ref.ref(); + new (&d) QArrayDataPointer<char>(*const_cast<QByteArray &>(array).data_ptr()); isShared = true; } void Heap::SharedArrayBuffer::destroy() { - if (data && !data->ref.deref()) - QTypedArrayData<char>::deallocate(data); + data().~QArrayDataPointer(); Object::destroy(); } QByteArray ArrayBuffer::asByteArray() const { - QByteArrayDataPtr ba = { d()->data }; - ba.ptr->ref.ref(); - return QByteArray(ba); + return QByteArray(d()->data()); } -void ArrayBuffer::detach() { - if (!d()->data->ref.isShared()) - return; - - QTypedArrayData<char> *oldData = d()->data; - - d()->data = QTypedArrayData<char>::allocate(oldData->size + 1); - if (!d()->data) { - engine()->throwRangeError(QStringLiteral("ArrayBuffer: out of memory")); - return; - } - - memcpy(d()->data->data(), oldData->data(), oldData->size + 1); - - if (!oldData->ref.deref()) - QTypedArrayData<char>::deallocate(oldData); +void ArrayBuffer::detach() +{ + d()->data().detach(); } @@ -200,7 +187,7 @@ ReturnedValue SharedArrayBufferPrototype::method_get_byteLength(const FunctionOb if (!a || a->isDetachedBuffer() || !a->isSharedArrayBuffer()) return b->engine()->throwTypeError(); - return Encode(a->d()->data->size); + return Encode(a->d()->data()->size); } ReturnedValue SharedArrayBufferPrototype::method_slice(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc) @@ -217,12 +204,12 @@ ReturnedValue SharedArrayBufferPrototype::slice(const FunctionObject *b, const V double start = argc > 0 ? argv[0].toInteger() : 0; double end = (argc < 2 || argv[1].isUndefined()) ? - a->d()->data->size : argv[1].toInteger(); + a->d()->data()->size : argv[1].toInteger(); if (scope.hasException()) return QV4::Encode::undefined(); - double first = (start < 0) ? qMax(a->d()->data->size + start, 0.) : qMin(start, (double)a->d()->data->size); - double final = (end < 0) ? qMax(a->d()->data->size + end, 0.) : qMin(end, (double)a->d()->data->size); + double first = (start < 0) ? qMax(a->d()->data()->size + start, 0.) : qMin(start, (double)a->d()->data()->size); + double final = (end < 0) ? qMax(a->d()->data()->size + end, 0.) : qMin(end, (double)a->d()->data()->size); const FunctionObject *constructor = a->speciesConstructor(scope, shared ? scope.engine->sharedArrayBufferCtor() : scope.engine->arrayBufferCtor()); if (!constructor) @@ -231,13 +218,13 @@ ReturnedValue SharedArrayBufferPrototype::slice(const FunctionObject *b, const V double newLen = qMax(final - first, 0.); ScopedValue argument(scope, QV4::Encode(newLen)); QV4::Scoped<SharedArrayBuffer> newBuffer(scope, constructor->callAsConstructor(argument, 1)); - if (!newBuffer || newBuffer->d()->data->size < (int)newLen || + if (!newBuffer || newBuffer->d()->data()->size < newLen || newBuffer->isDetachedBuffer() || (newBuffer->isSharedArrayBuffer() != shared) || newBuffer->sameValue(*a) || a->isDetachedBuffer()) return scope.engine->throwTypeError(); - memcpy(newBuffer->d()->data->data(), a->d()->data->data() + (uint)first, newLen); + memcpy(newBuffer->d()->data()->data(), a->d()->data()->data() + (uint)first, newLen); return newBuffer->asReturnedValue(); } @@ -265,7 +252,7 @@ ReturnedValue ArrayBufferPrototype::method_get_byteLength(const FunctionObject * if (!a || a->isDetachedBuffer() || a->isSharedArrayBuffer()) return f->engine()->throwTypeError(); - return Encode(a->d()->data->size); + return Encode(a->d()->data()->size); } ReturnedValue ArrayBufferPrototype::method_slice(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc) diff --git a/src/qml/jsruntime/qv4arraybuffer_p.h b/src/qml/jsruntime/qv4arraybuffer_p.h index 8344fa2554..1873c41261 100644 --- a/src/qml/jsruntime/qv4arraybuffer_p.h +++ b/src/qml/jsruntime/qv4arraybuffer_p.h @@ -52,6 +52,7 @@ #include "qv4object_p.h" #include "qv4functionobject_p.h" +#include <QtCore/qarraydatapointer.h> QT_BEGIN_NAMESPACE @@ -71,12 +72,14 @@ struct Q_QML_PRIVATE_EXPORT SharedArrayBuffer : Object { void init(size_t length); void init(const QByteArray& array); void destroy(); - QTypedArrayData<char> *data; + std::aligned_storage_t<sizeof(QArrayDataPointer<char>), alignof(QArrayDataPointer<char>)> d; + const QArrayDataPointer<char> &data() const { return *reinterpret_cast<const QArrayDataPointer<char> *>(&d); } + QArrayDataPointer<char> &data() { return *reinterpret_cast<QArrayDataPointer<char> *>(&d); } bool isShared; - uint byteLength() const { return data ? data->size : 0; } + uint byteLength() const { return data().size; } - bool isDetachedBuffer() const { return !data; } + bool isDetachedBuffer() const { return data().isNull(); } bool isSharedArrayBuffer() const { return isShared; } }; @@ -90,9 +93,7 @@ struct Q_QML_PRIVATE_EXPORT ArrayBuffer : SharedArrayBuffer { isShared = false; } void detachArrayBuffer() { - if (data && !data->ref.deref()) - QTypedArrayData<char>::deallocate(data); - data = nullptr; + data().clear(); } }; @@ -124,11 +125,11 @@ struct Q_QML_PRIVATE_EXPORT SharedArrayBuffer : Object QByteArray asByteArray() const; uint byteLength() const { return d()->byteLength(); } - char *data() { Q_ASSERT(d()->data); return d()->data->data(); } - const char *constData() { Q_ASSERT(d()->data); return d()->data->data(); } + char *data() { return d()->data()->data(); } + const char *constData() { return d()->data()->data(); } - bool isShared() { return d()->data->ref.isShared(); } - bool isDetachedBuffer() const { return !d()->data; } + bool isShared() { return d()->data()->isShared(); } + bool isDetachedBuffer() const { return d()->data().isNull(); } bool isSharedArrayBuffer() const { return d()->isShared; } }; @@ -140,11 +141,11 @@ struct Q_QML_PRIVATE_EXPORT ArrayBuffer : SharedArrayBuffer QByteArray asByteArray() const; uint byteLength() const { return d()->byteLength(); } - char *data() { detach(); return d()->data ? d()->data->data() : nullptr; } + char *data() { if (d()->data().needsDetach()) detach(); return d()->data().data(); } // ### is that detach needed? - const char *constData() { detach(); return d()->data ? d()->data->data() : nullptr; } + const char *constData() const { return d()->data().data(); } - bool isShared() { return d()->data && d()->data->ref.isShared(); } + bool isShared() { return d()->data()->isShared(); } void detach(); void detachArrayBuffer() { d()->detachArrayBuffer(); } }; diff --git a/src/qml/jsruntime/qv4dataview.cpp b/src/qml/jsruntime/qv4dataview.cpp index 5ab8cf2dcb..bb1acb963e 100644 --- a/src/qml/jsruntime/qv4dataview.cpp +++ b/src/qml/jsruntime/qv4dataview.cpp @@ -85,7 +85,7 @@ ReturnedValue DataViewCtor::virtualCallAsConstructor(const FunctionObject *f, co if (buffer->isDetachedBuffer()) return scope.engine->throwTypeError(); - uint bufferLength = buffer->d()->data->size; + uint bufferLength = buffer->d()->data()->size; if (offset > bufferLength) return scope.engine->throwRangeError(QStringLiteral("DataView: constructor arguments out of range")); @@ -197,7 +197,7 @@ ReturnedValue DataViewPrototype::method_getChar(const FunctionObject *b, const V return e->throwRangeError(QStringLiteral("index out of range")); idx += v->d()->byteOffset; - T t = T(v->d()->buffer->data->data()[idx]); + T t = T(v->d()->buffer->data()->data()[idx]); return Encode((int)t); } @@ -221,8 +221,8 @@ ReturnedValue DataViewPrototype::method_get(const FunctionObject *b, const Value bool littleEndian = argc < 2 ? false : argv[1].toBoolean(); T t = littleEndian - ? qFromLittleEndian<T>((uchar *)v->d()->buffer->data->data() + idx) - : qFromBigEndian<T>((uchar *)v->d()->buffer->data->data() + idx); + ? qFromLittleEndian<T>((uchar *)v->d()->buffer->data()->data() + idx) + : qFromBigEndian<T>((uchar *)v->d()->buffer->data()->data() + idx); return Encode(t); } @@ -252,8 +252,8 @@ ReturnedValue DataViewPrototype::method_getFloat(const FunctionObject *b, const float f; } u; u.i = littleEndian - ? qFromLittleEndian<uint>((uchar *)v->d()->buffer->data->data() + idx) - : qFromBigEndian<uint>((uchar *)v->d()->buffer->data->data() + idx); + ? qFromLittleEndian<uint>((uchar *)v->d()->buffer->data()->data() + idx) + : qFromBigEndian<uint>((uchar *)v->d()->buffer->data()->data() + idx); return Encode(u.f); } else { Q_ASSERT(sizeof(T) == 8); @@ -262,8 +262,8 @@ ReturnedValue DataViewPrototype::method_getFloat(const FunctionObject *b, const double d; } u; u.i = littleEndian - ? qFromLittleEndian<quint64>((uchar *)v->d()->buffer->data->data() + idx) - : qFromBigEndian<quint64>((uchar *)v->d()->buffer->data->data() + idx); + ? qFromLittleEndian<quint64>((uchar *)v->d()->buffer->data()->data() + idx) + : qFromBigEndian<quint64>((uchar *)v->d()->buffer->data()->data() + idx); return Encode(u.d); } } @@ -288,7 +288,7 @@ ReturnedValue DataViewPrototype::method_setChar(const FunctionObject *b, const V return e->throwRangeError(QStringLiteral("index out of range")); idx += v->d()->byteOffset; - v->d()->buffer->data->data()[idx] = (char)val; + v->d()->buffer->data()->data()[idx] = (char)val; RETURN_UNDEFINED(); } @@ -316,9 +316,9 @@ ReturnedValue DataViewPrototype::method_set(const FunctionObject *b, const Value if (littleEndian) - qToLittleEndian<T>(val, (uchar *)v->d()->buffer->data->data() + idx); + qToLittleEndian<T>(val, (uchar *)v->d()->buffer->data()->data() + idx); else - qToBigEndian<T>(val, (uchar *)v->d()->buffer->data->data() + idx); + qToBigEndian<T>(val, (uchar *)v->d()->buffer->data()->data() + idx); RETURN_UNDEFINED(); } @@ -352,9 +352,9 @@ ReturnedValue DataViewPrototype::method_setFloat(const FunctionObject *b, const } u; u.f = val; if (littleEndian) - qToLittleEndian(u.i, (uchar *)v->d()->buffer->data->data() + idx); + qToLittleEndian(u.i, (uchar *)v->d()->buffer->data()->data() + idx); else - qToBigEndian(u.i, (uchar *)v->d()->buffer->data->data() + idx); + qToBigEndian(u.i, (uchar *)v->d()->buffer->data()->data() + idx); } else { Q_ASSERT(sizeof(T) == 8); union { @@ -363,9 +363,9 @@ ReturnedValue DataViewPrototype::method_setFloat(const FunctionObject *b, const } u; u.d = val; if (littleEndian) - qToLittleEndian(u.i, (uchar *)v->d()->buffer->data->data() + idx); + qToLittleEndian(u.i, (uchar *)v->d()->buffer->data()->data() + idx); else - qToBigEndian(u.i, (uchar *)v->d()->buffer->data->data() + idx); + qToBigEndian(u.i, (uchar *)v->d()->buffer->data()->data() + idx); } RETURN_UNDEFINED(); } diff --git a/src/qml/jsruntime/qv4executablecompilationunit.cpp b/src/qml/jsruntime/qv4executablecompilationunit.cpp index fa4a1f1ce4..962b23fad6 100644 --- a/src/qml/jsruntime/qv4executablecompilationunit.cpp +++ b/src/qml/jsruntime/qv4executablecompilationunit.cpp @@ -817,7 +817,7 @@ QQmlRefPointer<QQmlPropertyCache> ResolvedTypeReference::createPropertyCache(QQm if (typePropertyCache) { return typePropertyCache; } else if (type.isValid()) { - typePropertyCache = QQmlEnginePrivate::get(engine)->cache(type.metaObject(), minorVersion); + typePropertyCache = QQmlEnginePrivate::get(engine)->cache(type.metaObject(), version); return typePropertyCache; } else { Q_ASSERT(compilationUnit); diff --git a/src/qml/jsruntime/qv4executablecompilationunit_p.h b/src/qml/jsruntime/qv4executablecompilationunit_p.h index 8cad18a3dc..c080978a87 100644 --- a/src/qml/jsruntime/qv4executablecompilationunit_p.h +++ b/src/qml/jsruntime/qv4executablecompilationunit_p.h @@ -326,17 +326,15 @@ private: struct ResolvedTypeReference { ResolvedTypeReference() - : majorVersion(0) - , minorVersion(0) - , isFullyDynamicType(false) + : version(QTypeRevision::zero()) + , isFullyDynamicType(false) {} QQmlType type; QQmlRefPointer<QQmlPropertyCache> typePropertyCache; QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit; - int majorVersion; - int minorVersion; + QTypeRevision version; // Types such as QQmlPropertyMap can add properties dynamically at run-time and // therefore cannot have a property cache installed when instantiated. bool isFullyDynamicType; diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp index 5a1b27fda6..ee42342bf2 100644 --- a/src/qml/jsruntime/qv4sequenceobject.cpp +++ b/src/qml/jsruntime/qv4sequenceobject.cpp @@ -80,7 +80,6 @@ static void generateWarning(QV4::ExecutionEngine *v4, const QString& description #if QT_CONFIG(qml_itemmodel) #define FOREACH_QML_SEQUENCE_TYPE_FOR_ITEMMODEL(F) \ F(QModelIndex, QModelIndex, QModelIndexList, QModelIndex()) \ - F(QModelIndex, QModelIndexVector, QVector<QModelIndex>, QModelIndex()) \ F(QModelIndex, QModelIndexStdVector, std::vector<QModelIndex>, QModelIndex()) \ F(QItemSelectionRange, QItemSelectionRange, QItemSelection, QItemSelectionRange()) #else @@ -88,9 +87,6 @@ static void generateWarning(QV4::ExecutionEngine *v4, const QString& description #endif #define FOREACH_QML_SEQUENCE_TYPE(F) \ - F(int, IntVector, QVector<int>, 0) \ - F(qreal, RealVector, QVector<qreal>, 0.0) \ - F(bool, BoolVector, QVector<bool>, false) \ F(int, IntStdVector, std::vector<int>, 0) \ F(qreal, RealStdVector, std::vector<qreal>, 0.0) \ F(bool, BoolStdVector, std::vector<bool>, false) \ @@ -99,10 +95,8 @@ static void generateWarning(QV4::ExecutionEngine *v4, const QString& description F(bool, Bool, QList<bool>, false) \ F(QString, String, QList<QString>, QString()) \ F(QString, QString, QStringList, QString()) \ - F(QString, StringVector, QVector<QString>, QString()) \ F(QString, StringStdVector, std::vector<QString>, QString()) \ F(QUrl, Url, QList<QUrl>, QUrl()) \ - F(QUrl, UrlVector, QVector<QUrl>, QUrl()) \ F(QUrl, UrlStdVector, std::vector<QUrl>, QUrl()) \ FOREACH_QML_SEQUENCE_TYPE_FOR_ITEMMODEL(F) @@ -377,24 +371,8 @@ public: ++arrayIndex; if (attrs) *attrs = QV4::Attr_Data; - - // TODO: Replace the container->at() below with operator[] in Qt6! - // TODO: But _not_ in Qt5! - // - // gcc 5.3.1 as shipped on RHEL 7.6 includes a copy of basic_string<char> - // into QtQml, when it sees a std::vector::at(). The basic_string symbols - // are publicly visible and preferred over the ones from libstdc++ when - // building user code. Therefore, removing this at() breaks binary - // compatibility. We _do_ want to remove it in Qt6, though. - // - // The exact mechanism is that at() checks its argument and can throw an - // out_of_range exception. The construction of this exception then triggers - // some string manipulation that uses the std::basic_string symbols. Clearly, - // this is a compiler bug. And clearly, we don't want the check as we can't - // catch the exception anyway. - if (pd) - pd->value = convertElementToValue(s->engine(), s->d()->container->at(index)); + pd->value = convertElementToValue(s->engine(), (*s->d()->container)[index]); return PropertyKey::fromArrayIndex(index); } @@ -672,12 +650,6 @@ void Heap::QQmlSequence<Container>::init(QObject *object, int propertyIndex, boo namespace QV4 { -typedef QQmlSequence<QVector<int> > QQmlIntVectorList; -DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlIntVectorList); -typedef QQmlSequence<QVector<qreal> > QQmlRealVectorList; -DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlRealVectorList); -typedef QQmlSequence<QVector<bool> > QQmlBoolVectorList; -DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlBoolVectorList); typedef QQmlSequence<std::vector<int> > QQmlIntStdVectorList; DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlIntStdVectorList); typedef QQmlSequence<std::vector<qreal> > QQmlRealStdVectorList; @@ -688,23 +660,17 @@ typedef QQmlSequence<QStringList> QQmlQStringList; DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlQStringList); typedef QQmlSequence<QList<QString> > QQmlStringList; DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlStringList); -typedef QQmlSequence<QVector<QString> > QQmlStringVectorList; -DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlStringVectorList); typedef QQmlSequence<std::vector<QString> > QQmlStringStdVectorList; -DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlStringStdVectorList); typedef QQmlSequence<QList<int> > QQmlIntList; DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlIntList); +DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlStringStdVectorList); typedef QQmlSequence<QList<QUrl> > QQmlUrlList; DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlUrlList); -typedef QQmlSequence<QVector<QUrl> > QQmlUrlVectorList; -DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlUrlVectorList); typedef QQmlSequence<std::vector<QUrl> > QQmlUrlStdVectorList; DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlUrlStdVectorList); #if QT_CONFIG(qml_itemmodel) typedef QQmlSequence<QModelIndexList> QQmlQModelIndexList; DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlQModelIndexList); -typedef QQmlSequence<QVector<QModelIndex> > QQmlQModelIndexVectorList; -DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlQModelIndexVectorList); typedef QQmlSequence<std::vector<QModelIndex> > QQmlQModelIndexStdVectorList; DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlQModelIndexStdVectorList); typedef QQmlSequence<QItemSelection> QQmlQItemSelectionRangeList; diff --git a/src/qml/jsruntime/qv4sparsearray.cpp b/src/qml/jsruntime/qv4sparsearray.cpp index 8930c9a94d..7457e724e2 100644 --- a/src/qml/jsruntime/qv4sparsearray.cpp +++ b/src/qml/jsruntime/qv4sparsearray.cpp @@ -359,7 +359,7 @@ static inline void qMapDeallocate(SparseArrayNode *node, int alignment) SparseArrayNode *SparseArray::createNode(uint sl, SparseArrayNode *parent, bool left) { - SparseArrayNode *node = static_cast<SparseArrayNode *>(qMapAllocate(sizeof(SparseArrayNode), Q_ALIGNOF(SparseArrayNode))); + SparseArrayNode *node = static_cast<SparseArrayNode *>(qMapAllocate(sizeof(SparseArrayNode), alignof(SparseArrayNode))); Q_CHECK_PTR(node); node->p = (quintptr)parent; diff --git a/src/qml/jsruntime/qv4sparsearray_p.h b/src/qml/jsruntime/qv4sparsearray_p.h index c1e50c8dcf..248fcdb02f 100644 --- a/src/qml/jsruntime/qv4sparsearray_p.h +++ b/src/qml/jsruntime/qv4sparsearray_p.h @@ -147,7 +147,7 @@ struct Q_QML_EXPORT SparseArray SparseArray(); ~SparseArray() { if (root()) - freeTree(header.left, Q_ALIGNOF(SparseArrayNode)); + freeTree(header.left, alignof(SparseArrayNode)); } SparseArray(const SparseArray &other); diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp index 223f4a4769..fc004a2ce0 100644 --- a/src/qml/jsruntime/qv4string.cpp +++ b/src/qml/jsruntime/qv4string.cpp @@ -91,18 +91,14 @@ bool String::virtualIsEqualTo(Managed *t, Managed *o) void Heap::String::init(const QString &t) { - Base::init(); - + QString mutableText(t); + StringOrSymbol::init(mutableText.data_ptr()); subtype = String::StringType_Unknown; - - text = const_cast<QString &>(t).data_ptr(); - text->ref.ref(); } void Heap::ComplexString::init(String *l, String *r) { - Base::init(); - + StringOrSymbol::init(); subtype = String::StringType_AddedString; left = l; @@ -125,7 +121,7 @@ void Heap::ComplexString::init(String *l, String *r) void Heap::ComplexString::init(Heap::String *ref, int from, int len) { Q_ASSERT(ref->length() >= from + len); - Base::init(); + StringOrSymbol::init(); subtype = String::StringType_SubString; @@ -136,11 +132,11 @@ void Heap::ComplexString::init(Heap::String *ref, int from, int len) void Heap::StringOrSymbol::destroy() { - if (text) { - internalClass->engine->memoryManager->changeUnmanagedHeapSizeUsage(qptrdiff(-text->size) * (int)sizeof(QChar)); - if (!text->ref.deref()) - QStringData::deallocate(text); + if (subtype < Heap::String::StringType_AddedString) { + internalClass->engine->memoryManager->changeUnmanagedHeapSizeUsage( + qptrdiff(-text()->size) * qptrdiff(sizeof(QChar))); } + text().~QStringPrivate(); Base::destroy(); } @@ -164,27 +160,27 @@ uint String::toUInt(bool *ok) const void String::createPropertyKeyImpl() const { - if (!d()->text) + if (d()->subtype >= Heap::String::StringType_AddedString) d()->simplifyString(); - Q_ASSERT(d()->text); + Q_ASSERT(d()->subtype < Heap::String::StringType_AddedString); engine()->identifierTable->asPropertyKey(this); } void Heap::String::simplifyString() const { - Q_ASSERT(!text); + Q_ASSERT(subtype >= StringType_AddedString); int l = length(); QString result(l, Qt::Uninitialized); QChar *ch = const_cast<QChar *>(result.constData()); append(this, ch); - text = result.data_ptr(); - text->ref.ref(); + text() = result.data_ptr(); const ComplexString *cs = static_cast<const ComplexString *>(this); identifier = PropertyKey::invalid(); cs->left = cs->right = nullptr; - internalClass->engine->memoryManager->changeUnmanagedHeapSizeUsage(qptrdiff(text->size) * (qptrdiff)sizeof(QChar)); + internalClass->engine->memoryManager->changeUnmanagedHeapSizeUsage( + qptrdiff(text().size) * qptrdiff(sizeof(QChar))); subtype = StringType_Unknown; } @@ -206,7 +202,7 @@ bool Heap::String::startsWithUpper() const offset = cs->from; } Q_ASSERT(str->subtype < Heap::String::StringType_Complex); - return str->text->size > offset && QChar::isUpper(str->text->data()[offset]); + return str->text().size > offset && QChar::isUpper(str->text().data()[offset]); } void Heap::String::append(const String *data, QChar *ch) @@ -228,21 +224,21 @@ void Heap::String::append(const String *data, QChar *ch) memcpy(ch, cs->left->toQString().constData() + cs->from, cs->len*sizeof(QChar)); ch += cs->len; } else { - memcpy(static_cast<void *>(ch), static_cast<const void *>(item->text->data()), item->text->size * sizeof(QChar)); - ch += item->text->size; + memcpy(static_cast<void *>(ch), item->text().data(), item->text().size * sizeof(QChar)); + ch += item->text().size; } } } void Heap::StringOrSymbol::createHashValue() const { - if (!text) { + if (subtype >= StringType_AddedString) { Q_ASSERT(internalClass->vtable->isString); static_cast<const Heap::String *>(this)->simplifyString(); } - Q_ASSERT(text); - const QChar *ch = reinterpret_cast<const QChar *>(text->data()); - const QChar *end = ch + text->size; + Q_ASSERT(subtype < StringType_AddedString); + const QChar *ch = reinterpret_cast<const QChar *>(text().data()); + const QChar *end = ch + text().size; stringHash = QV4::String::calculateHashValue(ch, end, &subtype); } diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h index 52fe09cd72..d5d11ef660 100644 --- a/src/qml/jsruntime/qv4string_p.h +++ b/src/qml/jsruntime/qv4string_p.h @@ -77,7 +77,18 @@ struct Q_QML_PRIVATE_EXPORT StringOrSymbol : Base StringType_Complex = StringType_AddedString }; - mutable QStringData *text; + void init() { + Base::init(); + new (&textStorage) QStringPrivate; + } + + void init(QStringPrivate text) + { + Base::init(); + new (&textStorage) QStringPrivate(std::move(text)); + } + + mutable std::aligned_storage<sizeof(QStringPrivate), alignof(QStringPrivate)>::type textStorage; mutable PropertyKey identifier; mutable uint subtype; mutable uint stringHash; @@ -85,12 +96,11 @@ struct Q_QML_PRIVATE_EXPORT StringOrSymbol : Base static void markObjects(Heap::Base *that, MarkStack *markStack); void destroy(); + QStringPrivate &text() const { return *reinterpret_cast<QStringPrivate *>(&textStorage); } + inline QString toQString() const { - if (!text) - return QString(); - QStringDataPtr ptr = { text }; - text->ref.ref(); - return QString(ptr); + QStringPrivate dd = text(); + return QString(std::move(dd)); } void createHashValue() const; inline unsigned hashValue() const { @@ -113,14 +123,12 @@ struct Q_QML_PRIVATE_EXPORT String : StringOrSymbol { void simplifyString() const; int length() const; std::size_t retainedTextSize() const { - return subtype >= StringType_Complex ? 0 : (std::size_t(text->size) * sizeof(QChar)); + return subtype >= StringType_Complex ? 0 : (std::size_t(text().size) * sizeof(QChar)); } inline QString toQString() const { if (subtype >= StringType_Complex) simplifyString(); - QStringDataPtr ptr = { text }; - text->ref.ref(); - return QString(ptr); + return StringOrSymbol::toQString(); } inline bool isEqualTo(const String *other) const { if (this == other) @@ -158,7 +166,7 @@ Q_STATIC_ASSERT(std::is_trivial< ComplexString >::value); inline int String::length() const { - return text ? text->size : static_cast<const ComplexString *>(this)->len; + return subtype < StringType_AddedString ? text().size : static_cast<const ComplexString *>(this)->len; } } @@ -252,7 +260,7 @@ public: } if (subtype) - *subtype = (charToUInt(ch) == '@') ? Heap::StringOrSymbol::StringType_Symbol : Heap::StringOrSymbol::StringType_Regular; + *subtype = (ch != end && charToUInt(ch) == '@') ? Heap::StringOrSymbol::StringType_Symbol : Heap::StringOrSymbol::StringType_Regular; return h; } }; diff --git a/src/qml/jsruntime/qv4symbol.cpp b/src/qml/jsruntime/qv4symbol.cpp index 004a9938e2..be6d821c14 100644 --- a/src/qml/jsruntime/qv4symbol.cpp +++ b/src/qml/jsruntime/qv4symbol.cpp @@ -50,10 +50,9 @@ DEFINE_OBJECT_VTABLE(SymbolObject); void Heap::Symbol::init(const QString &s) { Q_ASSERT(s.at(0) == QLatin1Char('@')); - identifier = PropertyKey::fromStringOrSymbol(this); QString desc(s); - text = desc.data_ptr(); - text->ref.ref(); + StringOrSymbol::init(desc.data_ptr()); + identifier = PropertyKey::fromStringOrSymbol(this); } void Heap::SymbolCtor::init(QV4::ExecutionContext *scope) diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp index d03b67aa27..f425c6c87f 100644 --- a/src/qml/jsruntime/qv4typedarray.cpp +++ b/src/qml/jsruntime/qv4typedarray.cpp @@ -338,8 +338,8 @@ ReturnedValue TypedArrayCtor::virtualCallAsConstructor(const FunctionObject *f, array->d()->byteLength = destByteLength; array->d()->byteOffset = 0; - const char *src = buffer->d()->data->data() + typedArray->d()->byteOffset; - char *dest = newBuffer->d()->data->data(); + const char *src = buffer->d()->data()->data() + typedArray->d()->byteOffset; + char *dest = newBuffer->d()->data()->data(); // check if src and new type have the same size. In that case we can simply memcpy the data if (srcElementSize == destElementSize) { @@ -420,7 +420,7 @@ ReturnedValue TypedArrayCtor::virtualCallAsConstructor(const FunctionObject *f, array->d()->byteOffset = 0; uint idx = 0; - char *b = newBuffer->d()->data->data(); + char *b = newBuffer->d()->data()->data(); ScopedValue val(scope); while (idx < l) { val = o->get(idx); @@ -480,7 +480,7 @@ ReturnedValue TypedArray::virtualGet(const Managed *m, PropertyKey id, const Val if (hasProperty) *hasProperty = true; - return a->d()->type->read(a->d()->buffer->data->data() + byteOffset); + return a->d()->type->read(a->d()->buffer->data()->data() + byteOffset); } bool TypedArray::virtualHasProperty(const Managed *m, PropertyKey id) @@ -538,7 +538,7 @@ bool TypedArray::virtualPut(Managed *m, PropertyKey id, const Value &value, Valu Value v = Value::fromReturnedValue(value.convertedToNumber()); if (scope.hasException() || a->d()->buffer->isDetachedBuffer()) return scope.engine->throwTypeError(); - a->d()->type->write(a->d()->buffer->data->data() + byteOffset, v); + a->d()->type->write(a->d()->buffer->data()->data() + byteOffset, v); return true; } @@ -569,7 +569,7 @@ bool TypedArray::virtualDefineOwnProperty(Managed *m, PropertyKey id, const Prop uint bytesPerElement = a->d()->type->bytesPerElement; uint byteOffset = a->d()->byteOffset + index * bytesPerElement; Q_ASSERT(byteOffset + bytesPerElement <= (uint)a->d()->buffer->byteLength()); - a->d()->type->write(a->d()->buffer->data->data() + byteOffset, v); + a->d()->type->write(a->d()->buffer->data()->data() + byteOffset, v); } return true; } @@ -713,7 +713,7 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_copyWithin(const FunctionObje if (from != to) { int elementSize = O->d()->type->bytesPerElement; - char *data = O->d()->buffer->data->data() + O->d()->byteOffset; + char *data = O->d()->buffer->data()->data() + O->d()->byteOffset; memmove(data + to*elementSize, data + from*elementSize, count*elementSize); } @@ -749,7 +749,7 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_every(const FunctionObject *b ScopedValue r(scope); Value *arguments = scope.alloc(3); - const char *data = v->d()->buffer->data->data(); + const char *data = v->d()->buffer->data()->data(); uint bytesPerElement = v->d()->type->bytesPerElement; uint byteOffset = v->d()->byteOffset; @@ -803,7 +803,7 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_fill(const FunctionObject *b, if (scope.hasException() || v->d()->buffer->isDetachedBuffer()) return scope.engine->throwTypeError(); - char *data = v->d()->buffer->data->data(); + char *data = v->d()->buffer->data()->data(); uint bytesPerElement = v->d()->type->bytesPerElement; uint byteOffset = v->d()->byteOffset; @@ -1422,7 +1422,7 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_set(const FunctionObject *b, uint idx = 0; if (buffer->isDetachedBuffer()) return scope.engine->throwTypeError(); - char *b = buffer->d()->data->data() + a->d()->byteOffset + offset*elementSize; + char *b = buffer->d()->data()->data() + a->d()->byteOffset + offset*elementSize; ScopedValue val(scope); while (idx < l) { val = o->get(idx); @@ -1451,8 +1451,8 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_set(const FunctionObject *b, if (offset > aLength || l > aLength - offset) RETURN_RESULT(scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range"))); - char *dest = buffer->d()->data->data() + a->d()->byteOffset + offset*elementSize; - const char *src = srcBuffer->d()->data->data() + srcTypedArray->d()->byteOffset; + char *dest = buffer->d()->data()->data() + a->d()->byteOffset + offset*elementSize; + const char *src = srcBuffer->d()->data()->data() + srcTypedArray->d()->byteOffset; if (srcTypedArray->d()->type == a->d()->type) { // same type of typed arrays, use memmove (as srcbuffer and buffer could be the same) memmove(dest, src, srcTypedArray->d()->byteLength); diff --git a/src/qml/jsruntime/qv4typedarray_p.h b/src/qml/jsruntime/qv4typedarray_p.h index 65656e3389..e590083bc3 100644 --- a/src/qml/jsruntime/qv4typedarray_p.h +++ b/src/qml/jsruntime/qv4typedarray_p.h @@ -156,8 +156,8 @@ struct Q_QML_PRIVATE_EXPORT TypedArray : Object return d()->byteLength/d()->type->bytesPerElement; } - QTypedArrayData<char> *arrayData() { - return d()->buffer->data; + QArrayDataPointer<char> *arrayData() { + return &d()->buffer->data(); } Heap::TypedArray::Type arrayType() const { diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g index f6d8bcf9c3..a246dfba7a 100644 --- a/src/qml/parser/qqmljs.g +++ b/src/qml/parser/qqmljs.g @@ -836,7 +836,15 @@ UiImport: UiImportHead Semicolon; UiVersionSpecifier: T_VERSION_NUMBER T_DOT T_VERSION_NUMBER; /. case $rule_number: { - auto version = new (pool) AST::UiVersionSpecifier(sym(1).dval, sym(3).dval); + const int major = sym(1).dval; + const int minor = sym(3).dval; + if (!QTypeRevision::isValidSegment(major) || !QTypeRevision::isValidSegment(minor)) { + diagnostic_messages.append( + compileError(loc(1), + QLatin1String("Invalid version. Version numbers must be >= 0 and < 255."))); + return false; + } + auto version = new (pool) AST::UiVersionSpecifier(major, minor); version->majorToken = loc(1); version->minorToken = loc(3); sym(1).UiVersionSpecifier = version; @@ -847,6 +855,13 @@ UiVersionSpecifier: T_VERSION_NUMBER T_DOT T_VERSION_NUMBER; UiVersionSpecifier: T_VERSION_NUMBER; /. case $rule_number: { + const int major = sym(1).dval; + if (!QTypeRevision::isValidSegment(major)) { + diagnostic_messages.append( + compileError(loc(1), + QLatin1String("Invalid major version. Version numbers must be >= 0 and < 255."))); + return false; + } auto version = new (pool) AST::UiVersionSpecifier(sym(1).dval, 0); version->majorToken = loc(1); sym(1).UiVersionSpecifier = version; diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h index 053e9fd2d3..b92a635228 100644 --- a/src/qml/parser/qqmljsast_p.h +++ b/src/qml/parser/qqmljsast_p.h @@ -57,6 +57,7 @@ #include <private/qqmljsmemorypool_p.h> #include <QtCore/qstring.h> +#include <QtCore/qversionnumber.h> QT_BEGIN_NAMESPACE @@ -646,7 +647,10 @@ class QML_PARSER_EXPORT UiVersionSpecifier : public Node public: QQMLJS_DECLARE_AST_NODE(UiVersionSpecifier) - UiVersionSpecifier(int majorum, int minorum) : majorVersion(majorum), minorVersion(minorum) { kind = K; } + UiVersionSpecifier(int majorum, int minorum) : version(QTypeRevision::fromVersion(majorum, minorum)) + { + kind = K; + } void accept0(BaseVisitor *visitor) override; @@ -658,8 +662,7 @@ public: } // attributes: - int majorVersion; - int minorVersion; + QTypeRevision version; SourceLocation majorToken; SourceLocation minorToken; }; diff --git a/src/qml/qml.pro b/src/qml/qml.pro index e39a8319b6..7bb3547ee9 100644 --- a/src/qml/qml.pro +++ b/src/qml/qml.pro @@ -71,7 +71,7 @@ MODULE_PLUGIN_TYPES = \ QMLTYPES_FILENAME = plugins.qmltypes QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQml QML_IMPORT_NAME = QtQml -IMPORT_VERSION = 2.$$QT_MINOR_VERSION +QML_IMPORT_VERSION = $$QT_VERSION CONFIG += qmltypes install_qmltypes install_metatypes load(qt_module) diff --git a/src/qml/qml/ftw/qhashedstring.cpp b/src/qml/qml/ftw/qhashedstring.cpp index 6c58ab87f4..4553fa9359 100644 --- a/src/qml/qml/ftw/qhashedstring.cpp +++ b/src/qml/qml/ftw/qhashedstring.cpp @@ -44,7 +44,7 @@ QT_BEGIN_NAMESPACE // Copy of QString's qMemCompare bool QHashedString::compare(const QChar *lhs, const QChar *rhs, int length) { - Q_ASSERT(lhs && rhs); + Q_ASSERT((lhs && rhs) || !length); const quint16 *a = (const quint16 *)lhs; const quint16 *b = (const quint16 *)rhs; diff --git a/src/qml/qml/ftw/qqmlthread.cpp b/src/qml/qml/ftw/qqmlthread.cpp index 7d2ad354d6..0f7726ef65 100644 --- a/src/qml/qml/ftw/qqmlthread.cpp +++ b/src/qml/qml/ftw/qqmlthread.cpp @@ -188,13 +188,7 @@ void QQmlThreadPrivate::threadEvent() lock(); for (;;) { - if (m_shutdown) { - quit(); - wakeOne(); - unlock(); - - return; - } else if (!threadList.isEmpty()) { + if (!threadList.isEmpty()) { m_threadProcessing = true; QQmlThread::Message *message = threadList.first(); @@ -206,6 +200,12 @@ void QQmlThreadPrivate::threadEvent() lock(); delete threadList.takeFirst(); + } else if (m_shutdown) { + quit(); + wakeOne(); + unlock(); + + return; } else { wakeOne(); @@ -242,6 +242,7 @@ void QQmlThread::shutdown() d->lock(); Q_ASSERT(!d->m_shutdown); + d->m_shutdown = true; for (;;) { if (d->mainSync || !d->mainList.isEmpty()) { d->unlock(); @@ -254,13 +255,10 @@ void QQmlThread::shutdown() } } - d->m_shutdown = true; - if (QCoreApplication::closingDown()) { + if (QCoreApplication::closingDown()) d->quit(); - } else { + else d->triggerThreadEvent(); - d->wait(); - } d->unlock(); d->QThread::wait(); diff --git a/src/qml/qml/ftw/qstringhash_p.h b/src/qml/qml/ftw/qstringhash_p.h index f9435b4919..fc73fdfa50 100644 --- a/src/qml/qml/ftw/qstringhash_p.h +++ b/src/qml/qml/ftw/qstringhash_p.h @@ -54,25 +54,31 @@ #include <private/qhashedstring_p.h> #include <private/qprimefornumbits_p.h> -#include <QtCore/qglobal.h> +#include <QtCore/qbytearray.h> +#include <QtCore/qstring.h> QT_BEGIN_NAMESPACE +static inline QString::DataPointer &mutableStringData(const QHashedString &key) +{ + return const_cast<QHashedString &>(key).data_ptr(); +} + class QStringHashData; class QStringHashNode { public: QStringHashNode() - : ckey(nullptr) { } QStringHashNode(const QHashedString &key) : length(key.length()), hash(key.hash()), symbolId(0) + , arrayData(mutableStringData(key).d_ptr()) + , strData(mutableStringData(key).data()) { - strData = const_cast<QHashedString &>(key).data_ptr(); + arrayData->ref(); setQString(true); - strData->ref.ref(); } QStringHashNode(const QHashedCStringRef &key) @@ -81,15 +87,21 @@ public: } QStringHashNode(const QStringHashNode &o) - : length(o.length), hash(o.hash), symbolId(o.symbolId), ckey(o.ckey) + : length(o.length), hash(o.hash), symbolId(o.symbolId), arrayData(o.arrayData) { setQString(o.isQString()); - if (isQString()) { strData->ref.ref(); } + if (isQString()) { + strData = o.strData; + arrayData->ref(); + } else { + ckey = o.ckey; + } } ~QStringHashNode() { - if (isQString()) { if (!strData->ref.deref()) free(strData); } + if (isQString() && !arrayData->deref()) + QTypedArrayData<ushort>::deallocate(arrayData); } QFlagPointer<QStringHashNode> next; @@ -98,15 +110,18 @@ public: quint32 hash = 0; quint32 symbolId = 0; + QTypedArrayData<ushort> *arrayData = nullptr; union { - const char *ckey; - QStringData *strData; + const char *ckey = nullptr; + ushort *strData; }; inline QHashedString key() const { - if (isQString()) - return QHashedString(QString((QChar *)strData->data(), length), hash); + if (isQString()) { + arrayData->ref(); + return QHashedString(QString(QStringPrivate(arrayData, strData, length)), hash); + } return QHashedString(QString::fromLatin1(ckey, length), hash); } @@ -114,16 +129,14 @@ public: bool isQString() const { return next.flag(); } void setQString(bool v) { if (v) next.setFlag(); else next.clearFlag(); } - inline char *cStrData() const { return (char *)ckey; } - inline quint16 *utf16Data() const { return (quint16 *)strData->data(); } + inline qsizetype size() const { return length; } + inline const char *cStrData() const { return ckey; } + inline const quint16 *utf16Data() const { return strData; } inline bool equals(const QV4::Value &string) const { QString s = string.toQStringNoThrow(); if (isQString()) { - QStringDataPtr dd; - dd.ptr = strData; - strData->ref.ref(); - return QString(dd) == s; + return QStringView(utf16Data(), length) == s; } else { return QLatin1String(cStrData(), length) == s; } @@ -133,10 +146,7 @@ public: if (length != string->d()->length() || hash != string->hashValue()) return false; if (isQString()) { - QStringDataPtr dd; - dd.ptr = strData; - strData->ref.ref(); - return QString(dd) == string->toQString(); + return QStringView(utf16Data(), length) == string->toQString(); } else { return QLatin1String(cStrData(), length) == string->toQString(); } @@ -510,8 +520,9 @@ void QStringHash<T>::initializeNode(Node *node, const QHashedString &key) { node->length = key.length(); node->hash = key.hash(); - node->strData = const_cast<QHashedString &>(key).data_ptr(); - node->strData->ref.ref(); + node->arrayData = mutableStringData(key).d_ptr(); + node->strData = mutableStringData(key).data(); + node->arrayData->ref(); node->setQString(true); } @@ -547,10 +558,11 @@ typename QStringHash<T>::Node *QStringHash<T>::takeNode(const Node &o) Node *rv = nodePool->nodes + nodePool->used++; rv->length = o.length; rv->hash = o.hash; + rv->arrayData = o.arrayData; if (o.isQString()) { rv->strData = o.strData; - rv->strData->ref.ref(); rv->setQString(true); + rv->arrayData->ref(); } else { rv->ckey = o.ckey; } diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp index fe4e2f4e55..ea6f15e9c2 100644 --- a/src/qml/qml/qqml.cpp +++ b/src/qml/qml/qqml.cpp @@ -62,19 +62,20 @@ void qmlClearTypeRegistrations() // Declared in qqml.h //From qqml.h bool qmlProtectModule(const char *uri, int majVersion) { - return QQmlMetaType::protectModule(QString::fromUtf8(uri), majVersion); + return QQmlMetaType::protectModule(QString::fromUtf8(uri), + QTypeRevision::fromMajorVersion(majVersion)); } //From qqml.h void qmlRegisterModule(const char *uri, int versionMajor, int versionMinor) { - QQmlMetaType::registerModule(uri, versionMajor, versionMinor); + QQmlMetaType::registerModule(uri, QTypeRevision::fromVersion(versionMajor, versionMinor)); } //From qqml.h int qmlTypeId(const char *uri, int versionMajor, int versionMinor, const char *qmlName) { - return QQmlMetaType::typeId(uri, versionMajor, versionMinor, qmlName); + return QQmlMetaType::typeId(uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName); } // From qqmlprivate.h @@ -104,9 +105,9 @@ QObject *QQmlPrivate::RegisterSingletonFunctor::operator()(QQmlEngine *qeng, QJS return m_object; }; -static QVector<int> availableRevisions(const QMetaObject *metaObject) +static QVector<QTypeRevision> availableRevisions(const QMetaObject *metaObject) { - QVector<int> revisions; + QVector<QTypeRevision> revisions; if (!metaObject) return revisions; const int propertyOffset = metaObject->propertyOffset(); @@ -115,7 +116,7 @@ static QVector<int> availableRevisions(const QMetaObject *metaObject) propertyIndex < propertyEnd; ++propertyIndex) { const QMetaProperty property = metaObject->property(propertyIndex); if (int revision = property.revision()) - revisions.append(revision); + revisions.append(QTypeRevision::fromEncodedVersion(revision)); } const int methodOffset = metaObject->methodOffset(); const int methodCount = metaObject->methodCount(); @@ -123,7 +124,7 @@ static QVector<int> availableRevisions(const QMetaObject *metaObject) methodIndex < methodEnd; ++methodIndex) { const QMetaMethod method = metaObject->method(methodIndex); if (int revision = method.revision()) - revisions.append(revision); + revisions.append(QTypeRevision::fromEncodedVersion(revision)); } // Need to also check parent meta objects, as their revisions are inherited. @@ -133,6 +134,54 @@ static QVector<int> availableRevisions(const QMetaObject *metaObject) return revisions; } +template<typename Registration> +void assignVersions(Registration *registration, QTypeRevision revision, + QTypeRevision defaultVersion) +{ + const quint8 majorVersion = revision.hasMajorVersion() ? revision.majorVersion() + : defaultVersion.majorVersion(); + registration->version = revision.hasMinorVersion() + ? QTypeRevision::fromVersion(majorVersion, revision.minorVersion()) + : QTypeRevision::fromMajorVersion(majorVersion); + registration->revision = revision; +} + +static QVector<QTypeRevision> prepareRevisions(const QMetaObject *metaObject, QTypeRevision added) +{ + auto revisions = availableRevisions(metaObject); + revisions.append(added); + return revisions; +} + +static void uniqueRevisions(QVector<QTypeRevision> *revisions, QTypeRevision defaultVersion, + QTypeRevision added) +{ + bool revisionsHaveMajorVersions = false; + for (QTypeRevision revision : QVector<QTypeRevision>(*revisions)) { // yes, copy + // allow any minor version for each explicitly specified past major one + if (revision.hasMajorVersion()) { + revisionsHaveMajorVersions = true; + if (revision.majorVersion() < defaultVersion.majorVersion()) + revisions->append(QTypeRevision::fromVersion(revision.majorVersion(), 254)); + } + } + + if (revisionsHaveMajorVersions) { + if (!added.hasMajorVersion()) { + // If added in unspecified major version, assume default one. + revisions->append(QTypeRevision::fromVersion(defaultVersion.majorVersion(), + added.minorVersion())); + } else if (added.majorVersion() < defaultVersion.majorVersion()) { + // If added in past major version, add .0 of default version. + revisions->append(QTypeRevision::fromVersion(defaultVersion.majorVersion(), 0)); + } + } + + std::sort(revisions->begin(), revisions->end()); + const auto it = std::unique(revisions->begin(), revisions->end()); + revisions->erase(it, revisions->end()); +} + /* This method is "over generalized" to allow us to (potentially) register more types of things in the future without adding exported symbols. @@ -164,8 +213,7 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data) nullptr, noCreateReason, type.uri, - type.versionMajor, - -1, + type.version, nullptr, type.metaObject, type.attachedPropertiesFunction, @@ -176,28 +224,26 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data) type.extensionObjectCreate, type.extensionMetaObject, nullptr, - -1 + QTypeRevision() }; - const int added = intClassInfo(type.classInfoMetaObject, "QML.AddedInMinorVersion", 0); - const int removed = intClassInfo(type.classInfoMetaObject, "QML.RemovedInMinorVersion", -1); + const QTypeRevision added = revisionClassInfo( + type.classInfoMetaObject, "QML.AddedInVersion", + QTypeRevision::fromMinorVersion(0)); + const QTypeRevision removed = revisionClassInfo( + type.classInfoMetaObject, "QML.RemovedInVersion"); - auto revisions = availableRevisions(type.metaObject); - revisions.append(qMax(added, 0)); + auto revisions = prepareRevisions(type.metaObject, added); if (type.attachedPropertiesMetaObject) revisions += availableRevisions(type.attachedPropertiesMetaObject); + uniqueRevisions(&revisions, type.version, added); - std::sort(revisions.begin(), revisions.end()); - const auto it = std::unique(revisions.begin(), revisions.end()); - revisions.erase(it, revisions.end()); - - const bool typeWasRemoved = removed >= added; - for (int revision : revisions) { + for (QTypeRevision revision : revisions) { if (revision < added) continue; // When removed, we still add revisions, but anonymous ones - if (typeWasRemoved && revision >= removed) { + if (removed.isValid() && !(revision < removed)) { revisionRegistration.elementName = nullptr; revisionRegistration.create = nullptr; } else { @@ -205,11 +251,8 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data) revisionRegistration.create = creatable ? type.create : nullptr; } - // Equivalent of qmlRegisterRevision<T, revision>(...) - revisionRegistration.versionMinor = revision; - revisionRegistration.revision = revision; + assignVersions(&revisionRegistration, revision, type.version); revisionRegistration.customParser = type.customParserFactory(); - qmlregister(TypeRegistration, &revisionRegistration); } break; @@ -221,36 +264,33 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data) RegisterSingletonType revisionRegistration = { QmlCurrentSingletonTypeRegistrationVersion, type.uri, - type.versionMajor, - -1, + type.version, elementName, type.scriptApi, nullptr, type.instanceMetaObject, type.typeId, - -1, + QTypeRevision(), type.generalizedQobjectApi }; - const int added = intClassInfo(type.classInfoMetaObject, "QML.AddedInMinorVersion", 0); - const int removed = intClassInfo(type.classInfoMetaObject, "QML.RemovedInMinorVersion", -1); + const QTypeRevision added = revisionClassInfo( + type.classInfoMetaObject, "QML.AddedInVersion", + QTypeRevision::fromMinorVersion(0)); + const QTypeRevision removed = revisionClassInfo( + type.classInfoMetaObject, "QML.RemovedInVersion"); - auto revisions = availableRevisions(type.instanceMetaObject); - revisions.append(qMax(added, 0)); + auto revisions = prepareRevisions(type.instanceMetaObject, added); + uniqueRevisions(&revisions, type.version, added); - std::sort(revisions.begin(), revisions.end()); - const auto it = std::unique(revisions.begin(), revisions.end()); - revisions.erase(it, revisions.end()); - - const bool typeWasRemoved = removed >= added; - for (int revision : qAsConst(revisions)) { + for (QTypeRevision revision : qAsConst(revisions)) { if (revision < added) continue; // When removed, we still add revisions, but anonymous ones - if (typeWasRemoved && revision >= removed) { + if (removed.isValid() && !(revision < removed)) { revisionRegistration.typeName = nullptr; revisionRegistration.scriptApi = nullptr; revisionRegistration.generalizedQobjectApi = nullptr; @@ -260,10 +300,7 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data) revisionRegistration.generalizedQobjectApi = type.generalizedQobjectApi; } - // Equivalent of qmlRegisterRevision<T, revision>(...) - revisionRegistration.versionMinor = revision; - revisionRegistration.revision = revision; - + assignVersions(&revisionRegistration, revision, type.version); qmlregister(SingletonRegistration, &revisionRegistration); } break; @@ -339,7 +376,7 @@ namespace QQmlPrivate { nullptr, uri, - versionMajor, + QTypeRevision::fromMajorVersion(versionMajor), &QQmlTypeNotAvailable::staticMetaObject, classInfoMetaObject, diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h index ef7fdd1945..b9445e48a8 100644 --- a/src/qml/qml/qqml.h +++ b/src/qml/qml/qqml.h @@ -44,6 +44,7 @@ #include <QtCore/qbytearray.h> #include <QtCore/qmetaobject.h> +#include <QtCore/qversionnumber.h> #define QML_VERSION 0x020000 #define QML_VERSION_STR "2.0" @@ -88,10 +89,16 @@ friend void QML_REGISTER_TYPES_AND_REVISIONS(const char *uri, int versionMajor); #define QML_ADDED_IN_MINOR_VERSION(VERSION) \ - Q_CLASSINFO("QML.AddedInMinorVersion", #VERSION) + Q_CLASSINFO("QML.AddedInVersion", Q_REVISION(VERSION)) + +#define QML_ADDED_IN_VERSION(MAJOR, MINOR) \ + Q_CLASSINFO("QML.AddedInVersion", Q_REVISION(MAJOR, MINOR)) #define QML_REMOVED_IN_MINOR_VERSION(VERSION) \ - Q_CLASSINFO("QML.RemovedInMinorVersion", #VERSION) + Q_CLASSINFO("QML.RemovedInVersion", Q_REVISION(VERSION)) + +#define QML_REMOVED_IN_VERSION(MAJOR, MINOR) \ + Q_CLASSINFO("QML.RemovedInVersion", Q_REVISION(MAJOR, MINOR)) #define QML_ATTACHED(ATTACHED_TYPE) \ Q_CLASSINFO("QML.Attached", #ATTACHED_TYPE) \ @@ -160,7 +167,7 @@ int qmlRegisterAnonymousType(const char *uri, int versionMajor) nullptr, QString(), - uri, versionMajor, 0, nullptr, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, 0), nullptr, &T::staticMetaObject, QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -172,7 +179,7 @@ int qmlRegisterAnonymousType(const char *uri, int versionMajor) nullptr, nullptr, nullptr, - 0 + QTypeRevision::zero() }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -203,7 +210,7 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin nullptr, reason, - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject, QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -215,7 +222,7 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin nullptr, nullptr, nullptr, - 0 + QTypeRevision::zero() }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -235,7 +242,7 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin nullptr, reason, - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject, QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -247,7 +254,7 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin nullptr, nullptr, nullptr, - metaObjectRevision + QTypeRevision::fromMinorVersion(metaObjectRevision) }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -274,7 +281,7 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve nullptr, reason, - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject, attached, attachedMetaObject, @@ -286,7 +293,7 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve QQmlPrivate::createParent<E>, &E::staticMetaObject, nullptr, - 0 + QTypeRevision::zero() }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -313,7 +320,7 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve nullptr, reason, - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject, attached, attachedMetaObject, @@ -325,7 +332,7 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve QQmlPrivate::createParent<E>, &E::staticMetaObject, nullptr, - metaObjectRevision + QTypeRevision::fromMinorVersion(metaObjectRevision) }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -346,7 +353,7 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c sizeof(T), QQmlPrivate::createInto<T>, QString(), - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject, QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -358,7 +365,7 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c nullptr, nullptr, nullptr, - 0 + QTypeRevision::zero() }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -377,7 +384,7 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c sizeof(T), QQmlPrivate::createInto<T>, QString(), - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject, QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -389,7 +396,7 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c nullptr, nullptr, nullptr, - metaObjectRevision + QTypeRevision::fromMinorVersion(metaObjectRevision) }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -408,7 +415,7 @@ int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor) sizeof(T), QQmlPrivate::createInto<T>, QString(), - uri, versionMajor, versionMinor, nullptr, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), nullptr, &T::staticMetaObject, QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -420,7 +427,7 @@ int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor) nullptr, nullptr, nullptr, - metaObjectRevision + QTypeRevision::fromMinorVersion(metaObjectRevision) }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -440,7 +447,7 @@ int qmlRegisterExtendedType(const char *uri, int versionMajor) nullptr, QString(), - uri, versionMajor, 0, nullptr, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, 0), nullptr, &T::staticMetaObject, QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -452,7 +459,7 @@ int qmlRegisterExtendedType(const char *uri, int versionMajor) QQmlPrivate::createParent<E>, &E::staticMetaObject, nullptr, - 0 + QTypeRevision::zero() }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -488,7 +495,7 @@ int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor, sizeof(T), QQmlPrivate::createInto<T>, QString(), - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject, attached, attachedMetaObject, @@ -500,7 +507,7 @@ int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor, QQmlPrivate::createParent<E>, &E::staticMetaObject, nullptr, - 0 + QTypeRevision::zero() }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -524,7 +531,7 @@ int qmlRegisterInterface(const char *typeName) qobject_interface_iid<T *>(), "", - 0 + QTypeRevision::zero() }; return QQmlPrivate::qmlregister(QQmlPrivate::InterfaceRegistration, &qmlInterface); @@ -543,7 +550,7 @@ int qmlRegisterInterface(const char *uri, int versionMajor) qobject_interface_iid<T *>(), uri, - versionMajor + QTypeRevision::fromVersion(versionMajor, 0) }; return QQmlPrivate::qmlregister(QQmlPrivate::InterfaceRegistration, &qmlInterface); @@ -563,7 +570,7 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor, sizeof(T), QQmlPrivate::createInto<T>, QString(), - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject, QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -575,7 +582,7 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor, nullptr, nullptr, parser, - 0 + QTypeRevision::zero() }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -595,7 +602,7 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor, sizeof(T), QQmlPrivate::createInto<T>, QString(), - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject, QQmlPrivate::attachedPropertiesFunc<T>(), QQmlPrivate::attachedPropertiesMetaObject<T>(), @@ -607,7 +614,7 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor, nullptr, nullptr, parser, - metaObjectRevision + QTypeRevision::fromMinorVersion(metaObjectRevision) }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -634,7 +641,7 @@ int qmlRegisterCustomExtendedType(const char *uri, int versionMajor, int version sizeof(T), QQmlPrivate::createInto<T>, QString(), - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject, attached, attachedMetaObject, @@ -646,7 +653,7 @@ int qmlRegisterCustomExtendedType(const char *uri, int versionMajor, int version QQmlPrivate::createParent<E>, &E::staticMetaObject, parser, - 0 + QTypeRevision::zero() }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -709,9 +716,9 @@ inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versi QQmlPrivate::RegisterSingletonType api = { 0, - uri, versionMajor, versionMinor, typeName, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), typeName, - callback, nullptr, nullptr, 0, 0, {} + callback, nullptr, nullptr, 0, QTypeRevision::zero(), {} }; return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api); @@ -727,9 +734,10 @@ inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versi QQmlPrivate::RegisterSingletonType api = { QmlCurrentSingletonTypeRegistrationVersion, - uri, versionMajor, versionMinor, typeName, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), typeName, - nullptr, nullptr, &T::staticMetaObject, qRegisterNormalizedMetaType<T *>(pointerName.constData()), 0, callback + nullptr, nullptr, &T::staticMetaObject, qRegisterNormalizedMetaType<T *>(pointerName.constData()), + QTypeRevision::zero(), callback }; return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api); @@ -746,9 +754,10 @@ inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versi QQmlPrivate::RegisterSingletonType api = { QmlCurrentSingletonTypeRegistrationVersion, - uri, versionMajor, versionMinor, typeName, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), typeName, - nullptr, nullptr, &T::staticMetaObject, qRegisterNormalizedMetaType<T *>(pointerName.constData()), 0, callback + nullptr, nullptr, &T::staticMetaObject, qRegisterNormalizedMetaType<T *>(pointerName.constData()), + QTypeRevision::zero(), callback }; return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api); @@ -774,8 +783,7 @@ inline int qmlRegisterSingletonType(const QUrl &url, const char *uri, int versio QQmlPrivate::RegisterCompositeSingletonType type = { url, uri, - versionMajor, - versionMinor, + QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName }; @@ -793,8 +801,7 @@ inline int qmlRegisterType(const QUrl &url, const char *uri, int versionMajor, i QQmlPrivate::RegisterCompositeType type = { url, uri, - versionMajor, - versionMinor, + QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName }; diff --git a/src/qml/qml/qqmlcomponent.h b/src/qml/qml/qqmlcomponent.h index cb5d5a787c..9a4ea711f3 100644 --- a/src/qml/qml/qqmlcomponent.h +++ b/src/qml/qml/qqmlcomponent.h @@ -71,6 +71,7 @@ class Q_QML_EXPORT QQmlComponent : public QObject Q_PROPERTY(Status status READ status NOTIFY statusChanged) Q_PROPERTY(QUrl url READ url CONSTANT) QML_NAMED_ELEMENT(Component) + QML_ADDED_IN_VERSION(2, 0) QML_ATTACHED(QQmlComponentAttached) Q_CLASSINFO("QML.Builtin", "QML") diff --git a/src/qml/qml/qqmlcomponentattached_p.h b/src/qml/qml/qqmlcomponentattached_p.h index 8ecd9da17d..eb6d35652b 100644 --- a/src/qml/qml/qqmlcomponentattached_p.h +++ b/src/qml/qml/qqmlcomponentattached_p.h @@ -66,6 +66,7 @@ class Q_QML_PRIVATE_EXPORT QQmlComponentAttached : public QObject // when registering QQmlComponent, but we cannot #include it from qqmlcomponent.h. Therefore we // force an anonymous type registration here. QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: QQmlComponentAttached(QObject *parent = nullptr); ~QQmlComponentAttached(); diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp index ecd5020482..02c2b87a6e 100644 --- a/src/qml/qml/qqmlcustomparser.cpp +++ b/src/qml/qml/qqmlcustomparser.cpp @@ -108,12 +108,6 @@ void QQmlCustomParser::error(const QV4::CompiledData::Location &location, const exceptions << error; } -struct StaticQtMetaObject : public QObject -{ - static const QMetaObject *get() - { return &staticQtMetaObject; } -}; - /*! If \a script is a simple enumeration expression (eg. Text.AlignLeft), returns the integer equivalent (eg. 1), and sets \a ok to true. @@ -149,12 +143,12 @@ int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const if (imports.isT1()) { QQmlImportNamespace *ns = nullptr; - if (!imports.asT1()->resolveType(scope, &type, nullptr, nullptr, &ns)) + if (!imports.asT1()->resolveType(scope, &type, nullptr, &ns)) return -1; if (!type.isValid() && ns != nullptr) { dot = nextDot(dot); if (dot == -1 || !imports.asT1()->resolveType(QString::fromUtf8(script.left(dot)), - &type, nullptr, nullptr, nullptr)) { + &type, nullptr, nullptr)) { return -1; } } @@ -183,7 +177,7 @@ int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const } QByteArray enumValue = script.mid(dot + 1); - const QMetaObject *mo = StaticQtMetaObject::get(); + const QMetaObject *mo = &Qt::staticMetaObject; int i = mo->enumeratorCount(); while (i--) { int v = mo->enumerator(i).keyToValue(enumValue.constData(), ok); diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index f97612ab75..c8b41d3684 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -118,7 +118,7 @@ int qmlRegisterUncreatableMetaObject(const QMetaObject &staticMetaObject, nullptr, reason, - uri, versionMajor, versionMinor, qmlName, &staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &staticMetaObject, QQmlAttachedPropertiesFunc(), nullptr, @@ -130,7 +130,7 @@ int qmlRegisterUncreatableMetaObject(const QMetaObject &staticMetaObject, nullptr, nullptr, nullptr, - 0 + QTypeRevision::zero() }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); @@ -195,35 +195,6 @@ int qmlRegisterUncreatableMetaObject(const QMetaObject &staticMetaObject, bool QQmlEnginePrivate::qml_debugging_enabled = false; bool QQmlEnginePrivate::s_designerMode = false; -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) -void QQmlEnginePrivate::registerQuickTypes() -{ - // Don't add anything here. These are only for backwards compatibility. - // Also, don't use qmlRegisterTypesAndRevisions as that will auto-add future revisions. - - const char uri[] = "QtQuick"; - - qmlRegisterType<QQmlComponent>(uri, 2, 0, "Component"); - qmlRegisterType<QObject>(uri, 2, 0, "QtObject"); - qmlRegisterType<QQmlBind>(uri, 2, 0, "Binding"); - qmlRegisterType<QQmlBind, 8>(uri, 2, 8, "Binding"); - qmlRegisterCustomType<QQmlConnections>(uri, 2, 0, "Connections", new QQmlConnectionsParser); - - // Connections revision 3 was added in QtQml 2.3, but only in QtQuick 2.7. - qmlRegisterCustomType<QQmlConnections, 3>(uri, 2, 7, "Connections", new QQmlConnectionsParser); - -#if QT_CONFIG(qml_animation) - qmlRegisterType<QQmlTimer>(uri, 2, 0,"Timer"); -#endif - qmlRegisterType<QQmlLoggingCategory>(uri, 2, 8, "LoggingCategory"); - qmlRegisterType<QQmlLoggingCategory, 12>(uri, 2, 12, "LoggingCategory"); -#if QT_CONFIG(qml_locale) - // Locale was added in QtQuick 2.0 and in QtQml 2.2 - qmlRegisterUncreatableType<QQmlLocale>(uri, 2, 0, "Locale", QQmlEngine::tr("Locale cannot be instantiated. Use Qt.locale()")); -#endif -} -#endif // QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - bool QQmlEnginePrivate::designerMode() { return s_designerMode; @@ -2269,7 +2240,7 @@ void QQmlEngine::setPluginPathList(const QStringList &paths) bool QQmlEngine::importPlugin(const QString &filePath, const QString &uri, QList<QQmlError> *errors) { Q_D(QQmlEngine); - return d->importDatabase.importDynamicPlugin(filePath, uri, QString(), -1, errors); + return d->importDatabase.importDynamicPlugin(filePath, uri, QString(), QTypeRevision(), errors); } #endif @@ -2326,17 +2297,6 @@ QString QQmlEngine::offlineStorageDatabaseFilePath(const QString &databaseName) return d->offlineStorageDatabaseDirectory() + QLatin1String(md5.result().toHex()); } -// #### Qt 6: Remove this function, it exists only for binary compatibility. -/*! - * \internal - */ -bool QQmlEngine::addNamedBundle(const QString &name, const QString &fileName) -{ - Q_UNUSED(name) - Q_UNUSED(fileName) - return false; -} - QString QQmlEnginePrivate::offlineStorageDatabaseDirectory() const { Q_Q(const QQmlEngine); @@ -2390,58 +2350,91 @@ static QQmlPropertyCache *propertyCacheForPotentialInlineComponentType(int t, co return (*iter)->rootPropertyCache().data(); } +/*! + * \internal + * + * Look up by type's baseMetaObject. + */ QQmlMetaObject QQmlEnginePrivate::rawMetaObjectForType(int t) const { - Locker locker(this); - auto iter = m_compositeTypes.constFind(t); - if (iter != m_compositeTypes.cend()) { - return propertyCacheForPotentialInlineComponentType(t, iter); - } else { - QQmlType type = QQmlMetaType::qmlType(t); - return QQmlMetaObject(type.baseMetaObject()); - } + if (QQmlPropertyCache *composite = findPropertyCacheInCompositeTypes(t)) + return QQmlMetaObject(composite); + + QQmlType type = QQmlMetaType::qmlType(t); + return QQmlMetaObject(type.baseMetaObject()); } +/*! + * \internal + * + * Look up by type's metaObject. + */ QQmlMetaObject QQmlEnginePrivate::metaObjectForType(int t) const { - Locker locker(this); - auto iter = m_compositeTypes.constFind(t); - if (iter != m_compositeTypes.cend()) { - return propertyCacheForPotentialInlineComponentType(t, iter); - } else { - QQmlType type = QQmlMetaType::qmlType(t); - return QQmlMetaObject(type.metaObject()); - } + if (QQmlPropertyCache *composite = findPropertyCacheInCompositeTypes(t)) + return QQmlMetaObject(composite); + + QQmlType type = QQmlMetaType::qmlType(t); + return QQmlMetaObject(type.metaObject()); } +/*! + * \internal + * + * Look up by type's metaObject and version. + */ QQmlPropertyCache *QQmlEnginePrivate::propertyCacheForType(int t) { - Locker locker(this); - auto iter = m_compositeTypes.constFind(t); - if (iter != m_compositeTypes.cend()) { - return propertyCacheForPotentialInlineComponentType(t, iter); - } else { - QQmlType type = QQmlMetaType::qmlType(t); - locker.unlock(); - return type.isValid() ? cache(type.metaObject()) : nullptr; - } + if (QQmlPropertyCache *composite = findPropertyCacheInCompositeTypes(t)) + return composite; + + QQmlType type = QQmlMetaType::qmlType(t); + return type.isValid() ? cache(type.metaObject(), type.version()) : nullptr; +} + +/*! + * \internal + * + * Look up by type's baseMetaObject and unspecified/any version. + * TODO: Is this correct? Passing a plain QTypeRevision() rather than QTypeRevision::zero() or + * the actual type's version seems strange. The behavior has been in place for a while. + */ +QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t) +{ + if (QQmlPropertyCache *composite = findPropertyCacheInCompositeTypes(t)) + return composite; + + QQmlType type = QQmlMetaType::qmlType(t); + return type.isValid() ? cache(type.baseMetaObject(), QTypeRevision()) : nullptr; } -QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t, int minorVersion) +/*! + * \internal + * + * Look up by QQmlType and version. We only fall back to lookup by metaobject if the type + * has no revisiononed attributes here. Unspecified versions are interpreted as "any". + */ +QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t, QTypeRevision version) +{ + if (QQmlPropertyCache *composite = findPropertyCacheInCompositeTypes(t)) + return composite; + + QQmlType type = QQmlMetaType::qmlType(t); + if (!type.isValid()) + return nullptr; + + return type.containsRevisionedAttributes() + ? QQmlMetaType::propertyCache(type, version) + : cache(type.metaObject(), version); +} + +QQmlPropertyCache *QQmlEnginePrivate::findPropertyCacheInCompositeTypes(int t) const { Locker locker(this); auto iter = m_compositeTypes.constFind(t); - if (iter != m_compositeTypes.cend()) { - return propertyCacheForPotentialInlineComponentType(t, iter); - } else { - QQmlType type = QQmlMetaType::qmlType(t); - locker.unlock(); - - if (minorVersion >= 0) - return type.isValid() ? cache(type, minorVersion) : nullptr; - else - return type.isValid() ? cache(type.baseMetaObject()) : nullptr; - } + return (iter == m_compositeTypes.constEnd()) + ? nullptr + : propertyCacheForPotentialInlineComponentType(t, iter); } void QQmlEnginePrivate::registerInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit) diff --git a/src/qml/qml/qqmlengine.h b/src/qml/qml/qqmlengine.h index 31fe3a1849..a686d8a1d9 100644 --- a/src/qml/qml/qqmlengine.h +++ b/src/qml/qml/qqmlengine.h @@ -112,7 +112,9 @@ public: void setPluginPathList(const QStringList &paths); void addPluginPath(const QString& dir); - bool addNamedBundle(const QString &name, const QString &fileName); +#if QT_DEPRECATED_SINCE(6, 0) + QT_DEPRECATED bool addNamedBundle(const QString &, const QString &) { return false; } +#endif #if QT_CONFIG(library) bool importPlugin(const QString &filePath, const QString &uri, QList<QQmlError> *errors); diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h index 263c69e2d8..424335b61a 100644 --- a/src/qml/qml/qqmlengine_p.h +++ b/src/qml/qml/qqmlengine_p.h @@ -105,6 +105,7 @@ struct QObjectForeign { Q_GADGET QML_FOREIGN(QObject) QML_NAMED_ELEMENT(QtObject) + QML_ADDED_IN_VERSION(2, 0) Q_CLASSINFO("QML.Root", "QML") }; @@ -216,7 +217,7 @@ public: QString offlineStorageDatabaseDirectory() const; // These methods may be called from the loader thread - inline QQmlPropertyCache *cache(const QQmlType &, int); + inline QQmlPropertyCache *cache(const QQmlType &, QTypeRevision version); using QJSEnginePrivate::cache; // These methods may be called from the loader thread @@ -228,7 +229,8 @@ public: QQmlMetaObject rawMetaObjectForType(int) const; QQmlMetaObject metaObjectForType(int) const; QQmlPropertyCache *propertyCacheForType(int); - QQmlPropertyCache *rawPropertyCacheForType(int, int minorVersion = -1); + QQmlPropertyCache *rawPropertyCacheForType(int); + QQmlPropertyCache *rawPropertyCacheForType(int, QTypeRevision version); void registerInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit); void unregisterInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit); QV4::ExecutableCompilationUnit *obtainExecutableCompilationUnit(int typeId); @@ -260,9 +262,6 @@ public: static QList<QQmlError> qmlErrorFromDiagnostics(const QString &fileName, const QList<QQmlJS::DiagnosticMessage> &diagnosticMessages); static void defineModule(); -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - static void registerQuickTypes(); -#endif static bool designerMode(); static void activateDesignerMode(); @@ -301,6 +300,7 @@ private: void doDeleteInEngineThread(); void cleanupScarceResources(); + QQmlPropertyCache *findPropertyCacheInCompositeTypes(int t) const; }; /* @@ -399,15 +399,15 @@ Returns a QQmlPropertyCache for \a type with \a minorVersion. The returned cache is not referenced, so if it is to be stored, call addref(). */ -QQmlPropertyCache *QQmlEnginePrivate::cache(const QQmlType &type, int minorVersion) +QQmlPropertyCache *QQmlEnginePrivate::cache(const QQmlType &type, QTypeRevision version) { Q_ASSERT(type.isValid()); - if (minorVersion == -1 || !type.containsRevisionedAttributes()) - return cache(type.metaObject(), minorVersion); + if (!version.hasMinorVersion() || !type.containsRevisionedAttributes()) + return cache(type.metaObject(), version); Locker locker(this); - return QQmlMetaType::propertyCache(type, minorVersion); + return QQmlMetaType::propertyCache(type, version); } QV4::ExecutionEngine *QQmlEnginePrivate::getV4Engine(QQmlEngine *e) diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index e442f07527..ee512a5137 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -213,12 +213,12 @@ public: QQmlImportNamespace *importNamespace(const QString &prefix) const; bool addLibraryImport(const QString& uri, const QString &prefix, - int vmaj, int vmin, const QString &qmldirIdentifier, const QString &qmldirUrl, bool incomplete, + QTypeRevision version, const QString &qmldirIdentifier, + const QString &qmldirUrl, bool incomplete, QQmlImportDatabase *database, QList<QQmlError> *errors); - bool addFileImport(const QString &uri, const QString &prefix, - int vmaj, int vmin, + bool addFileImport(const QString &uri, const QString &prefix, QTypeRevision version, bool isImplicitImport, bool incomplete, QQmlImportDatabase *database, QList<QQmlError> *errors); @@ -227,7 +227,7 @@ public: QQmlImportDatabase *database, QList<QQmlError> *errors); - bool resolveType(const QHashedStringRef &type, int *vmajor, int *vminor, + bool resolveType(const QHashedStringRef &type, QTypeRevision *version_return, QQmlType *type_return, QList<QQmlError> *errors, QQmlType::RegistrationType registrationType, bool *typeRecursionDetected = nullptr); @@ -247,14 +247,13 @@ public: QQmlTypeLoader *typeLoader; static QQmlImports::LocalQmldirResult locateLocalQmldir( - const QString &uri, int vmaj, int vmin, QQmlImportDatabase *database, + const QString &uri, QTypeRevision version, QQmlImportDatabase *database, QString *outQmldirFilePath, QString *outUrl); - static bool validateQmldirVersion(const QQmlTypeLoaderQmldirContent &qmldir, const QString &uri, int vmaj, int vmin, - QList<QQmlError> *errors); + static bool validateQmldirVersion(const QQmlTypeLoaderQmldirContent &qmldir, const QString &uri, + QTypeRevision version, QList<QQmlError> *errors); - bool importExtension(const QString &absoluteFilePath, const QString &uri, - int vmaj, int vmin, + bool importExtension(const QString &absoluteFilePath, const QString &uri, QTypeRevision version, QQmlImportDatabase *database, const QQmlTypeLoaderQmldirContent &qmldir, QList<QQmlError> *errors); @@ -264,10 +263,10 @@ public: QString resolvedUri(const QString &dir_arg, QQmlImportDatabase *database); - QQmlImportInstance *addImportToNamespace(QQmlImportNamespace *nameSpace, - const QString &uri, const QString &url, - int vmaj, int vmin, QV4::CompiledData::Import::ImportType type, - QList<QQmlError> *errors, bool lowPrecedence = false); + QQmlImportInstance *addImportToNamespace(QQmlImportNamespace *nameSpace, const QString &uri, + const QString &url, QTypeRevision version, + QV4::CompiledData::Import::ImportType type, + QList<QQmlError> *errors, bool lowPrecedence = false); bool populatePluginPairVector(QVector<StaticPluginPair> &result, const QString &uri, const QStringList &versionUris, const QString &qmldirPath, QList<QQmlError> *errors); @@ -344,9 +343,9 @@ void QQmlImports::populateCache(QQmlTypeNameCache *cache) const for (int ii = set.imports.count() - 1; ii >= 0; --ii) { const QQmlImportInstance *import = set.imports.at(ii); - QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->majversion); + QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->version); if (module) { - cache->m_anonymousImports.append(QQmlTypeModuleVersion(module, import->minversion)); + cache->m_anonymousImports.append(QQmlTypeModuleVersion(module, import->version)); } } @@ -360,10 +359,10 @@ void QQmlImports::populateCache(QQmlTypeNameCache *cache) const for (int ii = set.imports.count() - 1; ii >= 0; --ii) { const QQmlImportInstance *import = set.imports.at(ii); - QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->majversion); + QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->version); if (module) { QQmlImportRef &typeimport = cache->m_namedImports[set.prefix]; - typeimport.modules.append(QQmlTypeModuleVersion(module, import->minversion)); + typeimport.modules.append(QQmlTypeModuleVersion(module, import->version)); } } } @@ -395,36 +394,35 @@ void findCompositeSingletons(const QQmlImportNamespace &set, QList<QQmlImports:: const QQmlDirComponents &components = import->qmlDirComponents; - const int importMajorVersion = import->majversion; - const int importMinorVersion = import->minversion; - auto shouldSkipSingleton = [importMajorVersion, importMinorVersion](int singletonMajorVersion, int singletonMinorVersion) -> bool { - return importMajorVersion != -1 && - (singletonMajorVersion > importMajorVersion || (singletonMajorVersion == importMajorVersion && singletonMinorVersion > importMinorVersion)); + const QTypeRevision importVersion = import->version; + auto shouldSkipSingleton = [importVersion](QTypeRevision singletonVersion) -> bool { + return importVersion.hasMajorVersion() && + (singletonVersion.majorVersion() > importVersion.majorVersion() + || (singletonVersion.majorVersion() == importVersion.majorVersion() + && singletonVersion.minorVersion() > importVersion.minorVersion())); }; ConstIterator cend = components.constEnd(); for (ConstIterator cit = components.constBegin(); cit != cend; ++cit) { if (cit->singleton && excludeBaseUrl(import->url, cit->fileName, baseUrl.toString())) { - if (shouldSkipSingleton(cit->majorVersion, cit->minorVersion)) + if (shouldSkipSingleton(cit->version)) continue; QQmlImports::CompositeSingletonReference ref; ref.typeName = cit->typeName; ref.prefix = set.prefix; - ref.majorVersion = cit->majorVersion; - ref.minorVersion = cit->minorVersion; + ref.version = cit->version; resultList.append(ref); } } - if (QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->majversion)) { + if (QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->version)) { module->walkCompositeSingletons([&resultList, &set, &shouldSkipSingleton](const QQmlType &singleton) { - if (shouldSkipSingleton(singleton.majorVersion(), singleton.minorVersion())) + if (shouldSkipSingleton(singleton.version())) return; QQmlImports::CompositeSingletonReference ref; ref.typeName = singleton.elementName(); ref.prefix = set.prefix; - ref.majorVersion = singleton.majorVersion(); - ref.minorVersion = singleton.minorVersion(); + ref.version = singleton.version(); resultList.append(ref); }); } @@ -461,9 +459,9 @@ QList<QQmlImports::CompositeSingletonReference> QQmlImports::resolvedCompositeSi if (lhs.typeName != rhs.typeName) return lhs.typeName < rhs.typeName; - return lhs.majorVersion != rhs.majorVersion - ? lhs.majorVersion < rhs.majorVersion - : lhs.minorVersion < rhs.minorVersion; + return lhs.version.majorVersion() != rhs.version.majorVersion() + ? lhs.version.majorVersion() < rhs.version.majorVersion() + : lhs.version.minorVersion() < rhs.version.minorVersion(); }); return compositeSingletons; @@ -532,7 +530,8 @@ static QString joinStringRefs(const QVector<QStringRef> &refs, const QChar &sep) - base/QtQml.2/Models/qmldir - base/QtQml/Models/qmldir */ -QStringList QQmlImports::completeQmldirPaths(const QString &uri, const QStringList &basePaths, int vmaj, int vmin) +QStringList QQmlImports::completeQmldirPaths(const QString &uri, const QStringList &basePaths, + QTypeRevision version) { const QVector<QStringRef> parts = uri.splitRef(Dot, QString::SkipEmptyParts); @@ -540,8 +539,8 @@ QStringList QQmlImports::completeQmldirPaths(const QString &uri, const QStringLi // fully & partially versioned parts + 1 unversioned for each base path qmlDirPathsPaths.reserve(basePaths.count() * (2 * parts.count() + 1)); - for (int version = FullyVersioned; version <= Unversioned; ++version) { - const QString ver = versionString(vmaj, vmin, static_cast<QQmlImports::ImportVersion>(version)); + for (int versionMode = FullyVersioned; versionMode <= Unversioned; ++versionMode) { + const QString ver = versionString(version, QQmlImports::ImportVersion(versionMode)); for (const QString &path : basePaths) { QString dir = path; @@ -551,7 +550,7 @@ QStringList QQmlImports::completeQmldirPaths(const QString &uri, const QStringLi // append to the end qmlDirPathsPaths += dir + joinStringRefs(parts, Slash) + ver + Slash_qmldir; - if (version != Unversioned) { + if (versionMode != Unversioned) { // insert in the middle for (int index = parts.count() - 2; index >= 0; --index) { qmlDirPathsPaths += dir + joinStringRefs(parts.mid(0, index + 1), Slash) @@ -565,14 +564,14 @@ QStringList QQmlImports::completeQmldirPaths(const QString &uri, const QStringLi return qmlDirPathsPaths; } -QString QQmlImports::versionString(int vmaj, int vmin, ImportVersion version) +QString QQmlImports::versionString(QTypeRevision version, ImportVersion versionMode) { - if (version == QQmlImports::FullyVersioned) { + if (versionMode == QQmlImports::FullyVersioned) { // extension with fully encoded version number (eg. MyModule.3.2) - return QString::asprintf(".%d.%d", vmaj, vmin); - } else if (version == QQmlImports::PartiallyVersioned) { + return QString::asprintf(".%d.%d", version.majorVersion(), version.minorVersion()); + } else if (versionMode == QQmlImports::PartiallyVersioned) { // extension with encoded version major (eg. MyModule.3) - return QString::asprintf(".%d", vmaj); + return QString::asprintf(".%d", version.majorVersion()); } // else extension without version number (eg. MyModule) return QString(); } @@ -591,7 +590,7 @@ QString QQmlImports::versionString(int vmaj, int vmin, ImportVersion version) \sa addFileImport(), addLibraryImport */ bool QQmlImports::resolveType(const QHashedStringRef &type, - QQmlType *type_return, int *vmaj, int *vmin, + QQmlType *type_return, QTypeRevision *version_return, QQmlImportNamespace** ns_return, QList<QQmlError> *errors, QQmlType::RegistrationType registrationType, bool *typeRecursionDetected) const @@ -603,7 +602,7 @@ bool QQmlImports::resolveType(const QHashedStringRef &type, return true; } if (type_return) { - if (d->resolveType(type, vmaj, vmin, type_return, errors, registrationType, + if (d->resolveType(type, version_return, type_return, errors, registrationType, typeRecursionDetected)) { if (qmlImportTrace()) { #define RESOLVE_TYPE_DEBUG qDebug().nospace() << "QQmlImports(" << qPrintable(baseUrl().toString()) \ @@ -627,7 +626,9 @@ bool QQmlImports::resolveType(const QHashedStringRef &type, return false; } -bool QQmlImportInstance::setQmldirContent(const QString &resolvedUrl, const QQmlTypeLoaderQmldirContent &qmldir, QQmlImportNamespace *nameSpace, QList<QQmlError> *errors) +bool QQmlImportInstance::setQmldirContent(const QString &resolvedUrl, + const QQmlTypeLoaderQmldirContent &qmldir, + QQmlImportNamespace *nameSpace, QList<QQmlError> *errors) { Q_ASSERT(resolvedUrl.endsWith(Slash)); url = resolvedUrl; @@ -648,24 +649,27 @@ bool QQmlImportInstance::setQmldirContent(const QString &resolvedUrl, const QQml } } - qmlDirScripts = getVersionedScripts(scripts, majversion, minversion); + qmlDirScripts = getVersionedScripts(scripts, version); } return true; } -QQmlDirScripts QQmlImportInstance::getVersionedScripts(const QQmlDirScripts &qmldirscripts, int vmaj, int vmin) +QQmlDirScripts QQmlImportInstance::getVersionedScripts(const QQmlDirScripts &qmldirscripts, + QTypeRevision version) { QMap<QString, QQmlDirParser::Script> versioned; for (QList<QQmlDirParser::Script>::const_iterator sit = qmldirscripts.constBegin(); sit != qmldirscripts.constEnd(); ++sit) { // Only include scripts that match our requested version - if (((vmaj == -1) || (sit->majorVersion == vmaj)) && - ((vmin == -1) || (sit->minorVersion <= vmin))) { + if ((!version.hasMajorVersion() || (sit->version.majorVersion() == version.majorVersion())) + && (!version.hasMinorVersion() + || (sit->version.minorVersion() <= version.minorVersion()))) { // Load the highest version that matches QMap<QString, QQmlDirParser::Script>::iterator vit = versioned.find(sit->nameSpace); - if (vit == versioned.end() || (vit->minorVersion < sit->minorVersion)) { + if (vit == versioned.end() + || (vit->version.minorVersion() < sit->version.minorVersion())) { versioned.insert(sit->nameSpace, *sit); } } @@ -685,26 +689,25 @@ QQmlDirScripts QQmlImportInstance::getVersionedScripts(const QQmlDirScripts &qml If the return pointer is 0, the corresponding search is not done. */ bool QQmlImports::resolveType(QQmlImportNamespace *ns, const QHashedStringRef &type, - QQmlType *type_return, int *vmaj, int *vmin, + QQmlType *type_return, QTypeRevision *version_return, QQmlType::RegistrationType registrationType) const { - return ns->resolveType(d->typeLoader, type, vmaj, vmin, type_return, nullptr, nullptr, registrationType); + return ns->resolveType(d->typeLoader, type, version_return, type_return, nullptr, nullptr, + registrationType); } bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef& type, - int *vmajor, int *vminor, QQmlType *type_return, QString *base, - bool *typeRecursionDetected, + QTypeRevision *version_return, QQmlType *type_return, + QString *base, bool *typeRecursionDetected, QQmlType::RegistrationType registrationType, QQmlImport::RecursionRestriction recursionRestriction, QList<QQmlError> *errors) const { - if (majversion >= 0 && minversion >= 0) { - QQmlType t = QQmlMetaType::qmlType(type, uri, majversion, minversion); + if (version.hasMajorVersion() && version.hasMinorVersion()) { + QQmlType t = QQmlMetaType::qmlType(type, uri, version); if (t.isValid()) { - if (vmajor) - *vmajor = majversion; - if (vminor) - *vminor = minversion; + if (version_return) + *version_return = version; if (type_return) *type_return = t; return true; @@ -764,14 +767,16 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt break; } - // importing version -1 means import ALL versions - if ((majversion == -1) || - (implicitlyImported && c.internal) || // allow the implicit import of internal types - (c.majorVersion == majversion && c.minorVersion <= minversion)) { + // importing invalid version means import ALL versions + if (!version.hasMajorVersion() || (implicitlyImported && c.internal) + // allow the implicit import of internal types + || (c.version.majorVersion() == version.majorVersion() + && c.version.minorVersion() <= version.minorVersion())) { // Is this better than the previous candidate? - if ((candidate == end) || - (c.majorVersion > candidate->majorVersion) || - ((c.majorVersion == candidate->majorVersion) && (c.minorVersion > candidate->minorVersion))) { + if ((candidate == end) + || (c.version.majorVersion() > candidate->version.majorVersion()) + || ((c.version.majorVersion() == candidate->version.majorVersion()) + && (c.version.minorVersion() > candidate->version.minorVersion()))) { if (base) { componentUrl = resolveLocalUrl(QString(url + c.typeName + dotqml_string), c.fileName); if (c.internal) { @@ -799,12 +804,9 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt if (!base) // ensure we have a componentUrl componentUrl = resolveLocalUrl(QString(url + candidate->typeName + dotqml_string), candidate->fileName); QQmlType returnType = QQmlMetaType::typeForUrl(componentUrl, type, isCompositeSingleton, - nullptr, candidate->majorVersion, - candidate->minorVersion); - if (vmajor) - *vmajor = candidate->majorVersion; - if (vminor) - *vminor = candidate->minorVersion; + nullptr, candidate->version); + if (version_return) + *version_return = candidate->version; if (type_return) *type_return = returnType; return returnType.isValid(); @@ -856,14 +858,14 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt return false; } -bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, int *vmajor, int *vminor, +bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, QTypeRevision *version_return, QQmlType *type_return, QList<QQmlError> *errors, QQmlType::RegistrationType registrationType, bool *typeRecursionDetected) { const QVector<QHashedStringRef> splitName = type.split(Dot); auto resolveTypeInNamespace = [&](QHashedStringRef unqualifiedtype, QQmlImportNamespace *nameSpace, QList<QQmlError> *errors) -> bool { - if (nameSpace->resolveType(typeLoader, unqualifiedtype, vmajor, vminor, type_return, &base, errors, + if (nameSpace->resolveType(typeLoader, unqualifiedtype, version_return, type_return, &base, errors, registrationType, typeRecursionDetected)) return true; if (nameSpace->imports.count() == 1 && !nameSpace->imports.at(0)->isLibrary && type_return && nameSpace != &unqualifiedset) { @@ -976,7 +978,7 @@ QQmlImportInstance *QQmlImportNamespace::findImport(const QString &uri) const } bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type, - int *vmajor, int *vminor, QQmlType *type_return, + QTypeRevision *version_return, QQmlType *type_return, QString *base, QList<QQmlError> *errors, QQmlType::RegistrationType registrationType, bool *typeRecursionDetected) @@ -990,13 +992,13 @@ bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QHashedS for (int i=0; i<imports.count(); ++i) { const QQmlImportInstance *import = imports.at(i); - if (import->resolveType(typeLoader, type, vmajor, vminor, type_return, base, + if (import->resolveType(typeLoader, type, version_return, type_return, base, typeRecursionDetected, registrationType, recursionRestriction, errors)) { if (qmlCheckTypes()) { // check for type clashes for (int j = i+1; j<imports.count(); ++j) { const QQmlImportInstance *import2 = imports.at(j); - if (import2->resolveType(typeLoader, type, vmajor, vminor, nullptr, base, + if (import2->resolveType(typeLoader, type, version_return, nullptr, base, nullptr, registrationType)) { if (errors) { QString u1 = import->url; @@ -1023,9 +1025,11 @@ bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QHashedS error.setDescription(QQmlImportDatabase::tr("is ambiguous. Found in %1 and in %2").arg(u1).arg(u2)); } else { error.setDescription(QQmlImportDatabase::tr("is ambiguous. Found in %1 in version %2.%3 and %4.%5") - .arg(u1) - .arg(import->majversion).arg(import->minversion) - .arg(import2->majversion).arg(import2->minversion)); + .arg(u1) + .arg(import->version.majorVersion()) + .arg(import->version.minorVersion()) + .arg(import2->version.majorVersion()) + .arg(import2->version.minorVersion())); } errors->prepend(error); } @@ -1071,18 +1075,19 @@ QQmlImportNamespace *QQmlImportsPrivate::findQualifiedNamespace(const QHashedStr QtQml.Models, \a vmaj is 2, and \a vmin is 0, this method returns the following: [QtQml.Models.2.0, QtQml.2.0.Models, QtQml.Models.2, QtQml.2.Models, QtQml.Models] */ -static QStringList versionUriList(const QString &uri, int vmaj, int vmin) +static QStringList versionUriList(const QString &uri, QTypeRevision version) { QStringList result; - for (int version = QQmlImports::FullyVersioned; version <= QQmlImports::Unversioned; ++version) { + for (int mode = QQmlImports::FullyVersioned; mode <= QQmlImports::Unversioned; ++mode) { int index = uri.length(); do { QString versionUri = uri; - versionUri.insert(index, QQmlImports::versionString(vmaj, vmin, static_cast<QQmlImports::ImportVersion>(version))); + versionUri.insert(index, QQmlImports::versionString( + version, QQmlImports::ImportVersion(mode))); result += versionUri; index = uri.lastIndexOf(Dot, index - 1); - } while (index > 0 && version != QQmlImports::Unversioned); + } while (index > 0 && mode != QQmlImports::Unversioned); } return result; } @@ -1147,8 +1152,7 @@ Import an extension defined by a qmldir file. \a qmldirFilePath is a raw file path. */ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath, - const QString &uri, - int vmaj, int vmin, + const QString &uri, QTypeRevision version, QQmlImportDatabase *database, const QQmlTypeLoaderQmldirContent &qmldir, QList<QQmlError> *errors) @@ -1173,13 +1177,7 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath, if (qmldirPluginCount == 0) return true; - if (database->qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(qmldirFilePath)) { - if ((vmaj >= 0 && vmin >= 0) - ? !QQmlMetaType::isModule(uri, vmaj, vmin) - : !QQmlMetaType::isAnyModule(uri)) { - QQmlMetaType::qmlRegisterModuleTypes(uri, vmaj); - } - } else { + if (!database->qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(qmldirFilePath)) { // First search for listed qmldir plugins dynamically. If we cannot resolve them all, we continue // searching static plugins that has correct metadata uri. Note that since we only know the uri // for a static plugin, and not the filename, we cannot know which static plugin belongs to which @@ -1201,7 +1199,7 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath, QString resolvedFilePath = database->resolvePlugin(typeLoader, qmldirPath, plugin.path, plugin.name); if (!resolvedFilePath.isEmpty()) { dynamicPluginsFound++; - if (!database->importDynamicPlugin(resolvedFilePath, uri, typeNamespace, vmaj, errors)) { + if (!database->importDynamicPlugin(resolvedFilePath, uri, typeNamespace, version, errors)) { if (errors) { // XXX TODO: should we leave the import plugin error alone? // Here, we pop it off the top and coalesce it into this error's message. @@ -1226,7 +1224,7 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath, // versioned to unversioned, we need to compare with differnt version strings. If a module // has several plugins, they must all have the same version. Start by populating pluginPairs // with relevant plugins to cut the list short early on: - const QStringList versionUris = versionUriList(uri, vmaj, vmin); + const QStringList versionUris = versionUriList(uri, version); QVector<StaticPluginPair> pluginPairs; if (!populatePluginPairVector(pluginPairs, uri, versionUris, qmldirFilePath, errors)) return false; @@ -1238,7 +1236,7 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath, if (versionUri == metaTagUri.toString()) { staticPluginsFound++; QObject *instance = pair.first.instance(); - if (!database->importStaticPlugin(instance, basePath, uri, typeNamespace, vmaj, errors)) { + if (!database->importStaticPlugin(instance, basePath, uri, typeNamespace, version, errors)) { if (errors) { QQmlError poppedError = errors->takeFirst(); QQmlError error; @@ -1341,10 +1339,11 @@ and fills in outQmldirFilePath and outQmldirUrl appropriately. Otherwise return false. */ QQmlImports::LocalQmldirResult QQmlImportsPrivate::locateLocalQmldir( - const QString &uri, int vmaj, int vmin, QQmlImportDatabase *database, + const QString &uri, QTypeRevision version, QQmlImportDatabase *database, QString *outQmldirFilePath, QString *outQmldirPathUrl) { - Q_ASSERT(vmaj >= 0 && vmin >= 0); // Versions are always specified for libraries + // Versions are always specified for libraries + Q_ASSERT(version.hasMajorVersion() && version.hasMinorVersion()); // Check cache first @@ -1355,7 +1354,7 @@ QQmlImports::LocalQmldirResult QQmlImportsPrivate::locateLocalQmldir( cacheHead = *cachePtr; QQmlImportDatabase::QmldirCache *cache = cacheHead; while (cache) { - if (cache->versionMajor == vmaj && cache->versionMinor == vmin) { + if (cache->version == version) { *outQmldirFilePath = cache->qmldirFilePath; *outQmldirPathUrl = cache->qmldirPathUrl; return cache->qmldirFilePath.isEmpty() ? QQmlImports::QmldirNotFound @@ -1375,7 +1374,7 @@ QQmlImports::LocalQmldirResult QQmlImportsPrivate::locateLocalQmldir( // Search local import paths for a matching version const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths( - uri, localImportPaths, vmaj, vmin); + uri, localImportPaths, version); bool pathTurnedRemote = false; for (QString qmldirPath : qmlDirPaths) { if (interceptor) { @@ -1397,8 +1396,7 @@ QQmlImports::LocalQmldirResult QQmlImportsPrivate::locateLocalQmldir( url = QUrl::fromLocalFile(absolutePath.toString()).toString(); QQmlImportDatabase::QmldirCache *cache = new QQmlImportDatabase::QmldirCache; - cache->versionMajor = vmaj; - cache->versionMinor = vmin; + cache->version = version; cache->qmldirFilePath = absoluteFilePath; cache->qmldirPathUrl = url; cache->next = cacheHead; @@ -1412,19 +1410,19 @@ QQmlImports::LocalQmldirResult QQmlImportsPrivate::locateLocalQmldir( } QQmlImportDatabase::QmldirCache *cache = new QQmlImportDatabase::QmldirCache; - cache->versionMajor = vmaj; - cache->versionMinor = vmin; + cache->version = version; cache->next = cacheHead; database->qmldirCache.insert(uri, cache); return pathTurnedRemote ? QQmlImports::QmldirInterceptedToRemote : QQmlImports::QmldirNotFound; } -bool QQmlImportsPrivate::validateQmldirVersion(const QQmlTypeLoaderQmldirContent &qmldir, const QString &uri, int vmaj, int vmin, +bool QQmlImportsPrivate::validateQmldirVersion(const QQmlTypeLoaderQmldirContent &qmldir, + const QString &uri, QTypeRevision version, QList<QQmlError> *errors) { - int lowest_min = INT_MAX; - int highest_min = INT_MIN; + quint8 lowest_min = std::numeric_limits<quint8>::max(); + quint8 highest_min = 0; typedef QQmlDirComponents::const_iterator ConstIterator; const QQmlDirComponents &components = qmldir.components(); @@ -1432,21 +1430,20 @@ bool QQmlImportsPrivate::validateQmldirVersion(const QQmlTypeLoaderQmldirContent ConstIterator cend = components.constEnd(); for (ConstIterator cit = components.constBegin(); cit != cend; ++cit) { for (ConstIterator cit2 = components.constBegin(); cit2 != cit; ++cit2) { - if ((cit2->typeName == cit->typeName) && - (cit2->majorVersion == cit->majorVersion) && - (cit2->minorVersion == cit->minorVersion)) { + if (cit2->typeName == cit->typeName && cit2->version == cit->version) { // This entry clashes with a predecessor QQmlError error; error.setDescription(QQmlImportDatabase::tr("\"%1\" version %2.%3 is defined more than once in module \"%4\"") - .arg(cit->typeName).arg(cit->majorVersion).arg(cit->minorVersion).arg(uri)); + .arg(cit->typeName).arg(cit->version.majorVersion()) + .arg(cit->version.minorVersion()).arg(uri)); errors->prepend(error); return false; } } - if (cit->majorVersion == vmaj) { - lowest_min = qMin(lowest_min, cit->minorVersion); - highest_min = qMax(highest_min, cit->minorVersion); + if (cit->version.majorVersion() == version.majorVersion()) { + lowest_min = qMin(lowest_min, cit->version.minorVersion()); + highest_min = qMax(highest_min, cit->version.minorVersion()); } } @@ -1456,27 +1453,27 @@ bool QQmlImportsPrivate::validateQmldirVersion(const QQmlTypeLoaderQmldirContent SConstIterator send = scripts.constEnd(); for (SConstIterator sit = scripts.constBegin(); sit != send; ++sit) { for (SConstIterator sit2 = scripts.constBegin(); sit2 != sit; ++sit2) { - if ((sit2->nameSpace == sit->nameSpace) && - (sit2->majorVersion == sit->majorVersion) && - (sit2->minorVersion == sit->minorVersion)) { + if (sit2->nameSpace == sit->nameSpace && sit2->version == sit->version) { // This entry clashes with a predecessor QQmlError error; error.setDescription(QQmlImportDatabase::tr("\"%1\" version %2.%3 is defined more than once in module \"%4\"") - .arg(sit->nameSpace).arg(sit->majorVersion).arg(sit->minorVersion).arg(uri)); + .arg(sit->nameSpace).arg(sit->version.majorVersion()) + .arg(sit->version.minorVersion()).arg(uri)); errors->prepend(error); return false; } } - if (sit->majorVersion == vmaj) { - lowest_min = qMin(lowest_min, sit->minorVersion); - highest_min = qMax(highest_min, sit->minorVersion); + if (sit->version.majorVersion() == version.majorVersion()) { + lowest_min = qMin(lowest_min, sit->version.minorVersion()); + highest_min = qMax(highest_min, sit->version.minorVersion()); } } - if (lowest_min > vmin || highest_min < vmin) { + if (lowest_min > version.minorVersion() || highest_min < version.minorVersion()) { QQmlError error; - error.setDescription(QQmlImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri).arg(vmaj).arg(vmin)); + error.setDescription(QQmlImportDatabase::tr("module \"%1\" version %2.%3 is not installed") + .arg(uri).arg(version.majorVersion()).arg(version.minorVersion())); errors->prepend(error); return false; } @@ -1503,10 +1500,9 @@ QQmlImportNamespace *QQmlImportsPrivate::importNamespace(const QString &prefix) return nameSpace; } -QQmlImportInstance *QQmlImportsPrivate::addImportToNamespace(QQmlImportNamespace *nameSpace, - const QString &uri, const QString &url, int vmaj, int vmin, - QV4::CompiledData::Import::ImportType type, - QList<QQmlError> *errors, bool lowPrecedence) +QQmlImportInstance *QQmlImportsPrivate::addImportToNamespace( + QQmlImportNamespace *nameSpace, const QString &uri, const QString &url, QTypeRevision version, + QV4::CompiledData::Import::ImportType type, QList<QQmlError> *errors, bool lowPrecedence) { Q_ASSERT(nameSpace); Q_ASSERT(errors); @@ -1517,8 +1513,7 @@ QQmlImportInstance *QQmlImportsPrivate::addImportToNamespace(QQmlImportNamespace import->uri = uri; import->url = url; import->localDirectoryPath = QQmlFile::urlToLocalFileOrQrc(url); - import->majversion = vmaj; - import->minversion = vmin; + import->version = version; import->isLibrary = (type == QV4::CompiledData::Import::ImportLibrary); if (lowPrecedence) @@ -1529,10 +1524,10 @@ QQmlImportInstance *QQmlImportsPrivate::addImportToNamespace(QQmlImportNamespace return import; } -bool QQmlImportsPrivate::addLibraryImport(const QString& uri, const QString &prefix, - int vmaj, int vmin, const QString &qmldirIdentifier, const QString &qmldirUrl, bool incomplete, - QQmlImportDatabase *database, - QList<QQmlError> *errors) +bool QQmlImportsPrivate::addLibraryImport( + const QString& uri, const QString &prefix, QTypeRevision version, + const QString &qmldirIdentifier, const QString &qmldirUrl, bool incomplete, + QQmlImportDatabase *database, QList<QQmlError> *errors) { Q_ASSERT(database); Q_ASSERT(errors); @@ -1540,7 +1535,9 @@ bool QQmlImportsPrivate::addLibraryImport(const QString& uri, const QString &pre QQmlImportNamespace *nameSpace = importNamespace(prefix); Q_ASSERT(nameSpace); - QQmlImportInstance *inserted = addImportToNamespace(nameSpace, uri, qmldirUrl, vmaj, vmin, QV4::CompiledData::Import::ImportLibrary, errors); + QQmlImportInstance *inserted = addImportToNamespace( + nameSpace, uri, qmldirUrl, version, + QV4::CompiledData::Import::ImportLibrary, errors); Q_ASSERT(inserted); if (!incomplete) { @@ -1551,7 +1548,7 @@ bool QQmlImportsPrivate::addLibraryImport(const QString& uri, const QString &pre return false; if (qmldir.hasContent()) { - if (!importExtension(qmldir.pluginLocation(), uri, vmaj, vmin, database, qmldir, errors)) + if (!importExtension(qmldir.pluginLocation(), uri, version, database, qmldir, errors)) return false; if (!inserted->setQmldirContent(qmldirUrl, qmldir, nameSpace, errors)) @@ -1560,18 +1557,22 @@ bool QQmlImportsPrivate::addLibraryImport(const QString& uri, const QString &pre } // Ensure that we are actually providing something - if ((vmaj < 0) || (vmin < 0) || !QQmlMetaType::isModule(uri, vmaj, vmin)) { + if (!version.hasMajorVersion() || !version.hasMinorVersion() + || !QQmlMetaType::isModule(uri, version)) { if (inserted->qmlDirComponents.isEmpty() && inserted->qmlDirScripts.isEmpty()) { QQmlError error; - if (QQmlMetaType::isAnyModule(uri)) - error.setDescription(QQmlImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri).arg(vmaj).arg(vmin)); - else + if (QQmlMetaType::isAnyModule(uri)) { + error.setDescription(QQmlImportDatabase::tr("module \"%1\" version %2.%3 is not installed") + .arg(uri).arg(version.majorVersion()).arg(version.minorVersion())); + } else { error.setDescription(QQmlImportDatabase::tr("module \"%1\" is not installed").arg(uri)); + } errors->prepend(error); return false; - } else if ((vmaj >= 0) && (vmin >= 0) && qmldir.hasContent()) { + } else if (version.hasMajorVersion() && version.hasMinorVersion() + && qmldir.hasContent()) { // Verify that the qmldir content is valid for this version - if (!validateQmldirVersion(qmldir, uri, vmaj, vmin, errors)) + if (!validateQmldirVersion(qmldir, uri, version, errors)) return false; } } @@ -1580,10 +1581,9 @@ bool QQmlImportsPrivate::addLibraryImport(const QString& uri, const QString &pre return true; } -bool QQmlImportsPrivate::addFileImport(const QString& uri, const QString &prefix, - int vmaj, int vmin, - bool isImplicitImport, bool incomplete, QQmlImportDatabase *database, - QList<QQmlError> *errors) +bool QQmlImportsPrivate::addFileImport(const QString& uri, const QString &prefix, QTypeRevision version, + bool isImplicitImport, bool incomplete, + QQmlImportDatabase *database, QList<QQmlError> *errors) { Q_ASSERT(errors); @@ -1659,7 +1659,9 @@ bool QQmlImportsPrivate::addFileImport(const QString& uri, const QString &prefix } } - QQmlImportInstance *inserted = addImportToNamespace(nameSpace, importUri, url, vmaj, vmin, QV4::CompiledData::Import::ImportFile, errors, isImplicitImport); + QQmlImportInstance *inserted = addImportToNamespace( + nameSpace, importUri, url, version, QV4::CompiledData::Import::ImportFile, + errors, isImplicitImport); Q_ASSERT(inserted); if (!incomplete && !qmldirIdentifier.isEmpty()) { @@ -1668,7 +1670,7 @@ bool QQmlImportsPrivate::addFileImport(const QString& uri, const QString &prefix return false; if (qmldir.hasContent()) { - if (!importExtension(qmldir.pluginLocation(), importUri, vmaj, vmin, database, qmldir, errors)) + if (!importExtension(qmldir.pluginLocation(), importUri, version, database, qmldir, errors)) return false; if (!inserted->setQmldirContent(url, qmldir, nameSpace, errors)) @@ -1692,26 +1694,27 @@ bool QQmlImportsPrivate::updateQmldirContent(const QString &uri, const QString & return false; if (qmldir.hasContent()) { - int vmaj = import->majversion; - int vmin = import->minversion; - if (!importExtension(qmldir.pluginLocation(), uri, vmaj, vmin, database, qmldir, errors)) + QTypeRevision version = import->version; + if (!importExtension(qmldir.pluginLocation(), uri, version, database, qmldir, errors)) return false; if (import->setQmldirContent(qmldirUrl, qmldir, nameSpace, errors)) { if (import->qmlDirComponents.isEmpty() && import->qmlDirScripts.isEmpty()) { // The implicit import qmldir can be empty, and plugins have no extra versions - if (uri != QLatin1String(".") && !QQmlMetaType::isModule(uri, vmaj, vmin)) { + if (uri != QLatin1String(".") && !QQmlMetaType::isModule(uri, version)) { QQmlError error; - if (QQmlMetaType::isAnyModule(uri)) - error.setDescription(QQmlImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri).arg(vmaj).arg(vmin)); - else + if (QQmlMetaType::isAnyModule(uri)) { + error.setDescription(QQmlImportDatabase::tr("module \"%1\" version %2.%3 is not installed") + .arg(uri).arg(version.majorVersion()).arg(version.minorVersion())); + } else { error.setDescription(QQmlImportDatabase::tr("module \"%1\" is not installed").arg(uri)); + } errors->prepend(error); return false; } - } else if ((vmaj >= 0) && (vmin >= 0)) { + } else if (version.hasMajorVersion() && version.hasMinorVersion()) { // Verify that the qmldir content is valid for this version - if (!validateQmldirVersion(qmldir, uri, vmaj, vmin, errors)) + if (!validateQmldirVersion(qmldir, uri, version, errors)) return false; } return true; @@ -1745,7 +1748,8 @@ bool QQmlImports::addImplicitImport(QQmlImportDatabase *importDb, QList<QQmlErro << ")::addImplicitImport"; bool incomplete = !isLocal(baseUrl()); - return d->addFileImport(QLatin1String("."), QString(), -1, -1, true, incomplete, importDb, errors); + return d->addFileImport(QLatin1String("."), QString(), QTypeRevision(), true, incomplete, + importDb, errors); } /*! @@ -1756,8 +1760,7 @@ bool QQmlImports::addInlineComponentImport(QQmlImportInstance *const importInsta importInstance->url = importUrl.toString(); importInstance->uri = name; importInstance->isInlineComponent = true; - importInstance->majversion = 0; - importInstance->minversion = 0; + importInstance->version = QTypeRevision::zero(); importInstance->containingType = containingType; d->unqualifiedset.imports.push_back(importInstance); return true; @@ -1785,7 +1788,7 @@ bool QQmlImports::addInlineComponentImport(QQmlImportInstance *const importInsta filled appropriately. */ bool QQmlImports::addFileImport(QQmlImportDatabase *importDb, - const QString& uri, const QString& prefix, int vmaj, int vmin, + const QString& uri, const QString& prefix, QTypeRevision version, bool incomplete, QList<QQmlError> *errors) { Q_ASSERT(importDb); @@ -1793,13 +1796,13 @@ bool QQmlImports::addFileImport(QQmlImportDatabase *importDb, if (qmlImportTrace()) qDebug().nospace() << "QQmlImports(" << qPrintable(baseUrl().toString()) << ')' << "::addFileImport: " - << uri << ' ' << vmaj << '.' << vmin << " as " << prefix; + << uri << ' ' << version << " as " << prefix; - return d->addFileImport(uri, prefix, vmaj, vmin, false, incomplete, importDb, errors); + return d->addFileImport(uri, prefix, version, false, incomplete, importDb, errors); } bool QQmlImports::addLibraryImport(QQmlImportDatabase *importDb, - const QString &uri, const QString &prefix, int vmaj, int vmin, + const QString &uri, const QString &prefix, QTypeRevision version, const QString &qmldirIdentifier, const QString& qmldirUrl, bool incomplete, QList<QQmlError> *errors) { Q_ASSERT(importDb); @@ -1807,9 +1810,9 @@ bool QQmlImports::addLibraryImport(QQmlImportDatabase *importDb, if (qmlImportTrace()) qDebug().nospace() << "QQmlImports(" << qPrintable(baseUrl().toString()) << ')' << "::addLibraryImport: " - << uri << ' ' << vmaj << '.' << vmin << " as " << prefix; + << uri << ' ' << version << " as " << prefix; - return d->addLibraryImport(uri, prefix, vmaj, vmin, qmldirIdentifier, qmldirUrl, incomplete, importDb, errors); + return d->addLibraryImport(uri, prefix, version, qmldirIdentifier, qmldirUrl, incomplete, importDb, errors); } bool QQmlImports::updateQmldirContent(QQmlImportDatabase *importDb, @@ -1827,10 +1830,10 @@ bool QQmlImports::updateQmldirContent(QQmlImportDatabase *importDb, } QQmlImports::LocalQmldirResult QQmlImports::locateLocalQmldir( - QQmlImportDatabase *importDb, const QString &uri, int vmaj, int vmin, + QQmlImportDatabase *importDb, const QString &uri, QTypeRevision version, QString *qmldirFilePath, QString *url) { - return d->locateLocalQmldir(uri, vmaj, vmin, importDb, qmldirFilePath, url); + return d->locateLocalQmldir(uri, version, importDb, qmldirFilePath, url); } bool QQmlImports::isLocal(const QString &url) @@ -2139,19 +2142,21 @@ void QQmlImportDatabase::setImportPathList(const QStringList &paths) \internal */ static bool registerPluginTypes(QObject *instance, const QString &basePath, const QString &uri, - const QString &typeNamespace, int vmaj, QList<QQmlError> *errors) + const QString &typeNamespace, QTypeRevision version, + QList<QQmlError> *errors) { if (qmlImportTrace()) qDebug().nospace() << "QQmlImportDatabase::registerPluginTypes: " << uri << " from " << basePath; - if (!QQmlMetaType::registerPluginTypes(instance, basePath, uri, typeNamespace, vmaj, errors)) + if (!QQmlMetaType::registerPluginTypes(instance, basePath, uri, typeNamespace, version, errors)) return false; - if (vmaj >= 0 && !typeNamespace.isEmpty() && !QQmlMetaType::protectModule(uri, vmaj)) { + if (version.hasMajorVersion() && !typeNamespace.isEmpty() + && !QQmlMetaType::protectModule(uri, version)) { QQmlError error; error.setDescription( QString::fromLatin1("Cannot protect module %1 %2 as it was never registered") - .arg(uri).arg(vmaj)); + .arg(uri).arg(version.majorVersion())); errors->append(error); return false; } @@ -2162,8 +2167,9 @@ static bool registerPluginTypes(QObject *instance, const QString &basePath, cons /*! \internal */ -bool QQmlImportDatabase::importStaticPlugin(QObject *instance, const QString &basePath, - const QString &uri, const QString &typeNamespace, int vmaj, QList<QQmlError> *errors) +bool QQmlImportDatabase::importStaticPlugin( + QObject *instance, const QString &basePath, const QString &uri, + const QString &typeNamespace, QTypeRevision version, QList<QQmlError> *errors) { // Dynamic plugins are differentiated by their filepath. For static plugins we // don't have that information so we use their address as key instead. @@ -2186,7 +2192,7 @@ bool QQmlImportDatabase::importStaticPlugin(QObject *instance, const QString &ba plugin.loader = nullptr; plugins->insert(uniquePluginID, plugin); - if (!registerPluginTypes(instance, basePath, uri, typeNamespace, vmaj, errors)) + if (!registerPluginTypes(instance, basePath, uri, typeNamespace, version, errors)) return false; } @@ -2206,8 +2212,9 @@ bool QQmlImportDatabase::importStaticPlugin(QObject *instance, const QString &ba /*! \internal */ -bool QQmlImportDatabase::importDynamicPlugin(const QString &filePath, const QString &uri, - const QString &typeNamespace, int vmaj, QList<QQmlError> *errors) +bool QQmlImportDatabase::importDynamicPlugin( + const QString &filePath, const QString &uri, const QString &typeNamespace, + QTypeRevision version, QList<QQmlError> *errors) { QFileInfo fileInfo(filePath); const QString absoluteFilePath = fileInfo.absoluteFilePath(); @@ -2261,7 +2268,7 @@ bool QQmlImportDatabase::importDynamicPlugin(const QString &filePath, const QStr plugins->insert(absoluteFilePath, plugin); // Continue with shared code path for dynamic and static plugins: - if (!registerPluginTypes(instance, fileInfo.absolutePath(), uri, typeNamespace, vmaj, errors)) + if (!registerPluginTypes(instance, fileInfo.absolutePath(), uri, typeNamespace, version, errors)) return false; } } diff --git a/src/qml/qml/qqmlimport_p.h b/src/qml/qml/qqmlimport_p.h index 2e994fd27f..7416bb7a4c 100644 --- a/src/qml/qml/qqmlimport_p.h +++ b/src/qml/qml/qqmlimport_p.h @@ -81,8 +81,7 @@ struct QQmlImportInstance QString url; // the base path of the import QString localDirectoryPath; // the base path of the import if it's a local file QQmlType containingType; // points to the containing type for inline components - int majversion; // the major version imported - int minversion; // the minor version imported + QTypeRevision version; // the version imported bool isLibrary; // true means that this is not a file import bool implicitlyImported = false; bool isInlineComponent = false; @@ -92,10 +91,11 @@ struct QQmlImportInstance bool setQmldirContent(const QString &resolvedUrl, const QQmlTypeLoaderQmldirContent &qmldir, QQmlImportNamespace *nameSpace, QList<QQmlError> *errors); - static QQmlDirScripts getVersionedScripts(const QQmlDirScripts &qmldirscripts, int vmaj, int vmin); + static QQmlDirScripts getVersionedScripts(const QQmlDirScripts &qmldirscripts, + QTypeRevision version); bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type, - int *vmajor, int *vminor, QQmlType* type_return, + QTypeRevision *version_return, QQmlType* type_return, QString *base = nullptr, bool *typeRecursionDetected = nullptr, QQmlType::RegistrationType = QQmlType::AnyRegistrationType, QQmlImport::RecursionRestriction recursionRestriction = QQmlImport::PreventRecursion, @@ -113,7 +113,7 @@ public: QQmlImportInstance *findImport(const QString &uri) const; bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef& type, - int *vmajor, int *vminor, QQmlType* type_return, + QTypeRevision *version_return, QQmlType* type_return, QString *base = nullptr, QList<QQmlError> *errors = nullptr, QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType, bool *typeRecursionDeteced = nullptr); @@ -140,14 +140,14 @@ public: bool resolveType(const QHashedStringRef &type, QQmlType *type_return, - int *version_major, int *version_minor, + QTypeRevision *version_return, QQmlImportNamespace **ns_return, QList<QQmlError> *errors = nullptr, QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType, bool *typeRecursionDetected = nullptr) const; bool resolveType(QQmlImportNamespace *, const QHashedStringRef& type, - QQmlType *type_return, int *version_major, int *version_minor, + QQmlType *type_return, QTypeRevision *version_return, QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType) const; @@ -156,11 +156,11 @@ public: bool addInlineComponentImport(QQmlImportInstance *const importInstance, const QString &name, const QUrl importUrl, QQmlType containingType); bool addFileImport(QQmlImportDatabase *, - const QString& uri, const QString& prefix, int vmaj, int vmin, bool incomplete, - QList<QQmlError> *errors); + const QString& uri, const QString& prefix, QTypeRevision version, + bool incomplete, QList<QQmlError> *errors); bool addLibraryImport(QQmlImportDatabase *importDb, - const QString &uri, const QString &prefix, int vmaj, int vmin, + const QString &uri, const QString &prefix, QTypeRevision version, const QString &qmldirIdentifier, const QString &qmldirUrl, bool incomplete, QList<QQmlError> *errors); bool updateQmldirContent(QQmlImportDatabase *importDb, @@ -174,7 +174,7 @@ public: }; LocalQmldirResult locateLocalQmldir( - QQmlImportDatabase *, const QString &uri, int vmaj, int vmin, + QQmlImportDatabase *, const QString &uri, QTypeRevision version, QString *qmldirFilePath, QString *url); void populateCache(QQmlTypeNameCache *cache) const; @@ -192,14 +192,14 @@ public: { QString typeName; QString prefix; - int majorVersion; - int minorVersion; + QTypeRevision version; }; QList<CompositeSingletonReference> resolvedCompositeSingletons() const; - static QStringList completeQmldirPaths(const QString &uri, const QStringList &basePaths, int vmaj, int vmin); - static QString versionString(int vmaj, int vmin, ImportVersion version); + static QStringList completeQmldirPaths(const QString &uri, const QStringList &basePaths, + QTypeRevision version); + static QString versionString(QTypeRevision version, ImportVersion importVersion); static bool isLocal(const QString &url); static bool isLocal(const QUrl &url); @@ -222,7 +222,9 @@ public: ~QQmlImportDatabase(); #if QT_CONFIG(library) - bool importDynamicPlugin(const QString &filePath, const QString &uri, const QString &importNamespace, int vmaj, QList<QQmlError> *errors); + bool importDynamicPlugin(const QString &filePath, const QString &uri, + const QString &importNamespace, QTypeRevision version, + QList<QQmlError> *errors); bool removeDynamicPlugin(const QString &filePath); QStringList dynamicPlugins() const; #endif @@ -245,13 +247,13 @@ private: const QString &qmldirPath, const QString &qmldirPluginPath, const QString &baseName); bool importStaticPlugin(QObject *instance, const QString &basePath, const QString &uri, - const QString &typeNamespace, int vmaj, QList<QQmlError> *errors); + const QString &typeNamespace, QTypeRevision version, + QList<QQmlError> *errors); void clearDirCache(); void finalizePlugin(QObject *instance, const QString &path, const QString &uri); struct QmldirCache { - int versionMajor; - int versionMinor; + QTypeRevision version; QString qmldirFilePath; QString qmldirPathUrl; QmldirCache *next; diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp index 7af6af276a..bc227ad713 100644 --- a/src/qml/qml/qqmllocale.cpp +++ b/src/qml/qml/qqmllocale.cpp @@ -835,7 +835,7 @@ QV4::ReturnedValue QQmlLocale::locale(ExecutionEngine *engine, const QString &lo { QLocale qlocale; if (!localeName.isEmpty()) - qlocale = localeName; + qlocale = QLocale(localeName); return wrap(engine, qlocale); } diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h index 1d6fdb12a7..d7bff5a1b7 100644 --- a/src/qml/qml/qqmllocale_p.h +++ b/src/qml/qml/qqmllocale_p.h @@ -96,7 +96,7 @@ class Q_QML_PRIVATE_EXPORT QQmlLocale Q_GADGET QML_NAMED_ELEMENT(Locale) QML_UNCREATABLE("Locale cannot be instantiated. Use Qt.locale().") - QML_ADDED_IN_MINOR_VERSION(2) + QML_ADDED_IN_VERSION(2, 2) public: ~QQmlLocale(); diff --git a/src/qml/qml/qqmlloggingcategory_p.h b/src/qml/qml/qqmlloggingcategory_p.h index c7377528b4..9cee029a9b 100644 --- a/src/qml/qml/qqmlloggingcategory_p.h +++ b/src/qml/qml/qqmlloggingcategory_p.h @@ -66,9 +66,9 @@ class QQmlLoggingCategory : public QObject, public QQmlParserStatus Q_INTERFACES(QQmlParserStatus) Q_PROPERTY(QString name READ name WRITE setName) - Q_PROPERTY(DefaultLogLevel defaultLogLevel READ defaultLogLevel WRITE setDefaultLogLevel REVISION 12) + Q_PROPERTY(DefaultLogLevel defaultLogLevel READ defaultLogLevel WRITE setDefaultLogLevel REVISION(2, 12)) QML_NAMED_ELEMENT(LoggingCategory) - QML_ADDED_IN_MINOR_VERSION(8) + QML_ADDED_IN_VERSION(2, 8) public: enum DefaultLogLevel { diff --git a/src/qml/qml/qqmlmetaobject.cpp b/src/qml/qml/qqmlmetaobject.cpp index a967f46b12..a87865fd81 100644 --- a/src/qml/qml/qqmlmetaobject.cpp +++ b/src/qml/qml/qqmlmetaobject.cpp @@ -44,12 +44,6 @@ QT_BEGIN_NAMESPACE -struct StaticQtMetaObject : public QObject -{ - static const QMetaObject *get() - { return &staticQtMetaObject; } -}; - static bool isNamedEnumeratorInScope(const QMetaObject *resolvedMetaObject, const QByteArray &scope, const QByteArray &name) { @@ -74,7 +68,7 @@ static bool isNamedEnumerator(const QMetaObject *metaObj, const QByteArray &scop } if (scope == "Qt") - return isNamedEnumeratorInScope(StaticQtMetaObject::get(), scope, name); + return isNamedEnumeratorInScope(&Qt::staticMetaObject, scope, name); if (isNamedEnumeratorInScope(metaObj, scope, name)) return true; diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index b2a769cab4..0baf142913 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -92,12 +92,11 @@ static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data, d->typeId = type.typeId; d->listId = type.listId; d->isSetup = true; - d->version_min = 0; - if (type.version > 0) { + if (type.structVersion > 0) { d->module = QString::fromUtf8(type.uri); - d->version_maj = type.versionMajor; + d->version = type.version; } else { - d->version_maj = 0; + d->version = QTypeRevision::zero(); } data->registerType(d); return d; @@ -110,28 +109,30 @@ static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data, const QString &el data->registerType(d); d->setName(QString::fromUtf8(type.uri), elementName); - d->version_maj = type.versionMajor; - d->version_min = type.versionMinor; + d->version = type.version; - if (type.qobjectApi || (type.version >= 3 && type.generalizedQobjectApi)) { - if (type.version >= 1) // static metaobject added in version 1 + if (type.qobjectApi || (type.structVersion >= 3 && type.generalizedQobjectApi)) { + if (type.structVersion >= 1) // static metaobject added in version 1 d->baseMetaObject = type.instanceMetaObject; - if (type.version >= 2) // typeId added in version 2 + if (type.structVersion >= 2) // typeId added in version 2 d->typeId = type.typeId; - if (type.version >= 2) // revisions added in version 2 + if (type.structVersion >= 2) // revisions added in version 2 d->revision = type.revision; } d->extraData.sd->singletonInstanceInfo = new QQmlType::SingletonInstanceInfo; d->extraData.sd->singletonInstanceInfo->scriptCallback = type.scriptApi; - if (type.version >= 3) { + if (type.structVersion >= 3) { d->extraData.sd->singletonInstanceInfo->qobjectCallback = type.generalizedQobjectApi; } else { d->extraData.sd->singletonInstanceInfo->qobjectCallback = type.qobjectApi; } d->extraData.sd->singletonInstanceInfo->typeName = QString::fromUtf8(type.typeName); d->extraData.sd->singletonInstanceInfo->instanceMetaObject - = ((type.qobjectApi || (type.version >= 3 && type.generalizedQobjectApi) ) && type.version >= 1) ? type.instanceMetaObject : nullptr; + = ((type.qobjectApi || (type.structVersion >= 3 && type.generalizedQobjectApi) ) + && type.structVersion >= 1) + ? type.instanceMetaObject + : nullptr; return d; } @@ -143,9 +144,8 @@ static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data, const QString &el data->registerType(d); d->setName(QString::fromUtf8(type.uri), elementName); - d->version_maj = type.versionMajor; - d->version_min = type.versionMinor; - if (type.version >= 1) // revisions added in version 1 + d->version = type.version; + if (type.structVersion >= 1) // revisions added in version 1 d->revision = type.revision; d->typeId = type.typeId; d->listId = type.listId; @@ -181,8 +181,7 @@ static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data, const QString &el auto *d = new QQmlTypePrivate(QQmlType::CompositeType); data->registerType(d); d->setName(QString::fromUtf8(type.uri), elementName); - d->version_maj = type.versionMajor; - d->version_min = type.versionMinor; + d->version = type.version; d->extraData.fd->url = QQmlTypeLoader::normalize(type.url); return d; @@ -195,8 +194,7 @@ static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data, const QString &el data->registerType(d); d->setName(QString::fromUtf8(type.uri), elementName); - d->version_maj = type.versionMajor; - d->version_min = type.versionMinor; + d->version = type.version; d->extraData.sd->singletonInstanceInfo = new QQmlType::SingletonInstanceInfo; d->extraData.sd->singletonInstanceInfo->url = QQmlTypeLoader::normalize(type.url); @@ -272,35 +270,32 @@ void QQmlMetaType::clone(QMetaObjectBuilder &builder, const QMetaObject *mo, } } -void QQmlMetaType::qmlInsertModuleRegistration(const QString &uri, int majorVersion, - void (*registerFunction)()) +void QQmlMetaType::qmlInsertModuleRegistration(const QString &uri, void (*registerFunction)()) { - const QQmlMetaTypeData::VersionedUri versionedUri(uri, majorVersion); QQmlMetaTypeDataPtr data; - if (data->moduleTypeRegistrationFunctions.contains(versionedUri)) - qFatal("Cannot add multiple registrations for %s %d", qPrintable(uri), majorVersion); + if (data->moduleTypeRegistrationFunctions.contains(uri)) + qFatal("Cannot add multiple registrations for %s", qPrintable(uri)); else - data->moduleTypeRegistrationFunctions.insert(versionedUri, registerFunction); + data->moduleTypeRegistrationFunctions.insert(uri, registerFunction); } -void QQmlMetaType::qmlRemoveModuleRegistration(const QString &uri, int majorVersion) +void QQmlMetaType::qmlRemoveModuleRegistration(const QString &uri) { - const QQmlMetaTypeData::VersionedUri versionedUri(uri, majorVersion); QQmlMetaTypeDataPtr data; if (!data.isValid()) return; // shutdown/deletion race. Not a problem. - if (!data->moduleTypeRegistrationFunctions.contains(versionedUri)) - qFatal("Cannot remove multiple registrations for %s %d", qPrintable(uri), majorVersion); + if (!data->moduleTypeRegistrationFunctions.contains(uri)) + qFatal("Cannot remove multiple registrations for %s", qPrintable(uri)); else - data->moduleTypeRegistrationFunctions.remove(versionedUri); + data->moduleTypeRegistrationFunctions.remove(uri); } -bool QQmlMetaType::qmlRegisterModuleTypes(const QString &uri, int majorVersion) +bool QQmlMetaType::qmlRegisterModuleTypes(const QString &uri) { QQmlMetaTypeDataPtr data; - return data->registerModuleTypes(QQmlMetaTypeData::VersionedUri(uri, majorVersion)); + return data->registerModuleTypes(uri); } /*! @@ -350,7 +345,7 @@ void QQmlMetaType::unregisterAutoParentFunction(const QQmlPrivate::AutoParentFun QQmlType QQmlMetaType::registerInterface(const QQmlPrivate::RegisterInterface &type) { - if (type.version > 1) + if (type.structVersion > 1) qFatal("qmlRegisterType(): Cannot mix incompatible QML versions."); QQmlMetaTypeDataPtr data; @@ -386,7 +381,7 @@ QString registrationTypeString(QQmlType::RegistrationType typeType) // NOTE: caller must hold a QMutexLocker on "data" bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *data, - const char *uri, const QString &typeName, int majorVersion) + const char *uri, const QString &typeName, QTypeRevision version) { if (!typeName.isEmpty()) { if (typeName.at(0).isLower()) { @@ -407,14 +402,14 @@ bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *da if (uri && !typeName.isEmpty()) { QString nameSpace = QString::fromUtf8(uri); - QQmlMetaTypeData::VersionedUri versionedUri; - versionedUri.uri = nameSpace; - versionedUri.majorVersion = majorVersion; + QQmlMetaTypeData::VersionedUri versionedUri(nameSpace, version); if (QQmlTypeModule* qqtm = data->uriToModule.value(versionedUri, 0)){ if (qqtm->isLocked()){ QString failure(QCoreApplication::translate("qmlRegisterType", "Cannot install %1 '%2' into protected module '%3' version '%4'")); - data->recordTypeRegFailure(failure.arg(registrationTypeString(typeType)).arg(typeName).arg(nameSpace).arg(majorVersion)); + data->recordTypeRegFailure(failure.arg(registrationTypeString(typeType)) + .arg(typeName).arg(nameSpace) + .arg(version.majorVersion())); return false; } } @@ -424,9 +419,9 @@ bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *da } // NOTE: caller must hold a QMutexLocker on "data" -QQmlTypeModule *getTypeModule(const QHashedString &uri, int majorVersion, QQmlMetaTypeData *data) +QQmlTypeModule *getTypeModule(const QHashedString &uri, QTypeRevision version, QQmlMetaTypeData *data) { - QQmlMetaTypeData::VersionedUri versionedUri(uri, majorVersion); + QQmlMetaTypeData::VersionedUri versionedUri(uri, version); QQmlTypeModule *module = data->uriToModule.value(versionedUri); if (!module) { module = new QQmlTypeModule(versionedUri.uri, versionedUri.majorVersion); @@ -463,7 +458,7 @@ void addTypeToData(QQmlTypePrivate *type, QQmlMetaTypeData *data) if (!type->module.isEmpty()) { const QHashedString &mod = type->module; - QQmlTypeModule *module = getTypeModule(mod, type->version_maj, data); + QQmlTypeModule *module = getTypeModule(mod, type->version, data); Q_ASSERT(module); module->add(type); } @@ -474,7 +469,7 @@ QQmlType QQmlMetaType::registerType(const QQmlPrivate::RegisterType &type) QQmlMetaTypeDataPtr data; QString elementName = QString::fromUtf8(type.elementName); - if (!checkRegistration(QQmlType::CppType, data, type.uri, elementName, type.versionMajor)) + if (!checkRegistration(QQmlType::CppType, data, type.uri, elementName, type.version)) return QQmlType(); QQmlTypePrivate *priv = createQQmlType(data, elementName, type); @@ -491,7 +486,7 @@ QQmlType QQmlMetaType::registerSingletonType(const QQmlPrivate::RegisterSingleto QQmlMetaTypeDataPtr data; QString typeName = QString::fromUtf8(type.typeName); - if (!checkRegistration(QQmlType::SingletonType, data, type.uri, typeName, type.versionMajor)) + if (!checkRegistration(QQmlType::SingletonType, data, type.uri, typeName, type.version)) return QQmlType(); QQmlTypePrivate *priv = createQQmlType(data, typeName, type); @@ -511,7 +506,7 @@ QQmlType QQmlMetaType::registerCompositeSingletonType(const QQmlPrivate::Registe if (*(type.uri) == '\0') fileImport = true; if (!checkRegistration(QQmlType::CompositeSingletonType, data, fileImport ? nullptr : type.uri, - typeName, type.versionMajor)) { + typeName, type.version)) { return QQmlType(); } @@ -533,7 +528,7 @@ QQmlType QQmlMetaType::registerCompositeType(const QQmlPrivate::RegisterComposit bool fileImport = false; if (*(type.uri) == '\0') fileImport = true; - if (!checkRegistration(QQmlType::CompositeType, data, fileImport?nullptr:type.uri, typeName, type.versionMajor)) + if (!checkRegistration(QQmlType::CompositeType, data, fileImport?nullptr:type.uri, typeName, type.version)) return QQmlType(); QQmlTypePrivate *priv = createQQmlType(data, typeName, type); @@ -581,7 +576,7 @@ void QQmlMetaType::unregisterInternalCompositeType(const CompositeMetaTypeIds &t int QQmlMetaType::registerUnitCacheHook( const QQmlPrivate::RegisterQmlUnitCacheHook &hookRegistration) { - if (hookRegistration.version > 0) + if (hookRegistration.structVersion > 0) qFatal("qmlRegisterType(): Cannot mix incompatible QML versions."); QQmlMetaTypeDataPtr data; @@ -589,40 +584,37 @@ int QQmlMetaType::registerUnitCacheHook( return 0; } -bool QQmlMetaType::protectModule(const QString &uri, int majVersion) +bool QQmlMetaType::protectModule(const QString &uri, QTypeRevision version) { QQmlMetaTypeDataPtr data; - QQmlMetaTypeData::VersionedUri versionedUri; - versionedUri.uri = uri; - versionedUri.majorVersion = majVersion; - - if (QQmlTypeModule* qqtm = data->uriToModule.value(versionedUri, 0)) { + if (QQmlTypeModule* qqtm = data->uriToModule.value( + QQmlMetaTypeData::VersionedUri(uri, version), nullptr)) { qqtm->lock(); return true; } return false; } -void QQmlMetaType::registerModule(const char *uri, int versionMajor, int versionMinor) +void QQmlMetaType::registerModule(const char *uri, QTypeRevision version) { QQmlMetaTypeDataPtr data; - QQmlTypeModule *module = getTypeModule(QString::fromUtf8(uri), versionMajor, data); + QQmlTypeModule *module = getTypeModule(QString::fromUtf8(uri), version, data); Q_ASSERT(module); - module->addMinorVersion(versionMinor); + module->addMinorVersion(version.minorVersion()); } -int QQmlMetaType::typeId(const char *uri, int versionMajor, int versionMinor, const char *qmlName) +int QQmlMetaType::typeId(const char *uri, QTypeRevision version, const char *qmlName) { QQmlMetaTypeDataPtr data; - QQmlTypeModule *module = getTypeModule(QString::fromUtf8(uri), versionMajor, data); + QQmlTypeModule *module = getTypeModule(QString::fromUtf8(uri), version, data); if (!module) return -1; - QQmlType type = module->type(QHashedStringRef(QString::fromUtf8(qmlName)), versionMinor); + QQmlType type = module->type(QHashedStringRef(QString::fromUtf8(qmlName)), version); if (!type.isValid()) return -1; @@ -636,12 +628,12 @@ void QQmlMetaType::registerUndeletableType(const QQmlType &dtype) } static bool namespaceContainsRegistrations(const QQmlMetaTypeData *data, const QString &uri, - int majorVersion) + QTypeRevision version) { // Has any type previously been installed to this namespace? QHashedString nameSpace(uri); for (const QQmlType &type : data->types) { - if (type.module() == nameSpace && type.majorVersion() == majorVersion) + if (type.module() == nameSpace && type.version().majorVersion() == version.majorVersion()) return true; } @@ -668,8 +660,8 @@ public: bool QQmlMetaType::registerPluginTypes(QObject *instance, const QString &basePath, - const QString &uri, const QString &typeNamespace, int vmaj, - QList<QQmlError> *errors) + const QString &uri, const QString &typeNamespace, + QTypeRevision version, QList<QQmlError> *errors) { if (!typeNamespace.isEmpty() && typeNamespace != uri) { // This is an 'identified' module @@ -690,7 +682,7 @@ bool QQmlMetaType::registerPluginTypes(QObject *instance, const QString &basePat QQmlMetaTypeRegistrationFailureRecorder failureRecorder(data, &failures); if (!typeNamespace.isEmpty()) { // This is an 'identified' module - if (namespaceContainsRegistrations(data, typeNamespace, vmaj)) { + if (namespaceContainsRegistrations(data, typeNamespace, version)) { // Other modules have already installed to this namespace if (errors) { QQmlError error; @@ -732,7 +724,7 @@ bool QQmlMetaType::registerPluginTypes(QObject *instance, const QString &basePat iface->registerTypes(moduleId); } - data->registerModuleTypes(QQmlMetaTypeData::VersionedUri(uri, vmaj)); + data->registerModuleTypes(uri); if (!failures.isEmpty()) { if (errors) { @@ -763,7 +755,7 @@ bool QQmlMetaType::registerPluginTypes(QObject *instance, const QString &basePat QQmlType QQmlMetaType::typeForUrl(const QString &urlString, const QHashedStringRef &qualifiedType, bool isCompositeSingleton, QList<QQmlError> *errors, - int majorVersion, int minorVersion) + QTypeRevision version) { // ### unfortunate (costly) conversion const QUrl url = QQmlTypeLoader::normalize(QUrl(urlString)); @@ -808,11 +800,10 @@ QQmlType QQmlMetaType::typeForUrl(const QString &urlString, const QQmlType::RegistrationType registrationType = isCompositeSingleton ? QQmlType::CompositeSingletonType : QQmlType::CompositeType; - if (checkRegistration(registrationType, data, nullptr, typeName, majorVersion)) { + if (checkRegistration(registrationType, data, nullptr, typeName, version)) { auto *priv = new QQmlTypePrivate(registrationType); priv->setName(QString(), typeName); - priv->version_maj = majorVersion; - priv->version_min = minorVersion; + priv->version = version; if (isCompositeSingleton) { priv->extraData.sd->singletonInstanceInfo = new QQmlType::SingletonInstanceInfo; @@ -865,14 +856,12 @@ bool QQmlMetaType::isAnyModule(const QString &uri) /* Returns true if a module \a uri of this version is installed and locked; */ -bool QQmlMetaType::isLockedModule(const QString &uri, int majVersion) +bool QQmlMetaType::isLockedModule(const QString &uri, QTypeRevision version) { QQmlMetaTypeDataPtr data; - QQmlMetaTypeData::VersionedUri versionedUri; - versionedUri.uri = uri; - versionedUri.majorVersion = majVersion; - if (QQmlTypeModule* qqtm = data->uriToModule.value(versionedUri, 0)) + if (QQmlTypeModule* qqtm = data->uriToModule.value( + QQmlMetaTypeData::VersionedUri(uri, version), nullptr)) return qqtm->isLocked(); return false; } @@ -884,24 +873,24 @@ bool QQmlMetaType::isLockedModule(const QString &uri, int majVersion) So if only 4.7 and 4.9 have been registered, 4.7,4.8, and 4.9 are valid, but not 4.6 nor 4.10. */ -bool QQmlMetaType::isModule(const QString &module, int versionMajor, int versionMinor) +bool QQmlMetaType::isModule(const QString &module, QTypeRevision version) { - Q_ASSERT(versionMajor >= 0 && versionMinor >= 0); + Q_ASSERT(version.hasMajorVersion() && version.hasMinorVersion()); QQmlMetaTypeDataPtr data; // first, check Types QQmlTypeModule *tm = - data->uriToModule.value(QQmlMetaTypeData::VersionedUri(module, versionMajor)); - if (tm && tm->minimumMinorVersion() <= versionMinor && tm->maximumMinorVersion() >= versionMinor) + data->uriToModule.value(QQmlMetaTypeData::VersionedUri(module, version)); + if (tm && tm->minimumMinorVersion() <= version.minorVersion() && tm->maximumMinorVersion() >= version.minorVersion()) return true; return false; } -QQmlTypeModule *QQmlMetaType::typeModule(const QString &uri, int majorVersion) +QQmlTypeModule *QQmlMetaType::typeModule(const QString &uri, QTypeRevision version) { QQmlMetaTypeDataPtr data; - return data->uriToModule.value(QQmlMetaTypeData::VersionedUri(uri, majorVersion)); + return data->uriToModule.value(QQmlMetaTypeData::VersionedUri(uri, version)); } QList<QQmlPrivate::AutoParentFunction> QQmlMetaType::parentFunctions() @@ -1120,7 +1109,7 @@ QQmlMetaType::StringConverter QQmlMetaType::customStringConverter(int type) Returns the type (if any) of URI-qualified named \a qualifiedName and version specified by \a version_major and \a version_minor. */ -QQmlType QQmlMetaType::qmlType(const QString &qualifiedName, int version_major, int version_minor) +QQmlType QQmlMetaType::qmlType(const QString &qualifiedName, QTypeRevision version) { int slash = qualifiedName.indexOf(QLatin1Char('/')); if (slash <= 0) @@ -1129,23 +1118,23 @@ QQmlType QQmlMetaType::qmlType(const QString &qualifiedName, int version_major, QHashedStringRef module(qualifiedName.constData(), slash); QHashedStringRef name(qualifiedName.constData() + slash + 1, qualifiedName.length() - slash - 1); - return qmlType(name, module, version_major, version_minor); + return qmlType(name, module, version); } /*! Returns the type (if any) of \a name in \a module and version specified by \a version_major and \a version_minor. */ -QQmlType QQmlMetaType::qmlType(const QHashedStringRef &name, const QHashedStringRef &module, int version_major, int version_minor) +QQmlType QQmlMetaType::qmlType(const QHashedStringRef &name, const QHashedStringRef &module, + QTypeRevision version) { - Q_ASSERT(version_major >= 0 && version_minor >= 0); + Q_ASSERT(version.hasMajorVersion() && version.hasMinorVersion()); const QQmlMetaTypeDataPtr data; QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.constFind(name); while (it != data->nameToType.cend() && it.key() == name) { QQmlType t(*it); - // XXX version_major<0 just a kludge for QQmlPropertyPrivate::initProperty - if (version_major < 0 || module.isEmpty() || t.availableInVersion(module, version_major,version_minor)) + if (module.isEmpty() || t.availableInVersion(module, version)) return t; ++it; } @@ -1168,15 +1157,16 @@ QQmlType QQmlMetaType::qmlType(const QMetaObject *metaObject) by \a version_major and \a version_minor in module specified by \a uri. Returns null if no type is registered. */ -QQmlType QQmlMetaType::qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, int version_major, int version_minor) +QQmlType QQmlMetaType::qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, + QTypeRevision version) { - Q_ASSERT(version_major >= 0 && version_minor >= 0); + Q_ASSERT(version.hasMajorVersion() && version.hasMinorVersion()); const QQmlMetaTypeDataPtr data; QQmlMetaTypeData::MetaObjects::const_iterator it = data->metaObjectToType.constFind(metaObject); while (it != data->metaObjectToType.cend() && it.key() == metaObject) { QQmlType t(*it); - if (version_major < 0 || module.isEmpty() || t.availableInVersion(module, version_major,version_minor)) + if (module.isEmpty() || t.availableInVersion(module, version)) return t; ++it; } @@ -1226,16 +1216,16 @@ QQmlType QQmlMetaType::qmlType(const QUrl &unNormalizedUrl, bool includeNonFileI return QQmlType(); } -QQmlPropertyCache *QQmlMetaType::propertyCache(const QMetaObject *metaObject, int minorVersion) +QQmlPropertyCache *QQmlMetaType::propertyCache(const QMetaObject *metaObject, QTypeRevision version) { QQmlMetaTypeDataPtr data; // not const: the cache is created on demand - return data->propertyCache(metaObject, minorVersion); + return data->propertyCache(metaObject, version); } -QQmlPropertyCache *QQmlMetaType::propertyCache(const QQmlType &type, int minorVersion) +QQmlPropertyCache *QQmlMetaType::propertyCache(const QQmlType &type, QTypeRevision version) { QQmlMetaTypeDataPtr data; // not const: the cache is created on demand - return data->propertyCache(type, minorVersion); + return data->propertyCache(type, version); } void QQmlMetaType::unregisterType(int typeIndex) @@ -1250,7 +1240,7 @@ void QQmlMetaType::unregisterType(int typeIndex) removeQQmlTypePrivate(data->metaObjectToType, d); for (auto & module : data->uriToModule) module->remove(d); - data->clearPropertyCachesForMinorVersion(typeIndex); + data->clearPropertyCachesForVersion(typeIndex); data->types[typeIndex] = QQmlType(); data->undeletableTypes.remove(type); } @@ -1282,7 +1272,7 @@ void QQmlMetaType::freeUnusedTypesAndCaches() for (auto &module : data->uriToModule) module->remove(d); - data->clearPropertyCachesForMinorVersion(d->index); + data->clearPropertyCachesForVersion(d->index); *it = QQmlType(); } else { ++it; diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index 0c5bc043c4..0fc179fd34 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -81,20 +81,20 @@ public: static QQmlType registerCompositeSingletonType(const QQmlPrivate::RegisterCompositeSingletonType &type); static QQmlType registerCompositeType(const QQmlPrivate::RegisterCompositeType &type); static bool registerPluginTypes(QObject *instance, const QString &basePath, - const QString &uri, const QString &typeNamespace, int vmaj, - QList<QQmlError> *errors); + const QString &uri, const QString &typeNamespace, + QTypeRevision version, QList<QQmlError> *errors); static QQmlType typeForUrl(const QString &urlString, const QHashedStringRef& typeName, bool isCompositeSingleton, QList<QQmlError> *errors, - int majorVersion = -1, int minorVersion = -1); + QTypeRevision version = QTypeRevision()); static void unregisterType(int type); static CompositeMetaTypeIds registerInternalCompositeType(const QByteArray &className); static void unregisterInternalCompositeType(const CompositeMetaTypeIds &typeIds); - static void registerModule(const char *uri, int versionMajor, int versionMinor); - static bool protectModule(const QString &uri, int majVersion); + static void registerModule(const char *uri, QTypeRevision version); + static bool protectModule(const QString &uri, QTypeRevision version); - static int typeId(const char *uri, int versionMajor, int versionMinor, const char *qmlName); + static int typeId(const char *uri, QTypeRevision version, const char *qmlName); static void registerUndeletableType(const QQmlType &dtype); @@ -108,15 +108,16 @@ public: QmlType }; - static QQmlType qmlType(const QString &qualifiedName, int, int); - static QQmlType qmlType(const QHashedStringRef &name, const QHashedStringRef &module, int, int); + static QQmlType qmlType(const QString &qualifiedName, QTypeRevision version); + static QQmlType qmlType(const QHashedStringRef &name, const QHashedStringRef &module, QTypeRevision version); static QQmlType qmlType(const QMetaObject *); - static QQmlType qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, int version_major, int version_minor); + static QQmlType qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, QTypeRevision version); static QQmlType qmlType(int typeId, TypeIdCategory category = TypeIdCategory::MetaType); static QQmlType qmlType(const QUrl &unNormalizedUrl, bool includeNonFileImports = false); - static QQmlPropertyCache *propertyCache(const QMetaObject *metaObject, int minorVersion = -1); - static QQmlPropertyCache *propertyCache(const QQmlType &type, int minorVersion); + static QQmlPropertyCache *propertyCache(const QMetaObject *metaObject, + QTypeRevision version = QTypeRevision()); + static QQmlPropertyCache *propertyCache(const QQmlType &type, QTypeRevision version); static void freeUnusedTypesAndCaches(); @@ -150,9 +151,9 @@ public: static StringConverter customStringConverter(int); static bool isAnyModule(const QString &uri); - static bool isLockedModule(const QString &uri, int majorVersion); - static bool isModule(const QString &module, int versionMajor, int versionMinor); - static QQmlTypeModule *typeModule(const QString &uri, int majorVersion); + static bool isLockedModule(const QString &uri, QTypeRevision version); + static bool isModule(const QString &module, QTypeRevision version); + static QQmlTypeModule *typeModule(const QString &uri, QTypeRevision version); static QList<QQmlPrivate::AutoParentFunction> parentFunctions(); @@ -197,11 +198,10 @@ public: static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo, const QMetaObject *ignoreStart, const QMetaObject *ignoreEnd); - static void qmlInsertModuleRegistration(const QString &uri, int majorVersion, - void (*registerFunction)()); - static void qmlRemoveModuleRegistration(const QString &uri, int majorVersion); + static void qmlInsertModuleRegistration(const QString &uri, void (*registerFunction)()); + static void qmlRemoveModuleRegistration(const QString &uri); - static bool qmlRegisterModuleTypes(const QString &uri, int majorVersion); + static bool qmlRegisterModuleTypes(const QString &uri); static int qmlRegisteredListTypeCount(); }; diff --git a/src/qml/qml/qqmlmetatypedata.cpp b/src/qml/qml/qqmlmetatypedata.cpp index ed885eaa97..a34a0c1ae4 100644 --- a/src/qml/qml/qqmlmetatypedata.cpp +++ b/src/qml/qml/qqmlmetatypedata.cpp @@ -78,9 +78,9 @@ void QQmlMetaTypeData::registerType(QQmlTypePrivate *priv) priv->release(); } -bool QQmlMetaTypeData::registerModuleTypes(const QQmlMetaTypeData::VersionedUri &versionedUri) +bool QQmlMetaTypeData::registerModuleTypes(const QString &uri) { - auto function = moduleTypeRegistrationFunctions.constFind(versionedUri); + auto function = moduleTypeRegistrationFunctions.constFind(uri); if (function != moduleTypeRegistrationFunctions.constEnd()) { (*function)(); return true; @@ -88,28 +88,28 @@ bool QQmlMetaTypeData::registerModuleTypes(const QQmlMetaTypeData::VersionedUri return false; } -QQmlPropertyCache *QQmlMetaTypeData::propertyCacheForMinorVersion(int index, int minorVersion) const +QQmlPropertyCache *QQmlMetaTypeData::propertyCacheForVersion(int index, QTypeRevision version) const { return (index < typePropertyCaches.length()) - ? typePropertyCaches.at(index).value(minorVersion).data() + ? typePropertyCaches.at(index).value(version).data() : nullptr; } -void QQmlMetaTypeData::setPropertyCacheForMinorVersion(int index, int minorVersion, - QQmlPropertyCache *cache) +void QQmlMetaTypeData::setPropertyCacheForVersion(int index, QTypeRevision version, + QQmlPropertyCache *cache) { if (index >= typePropertyCaches.length()) typePropertyCaches.resize(index + 1); - typePropertyCaches[index][minorVersion] = cache; + typePropertyCaches[index][version] = cache; } -void QQmlMetaTypeData::clearPropertyCachesForMinorVersion(int index) +void QQmlMetaTypeData::clearPropertyCachesForVersion(int index) { if (index < typePropertyCaches.length()) typePropertyCaches[index].clear(); } -QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QMetaObject *metaObject, int minorVersion) +QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QMetaObject *metaObject, QTypeRevision version) { if (QQmlPropertyCache *rv = propertyCaches.value(metaObject)) return rv; @@ -119,29 +119,36 @@ QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QMetaObject *metaObject propertyCaches.insert(metaObject, rv); return rv; } - QQmlPropertyCache *super = propertyCache(metaObject->superClass(), minorVersion); - QQmlPropertyCache *rv = super->copyAndAppend(metaObject, minorVersion); + QQmlPropertyCache *super = propertyCache(metaObject->superClass(), version); + QQmlPropertyCache *rv = super->copyAndAppend(metaObject, version); propertyCaches.insert(metaObject, rv); return rv; } -QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QQmlType &type, int minorVersion) +QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QQmlType &type, QTypeRevision version) { Q_ASSERT(type.isValid()); - if (QQmlPropertyCache *pc = propertyCacheForMinorVersion(type.index(), minorVersion)) + if (QQmlPropertyCache *pc = propertyCacheForVersion(type.index(), version)) return pc; QVector<QQmlType> types; - int maxMinorVersion = 0; + quint8 maxMinorVersion = 0; const QMetaObject *metaObject = type.metaObject(); + const QTypeRevision combinedVersion = version.hasMajorVersion() + ? version + : (version.hasMinorVersion() + ? QTypeRevision::fromVersion(type.version().majorVersion(), + version.minorVersion()) + : type.version()); + while (metaObject) { - QQmlType t = QQmlMetaType::qmlType(metaObject, type.module(), type.majorVersion(), minorVersion); + QQmlType t = QQmlMetaType::qmlType(metaObject, type.module(), combinedVersion); if (t.isValid()) { - maxMinorVersion = qMax(maxMinorVersion, t.minorVersion()); + maxMinorVersion = qMax(maxMinorVersion, t.version().minorVersion()); types << t; } else { types << QQmlType(); @@ -150,12 +157,14 @@ QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QQmlType &type, int min metaObject = metaObject->superClass(); } - if (QQmlPropertyCache *pc = propertyCacheForMinorVersion(type.index(), maxMinorVersion)) { - setPropertyCacheForMinorVersion(type.index(), minorVersion, pc); + const QTypeRevision maxVersion = QTypeRevision::fromVersion(combinedVersion.majorVersion(), + maxMinorVersion); + if (QQmlPropertyCache *pc = propertyCacheForVersion(type.index(), maxVersion)) { + setPropertyCacheForVersion(type.index(), maxVersion, pc); return pc; } - QQmlPropertyCache *raw = propertyCache(type.metaObject(), minorVersion); + QQmlPropertyCache *raw = propertyCache(type.metaObject(), combinedVersion); bool hasCopied = false; @@ -164,7 +173,7 @@ QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QQmlType &type, int min if (!currentType.isValid()) continue; - int rev = currentType.metaObjectRevision(); + QTypeRevision rev = currentType.metaObjectRevision(); int moIndex = types.count() - 1 - ii; if (raw->allowedRevision(moIndex) != rev) { @@ -222,13 +231,13 @@ QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QQmlType &type, int min } #endif - setPropertyCacheForMinorVersion(type.index(), minorVersion, raw); + setPropertyCacheForVersion(type.index(), version, raw); if (hasCopied) raw->release(); - if (minorVersion != maxMinorVersion) - setPropertyCacheForMinorVersion(type.index(), maxMinorVersion, raw); + if (version != maxVersion) + setPropertyCacheForVersion(type.index(), maxVersion, raw); return raw; } diff --git a/src/qml/qml/qqmlmetatypedata_p.h b/src/qml/qml/qqmlmetatypedata_p.h index e51d4ca1a4..26fc566653 100644 --- a/src/qml/qml/qqmlmetatypedata_p.h +++ b/src/qml/qml/qqmlmetatypedata_p.h @@ -83,25 +83,24 @@ struct QQmlMetaTypeData MetaObjects metaObjectToType; typedef QHash<int, QQmlMetaType::StringConverter> StringConverters; StringConverters stringConverters; - QVector<QHash<int, QQmlRefPointer<QQmlPropertyCache>>> typePropertyCaches; + QVector<QHash<QTypeRevision, QQmlRefPointer<QQmlPropertyCache>>> typePropertyCaches; struct VersionedUri { - VersionedUri() - : majorVersion(0) {} - VersionedUri(const QHashedString &uri, int majorVersion) - : uri(uri), majorVersion(majorVersion) {} + VersionedUri() : majorVersion(0) {} + VersionedUri(const QHashedString &uri, QTypeRevision version) + : uri(uri), majorVersion(version.majorVersion()) {} bool operator==(const VersionedUri &other) const { return other.majorVersion == majorVersion && other.uri == uri; } QHashedString uri; - int majorVersion; + quint8 majorVersion; }; typedef QHash<VersionedUri, QQmlTypeModule *> TypeModules; TypeModules uriToModule; - QHash<VersionedUri, void (*)()> moduleTypeRegistrationFunctions; - bool registerModuleTypes(const VersionedUri &versionedUri); + QHash<QString, void (*)()> moduleTypeRegistrationFunctions; + bool registerModuleTypes(const QString &uri); QBitArray objects; QBitArray interfaces; @@ -114,12 +113,12 @@ struct QQmlMetaTypeData QHash<const QMetaObject *, QQmlPropertyCache *> propertyCaches; - QQmlPropertyCache *propertyCacheForMinorVersion(int index, int minorVersion) const; - void setPropertyCacheForMinorVersion(int index, int minorVersion, QQmlPropertyCache *cache); - void clearPropertyCachesForMinorVersion(int index); + QQmlPropertyCache *propertyCacheForVersion(int index, QTypeRevision version) const; + void setPropertyCacheForVersion(int index, QTypeRevision version, QQmlPropertyCache *cache); + void clearPropertyCachesForVersion(int index); - QQmlPropertyCache *propertyCache(const QMetaObject *metaObject, int minorVersion); - QQmlPropertyCache *propertyCache(const QQmlType &type, int minorVersion); + QQmlPropertyCache *propertyCache(const QMetaObject *metaObject, QTypeRevision version); + QQmlPropertyCache *propertyCache(const QQmlType &type, QTypeRevision version); void setTypeRegistrationFailures(QStringList *failures) { diff --git a/src/qml/qml/qqmlmoduleregistration.cpp b/src/qml/qml/qqmlmoduleregistration.cpp index b7bc3555a6..422a5c0551 100644 --- a/src/qml/qml/qqmlmoduleregistration.cpp +++ b/src/qml/qml/qqmlmoduleregistration.cpp @@ -39,27 +39,33 @@ #include <QtQml/private/qqmlmetatype_p.h> #include <QtQml/qqmlmoduleregistration.h> +#include <QtCore/qversionnumber.h> QT_BEGIN_NAMESPACE struct QQmlModuleRegistrationPrivate { const QString uri; - const int majorVersion; }; +QQmlModuleRegistration::QQmlModuleRegistration(const char *uri, void (*registerFunction)()) : + d(new QQmlModuleRegistrationPrivate { QString::fromUtf8(uri) }) +{ + QQmlMetaType::qmlInsertModuleRegistration(d->uri, registerFunction); +} + +#if QT_DEPRECATED_SINCE(6, 0) QQmlModuleRegistration::QQmlModuleRegistration( - const char *uri, int majorVersion, - void (*registerFunction)()) : - d(new QQmlModuleRegistrationPrivate { QString::fromUtf8(uri), majorVersion }) + const char *uri, int majorVersion, void (*registerFunction)()) : + QQmlModuleRegistration(uri, registerFunction) { - QQmlMetaType::qmlInsertModuleRegistration(d->uri, d->majorVersion, - registerFunction); + Q_UNUSED(majorVersion); } +#endif QQmlModuleRegistration::~QQmlModuleRegistration() { - QQmlMetaType::qmlRemoveModuleRegistration(d->uri, d->majorVersion); + QQmlMetaType::qmlRemoveModuleRegistration(d->uri); delete d; } diff --git a/src/qml/qml/qqmlmoduleregistration.h b/src/qml/qml/qqmlmoduleregistration.h index 6f553a2823..3db535faa0 100644 --- a/src/qml/qml/qqmlmoduleregistration.h +++ b/src/qml/qml/qqmlmoduleregistration.h @@ -49,9 +49,14 @@ class Q_QML_EXPORT QQmlModuleRegistration { Q_DISABLE_COPY_MOVE(QQmlModuleRegistration) public: - QQmlModuleRegistration(const char *uri, int majorVersion, void (*registerFunction)()); + QQmlModuleRegistration(const char *uri, void (*registerFunction)()); ~QQmlModuleRegistration(); +#if QT_DEPRECATED_SINCE(6, 0) + QT_DEPRECATED_X("Use registration without major version") + QQmlModuleRegistration(const char *uri, int majorVersion, void (*registerFunction)()); +#endif + private: QQmlModuleRegistrationPrivate *d = nullptr; }; diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h index d6a9e73763..2e4bc60f79 100644 --- a/src/qml/qml/qqmlprivate.h +++ b/src/qml/qml/qqmlprivate.h @@ -63,6 +63,7 @@ #include <QtCore/qvariant.h> #include <QtCore/qurl.h> #include <QtCore/qpointer.h> +#include <QtCore/qversionnumber.h> #include <QtCore/qmetaobject.h> #include <QtCore/qdebug.h> @@ -343,7 +344,7 @@ namespace QQmlPrivate typedef AutoParentResult (*AutoParentFunction)(QObject *object, QObject *parent); struct RegisterType { - int version; + int structVersion; int typeId; int listId; @@ -352,8 +353,7 @@ namespace QQmlPrivate QString noCreationReason; const char *uri; - int versionMajor; - int versionMinor; + QTypeRevision version; const char *elementName; const QMetaObject *metaObject; @@ -369,12 +369,12 @@ namespace QQmlPrivate QQmlCustomParser *customParser; - int revision; + QTypeRevision revision; // If this is extended ensure "version" is bumped!!! }; struct RegisterTypeAndRevisions { - int version; + int structVersion; int typeId; int listId; @@ -382,7 +382,7 @@ namespace QQmlPrivate void (*create)(void *); const char *uri; - int versionMajor; + QTypeRevision version; const QMetaObject *metaObject; const QMetaObject *classInfoMetaObject; @@ -401,7 +401,7 @@ namespace QQmlPrivate }; struct RegisterInterface { - int version; + int structVersion; int typeId; int listId; @@ -409,7 +409,7 @@ namespace QQmlPrivate const char *iid; const char *uri; - int versionMajor; + QTypeRevision version; }; struct RegisterAutoParent { @@ -419,26 +419,25 @@ namespace QQmlPrivate }; struct RegisterSingletonType { - int version; + int structVersion; const char *uri; - int versionMajor; - int versionMinor; + QTypeRevision version; const char *typeName; QJSValue (*scriptApi)(QQmlEngine *, QJSEngine *); QObject *(*qobjectApi)(QQmlEngine *, QJSEngine *); const QMetaObject *instanceMetaObject; // new in version 1 int typeId; // new in version 2 - int revision; // new in version 2 + QTypeRevision revision; // new in version 2 std::function<QObject*(QQmlEngine *, QJSEngine *)> generalizedQobjectApi; // new in version 3 // If this is extended ensure "version" is bumped!!! }; struct RegisterSingletonTypeAndRevisions { - int version; + int structVersion; const char *uri; - int versionMajor; + QTypeRevision version; QJSValue (*scriptApi)(QQmlEngine *, QJSEngine *); const QMetaObject *instanceMetaObject; @@ -451,16 +450,14 @@ namespace QQmlPrivate struct RegisterCompositeType { QUrl url; const char *uri; - int versionMajor; - int versionMinor; + QTypeRevision version; const char *typeName; }; struct RegisterCompositeSingletonType { QUrl url; const char *uri; - int versionMajor; - int versionMinor; + QTypeRevision version; const char *typeName; }; @@ -472,7 +469,7 @@ namespace QQmlPrivate typedef const CachedQmlUnit *(*QmlUnitCacheLookupFunction)(const QUrl &url); struct RegisterQmlUnitCacheHook { - int version; + int structVersion; QmlUnitCacheLookupFunction lookupCachedQmlUnit; }; @@ -516,11 +513,13 @@ namespace QQmlPrivate return metaObject->classInfo(indexOfOwnClassInfo(metaObject, key)).value(); } - inline int intClassInfo(const QMetaObject *metaObject, const char *key, int defaultValue = 0) + inline QTypeRevision revisionClassInfo(const QMetaObject *metaObject, const char *key, + QTypeRevision defaultValue = QTypeRevision()) { const int index = indexOfOwnClassInfo(metaObject, key); return (index == -1) ? defaultValue - : QByteArray(metaObject->classInfo(index).value()).toInt(); + : QTypeRevision::fromEncodedVersion( + QByteArray(metaObject->classInfo(index).value()).toInt()); } inline bool boolClassInfo(const QMetaObject *metaObject, const char *key, @@ -605,7 +604,7 @@ namespace QQmlPrivate 0, uri, - versionMajor, + QTypeRevision::fromMajorVersion(versionMajor), nullptr, @@ -633,7 +632,7 @@ namespace QQmlPrivate Constructors<T>::createInto, uri, - versionMajor, + QTypeRevision::fromMajorVersion(versionMajor), &T::staticMetaObject, classInfoMetaObject, diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp index 0e5534fc04..7ba3d7b813 100644 --- a/src/qml/qml/qqmlpropertycache.cpp +++ b/src/qml/qml/qqmlpropertycache.cpp @@ -127,11 +127,11 @@ QQmlPropertyData::flagsForProperty(const QMetaProperty &p) static void populate(QQmlPropertyData *data, const QMetaProperty &p) { - Q_ASSERT(p.revision() <= Q_INT16_MAX); + Q_ASSERT(p.revision() <= std::numeric_limits<quint16>::max()); data->setCoreIndex(p.propertyIndex()); data->setNotifyIndex(QMetaObjectPrivate::signalIndex(p.notifySignal())); data->setFlags(fastFlagsForProperty(p)); - data->setRevision(p.revision()); + data->setRevision(QTypeRevision::fromEncodedVersion(p.revision())); } void QQmlPropertyData::lazyLoad(const QMetaProperty &p) @@ -183,8 +183,8 @@ void QQmlPropertyData::load(const QMetaMethod &m) if (m.attributes() & QMetaMethod::Cloned) m_flags.setIsCloned(true); - Q_ASSERT(m.revision() <= Q_INT16_MAX); - setRevision(m.revision()); + Q_ASSERT(m.revision() <= std::numeric_limits<quint16>::max()); + setRevision(QTypeRevision::fromEncodedVersion(m.revision())); } void QQmlPropertyData::lazyLoad(const QMetaMethod &m) @@ -212,14 +212,14 @@ QQmlPropertyCache::QQmlPropertyCache() /*! Creates a new QQmlPropertyCache of \a metaObject. */ -QQmlPropertyCache::QQmlPropertyCache(const QMetaObject *metaObject, int metaObjectRevision) +QQmlPropertyCache::QQmlPropertyCache(const QMetaObject *metaObject, QTypeRevision metaObjectRevision) : QQmlPropertyCache() { Q_ASSERT(metaObject); update(metaObject); - if (metaObjectRevision > 0) { + if (metaObjectRevision.isValid() && metaObjectRevision != QTypeRevision::zero()) { // Set the revision of the meta object that this cache describes to be // 'metaObjectRevision'. This is useful when constructing a property cache // from a type that was created directly in C++, and not through QML. For such @@ -291,14 +291,15 @@ QQmlPropertyCache *QQmlPropertyCache::copyAndReserve(int propertyCount, int meth This is different from QMetaMethod::methodIndex(). */ void QQmlPropertyCache::appendProperty(const QString &name, QQmlPropertyData::Flags flags, - int coreIndex, int propType, int minorVersion, int notifyIndex) + int coreIndex, int propType, QTypeRevision version, + int notifyIndex) { QQmlPropertyData data; data.setPropType(propType); data.setCoreIndex(coreIndex); data.setNotifyIndex(notifyIndex); data.setFlags(flags); - data.setTypeMinorVersion(minorVersion); + data.setTypeVersion(version); QQmlPropertyData *old = findNamedProperty(name); if (old) @@ -433,12 +434,12 @@ QQmlPropertyCache::copyAndAppend(const QMetaObject *metaObject, QQmlPropertyData::Flags methodFlags, QQmlPropertyData::Flags signalFlags) { - return copyAndAppend(metaObject, -1, propertyFlags, methodFlags, signalFlags); + return copyAndAppend(metaObject, QTypeRevision(), propertyFlags, methodFlags, signalFlags); } QQmlPropertyCache * QQmlPropertyCache::copyAndAppend(const QMetaObject *metaObject, - int typeMinorVersion, + QTypeRevision typeVersion, QQmlPropertyData::Flags propertyFlags, QQmlPropertyData::Flags methodFlags, QQmlPropertyData::Flags signalFlags) @@ -452,13 +453,13 @@ QQmlPropertyCache::copyAndAppend(const QMetaObject *metaObject, QMetaObjectPrivate::get(metaObject)->signalCount + QMetaObjectPrivate::get(metaObject)->propertyCount); - rv->append(metaObject, typeMinorVersion, propertyFlags, methodFlags, signalFlags); + rv->append(metaObject, typeVersion, propertyFlags, methodFlags, signalFlags); return rv; } void QQmlPropertyCache::append(const QMetaObject *metaObject, - int typeMinorVersion, + QTypeRevision typeVersion, QQmlPropertyData::Flags propertyFlags, QQmlPropertyData::Flags methodFlags, QQmlPropertyData::Flags signalFlags) @@ -467,7 +468,7 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject, bool dynamicMetaObject = isDynamicMetaObject(metaObject); - allowedRevisionCache.append(0); + allowedRevisionCache.append(QTypeRevision::zero()); int methodCount = metaObject->methodCount(); Q_ASSERT(QMetaObjectPrivate::get(metaObject)->revision >= 4); @@ -612,7 +613,7 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject, data->setFlags(propertyFlags); data->lazyLoad(p); - data->setTypeMinorVersion(typeMinorVersion); + data->setTypeVersion(typeVersion); data->m_flags.setIsDirect(!dynamicMetaObject); @@ -697,7 +698,7 @@ void QQmlPropertyCache::updateRecur(const QMetaObject *metaObject) updateRecur(metaObject->superClass()); - append(metaObject, -1); + append(metaObject, QTypeRevision()); } void QQmlPropertyCache::update(const QMetaObject *metaObject) @@ -745,7 +746,7 @@ void QQmlPropertyCache::invalidate(const QMetaObject *metaObject) methodIndexCacheStart = parent()->methodIndexCache.count() + parent()->methodIndexCacheStart; signalHandlerIndexCacheStart = parent()->signalHandlerIndexCache.count() + parent()->signalHandlerIndexCacheStart; stringCache.linkAndReserve(parent()->stringCache, reserve); - append(metaObject, -1); + append(metaObject, QTypeRevision()); } else { propertyIndexCacheStart = 0; methodIndexCacheStart = 0; @@ -1066,13 +1067,10 @@ static inline const QMetaObjectPrivate *priv(const uint* data) static inline const QByteArray stringData(const QMetaObject *mo, int index) { - Q_ASSERT(priv(mo->d.data)->revision >= 7); - const QByteArrayDataPtr data = { const_cast<QByteArrayData*>(&mo->d.stringdata[index]) }; - Q_ASSERT(data.ptr->ref.isStatic()); - Q_ASSERT(data.ptr->alloc == 0); - Q_ASSERT(data.ptr->capacityReserved == 0); - Q_ASSERT(data.ptr->size >= 0); - return data; + uint offset = mo->d.stringdata[2*index]; + uint length = mo->d.stringdata[2*index + 1]; + const char *string = reinterpret_cast<const char *>(mo->d.stringdata) + offset; + return QByteArray::fromRawData(string, length); } bool QQmlPropertyCache::isDynamicMetaObject(const QMetaObject *mo) diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h index a5340cec37..9e6eaf9778 100644 --- a/src/qml/qml/qqmlpropertycache_p.h +++ b/src/qml/qml/qqmlpropertycache_p.h @@ -60,6 +60,7 @@ #include <private/qlinkedstringhash_p.h> #include <QtCore/qvarlengtharray.h> #include <QtCore/qvector.h> +#include <QtCore/qversionnumber.h> #include <private/qv4value_p.h> #include <private/qqmlpropertydata_p.h> @@ -80,7 +81,7 @@ class Q_QML_PRIVATE_EXPORT QQmlPropertyCache : public QQmlRefCount { public: QQmlPropertyCache(); - QQmlPropertyCache(const QMetaObject *, int metaObjectRevision = 0); + QQmlPropertyCache(const QMetaObject *, QTypeRevision metaObjectRevision = QTypeRevision::zero()); ~QQmlPropertyCache() override; void update(const QMetaObject *); @@ -92,7 +93,8 @@ public: QQmlPropertyData::Flags propertyFlags = QQmlPropertyData::Flags(), QQmlPropertyData::Flags methodFlags = QQmlPropertyData::Flags(), QQmlPropertyData::Flags signalFlags = QQmlPropertyData::Flags()); - QQmlPropertyCache *copyAndAppend(const QMetaObject *, int typeMinorVersion, + QQmlPropertyCache *copyAndAppend( + const QMetaObject *, QTypeRevision typeVersion, QQmlPropertyData::Flags propertyFlags = QQmlPropertyData::Flags(), QQmlPropertyData::Flags methodFlags = QQmlPropertyData::Flags(), QQmlPropertyData::Flags signalFlags = QQmlPropertyData::Flags()); @@ -100,7 +102,7 @@ public: QQmlPropertyCache *copyAndReserve(int propertyCount, int methodCount, int signalCount, int enumCount); void appendProperty(const QString &, QQmlPropertyData::Flags flags, int coreIndex, - int propType, int revision, int notifyIndex); + int propType, QTypeRevision revision, int notifyIndex); void appendSignal(const QString &, QQmlPropertyData::Flags, int coreIndex, const int *types = nullptr, const QList<QByteArray> &names = QList<QByteArray>()); void appendMethod(const QString &, QQmlPropertyData::Flags flags, int coreIndex, int returnType, @@ -174,8 +176,8 @@ public: QByteArray checksum(bool *ok); - int allowedRevision(int index) const { return allowedRevisionCache[index]; } - void setAllowedRevision(int index, int allowed) { allowedRevisionCache[index] = allowed; } + QTypeRevision allowedRevision(int index) const { return allowedRevisionCache[index]; } + void setAllowedRevision(int index, QTypeRevision allowed) { allowedRevisionCache[index] = allowed; } private: friend class QQmlEnginePrivate; @@ -187,7 +189,7 @@ private: inline QQmlPropertyCache *copy(int reserve); - void append(const QMetaObject *, int typeMinorVersion, + void append(const QMetaObject *, QTypeRevision typeVersion, QQmlPropertyData::Flags propertyFlags = QQmlPropertyData::Flags(), QQmlPropertyData::Flags methodFlags = QQmlPropertyData::Flags(), QQmlPropertyData::Flags signalFlags = QQmlPropertyData::Flags()); @@ -196,7 +198,7 @@ private: typedef QVector<QQmlPropertyData> IndexCache; typedef QLinkedStringMultiHash<QPair<int, QQmlPropertyData *> > StringCache; - typedef QVector<int> AllowedRevisionCache; + typedef QVector<QTypeRevision> AllowedRevisionCache; QQmlPropertyData *findProperty(StringCache::ConstIterator it, QObject *, QQmlContextData *) const; QQmlPropertyData *findProperty(StringCache::ConstIterator it, const QQmlVMEMetaObject *, QQmlContextData *) const; @@ -352,8 +354,9 @@ QQmlPropertyCache::overrideData(QQmlPropertyData *data) const bool QQmlPropertyCache::isAllowedInRevision(QQmlPropertyData *data) const { - return (data->metaObjectOffset() == -1 && data->revision() == 0) || - (allowedRevisionCache[data->metaObjectOffset()] >= data->revision()); + return (data->metaObjectOffset() == -1 && data->revision() == QTypeRevision::zero()) + || (allowedRevisionCache[data->metaObjectOffset()].toEncodedVersion<quint16>() + >= data->revision().toEncodedVersion<quint16>()); } int QQmlPropertyCache::propertyCount() const diff --git a/src/qml/qml/qqmlpropertycachecreator.cpp b/src/qml/qml/qqmlpropertycachecreator.cpp index 36581bda4e..f132fb2d78 100644 --- a/src/qml/qml/qqmlpropertycachecreator.cpp +++ b/src/qml/qml/qqmlpropertycachecreator.cpp @@ -119,9 +119,12 @@ QQmlRefPointer<QQmlPropertyCache> QQmlBindingInstantiationContext::instantiating { if (instantiatingProperty) { if (instantiatingProperty->isQObject()) { - return enginePrivate->rawPropertyCacheForType(instantiatingProperty->propType(), instantiatingProperty->typeMinorVersion()); + // rawPropertyCacheForType assumes a given unspecified version means "any version". + // There is another overload that takes no version, which we shall not use here. + return enginePrivate->rawPropertyCacheForType(instantiatingProperty->propType(), + instantiatingProperty->typeVersion()); } else if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(instantiatingProperty->propType())) { - return enginePrivate->cache(vtmo, instantiatingProperty->typeMinorVersion()); + return enginePrivate->cache(vtmo, instantiatingProperty->typeVersion()); } } return QQmlRefPointer<QQmlPropertyCache>(); diff --git a/src/qml/qml/qqmlpropertycachecreator_p.h b/src/qml/qml/qqmlpropertycachecreator_p.h index d99f5b6e98..5e26eb1ea7 100644 --- a/src/qml/qml/qqmlpropertycachecreator_p.h +++ b/src/qml/qml/qqmlpropertycachecreator_p.h @@ -538,7 +538,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::crea pend = obj->propertiesEnd(); for ( ; p != pend; ++p, ++propertyIdx) { int propertyType = 0; - int propertTypeMinorVersion = 0; + QTypeRevision propertyTypeVersion = QTypeRevision::zero(); QQmlPropertyData::Flags propertyFlags; const QV4::CompiledData::BuiltinType type = p->builtinType(); @@ -557,7 +557,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::crea QQmlType qmltype; bool selfReference = false; - if (!imports->resolveType(stringAt(p->builtinTypeOrTypeNameIndex), &qmltype, nullptr, nullptr, nullptr, + if (!imports->resolveType(stringAt(p->builtinTypeOrTypeNameIndex), &qmltype, nullptr, nullptr, nullptr, QQmlType::AnyRegistrationType, &selfReference)) { return qQmlCompileError(p->location, QQmlPropertyCacheCreatorBase::tr("Invalid property type")); } @@ -599,7 +599,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::crea propertyType = qmltype.qListTypeId(); } else { propertyType = qmltype.typeId(); - propertTypeMinorVersion = qmltype.minorVersion(); + propertyTypeVersion = qmltype.version(); } } @@ -617,7 +617,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::crea if (!obj->defaultPropertyIsAlias && propertyIdx == obj->indexOfDefaultPropertyOrAlias) cache->_defaultPropertyName = propertyName; cache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++, - propertyType, propertTypeMinorVersion, effectiveSignalIndex); + propertyType, propertyTypeVersion, effectiveSignalIndex); effectiveSignalIndex++; } @@ -641,8 +641,8 @@ inline int QQmlPropertyCacheCreator<ObjectContainer>::metaTypeForParameter(const *customTypeName = typeName; QQmlType qmltype; bool selfReference = false; - if (!imports->resolveType(typeName, &qmltype, nullptr, nullptr, nullptr, nullptr, QQmlType::AnyRegistrationType, - &selfReference)) + if (!imports->resolveType(typeName, &qmltype, nullptr, nullptr, nullptr, + QQmlType::AnyRegistrationType, &selfReference)) return QMetaType::UnknownType; if (!qmltype.isComposite()) @@ -674,7 +674,7 @@ public: private: void appendAliasPropertiesInMetaObjectsWithinComponent(const CompiledObject &component, int firstObjectIndex, QQmlEnginePrivate *enginePriv); - QQmlJS::DiagnosticMessage propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, int *rev, QQmlPropertyData::Flags *propertyFlags, QQmlEnginePrivate *enginePriv); + QQmlJS::DiagnosticMessage propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, QTypeRevision *version, QQmlPropertyData::Flags *propertyFlags, QQmlEnginePrivate *enginePriv); void collectObjectsWithAliasesRecursively(int objectIndex, QVector<int> *objectsWithAliases) const; @@ -785,7 +785,7 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::collectObjectsWithAl } template <typename ObjectContainer> -inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, int *minorVersion, +inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, QTypeRevision *version, QQmlPropertyData::Flags *propertyFlags, QQmlEnginePrivate *enginePriv) { *type = 0; @@ -818,7 +818,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>: lastAlias = targetAlias; } while (lastAlias->aliasToLocalAlias); - return propertyDataForAlias(component, *lastAlias, type, minorVersion, propertyFlags, enginePriv); + return propertyDataForAlias(component, *lastAlias, type, version, propertyFlags, enginePriv); } const int targetObjectIndex = objectForId(component, alias.targetObjectId); @@ -841,7 +841,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>: else *type = typeRef->compilationUnit->metaTypeId; - *minorVersion = typeRef->minorVersion; + *version = typeRef->version; propertyFlags->type = QQmlPropertyData::Flags::QObjectDerivedType; } else { @@ -920,9 +920,10 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>: Q_ASSERT(alias->flags & QV4::CompiledData::Alias::Resolved); int type = 0; - int minorVersion = 0; + QTypeRevision version = QTypeRevision::zero(); QQmlPropertyData::Flags propertyFlags; - QQmlJS::DiagnosticMessage error = propertyDataForAlias(component, *alias, &type, &minorVersion, &propertyFlags, enginePriv); + QQmlJS::DiagnosticMessage error = propertyDataForAlias(component, *alias, &type, &version, + &propertyFlags, enginePriv); if (error.isValid()) return error; @@ -932,7 +933,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>: propertyCache->_defaultPropertyName = propertyName; propertyCache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++, - type, minorVersion, effectiveSignalIndex++); + type, version, effectiveSignalIndex++); } return QQmlJS::DiagnosticMessage(); diff --git a/src/qml/qml/qqmlpropertydata_p.h b/src/qml/qml/qqmlpropertydata_p.h index 7f70c34854..f21b502b50 100644 --- a/src/qml/qml/qqmlpropertydata_p.h +++ b/src/qml/qml/qqmlpropertydata_p.h @@ -53,6 +53,7 @@ #include <private/qobject_p.h> #include <QtCore/qglobal.h> +#include <QtCore/qversionnumber.h> QT_BEGIN_NAMESPACE @@ -251,7 +252,7 @@ public: bool isConstructor() const { return m_flags.isConstructor; } bool hasOverride() const { return overrideIndex() >= 0; } - bool hasRevision() const { return revision() != 0; } + bool hasRevision() const { return revision() != QTypeRevision::zero(); } bool isFullyResolved() const { return !m_flags.notFullyResolved; } @@ -290,12 +291,8 @@ public: m_coreIndex = qint16(idx); } - quint8 revision() const { return m_revision; } - void setRevision(quint8 rev) - { - Q_ASSERT(rev <= std::numeric_limits<quint8>::max()); - m_revision = quint8(rev); - } + QTypeRevision revision() const { return m_revision; } + void setRevision(QTypeRevision revision) { m_revision = revision; } /* If a property is a C++ type, then we store the minor * version of this type. @@ -315,12 +312,8 @@ public: * */ - quint8 typeMinorVersion() const { return m_typeMinorVersion; } - void setTypeMinorVersion(quint8 rev) - { - Q_ASSERT(rev <= std::numeric_limits<quint8>::max()); - m_typeMinorVersion = quint8(rev); - } + QTypeRevision typeVersion() const { return m_typeVersion; } + void setTypeVersion(QTypeRevision typeVersion) { m_typeVersion = typeVersion; } QQmlPropertyCacheMethodArguments *arguments() const { return m_arguments; } void setArguments(QQmlPropertyCacheMethodArguments *args) { m_arguments = args; } @@ -412,18 +405,20 @@ private: qint16 m_notifyIndex = -1; qint16 m_overrideIndex = -1; - quint8 m_revision = 0; - quint8 m_typeMinorVersion = 0; qint16 m_metaObjectOffset = -1; + quint16 m_reserved = 0; + + QTypeRevision m_revision = QTypeRevision::zero(); + QTypeRevision m_typeVersion = QTypeRevision::zero(); QQmlPropertyCacheMethodArguments *m_arguments = nullptr; StaticMetaCallFunction m_staticMetaCallFunction = nullptr; }; #if QT_POINTER_SIZE == 4 - Q_STATIC_ASSERT(sizeof(QQmlPropertyData) == 24); + Q_STATIC_ASSERT(sizeof(QQmlPropertyData) == 28); #else // QT_POINTER_SIZE == 8 - Q_STATIC_ASSERT(sizeof(QQmlPropertyData) == 32); + Q_STATIC_ASSERT(sizeof(QQmlPropertyData) == 40); #endif bool QQmlPropertyData::operator==(const QQmlPropertyData &other) const diff --git a/src/qml/qml/qqmlpropertyvalidator.cpp b/src/qml/qml/qqmlpropertyvalidator.cpp index c897ac8751..3fb2eb399f 100644 --- a/src/qml/qml/qqmlpropertyvalidator.cpp +++ b/src/qml/qml/qqmlpropertyvalidator.cpp @@ -192,7 +192,10 @@ QVector<QQmlJS::DiagnosticMessage> QQmlPropertyValidator::validateObject( QString typeName = stringAt(obj->inheritedTypeNameIndex); auto *objectType = resolvedType(obj->inheritedTypeNameIndex); if (objectType && objectType->type.isValid()) { - return recordError(binding->location, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(typeName).arg(name).arg(objectType->type.module()).arg(objectType->majorVersion).arg(objectType->minorVersion)); + return recordError(binding->location, tr("\"%1.%2\" is not available in %3 %4.%5.") + .arg(typeName).arg(name).arg(objectType->type.module()) + .arg(objectType->version.majorVersion()) + .arg(objectType->version.minorVersion())); } else { return recordError(binding->location, tr("\"%1.%2\" is not available due to component versioning.").arg(typeName).arg(name)); } @@ -212,7 +215,7 @@ QVector<QQmlJS::DiagnosticMessage> QQmlPropertyValidator::validateObject( if (name.constData()->isUpper() && !binding->isAttachedProperty()) { QQmlType type; QQmlImportNamespace *typeNamespace = nullptr; - imports.resolveType(stringAt(binding->propertyNameIndex), &type, nullptr, nullptr, &typeNamespace); + imports.resolveType(stringAt(binding->propertyNameIndex), &type, nullptr, &typeNamespace); if (typeNamespace) return recordError(binding->location, tr("Invalid use of namespace")); return recordError(binding->location, tr("Invalid attached object assignment")); @@ -744,8 +747,8 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateObjectBinding(QQmlPrope // We want to use the raw metaObject here as the raw metaobject is the // actual property type before we applied any extensions that might // effect the properties on the type, but don't effect assignability - // Using -1 for the minor version ensures that we get the raw metaObject. - QQmlPropertyCache *propertyMetaObject = enginePrivate->rawPropertyCacheForType(propType, -1); + // Not passing a version ensures that we get the raw metaObject. + QQmlPropertyCache *propertyMetaObject = enginePrivate->rawPropertyCacheForType(propType); if (propertyMetaObject) { // Will be true if the assigned type inherits propertyMetaObject diff --git a/src/qml/qml/qqmltype.cpp b/src/qml/qml/qqmltype.cpp index 96a35b0fe9..047da376c6 100644 --- a/src/qml/qml/qqmltype.cpp +++ b/src/qml/qml/qqmltype.cpp @@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE QQmlTypePrivate::QQmlTypePrivate(QQmlType::RegistrationType type) - : regType(type), iid(nullptr), typeId(0), listId(0), revision(0), + : regType(type), iid(nullptr), typeId(0), listId(0), revision(QTypeRevision::zero()), containsRevisionedAttributes(false), baseMetaObject(nullptr), index(-1), isSetup(false), isEnumFromCacheSetup(false), isEnumFromBaseSetup(false), haveSuperType(false) @@ -132,34 +132,29 @@ QHashedString QQmlType::module() const return d->module; } -int QQmlType::majorVersion() const +QTypeRevision QQmlType::version() const { if (!d) - return -1; - return d->version_maj; -} - -int QQmlType::minorVersion() const -{ - if (!d) - return -1; - return d->version_min; + return QTypeRevision(); + return d->version; } -bool QQmlType::availableInVersion(int vmajor, int vminor) const +bool QQmlType::availableInVersion(QTypeRevision version) const { - Q_ASSERT(vmajor >= 0 && vminor >= 0); + Q_ASSERT(version.hasMajorVersion() && version.hasMinorVersion()); if (!d) return false; - return vmajor == d->version_maj && vminor >= d->version_min; + return version.majorVersion() == d->version.majorVersion() + && version.minorVersion() >= d->version.minorVersion(); } -bool QQmlType::availableInVersion(const QHashedStringRef &module, int vmajor, int vminor) const +bool QQmlType::availableInVersion(const QHashedStringRef &module, QTypeRevision version) const { - Q_ASSERT(vmajor >= 0 && vminor >= 0); + Q_ASSERT(version.hasMajorVersion() && version.hasMinorVersion()); if (!d) return false; - return module == d->module && vmajor == d->version_maj && vminor >= d->version_min; + return module == d->module && version.majorVersion() == d->version.majorVersion() + && version.minorVersion() >= d->version.minorVersion(); } QQmlType QQmlTypePrivate::resolveCompositeBaseType(QQmlEnginePrivate *engine) const @@ -629,9 +624,9 @@ bool QQmlType::containsRevisionedAttributes() const return d->containsRevisionedAttributes; } -int QQmlType::metaObjectRevision() const +QTypeRevision QQmlType::metaObjectRevision() const { - return d ? d->revision : -1; + return d ? d->revision : QTypeRevision(); } QQmlAttachedPropertiesFunc QQmlType::attachedPropertiesFunction(QQmlEnginePrivate *engine) const diff --git a/src/qml/qml/qqmltype_p.h b/src/qml/qml/qqmltype_p.h index 387baa74bb..c33cad7c88 100644 --- a/src/qml/qml/qqmltype_p.h +++ b/src/qml/qml/qqmltype_p.h @@ -60,6 +60,7 @@ #include <QtQml/qjsvalue.h> #include <QtCore/qobject.h> +#include <QtCore/qversionnumber.h> QT_BEGIN_NAMESPACE @@ -98,11 +99,10 @@ public: QString elementName() const; QHashedString module() const; - int majorVersion() const; - int minorVersion() const; + QTypeRevision version() const; - bool availableInVersion(int vmajor, int vminor) const; - bool availableInVersion(const QHashedStringRef &module, int vmajor, int vminor) const; + bool availableInVersion(QTypeRevision version) const; + bool availableInVersion(const QHashedStringRef &module, QTypeRevision version) const; QObject *create() const; void create(QObject **, void **, size_t) const; @@ -129,7 +129,7 @@ public: const QMetaObject *metaObject() const; const QMetaObject *baseMetaObject() const; - int metaObjectRevision() const; + QTypeRevision metaObjectRevision() const; bool containsRevisionedAttributes() const; QQmlAttachedPropertiesFunc attachedPropertiesFunction(QQmlEnginePrivate *engine) const; diff --git a/src/qml/qml/qqmltype_p_p.h b/src/qml/qml/qqmltype_p_p.h index 43344827db..0d493c4871 100644 --- a/src/qml/qml/qqmltype_p_p.h +++ b/src/qml/qml/qqmltype_p_p.h @@ -157,11 +157,10 @@ public: QHashedString module; QString name; QString elementName; - int version_maj; - int version_min; int typeId; int listId; - int revision; + QTypeRevision version; + QTypeRevision revision; mutable bool containsRevisionedAttributes; mutable QQmlType superType; const QMetaObject *baseMetaObject; diff --git a/src/qml/qml/qqmltypecompiler.cpp b/src/qml/qml/qqmltypecompiler.cpp index d527fe0335..3518b21a70 100644 --- a/src/qml/qml/qqmltypecompiler.cpp +++ b/src/qml/qml/qqmltypecompiler.cpp @@ -257,7 +257,7 @@ QString QQmlTypeCompiler::bindingAsString(const QmlIR::Object *object, int scrip return object->bindingAsString(document, scriptIndex); } -void QQmlTypeCompiler::addImport(const QString &module, const QString &qualifier, int majorVersion, int minorVersion) +void QQmlTypeCompiler::addImport(const QString &module, const QString &qualifier, QTypeRevision version) { const quint32 moduleIdx = registerString(module); const quint32 qualifierIdx = registerString(qualifier); @@ -272,8 +272,7 @@ void QQmlTypeCompiler::addImport(const QString &module, const QString &qualifier auto pool = memoryPool(); QV4::CompiledData::Import *import = pool->New<QV4::CompiledData::Import>(); import->type = QV4::CompiledData::Import::ImportLibrary; - import->majorVersion = majorVersion; - import->minorVersion = minorVersion; + import->version = version; import->uriIndex = moduleIdx; import->qualifierIndex = qualifierIdx; document->imports.append(import); @@ -394,7 +393,10 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio auto *typeRef = resolvedType(obj->inheritedTypeNameIndex); const QQmlType type = typeRef ? typeRef->type : QQmlType(); if (type.isValid()) { - COMPILE_EXCEPTION(binding, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(typeName).arg(originalPropertyName).arg(type.module()).arg(type.majorVersion()).arg(type.minorVersion())); + COMPILE_EXCEPTION(binding, tr("\"%1.%2\" is not available in %3 %4.%5.") + .arg(typeName).arg(originalPropertyName).arg(type.module()) + .arg(type.version().majorVersion()) + .arg(type.version().minorVersion())); } else { COMPILE_EXCEPTION(binding, tr("\"%1.%2\" is not available due to component versioning.").arg(typeName).arg(originalPropertyName)); } @@ -530,12 +532,6 @@ bool QQmlEnumTypeResolver::resolveEnumBindings() return true; } -struct StaticQtMetaObject : public QObject -{ - static const QMetaObject *get() - { return &staticQtMetaObject; } -}; - bool QQmlEnumTypeResolver::assignEnumToBinding(QmlIR::Binding *binding, const QStringRef &enumName, int enumValue, bool isQtObject) { if (enumName.length() > 0 && enumName[0].isLower() && !isQtObject) { @@ -626,7 +622,7 @@ bool QQmlEnumTypeResolver::tryQualifiedEnumAssignment(const QmlIR::Object *obj, value = type.enumValue(compiler->enginePrivate(), QHashedStringRef(enumValue), &ok); } else { QByteArray enumName = enumValue.toUtf8(); - const QMetaObject *metaObject = StaticQtMetaObject::get(); + const QMetaObject *metaObject = &Qt::staticMetaObject; for (int ii = metaObject->enumeratorCount() - 1; !ok && ii >= 0; --ii) { QMetaEnum e = metaObject->enumerator(ii); value = e.keyToValue(enumName.constData(), &ok); @@ -655,7 +651,7 @@ int QQmlEnumTypeResolver::evaluateEnum(const QString &scope, const QStringRef &e return type.enumValue(compiler->enginePrivate(), QHashedStringRef(enumValue.constData(), enumValue.length()), ok); } - const QMetaObject *mo = StaticQtMetaObject::get(); + const QMetaObject *mo = &Qt::staticMetaObject; int i = mo->enumeratorCount(); const QByteArray ba = enumValue.toUtf8(); while (i--) { @@ -822,7 +818,12 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI if (!pd || !pd->isQObject()) continue; - QQmlPropertyCache *pc = enginePrivate->rawPropertyCacheForType(pd->propType(), pd->typeMinorVersion()); + // If the version is given, use it and look up by QQmlType. + // Otherwise, make sure we look up by metaobject. + // TODO: Is this correct? + QQmlPropertyCache *pc = pd->typeVersion().hasMinorVersion() + ? enginePrivate->rawPropertyCacheForType(pd->propType(), pd->typeVersion()) + : enginePrivate->rawPropertyCacheForType(pd->propType()); const QMetaObject *mo = pc ? pc->firstCppMetaObject() : nullptr; while (mo) { if (mo == &QQmlComponent::staticMetaObject) @@ -838,7 +839,7 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI Q_ASSERT(componentType.isValid()); const QString qualifier = QStringLiteral("QmlInternals"); - compiler->addImport(componentType.module(), qualifier, componentType.majorVersion(), componentType.minorVersion()); + compiler->addImport(componentType.module(), qualifier, componentType.version()); QmlIR::Object *syntheticComponent = pool->New<QmlIR::Object>(); syntheticComponent->init(pool, compiler->registerString(qualifier + QLatin1Char('.') + componentType.elementName()), compiler->registerString(QString())); @@ -848,8 +849,7 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI if (!containsResolvedType(syntheticComponent->inheritedTypeNameIndex)) { auto typeRef = new QV4::ResolvedTypeReference; typeRef->type = componentType; - typeRef->majorVersion = componentType.majorVersion(); - typeRef->minorVersion = componentType.minorVersion(); + typeRef->version = componentType.version(); insertResolvedType(syntheticComponent->inheritedTypeNameIndex, typeRef); } diff --git a/src/qml/qml/qqmltypecompiler_p.h b/src/qml/qml/qqmltypecompiler_p.h index 319df8673b..050c75b30d 100644 --- a/src/qml/qml/qqmltypecompiler_p.h +++ b/src/qml/qml/qqmltypecompiler_p.h @@ -124,7 +124,7 @@ public: QString bindingAsString(const QmlIR::Object *object, int scriptIndex) const; - void addImport(const QString &module, const QString &qualifier, int majorVersion, int minorVersion); + void addImport(const QString &module, const QString &qualifier, QTypeRevision version); QV4::ResolvedTypeReference *resolvedType(int id) const { diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp index ebe4e32b48..30d50b911e 100644 --- a/src/qml/qml/qqmltypedata.cpp +++ b/src/qml/qml/qqmltypedata.cpp @@ -182,8 +182,8 @@ bool QQmlTypeData::tryLoadFromDiskCache() const QV4::CompiledData::Import *import = m_compiledData->importAt(i); if (m_compiledData->stringAt(import->uriIndex) == QLatin1String(".") && import->qualifierIndex == 0 - && import->majorVersion == -1 - && import->minorVersion == -1) { + && !import->version.hasMajorVersion() + && !import->version.hasMinorVersion()) { QList<QQmlError> errors; auto pendingImport = std::make_shared<PendingImport>(this, import); if (!fetchQmldir(qmldirUrl, pendingImport, 1, &errors)) { @@ -213,9 +213,9 @@ bool QQmlTypeData::tryLoadFromDiskCache() QQmlType containingType; auto containingTypeName = finalUrl().fileName().split(QLatin1Char('.')).first(); - int major = -1, minor = -1; + QTypeRevision version; QQmlImportNamespace *ns = nullptr; - m_importCache.resolveType(containingTypeName, &containingType, &major, &minor, &ns); + m_importCache.resolveType(containingTypeName, &containingType, &version, &ns); for (auto&& ic: ics) { QString const nameString = m_compiledData->stringAt(ic.nameIndex); QByteArray const name = nameString.toUtf8(); @@ -651,9 +651,9 @@ void QQmlTypeData::continueLoadFromIR() { QQmlType containingType; auto containingTypeName = finalUrl().fileName().split(QLatin1Char('.')).first(); - int major = -1, minor = -1; + QTypeRevision version; QQmlImportNamespace *ns = nullptr; - m_importCache.resolveType(containingTypeName, &containingType, &major, &minor, &ns); + m_importCache.resolveType(containingTypeName, &containingType, &version, &ns); for (auto const& object: m_document->objects) { for (auto it = object->inlineComponentsBegin(); it != object->inlineComponentsEnd(); ++it) { QString const nameString = m_document->stringAt(it->nameIndex); @@ -679,8 +679,7 @@ void QQmlTypeData::continueLoadFromIR() // This qmldir is for the implicit import auto implicitImport = std::make_shared<PendingImport>(); implicitImport->uri = QLatin1String("."); - implicitImport->majorVersion = -1; - implicitImport->minorVersion = -1; + implicitImport->version = QTypeRevision(); QList<QQmlError> errors; if (!fetchQmldir(qmldirUrl, implicitImport, 1, &errors)) { @@ -824,11 +823,8 @@ void QQmlTypeData::resolveTypes() typeName = csRef.typeName; } - int majorVersion = csRef.majorVersion > -1 ? csRef.majorVersion : -1; - int minorVersion = csRef.minorVersion > -1 ? csRef.minorVersion : -1; - - if (!resolveType(typeName, majorVersion, minorVersion, ref, -1, -1, true, - QQmlType::CompositeSingletonType)) + QTypeRevision version = csRef.version; + if (!resolveType(typeName, version, ref, -1, -1, true, QQmlType::CompositeSingletonType)) return; if (ref.type.isCompositeSingleton()) { @@ -852,14 +848,13 @@ void QQmlTypeData::resolveTypes() const bool reportErrors = unresolvedRef->errorWhenNotFound; - int majorVersion = -1; - int minorVersion = -1; + QTypeRevision version; const QString name = stringAt(unresolvedRef.key()); bool *selfReferenceDetection = unresolvedRef->needsCreation ? nullptr : &ref.selfReference; - if (!resolveType(name, majorVersion, minorVersion, ref, unresolvedRef->location.line, + if (!resolveType(name, version, ref, unresolvedRef->location.line, unresolvedRef->location.column, reportErrors, QQmlType::AnyRegistrationType, selfReferenceDetection) && reportErrors) return; @@ -879,8 +874,7 @@ void QQmlTypeData::resolveTypes() } } } - ref.majorVersion = majorVersion; - ref.minorVersion = minorVersion; + ref.version = version; ref.location.line = unresolvedRef->location.line; ref.location.column = unresolvedRef->location.column; @@ -963,13 +957,10 @@ QQmlJS::DiagnosticMessage QQmlTypeData::buildTypeResolutionCaches( return qQmlCompileError(resolvedType->location, reason); } - if (ref->type.containsRevisionedAttributes()) { - ref->typePropertyCache = engine->cache(ref->type, - resolvedType->minorVersion); - } + if (ref->type.containsRevisionedAttributes()) + ref->typePropertyCache = engine->cache(ref->type, resolvedType->version); } - ref->majorVersion = resolvedType->majorVersion; - ref->minorVersion = resolvedType->minorVersion; + ref->version = resolvedType->version; ref->doDynamicTypeCheck(); resolvedTypeCache->insert(resolvedType.key(), ref.take()); } @@ -977,7 +968,7 @@ QQmlJS::DiagnosticMessage QQmlTypeData::buildTypeResolutionCaches( return noError; } -bool QQmlTypeData::resolveType(const QString &typeName, int &majorVersion, int &minorVersion, +bool QQmlTypeData::resolveType(const QString &typeName, QTypeRevision &version, TypeReference &ref, int lineNumber, int columnNumber, bool reportErrors, QQmlType::RegistrationType registrationType, bool *typeRecursionDetected) @@ -985,7 +976,7 @@ bool QQmlTypeData::resolveType(const QString &typeName, int &majorVersion, int & QQmlImportNamespace *typeNamespace = nullptr; QList<QQmlError> errors; - bool typeFound = m_importCache.resolveType(typeName, &ref.type, &majorVersion, &minorVersion, + bool typeFound = m_importCache.resolveType(typeName, &ref.type, &version, &typeNamespace, &errors, registrationType, typeRecursionDetected); if (!typeNamespace && !typeFound && !m_implicitImportLoaded) { @@ -993,7 +984,7 @@ bool QQmlTypeData::resolveType(const QString &typeName, int &majorVersion, int & if (loadImplicitImport()) { // Try again to find the type errors.clear(); - typeFound = m_importCache.resolveType(typeName, &ref.type, &majorVersion, &minorVersion, + typeFound = m_importCache.resolveType(typeName, &ref.type, &version, &typeNamespace, &errors, registrationType, typeRecursionDetected); } else { diff --git a/src/qml/qml/qqmltypedata_p.h b/src/qml/qml/qqmltypedata_p.h index d894090b36..1506ee2010 100644 --- a/src/qml/qml/qqmltypedata_p.h +++ b/src/qml/qml/qqmltypedata_p.h @@ -62,12 +62,11 @@ class Q_AUTOTEST_EXPORT QQmlTypeData : public QQmlTypeLoader::Blob public: struct TypeReference { - TypeReference() : majorVersion(0), minorVersion(0), needsCreation(true) {} + TypeReference() : version(QTypeRevision::zero()), needsCreation(true) {} QV4::CompiledData::Location location; QQmlType type; - int majorVersion; - int minorVersion; + QTypeRevision version; QQmlRefPointer<QQmlTypeData> typeData; bool selfReference = false; QString prefix; // used by CompositeSingleton types @@ -134,7 +133,7 @@ private: const QV4::CompiledData::DependentTypesHasher &dependencyHasher); void createTypeAndPropertyCaches(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache, const QV4::ResolvedTypeReferenceMap &resolvedTypeCache); - bool resolveType(const QString &typeName, int &majorVersion, int &minorVersion, + bool resolveType(const QString &typeName, QTypeRevision &version, TypeReference &ref, int lineNumber = -1, int columnNumber = -1, bool reportErrors = true, QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType, diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index f910fe1140..c5218bee33 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -487,8 +487,7 @@ QQmlTypeLoader::Blob::PendingImport::PendingImport(QQmlTypeLoader::Blob *blob, c type = static_cast<QV4::CompiledData::Import::ImportType>(quint32(import->type)); uri = blob->stringAt(import->uriIndex); qualifier = blob->stringAt(import->qualifierIndex); - majorVersion = import->majorVersion; - minorVersion = import->minorVersion; + version = import->version; location = import->location; } @@ -578,12 +577,13 @@ bool QQmlTypeLoader::Blob::addImport(QQmlTypeLoader::Blob::PendingImportPtr impo QString qmldirUrl; const QQmlImports::LocalQmldirResult qmldirResult = m_importCache.locateLocalQmldir( - importDatabase, import->uri, import->majorVersion, import->minorVersion, + importDatabase, import->uri, import->version, &qmldirFilePath, &qmldirUrl); if (qmldirResult == QQmlImports::QmldirFound) { // This is a local library import - if (!m_importCache.addLibraryImport(importDatabase, import->uri, import->qualifier, import->majorVersion, - import->minorVersion, qmldirFilePath, qmldirUrl, false, errors)) + if (!m_importCache.addLibraryImport( + importDatabase, import->uri, import->qualifier, + import->version, qmldirFilePath, qmldirUrl, false, errors)) return false; if (!loadImportDependencies(import, qmldirFilePath, errors)) @@ -605,19 +605,19 @@ bool QQmlTypeLoader::Blob::addImport(QQmlTypeLoader::Blob::PendingImportPtr impo } else if ( // Major version of module already registered: // We believe that the registration is complete. - QQmlMetaType::typeModule(import->uri, import->majorVersion) + QQmlMetaType::typeModule(import->uri, import->version) // Otherwise, try to register further module types. || (qmldirResult != QQmlImports::QmldirInterceptedToRemote - && QQmlMetaType::qmlRegisterModuleTypes(import->uri, import->majorVersion)) + && QQmlMetaType::qmlRegisterModuleTypes(import->uri)) // Otherwise, there is no way to register any further types. // Try with any module of that name. || QQmlMetaType::isAnyModule(import->uri)) { if (!m_importCache.addLibraryImport( - importDatabase, import->uri, import->qualifier, import->majorVersion, - import->minorVersion, QString(), QString(), false, errors)) { + importDatabase, import->uri, import->qualifier, import->version, + QString(), QString(), false, errors)) { return false; } } else { @@ -633,13 +633,15 @@ bool QQmlTypeLoader::Blob::addImport(QQmlTypeLoader::Blob::PendingImportPtr impo : QQmlImportDatabase::Remote); if (!remotePathList.isEmpty()) { // Add this library and request the possible locations for it - if (!m_importCache.addLibraryImport(importDatabase, import->uri, import->qualifier, import->majorVersion, - import->minorVersion, QString(), QString(), true, errors)) + if (!m_importCache.addLibraryImport( + importDatabase, import->uri, import->qualifier, import->version, + QString(), QString(), true, errors)) return false; // Probe for all possible locations int priority = 0; - const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths(import->uri, remotePathList, import->majorVersion, import->minorVersion); + const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths( + import->uri, remotePathList, import->version); for (const QString &qmldirPath : qmlDirPaths) { if (interceptor) { QUrl url = interceptor->intercept( @@ -671,8 +673,8 @@ bool QQmlTypeLoader::Blob::addImport(QQmlTypeLoader::Blob::PendingImportPtr impo incomplete = true; } - if (!m_importCache.addFileImport(importDatabase, import->uri, import->qualifier, import->majorVersion, - import->minorVersion, incomplete, errors)) + if (!m_importCache.addFileImport(importDatabase, import->uri, import->qualifier, + import->version, incomplete, errors)) return false; if (incomplete) { @@ -711,8 +713,7 @@ bool QQmlTypeLoader::Blob::loadImportDependencies(PendingImportPtr currentImport auto dependencyImport = std::make_shared<PendingImport>(); dependencyImport->uri = implicitImports; dependencyImport->qualifier = currentImport->qualifier; - dependencyImport->majorVersion = currentImport->majorVersion; - dependencyImport->minorVersion = currentImport->minorVersion; + dependencyImport->version = currentImport->version; if (!addImport(dependencyImport, errors)) return false; } diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h index adecf61896..a1ba2967e3 100644 --- a/src/qml/qml/qqmltypeloader_p.h +++ b/src/qml/qml/qqmltypeloader_p.h @@ -97,8 +97,7 @@ public: QString uri; QString qualifier; - int majorVersion = -1; - int minorVersion = -1; + QTypeRevision version; QV4::CompiledData::Location location; diff --git a/src/qml/qml/qqmltypemodule.cpp b/src/qml/qml/qqmltypemodule.cpp index 9d6f269030..e6bf796d74 100644 --- a/src/qml/qml/qqmltypemodule.cpp +++ b/src/qml/qml/qqmltypemodule.cpp @@ -45,7 +45,7 @@ QT_BEGIN_NAMESPACE -QQmlTypeModule::QQmlTypeModule(const QString &module, int majorVersion) +QQmlTypeModule::QQmlTypeModule(const QString &module, quint8 majorVersion) : d(new QQmlTypeModulePrivate(module, majorVersion)) { } @@ -61,23 +61,23 @@ QString QQmlTypeModule::module() const return d->module; } -int QQmlTypeModule::majorVersion() const +quint8 QQmlTypeModule::majorVersion() const { // No need to lock. d->majorVersion is const return d->majorVersion; } -int QQmlTypeModule::minimumMinorVersion() const +quint8 QQmlTypeModule::minimumMinorVersion() const { return d->minMinorVersion.loadRelaxed(); } -int QQmlTypeModule::maximumMinorVersion() const +quint8 QQmlTypeModule::maximumMinorVersion() const { return d->maxMinorVersion.loadRelaxed(); } -void QQmlTypeModule::addMinorVersion(int version) +void QQmlTypeModule::addMinorVersion(quint8 version) { for (int oldVersion = d->minMinorVersion.loadRelaxed(); oldVersion > version && !d->minMinorVersion.testAndSetOrdered(oldVersion, version); @@ -93,16 +93,16 @@ void QQmlTypeModule::addMinorVersion(int version) void QQmlTypeModule::add(QQmlTypePrivate *type) { QMutexLocker lock(&d->mutex); - addMinorVersion(type->version_min); + addMinorVersion(type->version.minorVersion()); QList<QQmlTypePrivate *> &list = d->typeHash[type->elementName]; for (int ii = 0; ii < list.count(); ++ii) { QQmlTypePrivate *in_list = list.at(ii); Q_ASSERT(in_list); - if (in_list->version_min < type->version_min) { + if (in_list->version.minorVersion() < type->version.minorVersion()) { list.insert(ii, type); return; - } else if (in_list->version_min == type->version_min) { + } else if (in_list->version.minorVersion() == type->version.minorVersion()) { list[ii] = type; return; } @@ -137,26 +137,26 @@ void QQmlTypeModule::lock() d->locked.storeRelaxed(1); } -QQmlType QQmlTypeModule::type(const QHashedStringRef &name, int minor) const +QQmlType QQmlTypeModule::type(const QHashedStringRef &name, QTypeRevision version) const { QMutexLocker lock(&d->mutex); QList<QQmlTypePrivate *> *types = d->typeHash.value(name); if (types) { for (int ii = 0; ii < types->count(); ++ii) - if (types->at(ii)->version_min <= minor) + if (types->at(ii)->version.minorVersion() <= version.minorVersion()) return QQmlType(types->at(ii)); } return QQmlType(); } -QQmlType QQmlTypeModule::type(const QV4::String *name, int minor) const +QQmlType QQmlTypeModule::type(const QV4::String *name, QTypeRevision version) const { QMutexLocker lock(&d->mutex); QList<QQmlTypePrivate *> *types = d->typeHash.value(name); if (types) { for (int ii = 0; ii < types->count(); ++ii) - if (types->at(ii)->version_min <= minor) + if (types->at(ii)->version.minorVersion() <= version.minorVersion()) return QQmlType(types->at(ii)); } diff --git a/src/qml/qml/qqmltypemodule_p.h b/src/qml/qml/qqmltypemodule_p.h index b84a91b5db..d3149567a3 100644 --- a/src/qml/qml/qqmltypemodule_p.h +++ b/src/qml/qml/qqmltypemodule_p.h @@ -53,6 +53,7 @@ #include <QtQml/qtqmlglobal.h> #include <QtCore/qstring.h> +#include <QtCore/qversionnumber.h> #include <functional> @@ -72,7 +73,7 @@ class QQmlTypeModulePrivate; class QQmlTypeModule { public: - QQmlTypeModule(const QString &uri = QString(), int majorVersion = 0); + QQmlTypeModule(const QString &uri = QString(), quint8 majorVersion = 0); ~QQmlTypeModule(); void add(QQmlTypePrivate *); @@ -82,14 +83,14 @@ public: void lock(); QString module() const; - int majorVersion() const; + quint8 majorVersion() const; - void addMinorVersion(int minorVersion); - int minimumMinorVersion() const; - int maximumMinorVersion() const; + void addMinorVersion(quint8 minorVersion); + quint8 minimumMinorVersion() const; + quint8 maximumMinorVersion() const; - QQmlType type(const QHashedStringRef &, int) const; - QQmlType type(const QV4::String *, int) const; + QQmlType type(const QHashedStringRef &, QTypeRevision version) const; + QQmlType type(const QV4::String *, QTypeRevision version) const; void walkCompositeSingletons(const std::function<void(const QQmlType &)> &callback) const; diff --git a/src/qml/qml/qqmltypemodule_p_p.h b/src/qml/qml/qqmltypemodule_p_p.h index b1dab1c4a0..5d4d2e458a 100644 --- a/src/qml/qml/qqmltypemodule_p_p.h +++ b/src/qml/qml/qqmltypemodule_p_p.h @@ -62,15 +62,15 @@ QT_BEGIN_NAMESPACE class QQmlTypeModulePrivate { public: - QQmlTypeModulePrivate(QString module, int majorVersion) : + QQmlTypeModulePrivate(QString module, quint8 majorVersion) : module(std::move(module)), majorVersion(majorVersion) {} const QString module; - const int majorVersion = 0; + const quint8 majorVersion = 0; // Can only ever decrease - QAtomicInt minMinorVersion = std::numeric_limits<int>::max(); + QAtomicInt minMinorVersion = std::numeric_limits<quint8>::max(); // Can only ever increase QAtomicInt maxMinorVersion = 0; diff --git a/src/qml/qml/qqmltypemoduleversion.cpp b/src/qml/qml/qqmltypemoduleversion.cpp index bbbfa1a7b6..207b77770a 100644 --- a/src/qml/qml/qqmltypemoduleversion.cpp +++ b/src/qml/qml/qqmltypemoduleversion.cpp @@ -49,11 +49,11 @@ QQmlTypeModuleVersion::QQmlTypeModuleVersion() { } -QQmlTypeModuleVersion::QQmlTypeModuleVersion(QQmlTypeModule *module, int minor) - : m_module(module), m_minor(minor) +QQmlTypeModuleVersion::QQmlTypeModuleVersion(QQmlTypeModule *module, QTypeRevision version) + : m_module(module), m_minor(version.minorVersion()) { Q_ASSERT(m_module); - Q_ASSERT(m_minor >= 0); + Q_ASSERT(QTypeRevision::isValidSegment(m_minor)); } QQmlTypeModuleVersion::QQmlTypeModuleVersion(const QQmlTypeModuleVersion &o) @@ -68,28 +68,18 @@ QQmlTypeModuleVersion &QQmlTypeModuleVersion::operator=(const QQmlTypeModuleVers return *this; } -QQmlTypeModule *QQmlTypeModuleVersion::module() const -{ - return m_module; -} - -int QQmlTypeModuleVersion::minorVersion() const -{ - return m_minor; -} - QQmlType QQmlTypeModuleVersion::type(const QHashedStringRef &name) const { if (!m_module) return QQmlType(); - return m_module->type(name, m_minor); + return m_module->type(name, QTypeRevision::fromMinorVersion(m_minor)); } QQmlType QQmlTypeModuleVersion::type(const QV4::String *name) const { if (!m_module) return QQmlType(); - return m_module->type(name, m_minor); + return m_module->type(name, QTypeRevision::fromMinorVersion(m_minor)); } QT_END_NAMESPACE diff --git a/src/qml/qml/qqmltypemoduleversion_p.h b/src/qml/qml/qqmltypemoduleversion_p.h index 20f4709ecb..b7e94ef27b 100644 --- a/src/qml/qml/qqmltypemoduleversion_p.h +++ b/src/qml/qml/qqmltypemoduleversion_p.h @@ -52,6 +52,7 @@ // #include <QtQml/qtqmlglobal.h> +#include <QtCore/qversionnumber.h> QT_BEGIN_NAMESPACE @@ -67,19 +68,16 @@ class QQmlTypeModuleVersion { public: QQmlTypeModuleVersion(); - QQmlTypeModuleVersion(QQmlTypeModule *, int); + QQmlTypeModuleVersion(QQmlTypeModule *, QTypeRevision); QQmlTypeModuleVersion(const QQmlTypeModuleVersion &); QQmlTypeModuleVersion &operator=(const QQmlTypeModuleVersion &); - QQmlTypeModule *module() const; - int minorVersion() const; - QQmlType type(const QHashedStringRef &) const; QQmlType type(const QV4::String *) const; private: QQmlTypeModule *m_module; - int m_minor; + quint8 m_minor; }; QT_END_NAMESPACE diff --git a/src/qml/qml/qqmltypenamecache.cpp b/src/qml/qml/qqmltypenamecache.cpp index 1015403226..45333668e3 100644 --- a/src/qml/qml/qqmltypenamecache.cpp +++ b/src/qml/qml/qqmltypenamecache.cpp @@ -101,7 +101,7 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QHashedStringRef &name) QQmlImportNamespace *typeNamespace = nullptr; QList<QQmlError> errors; QQmlType t; - bool typeFound = m_imports.resolveType(name, &t, nullptr, nullptr, &typeNamespace, &errors); + bool typeFound = m_imports.resolveType(name, &t, nullptr, &typeNamespace, &errors); if (typeFound) { return Result(t); } @@ -129,7 +129,7 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QHashedStringRef &name, QQmlImportNamespace *typeNamespace = nullptr; QList<QQmlError> errors; QQmlType t; - bool typeFound = m_imports.resolveType(qualifiedTypeName, &t, nullptr, nullptr, &typeNamespace, &errors); + bool typeFound = m_imports.resolveType(qualifiedTypeName, &t, nullptr, &typeNamespace, &errors); if (typeFound) { return Result(t); } @@ -155,7 +155,7 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QV4::String *name, QQml QList<QQmlError> errors; QQmlType t; bool typeRecursionDetected = false; - bool typeFound = m_imports.resolveType(typeName, &t, nullptr, nullptr, &typeNamespace, &errors, + bool typeFound = m_imports.resolveType(typeName, &t, nullptr, &typeNamespace, &errors, QQmlType::AnyRegistrationType, recursionRestriction == QQmlImport::AllowRecursion ? &typeRecursionDetected : nullptr); if (typeFound) { @@ -191,7 +191,7 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QV4::String *name, cons QQmlImportNamespace *typeNamespace = nullptr; QList<QQmlError> errors; QQmlType t; - bool typeFound = m_imports.resolveType(qualifiedTypeName, &t, nullptr, nullptr, &typeNamespace, &errors); + bool typeFound = m_imports.resolveType(qualifiedTypeName, &t, nullptr, &typeNamespace, &errors); if (typeFound) { return Result(t); } diff --git a/src/qml/qml/qqmltypenotavailable_p.h b/src/qml/qml/qqmltypenotavailable_p.h index 9bb19ed86c..97956fa982 100644 --- a/src/qml/qml/qqmltypenotavailable_p.h +++ b/src/qml/qml/qqmltypenotavailable_p.h @@ -58,6 +58,7 @@ QT_BEGIN_NAMESPACE class QQmlTypeNotAvailable : public QObject { Q_OBJECT QML_NAMED_ELEMENT(TypeNotAvailable) + QML_ADDED_IN_VERSION(2, 0) QML_UNCREATABLE("Type not available.") }; diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp index a86564a49a..254f1015e2 100644 --- a/src/qml/qml/qqmlvaluetype.cpp +++ b/src/qml/qml/qqmlvaluetype.cpp @@ -132,8 +132,10 @@ const QMetaObject *QQmlValueTypeFactoryImpl::metaObjectForMetaType(int t) return &QQmlRectValueType::staticMetaObject; case QMetaType::QRectF: return &QQmlRectFValueType::staticMetaObject; +#if QT_CONFIG(easingcurve) case QMetaType::QEasingCurve: return &QQmlEasingValueType::staticMetaObject; +#endif #if QT_CONFIG(qml_itemmodel) case QMetaType::QModelIndex: return &QQmlModelIndexValueType::staticMetaObject; @@ -214,7 +216,9 @@ const QMetaObject *QQmlValueTypeFactory::metaObjectForMetaType(int type) void QQmlValueTypeFactory::registerValueTypes(const char *uri, int versionMajor, int versionMinor) { +#if QT_CONFIG(easingcurve) qmlRegisterValueTypeEnums<QQmlEasingValueType>(uri, versionMajor, versionMinor, "Easing"); +#endif } QQmlValueType::QQmlValueType(int typeId, const QMetaObject *gadgetMetaObject) @@ -527,6 +531,7 @@ int QQmlRectValueType::bottom() const return v.bottom(); } +#if QT_CONFIG(easingcurve) QQmlEasingValueType::Type QQmlEasingValueType::type() const { return (QQmlEasingValueType::Type)v.type(); @@ -620,6 +625,8 @@ QVariantList QQmlEasingValueType::bezierCurve() const rv << QVariant(point.x()) << QVariant(point.y()); return rv; } +#endif // easingcurve + QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlvaluetype_p.h b/src/qml/qml/qqmlvaluetype_p.h index 29fa999725..e716f79ae3 100644 --- a/src/qml/qml/qqmlvaluetype_p.h +++ b/src/qml/qml/qqmlvaluetype_p.h @@ -60,7 +60,9 @@ #include <QtCore/qobject.h> #include <QtCore/qrect.h> +#if QT_CONFIG(easingcurve) #include <QtCore/qeasingcurve.h> +#endif #include <QtCore/qvariant.h> QT_BEGIN_NAMESPACE @@ -238,11 +240,13 @@ public: int bottom() const; }; +#if QT_CONFIG(easingcurve) struct QQmlEasingValueType { QEasingCurve v; Q_GADGET QML_NAMED_ELEMENT(Easing) + QML_ADDED_IN_VERSION(2, 0) QML_UNCREATABLE("Use the Type enum.") Q_PROPERTY(QQmlEasingValueType::Type type READ type WRITE setType FINAL) @@ -290,6 +294,7 @@ public: void setBezierCurve(const QVariantList &); QVariantList bezierCurve() const; }; +#endif struct QQmlPropertyValueType { @@ -316,7 +321,7 @@ int qmlRegisterValueTypeEnums(const char *uri, int versionMajor, int versionMino QString(), - uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + uri, QTypeRevision::fromVersion(versionMajor, versionMinor), qmlName, &T::staticMetaObject, nullptr, nullptr, @@ -325,7 +330,7 @@ int qmlRegisterValueTypeEnums(const char *uri, int versionMajor, int versionMino nullptr, nullptr, nullptr, - 0 + QTypeRevision::zero() }; return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index c820499703..c23542dd44 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -1203,25 +1203,15 @@ void QQmlXMLHttpRequest::requestFromUrl(const QUrl &url) if (m_method == QLatin1String("PUT")) { if (!xhrFileWrite()) { - if (qEnvironmentVariableIsSet("QML_XHR_ALLOW_FILE_WRITE")) { - qWarning("XMLHttpRequest: Tried to use PUT on a local file despite being disabled."); - return; - } else { - qWarning("XMLHttpRequest: Using PUT on a local file is dangerous " - "and will be disabled by default in a future Qt version." - "Set QML_XHR_ALLOW_FILE_WRITE to 1 if you wish to continue using this feature."); - } + qWarning("XMLHttpRequest: Using PUT on a local file is disabled by default.\n" + "Set QML_XHR_ALLOW_FILE_WRITE to 1 to enable this feature."); + return; } } else if (m_method == QLatin1String("GET")) { if (!xhrFileRead()) { - if (qEnvironmentVariableIsSet("QML_XHR_ALLOW_FILE_READ")) { - qWarning("XMLHttpRequest: Tried to use GET on a local file despite being disabled."); - return; - } else { - qWarning("XMLHttpRequest: Using GET on a local file is dangerous " - "and will be disabled by default in a future Qt version." - "Set QML_XHR_ALLOW_FILE_READ to 1 if you wish to continue using this feature."); - } + qWarning("XMLHttpRequest: Using GET on a local file is disabled by default.\n" + "Set QML_XHR_ALLOW_FILE_READ to 1 to enable this feature."); + return; } } else { qWarning("XMLHttpRequest: Unsupported method used on a local file"); diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 02628a9810..f4e529f2de 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -93,12 +93,6 @@ DEFINE_OBJECT_VTABLE(QtObject); return scope.engine->throwTypeError(QString::fromUtf8(msg)); \ } while (false) -struct StaticQtMetaObject : public QObject -{ - static const QMetaObject *get() - { return &staticQtMetaObject; } -}; - void Heap::QtObject::init(QQmlEngine *qmlEngine) { Heap::Object::init(); @@ -177,7 +171,7 @@ ReturnedValue QtObject::findAndAdd(const QString *name, bool &foundProperty) con ScopedString key(scope); ScopedValue value(scope); - const QMetaObject *qtMetaObject = StaticQtMetaObject::get(); + const QMetaObject *qtMetaObject = &Qt::staticMetaObject; for (int enumCount = qtMetaObject->enumeratorCount(); d()->enumeratorIterator < enumCount; ++d()->enumeratorIterator) { QMetaEnum enumerator = qtMetaObject->enumerator(d()->enumeratorIterator); diff --git a/src/qml/qmldirparser/qqmldirparser.cpp b/src/qml/qmldirparser/qqmldirparser.cpp index 36b47a3302..8d20490d5e 100644 --- a/src/qml/qmldirparser/qqmldirparser.cpp +++ b/src/qml/qmldirparser/qqmldirparser.cpp @@ -60,17 +60,17 @@ static int parseInt(const QStringRef &str, bool *ok) return number; } -static bool parseVersion(const QString &str, int *major, int *minor) +static QTypeRevision parseVersion(const QString &str) { const int dotIndex = str.indexOf(QLatin1Char('.')); if (dotIndex != -1 && str.indexOf(QLatin1Char('.'), dotIndex + 1) == -1) { bool ok = false; - *major = parseInt(QStringRef(&str, 0, dotIndex), &ok); - if (ok) - *minor = parseInt(QStringRef(&str, dotIndex + 1, str.length() - dotIndex - 1), &ok); - return ok; + const int major = parseInt(QStringRef(&str, 0, dotIndex), &ok); + if (!ok) return QTypeRevision(); + const int minor = parseInt(QStringRef(&str, dotIndex + 1, str.length() - dotIndex - 1), &ok); + return ok ? QTypeRevision::fromVersion(major, minor) : QTypeRevision(); } - return false; + return QTypeRevision(); } void QQmlDirParser::clear() @@ -203,7 +203,7 @@ bool QQmlDirParser::parse(const QString &source) QStringLiteral("internal types require 2 arguments, but %1 were provided").arg(sectionCount - 1)); continue; } - Component entry(sections[1], sections[2], -1, -1); + Component entry(sections[1], sections[2], QTypeRevision()); entry.internal = true; _components.insert(entry.typeName, entry); } else if (sections[0] == QLatin1String("singleton")) { @@ -214,16 +214,16 @@ bool QQmlDirParser::parse(const QString &source) } else if (sectionCount == 3) { // handle qmldir directory listing case where singleton is defined in the following pattern: // singleton TestSingletonType TestSingletonType.qml - Component entry(sections[1], sections[2], -1, -1); + Component entry(sections[1], sections[2], QTypeRevision()); entry.singleton = true; _components.insert(entry.typeName, entry); } else { // handle qmldir module listing case where singleton is defined in the following pattern: // singleton TestSingletonType 2.0 TestSingletonType20.qml - int major, minor; - if (parseVersion(sections[2], &major, &minor)) { + const QTypeRevision version = parseVersion(sections[2]); + if (version.isValid()) { const QString &fileName = sections[3]; - Component entry(sections[1], fileName, major, minor); + Component entry(sections[1], fileName, version); entry.singleton = true; _components.insert(entry.typeName, entry); } else { @@ -253,9 +253,9 @@ bool QQmlDirParser::parse(const QString &source) continue; } - int major, minor; - if (parseVersion(sections[2], &major, &minor)) { - Component entry(sections[1], QString(), major, minor); + const QTypeRevision version = parseVersion(sections[2]); + if (version.isValid()) { + Component entry(sections[1], QString(), version); entry.internal = true; _dependencies.insert(entry.typeName, entry); } else { @@ -270,19 +270,19 @@ bool QQmlDirParser::parse(const QString &source) _imports << sections[1]; } else if (sectionCount == 2) { // No version specified (should only be used for relative qmldir files) - const Component entry(sections[0], sections[1], -1, -1); + const Component entry(sections[0], sections[1], QTypeRevision()); _components.insert(entry.typeName, entry); } else if (sectionCount == 3) { - int major, minor; - if (parseVersion(sections[1], &major, &minor)) { + const QTypeRevision version = parseVersion(sections[1]); + if (version.isValid()) { const QString &fileName = sections[2]; if (fileName.endsWith(QLatin1String(".js")) || fileName.endsWith(QLatin1String(".mjs"))) { // A 'js' extension indicates a namespaced script import - const Script entry(sections[0], fileName, major, minor); + const Script entry(sections[0], fileName, version); _scripts.append(entry); } else { - const Component entry(sections[0], fileName, major, minor); + const Component entry(sections[0], fileName, version); _components.insert(entry.typeName, entry); } } else { @@ -387,15 +387,17 @@ QString QQmlDirParser::className() const QDebug &operator<< (QDebug &debug, const QQmlDirParser::Component &component) { - const QString output = QStringLiteral("{%1 %2.%3}"). - arg(component.typeName).arg(component.majorVersion).arg(component.minorVersion); + const QString output = QStringLiteral("{%1 %2.%3}") + .arg(component.typeName).arg(component.version.majorVersion()) + .arg(component.version.minorVersion()); return debug << qPrintable(output); } QDebug &operator<< (QDebug &debug, const QQmlDirParser::Script &script) { - const QString output = QStringLiteral("{%1 %2.%3}"). - arg(script.nameSpace).arg(script.majorVersion).arg(script.minorVersion); + const QString output = QStringLiteral("{%1 %2.%3}") + .arg(script.nameSpace).arg(script.version.majorVersion()) + .arg(script.version.minorVersion()); return debug << qPrintable(output); } diff --git a/src/qml/qmldirparser/qqmldirparser_p.h b/src/qml/qmldirparser/qqmldirparser_p.h index 3696a1aa12..ccdac8f484 100644 --- a/src/qml/qmldirparser/qqmldirparser_p.h +++ b/src/qml/qmldirparser/qqmldirparser_p.h @@ -54,6 +54,7 @@ #include <QtCore/QUrl> #include <QtCore/QHash> #include <QtCore/QDebug> +#include <QtCore/QTypeRevision> #include <private/qtqmlcompilerglobal_p.h> #include <private/qqmljsengine_p.h> #include <private/qqmljsdiagnosticmessage_p.h> @@ -101,8 +102,8 @@ public: { Component() = default; - Component(const QString &typeName, const QString &fileName, int majorVersion, int minorVersion) - : typeName(typeName), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion), + Component(const QString &typeName, const QString &fileName, QTypeRevision version) + : typeName(typeName), fileName(fileName), version(version), internal(false), singleton(false) { checkNonRelative("Component", typeName, fileName); @@ -110,8 +111,7 @@ public: QString typeName; QString fileName; - int majorVersion = 0; - int minorVersion = 0; + QTypeRevision version = QTypeRevision::zero(); bool internal = false; bool singleton = false; }; @@ -120,16 +120,15 @@ public: { Script() = default; - Script(const QString &nameSpace, const QString &fileName, int majorVersion, int minorVersion) - : nameSpace(nameSpace), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion) + Script(const QString &nameSpace, const QString &fileName, QTypeRevision version) + : nameSpace(nameSpace), fileName(fileName), version(version) { checkNonRelative("Script", nameSpace, fileName); } QString nameSpace; QString fileName; - int majorVersion = 0; - int minorVersion = 0; + QTypeRevision version = QTypeRevision::zero(); }; QMultiHash<QString,Component> components() const; diff --git a/src/qml/types/qqmlbind.cpp b/src/qml/types/qqmlbind.cpp index 6d6553259e..6d762401d0 100644 --- a/src/qml/types/qqmlbind.cpp +++ b/src/qml/types/qqmlbind.cpp @@ -73,8 +73,7 @@ public: , delayed(false) , pendingEval(false) , restoreBinding(true) - , restoreValue(false) - , restoreModeExplicit(false) + , restoreValue(true) , writingProperty(false) {} ~QQmlBindPrivate() { } @@ -93,7 +92,6 @@ public: bool pendingEval:1; bool restoreBinding:1; bool restoreValue:1; - bool restoreModeExplicit:1; bool writingProperty: 1; void validate(QObject *binding) const; @@ -196,13 +194,8 @@ QQmlBind::~QQmlBind() } \endcode - When the binding becomes inactive again, any direct bindings that were previously - set on the property will be restored. - - \note By default, a previously set literal value is not restored when the Binding becomes - inactive. Rather, the last value set by the now inactive Binding is retained. You can customize - the restoration behavior for literal values as well as bindings using the \l restoreMode - property. The default will change in Qt 6.0. + By default, any binding or value that was set perviously is restored when the binding becomes + inactive. You can customize the restoration behavior using the \l restoreMode property. \sa restoreMode */ @@ -371,8 +364,7 @@ void QQmlBind::setDelayed(bool delayed) \li Binding.RestoreBindingOrValue The original value is always restored. \endlist - \warning The default value is Binding.RestoreBinding. This will change in - Qt 6.0 to Binding.RestoreBindingOrValue. + The default value is \c Binding.RestoreBindingOrValue. If you rely on any specific behavior regarding the restoration of plain values when bindings get disabled you should migrate to explicitly set the @@ -395,7 +387,6 @@ QQmlBind::RestorationMode QQmlBind::restoreMode() const void QQmlBind::setRestoreMode(RestorationMode newMode) { Q_D(QQmlBind); - d->restoreModeExplicit = true; if (newMode != restoreMode()) { d->restoreValue = (newMode & RestoreValue); d->restoreBinding = (newMode & RestoreBinding); @@ -482,27 +473,11 @@ void QQmlBind::eval() Q_ASSERT(vmemo); vmemo->setVMEProperty(propPriv->core.coreIndex(), *d->v4Value.valueRef()); d->clearPrev(); - } else if (!d->restoreModeExplicit) { - qmlWarning(this) - << "Not restoring previous value because restoreMode has not been set.\n" - << "This behavior is deprecated.\n" - << "You have to import QtQml 2.15 after any QtQuick imports and set\n" - << "the restoreMode of the binding to fix this warning.\n" - << "In Qt < 6.0 the default is Binding.RestoreBinding.\n" - << "In Qt >= 6.0 the default is Binding.RestoreBindingOrValue."; } } else if (d->prevIsVariant) { if (d->restoreValue) { d->prop.write(d->prevValue); d->clearPrev(); - } else if (!d->restoreModeExplicit) { - qmlWarning(this) - << "Not restoring previous value because restoreMode has not been set.\n" - << "This behavior is deprecated.\n" - << "You have to import QtQml 2.15 after any QtQuick imports and set\n" - << "the restoreMode of the binding to fix this warning.\n" - << "In Qt < 6.0 the default is Binding.RestoreBinding.\n" - << "In Qt >= 6.0 the default is Binding.RestoreBindingOrValue.\n"; } } return; diff --git a/src/qml/types/qqmlbind_p.h b/src/qml/types/qqmlbind_p.h index c709224c23..052af0d167 100644 --- a/src/qml/types/qqmlbind_p.h +++ b/src/qml/types/qqmlbind_p.h @@ -77,11 +77,12 @@ private: Q_PROPERTY(QString property READ property WRITE setProperty) Q_PROPERTY(QJSValue value READ value WRITE setValue) Q_PROPERTY(bool when READ when WRITE setWhen) - Q_PROPERTY(bool delayed READ delayed WRITE setDelayed REVISION 8) + Q_PROPERTY(bool delayed READ delayed WRITE setDelayed REVISION(2, 8)) Q_PROPERTY(RestorationMode restoreMode READ restoreMode WRITE setRestoreMode - NOTIFY restoreModeChanged REVISION 14) + NOTIFY restoreModeChanged REVISION(2, 14)) Q_ENUM(RestorationMode) QML_NAMED_ELEMENT(Binding) + QML_ADDED_IN_VERSION(2, 0) public: QQmlBind(QObject *parent=nullptr); diff --git a/src/qml/types/qqmlconnections_p.h b/src/qml/types/qqmlconnections_p.h index 7bf688cf75..8ed874d9fc 100644 --- a/src/qml/types/qqmlconnections_p.h +++ b/src/qml/types/qqmlconnections_p.h @@ -69,9 +69,10 @@ class Q_AUTOTEST_EXPORT QQmlConnections : public QObject, public QQmlParserStatu Q_INTERFACES(QQmlParserStatus) Q_PROPERTY(QObject *target READ target WRITE setTarget NOTIFY targetChanged) - Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged REVISION 3) + Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged REVISION(2, 3)) Q_PROPERTY(bool ignoreUnknownSignals READ ignoreUnknownSignals WRITE setIgnoreUnknownSignals) QML_NAMED_ELEMENT(Connections) + QML_ADDED_IN_VERSION(2, 0) public: QQmlConnections(QObject *parent=nullptr); @@ -88,7 +89,7 @@ public: Q_SIGNALS: void targetChanged(); - Q_REVISION(3) void enabledChanged(); + Q_REVISION(2, 3) void enabledChanged(); private: void connectSignals(); diff --git a/src/qml/types/qqmltimer_p.h b/src/qml/types/qqmltimer_p.h index 0cd93e4659..a8236977c4 100644 --- a/src/qml/types/qqmltimer_p.h +++ b/src/qml/types/qqmltimer_p.h @@ -73,6 +73,7 @@ class Q_QML_PRIVATE_EXPORT QQmlTimer : public QObject, public QQmlParserStatus Q_PROPERTY(bool triggeredOnStart READ triggeredOnStart WRITE setTriggeredOnStart NOTIFY triggeredOnStartChanged) Q_PROPERTY(QObject *parent READ parent CONSTANT) QML_NAMED_ELEMENT(Timer) + QML_ADDED_IN_VERSION(2, 0) public: QQmlTimer(QObject *parent=nullptr); diff --git a/src/qmldebug/qqmldebugconnection.cpp b/src/qmldebug/qqmldebugconnection.cpp index 4e087ee6db..15c56fc20d 100644 --- a/src/qmldebug/qqmldebugconnection.cpp +++ b/src/qmldebug/qqmldebugconnection.cpp @@ -205,14 +205,14 @@ void QQmlDebugConnection::protocolReadyRead() QHash<QString, QQmlDebugClient *>::Iterator iter = d->plugins.begin(); for (; iter != d->plugins.end(); ++iter) { - const QString pluginName = iter.key(); - QQmlDebugClient::State newSate = QQmlDebugClient::Unavailable; + const QString &pluginName = iter.key(); + QQmlDebugClient::State newState = QQmlDebugClient::Unavailable; if (d->serverPlugins.contains(pluginName)) - newSate = QQmlDebugClient::Enabled; + newState = QQmlDebugClient::Enabled; if (oldServerPlugins.contains(pluginName) != d->serverPlugins.contains(pluginName)) { - iter.value()->stateChanged(newSate); + iter.value()->stateChanged(newState); } } } else { @@ -223,9 +223,10 @@ void QQmlDebugConnection::protocolReadyRead() if (iter == d->plugins.end()) { // We can get more messages for plugins we have removed because it takes time to // send the advertisement message but the removal is instant locally. - if (!d->removedPlugins.contains(name)) + if (!d->removedPlugins.contains(name)) { qWarning() << "QQmlDebugConnection: Message received for missing plugin" << name; + } } else { QQmlDebugClient *client = *iter; QByteArray message; @@ -307,7 +308,7 @@ void QQmlDebugConnection::close() bool QQmlDebugConnection::waitForConnected(int msecs) { Q_D(QQmlDebugConnection); - QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(d->device); + auto socket = qobject_cast<QAbstractSocket*>(d->device); if (!socket) { if (!d->server || (!d->server->hasPendingConnections() && !d->server->waitForNewConnection(msecs))) @@ -324,7 +325,7 @@ bool QQmlDebugConnection::waitForConnected(int msecs) QQmlDebugClient *QQmlDebugConnection::client(const QString &name) const { Q_D(const QQmlDebugConnection); - return d->plugins.value(name, 0); + return d->plugins.value(name, nullptr); } bool QQmlDebugConnection::addClient(const QString &name, QQmlDebugClient *client) @@ -371,9 +372,9 @@ bool QQmlDebugConnection::sendMessage(const QString &name, const QByteArray &mes void QQmlDebugConnectionPrivate::flush() { - if (QAbstractSocket *socket = qobject_cast<QAbstractSocket *>(device)) + if (auto socket = qobject_cast<QAbstractSocket *>(device)) socket->flush(); - else if (QLocalSocket *socket = qobject_cast<QLocalSocket *>(device)) + else if (auto socket = qobject_cast<QLocalSocket *>(device)) socket->flush(); } @@ -382,7 +383,7 @@ void QQmlDebugConnection::connectToHost(const QString &hostName, quint16 port) Q_D(QQmlDebugConnection); if (d->gotHello) close(); - QTcpSocket *socket = new QTcpSocket(this); + auto socket = new QTcpSocket(this); d->device = socket; d->createProtocol(); connect(socket, &QAbstractSocket::disconnected, this, &QQmlDebugConnection::socketDisconnected); @@ -430,8 +431,8 @@ public: } signals: - void socketError(QAbstractSocket::SocketError error); - void socketStateChanged(QAbstractSocket::SocketState state); + void socketError(QAbstractSocket::SocketError); + void socketStateChanged(QAbstractSocket::SocketState); }; void QQmlDebugConnection::newConnection() @@ -443,7 +444,7 @@ void QQmlDebugConnection::newConnection() d->device = socket; d->createProtocol(); connect(socket, &QLocalSocket::disconnected, this, &QQmlDebugConnection::socketDisconnected); - LocalSocketSignalTranslator *translator = new LocalSocketSignalTranslator(socket); + auto translator = new LocalSocketSignalTranslator(socket); connect(translator, &LocalSocketSignalTranslator::socketError, this, &QQmlDebugConnection::socketError); diff --git a/src/qmldebug/qqmldebugconnection_p.h b/src/qmldebug/qqmldebugconnection_p.h index ad9376886c..5abdd2943b 100644 --- a/src/qmldebug/qqmldebugconnection_p.h +++ b/src/qmldebug/qqmldebugconnection_p.h @@ -61,7 +61,6 @@ class QQmlDebugConnectionPrivate; class QQmlDebugConnection : public QObject { Q_OBJECT - Q_DISABLE_COPY(QQmlDebugConnection) Q_DECLARE_PRIVATE(QQmlDebugConnection) public: QQmlDebugConnection(QObject *parent = nullptr); diff --git a/src/qmlmodels/qmlmodels.pro b/src/qmlmodels/qmlmodels.pro index 4ac093556d..34380ee14e 100644 --- a/src/qmlmodels/qmlmodels.pro +++ b/src/qmlmodels/qmlmodels.pro @@ -12,8 +12,7 @@ HEADERS += \ $$PWD/qtqmlmodelsglobal.h SOURCES += \ - $$PWD/qqmlchangeset.cpp \ - $$PWD/qqmlmodelsmodule.cpp + $$PWD/qqmlchangeset.cpp qtConfig(qml-object-model) { SOURCES += \ @@ -65,9 +64,9 @@ qtConfig(qml-delegate-model) { } QMLTYPES_FILENAME = plugins.qmltypes -QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQml/Models.2 +QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQml/Models QML_IMPORT_NAME = QtQml.Models -IMPORT_VERSION = 2.$$QT_MINOR_VERSION +QML_IMPORT_VERSION = $$QT_VERSION CONFIG += qmltypes install_qmltypes install_metatypes load(qt_module) diff --git a/src/qmlmodels/qqmlabstractdelegatecomponent_p.h b/src/qmlmodels/qqmlabstractdelegatecomponent_p.h index 07cae6b092..853a7e8af8 100644 --- a/src/qmlmodels/qqmlabstractdelegatecomponent_p.h +++ b/src/qmlmodels/qqmlabstractdelegatecomponent_p.h @@ -65,6 +65,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlAbstractDelegateComponent : public QQmlComp { Q_OBJECT QML_NAMED_ELEMENT(AbstractDelegateComponent) + QML_ADDED_IN_VERSION(2, 0) QML_UNCREATABLE("Cannot create instance of abstract class AbstractDelegateComponent.") public: diff --git a/src/qmlmodels/qqmladaptormodel.cpp b/src/qmlmodels/qqmladaptormodel.cpp index 2126ad3dc5..8c8c37d237 100644 --- a/src/qmlmodels/qqmladaptormodel.cpp +++ b/src/qmlmodels/qqmladaptormodel.cpp @@ -1035,9 +1035,9 @@ int QQmlAdaptorModel::indexAt(int row, int column) const return column * rowCount() + row; } -void QQmlAdaptorModel::useImportVersion(int minorVersion) +void QQmlAdaptorModel::useImportVersion(QTypeRevision revision) { - modelItemRevision = minorVersion; + modelItemRevision = revision; } void QQmlAdaptorModel::objectDestroyed(QObject *) diff --git a/src/qmlmodels/qqmladaptormodel_p.h b/src/qmlmodels/qqmladaptormodel_p.h index ba54c864c6..2c90ffc1d1 100644 --- a/src/qmlmodels/qqmladaptormodel_p.h +++ b/src/qmlmodels/qqmladaptormodel_p.h @@ -115,7 +115,7 @@ public: QPersistentModelIndex rootIndex; QQmlListAccessor list; - int modelItemRevision = 0; + QTypeRevision modelItemRevision = QTypeRevision::zero(); QQmlAdaptorModel(); ~QQmlAdaptorModel(); @@ -132,7 +132,7 @@ public: int columnAt(int index) const; int indexAt(int row, int column) const; - void useImportVersion(int minorVersion); + void useImportVersion(QTypeRevision revision); inline bool adaptsAim() const { return qobject_cast<QAbstractItemModel *>(object()); } inline QAbstractItemModel *aim() { return static_cast<QAbstractItemModel *>(object()); } diff --git a/src/qmlmodels/qqmldelegatemodel_p.h b/src/qmlmodels/qqmldelegatemodel_p.h index 8aab4badca..f4578e130e 100644 --- a/src/qmlmodels/qqmldelegatemodel_p.h +++ b/src/qmlmodels/qqmldelegatemodel_p.h @@ -86,7 +86,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlDelegateModel : public QQmlInstanceModel, p Q_PROPERTY(QVariant rootIndex READ rootIndex WRITE setRootIndex NOTIFY rootIndexChanged) Q_CLASSINFO("DefaultProperty", "delegate") QML_NAMED_ELEMENT(DelegateModel) - QML_ADDED_IN_MINOR_VERSION(1) + QML_ADDED_IN_VERSION(2, 1) QML_ATTACHED(QQmlDelegateModelAttached) Q_INTERFACES(QQmlParserStatus) @@ -172,7 +172,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlDelegateModelGroup : public QObject Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) Q_PROPERTY(bool includeByDefault READ defaultInclude WRITE setDefaultInclude NOTIFY defaultIncludeChanged) QML_NAMED_ELEMENT(DelegateModelGroup) - QML_ADDED_IN_MINOR_VERSION(1) + QML_ADDED_IN_VERSION(2, 1) public: QQmlDelegateModelGroup(QObject *parent = nullptr); QQmlDelegateModelGroup(const QString &name, QQmlDelegateModel *model, int compositorType, QObject *parent = nullptr); diff --git a/src/qmlmodels/qqmldelegatemodel_p_p.h b/src/qmlmodels/qqmldelegatemodel_p_p.h index 40c6bcdb21..8684439508 100644 --- a/src/qmlmodels/qqmldelegatemodel_p_p.h +++ b/src/qmlmodels/qqmldelegatemodel_p_p.h @@ -100,8 +100,8 @@ class QQmlDelegateModelItem : public QObject { Q_OBJECT Q_PROPERTY(int index READ modelIndex NOTIFY modelIndexChanged) - Q_PROPERTY(int row READ modelRow NOTIFY rowChanged REVISION 12) - Q_PROPERTY(int column READ modelColumn NOTIFY columnChanged REVISION 12) + Q_PROPERTY(int row READ modelRow NOTIFY rowChanged REVISION(2, 12)) + Q_PROPERTY(int column READ modelColumn NOTIFY columnChanged REVISION(2, 12)) Q_PROPERTY(QObject *model READ modelObject CONSTANT) public: QQmlDelegateModelItem(const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType, @@ -162,8 +162,8 @@ public: Q_SIGNALS: void modelIndexChanged(); - Q_REVISION(12) void rowChanged(); - Q_REVISION(12) void columnChanged(); + Q_REVISION(2, 12) void rowChanged(); + Q_REVISION(2, 12) void columnChanged(); protected: void objectDestroyed(QObject *); diff --git a/src/qmlmodels/qqmlinstantiator_p.h b/src/qmlmodels/qqmlinstantiator_p.h index 60b611128d..fec5c3888a 100644 --- a/src/qmlmodels/qqmlinstantiator_p.h +++ b/src/qmlmodels/qqmlinstantiator_p.h @@ -73,7 +73,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlInstantiator : public QObject, public QQmlP Q_PROPERTY(QObject *object READ object NOTIFY objectChanged) Q_CLASSINFO("DefaultProperty", "delegate") QML_NAMED_ELEMENT(Instantiator) - QML_ADDED_IN_MINOR_VERSION(14) + QML_ADDED_IN_VERSION(2, 1) public: QQmlInstantiator(QObject *parent = nullptr); diff --git a/src/qmlmodels/qqmllistmodel.cpp b/src/qmlmodels/qqmllistmodel.cpp index e07951cab3..e58fc19178 100644 --- a/src/qmlmodels/qqmllistmodel.cpp +++ b/src/qmlmodels/qqmllistmodel.cpp @@ -271,19 +271,6 @@ const ListLayout::Role *ListLayout::getExistingRole(QV4::String *key) const return r; } -StringOrTranslation::StringOrTranslation(const QString &s) -{ - d.setFlag(); - setString(s); -} - -StringOrTranslation::StringOrTranslation(const QV4::CompiledData::Binding *binding) -{ - d.setFlag(); - clear(); - d = binding; -} - StringOrTranslation::~StringOrTranslation() { clear(); @@ -291,53 +278,48 @@ StringOrTranslation::~StringOrTranslation() void StringOrTranslation::setString(const QString &s) { - d.setFlag(); clear(); - QStringData *stringData = const_cast<QString &>(s).data_ptr(); - d = stringData; - if (stringData) - stringData->ref.ref(); + QString mutableString(s); + QString::DataPointer dataPointer = mutableString.data_ptr(); + arrayData = dataPointer->d_ptr(); + stringData = dataPointer->data(); + stringSize = mutableString.length(); + arrayData->ref(); } void StringOrTranslation::setTranslation(const QV4::CompiledData::Binding *binding) { - d.setFlag(); clear(); - d = binding; + this->binding = binding; } QString StringOrTranslation::toString(const QQmlListModel *owner) const { - if (d.isNull()) - return QString(); - if (d.isT1()) { - QStringDataPtr holder = { d.asT1() }; - holder.ptr->ref.ref(); - return QString(holder); + if (arrayData) { + arrayData->ref(); + return QString(QStringPrivate(arrayData, stringData, stringSize)); } if (!owner) return QString(); - return owner->m_compilationUnit->bindingValueAsString(d.asT2()); + return owner->m_compilationUnit->bindingValueAsString(binding); } QString StringOrTranslation::asString() const { - if (d.isNull()) + if (!arrayData) return QString(); - if (!d.isT1()) - return QString(); - QStringDataPtr holder = { d.asT1() }; - holder.ptr->ref.ref(); - return QString(holder); + arrayData->ref(); + return QString(QStringPrivate(arrayData, stringData, stringSize)); } void StringOrTranslation::clear() { - if (QStringData *strData = d.isT1() ? d.asT1() : nullptr) { - if (!strData->ref.deref()) - QStringData::deallocate(strData); - } - d = static_cast<QStringData *>(nullptr); + if (arrayData && !arrayData->deref()) + QTypedArrayData<ushort>::deallocate(arrayData); + arrayData = nullptr; + stringData = nullptr; + stringSize = 0; + binding = nullptr; } QObject *ListModel::getOrCreateModelObject(QQmlListModel *model, int elementIndex) @@ -1150,7 +1132,7 @@ int ListElement::setTranslationProperty(const ListLayout::Role &role, const QV4: void ListElement::setStringPropertyFast(const ListLayout::Role &role, const QString &s) { char *mem = getPropertyMemory(role); - new (mem) StringOrTranslation(s); + reinterpret_cast<StringOrTranslation *>(mem)->setString(s); } void ListElement::setDoublePropertyFast(const ListLayout::Role &role, double d) diff --git a/src/qmlmodels/qqmllistmodel_p.h b/src/qmlmodels/qqmllistmodel_p.h index 9a4358ac6f..bf4279cd05 100644 --- a/src/qmlmodels/qqmllistmodel_p.h +++ b/src/qmlmodels/qqmllistmodel_p.h @@ -82,9 +82,9 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlListModel : public QAbstractListModel Q_OBJECT Q_PROPERTY(int count READ count NOTIFY countChanged) Q_PROPERTY(bool dynamicRoles READ dynamicRoles WRITE setDynamicRoles) - Q_PROPERTY(QObject *agent READ agent CONSTANT REVISION(14)) + Q_PROPERTY(QObject *agent READ agent CONSTANT REVISION(2, 14)) QML_NAMED_ELEMENT(ListModel) - QML_ADDED_IN_MINOR_VERSION(1) + QML_ADDED_IN_VERSION(2, 0) public: QQmlListModel(QObject *parent=nullptr); @@ -175,7 +175,7 @@ class QQmlListElement : public QObject { Q_OBJECT QML_NAMED_ELEMENT(ListElement) - QML_ADDED_IN_MINOR_VERSION(1) + QML_ADDED_IN_VERSION(2, 0) }; class QQmlListModelParser : public QQmlCustomParser diff --git a/src/qmlmodels/qqmllistmodel_p_p.h b/src/qmlmodels/qqmllistmodel_p_p.h index 2ad5158050..f17004ed3b 100644 --- a/src/qmlmodels/qqmllistmodel_p_p.h +++ b/src/qmlmodels/qqmllistmodel_p_p.h @@ -252,18 +252,23 @@ private: struct StringOrTranslation { - explicit StringOrTranslation(const QString &s); - explicit StringOrTranslation(const QV4::CompiledData::Binding *binding); ~StringOrTranslation(); - bool isSet() const { return d.flag(); } - bool isTranslation() const { return d.isT2(); } + bool isSet() const { return binding || arrayData; } + bool isTranslation() const { return binding && !arrayData; } void setString(const QString &s); void setTranslation(const QV4::CompiledData::Binding *binding); QString toString(const QQmlListModel *owner) const; QString asString() const; private: void clear(); - QBiPointer<QStringData, const QV4::CompiledData::Binding> d; + + union { + ushort *stringData = nullptr; + const QV4::CompiledData::Binding *binding; + }; + + QTypedArrayData<ushort> *arrayData = nullptr; + uint stringSize = 0; }; /*! diff --git a/src/qmlmodels/qqmllistmodelworkeragent_p.h b/src/qmlmodels/qqmllistmodelworkeragent_p.h index f65909dcec..1700ff755f 100644 --- a/src/qmlmodels/qqmllistmodelworkeragent_p.h +++ b/src/qmlmodels/qqmllistmodelworkeragent_p.h @@ -73,6 +73,7 @@ class QQmlListModelWorkerAgent : public QObject Q_PROPERTY(int count READ count) Q_PROPERTY(QV4::ExecutionEngine *engine READ engine WRITE setEngine NOTIFY engineChanged) QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: QQmlListModelWorkerAgent(QQmlListModel *); diff --git a/src/qmlmodels/qqmlmodelsmodule.cpp b/src/qmlmodels/qqmlmodelsmodule.cpp deleted file mode 100644 index 155ded6c65..0000000000 --- a/src/qmlmodels/qqmlmodelsmodule.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qqmlmodelsmodule_p.h" -#include <private/qtqmlmodelsglobal_p.h> - -#if QT_CONFIG(qml_list_model) -#include <private/qqmllistmodel_p.h> -#include <private/qqmllistmodelworkeragent_p.h> -#endif -#if QT_CONFIG(qml_delegate_model) -#include <private/qqmlabstractdelegatecomponent_p.h> -#include <private/qqmldelegatemodel_p.h> -#include <private/qquickpackage_p.h> -#include <private/qqmlcomponentattached_p.h> -#endif -#if QT_CONFIG(qml_object_model) -#include <private/qqmlobjectmodel_p.h> -#include <private/qqmlinstantiator_p.h> -#endif - -QT_BEGIN_NAMESPACE - -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - -void QQmlModelsModule::registerQmlTypes() -{ - // Don't add anything here. These are only for backwards compatibility. - // Don't convert these to qmlRegisterTypesAndRevisions! - // -> the annotations in the headers are for the QtQml.Models module <- -#if QT_CONFIG(qml_object_model) - qmlRegisterType<QQmlInstantiator>("QtQml", 2, 1, "Instantiator"); // Only available in >= 2.1 - qmlRegisterAnonymousType<QQmlInstanceModel>("QtQml", 2); -#endif -} - -void QQmlModelsModule::registerQuickTypes() -{ - // Don't add anything here. These are only for backwards compatibility. - // Don't convert these to qmlRegisterTypesAndRevisions! - // -> the annotations in the headers are for the QtQml.Models module <- - - const char uri[] = "QtQuick"; - -#if QT_CONFIG(qml_object_model) - qmlRegisterType<QQmlInstantiator>(uri, 2, 1, "Instantiator"); - qmlRegisterAnonymousType<QQmlInstanceModel>(uri, 2); - qmlRegisterType<QQmlObjectModel>(uri, 2, 0, "VisualItemModel"); -#endif -#if QT_CONFIG(qml_list_model) - qmlRegisterType<QQmlListElement>(uri, 2, 0, "ListElement"); - qmlRegisterCustomType<QQmlListModel>(uri, 2, 0, "ListModel", new QQmlListModelParser); -#endif -#if QT_CONFIG(qml_delegate_model) - qmlRegisterType<QQmlDelegateModel>(uri, 2, 0, "VisualDataModel"); - qmlRegisterType<QQmlDelegateModelGroup>(uri, 2, 0, "VisualDataGroup"); - qmlRegisterType<QQuickPackage>(uri, 2, 0, "Package"); -#endif -} - -#endif // QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - -QT_END_NAMESPACE diff --git a/src/qmlmodels/qqmlmodelsmodule_p.h b/src/qmlmodels/qqmlmodelsmodule_p.h index feed0f88fe..70268f53f2 100644 --- a/src/qmlmodels/qqmlmodelsmodule_p.h +++ b/src/qmlmodels/qqmlmodelsmodule_p.h @@ -61,22 +61,13 @@ QT_BEGIN_NAMESPACE -class Q_QMLMODELS_PRIVATE_EXPORT QQmlModelsModule -{ -public: -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - static void registerQmlTypes(); - static void registerQuickTypes(); -#endif -}; - #if QT_CONFIG(itemmodel) struct QItemSelectionModelForeign { Q_GADGET QML_FOREIGN(QItemSelectionModel) QML_NAMED_ELEMENT(ItemSelectionModel) - QML_ADDED_IN_MINOR_VERSION(2) + QML_ADDED_IN_VERSION(2, 2) }; #endif diff --git a/src/qmlmodels/qqmlobjectmodel.cpp b/src/qmlmodels/qqmlobjectmodel.cpp index 90469d06c2..dac868a0a2 100644 --- a/src/qmlmodels/qqmlobjectmodel.cpp +++ b/src/qmlmodels/qqmlobjectmodel.cpp @@ -175,7 +175,8 @@ public: void clear() { Q_Q(QQmlObjectModel); - for (const Item &child : qAsConst(children)) + const auto copy = children; + for (const Item &child : copy) emit q->destroyingItem(child.item); remove(0, children.count()); } @@ -191,6 +192,8 @@ public: QList<Item> children; }; +Q_DECLARE_TYPEINFO(QQmlObjectModelPrivate::Item, Q_PRIMITIVE_TYPE); + /*! \qmltype ObjectModel diff --git a/src/qmlmodels/qqmlobjectmodel_p.h b/src/qmlmodels/qqmlobjectmodel_p.h index 7fb4f64676..5b3423b480 100644 --- a/src/qmlmodels/qqmlobjectmodel_p.h +++ b/src/qmlmodels/qqmlobjectmodel_p.h @@ -70,6 +70,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlInstanceModel : public QObject Q_PROPERTY(int count READ count NOTIFY countChanged) QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: enum ReusableFlag { @@ -125,7 +126,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlObjectModel : public QQmlInstanceModel Q_PROPERTY(QQmlListProperty<QObject> children READ children NOTIFY childrenChanged DESIGNABLE false) Q_CLASSINFO("DefaultProperty", "children") QML_NAMED_ELEMENT(ObjectModel) - QML_ADDED_IN_MINOR_VERSION(1) + QML_ADDED_IN_VERSION(2, 1) QML_ATTACHED(QQmlObjectModelAttached) public: @@ -146,14 +147,14 @@ public: static QQmlObjectModelAttached *qmlAttachedProperties(QObject *obj); - Q_REVISION(3) Q_INVOKABLE QObject *get(int index) const; - Q_REVISION(3) Q_INVOKABLE void append(QObject *object); - Q_REVISION(3) Q_INVOKABLE void insert(int index, QObject *object); - Q_REVISION(3) Q_INVOKABLE void move(int from, int to, int n = 1); - Q_REVISION(3) Q_INVOKABLE void remove(int index, int n = 1); + Q_REVISION(2, 3) Q_INVOKABLE QObject *get(int index) const; + Q_REVISION(2, 3) Q_INVOKABLE void append(QObject *object); + Q_REVISION(2, 3) Q_INVOKABLE void insert(int index, QObject *object); + Q_REVISION(2, 3) Q_INVOKABLE void move(int from, int to, int n = 1); + Q_REVISION(2, 3) Q_INVOKABLE void remove(int index, int n = 1); public Q_SLOTS: - Q_REVISION(3) void clear(); + Q_REVISION(2, 3) void clear(); Q_SIGNALS: void childrenChanged(); diff --git a/src/qmlmodels/qqmltableinstancemodel.cpp b/src/qmlmodels/qqmltableinstancemodel.cpp index 29c307a47a..c1f9df3114 100644 --- a/src/qmlmodels/qqmltableinstancemodel.cpp +++ b/src/qmlmodels/qqmltableinstancemodel.cpp @@ -83,9 +83,9 @@ QQmlTableInstanceModel::QQmlTableInstanceModel(QQmlContext *qmlContext, QObject { } -void QQmlTableInstanceModel::useImportVersion(int minorVersion) +void QQmlTableInstanceModel::useImportVersion(QTypeRevision version) { - m_adaptorModel.useImportVersion(minorVersion); + m_adaptorModel.useImportVersion(version); } QQmlTableInstanceModel::~QQmlTableInstanceModel() diff --git a/src/qmlmodels/qqmltableinstancemodel_p.h b/src/qmlmodels/qqmltableinstancemodel_p.h index 06d0db06aa..80ba7ddaaf 100644 --- a/src/qmlmodels/qqmltableinstancemodel_p.h +++ b/src/qmlmodels/qqmltableinstancemodel_p.h @@ -89,7 +89,7 @@ public: QQmlTableInstanceModel(QQmlContext *qmlContext, QObject *parent = nullptr); ~QQmlTableInstanceModel() override; - void useImportVersion(int minorVersion); + void useImportVersion(QTypeRevision version); int count() const override { return m_adaptorModel.count(); } int rows() const { return m_adaptorModel.rowCount(); } diff --git a/src/qmlmodels/qquickpackage_p.h b/src/qmlmodels/qquickpackage_p.h index 97f3bab9bc..f40ffe552a 100644 --- a/src/qmlmodels/qquickpackage_p.h +++ b/src/qmlmodels/qquickpackage_p.h @@ -67,7 +67,7 @@ class Q_AUTOTEST_EXPORT QQuickPackage : public QObject Q_CLASSINFO("DefaultProperty", "data") QML_NAMED_ELEMENT(Package) - QML_ADDED_IN_MINOR_VERSION(14) + QML_ADDED_IN_VERSION(2, 0) QML_ATTACHED(QQuickPackageAttached) Q_PROPERTY(QQmlListProperty<QObject> data READ data) diff --git a/src/qmltest/quicktest.cpp b/src/qmltest/quicktest.cpp index 470b3c0f7a..96a5c20f22 100644 --- a/src/qmltest/quicktest.cpp +++ b/src/qmltest/quicktest.cpp @@ -52,7 +52,7 @@ #include <QtQml/qqmlpropertymap.h> #include <QtQuick/private/qquickitem_p.h> #include <QtQuick/qquickitem.h> -#include <QtGui/qopengl.h> +#include <qopengl.h> #include <QtCore/qurl.h> #include <QtCore/qfileinfo.h> #include <QtCore/qdir.h> diff --git a/src/qmltest/quicktestresult_p.h b/src/qmltest/quicktestresult_p.h index 81b9d78830..7ebfb21186 100644 --- a/src/qmltest/quicktestresult_p.h +++ b/src/qmltest/quicktestresult_p.h @@ -158,10 +158,10 @@ public Q_SLOTS: QObject *grabImage(QQuickItem *item); - Q_REVISION(1) QObject *findChild(QObject *parent, const QString &objectName); + Q_REVISION(1, 1) QObject *findChild(QObject *parent, const QString &objectName); - Q_REVISION(13) bool isPolishScheduled(QQuickItem *item) const; - Q_REVISION(13) bool waitForItemPolished(QQuickItem *item, int timeout); + Q_REVISION(1, 13) bool isPolishScheduled(QQuickItem *item) const; + Q_REVISION(1, 13) bool waitForItemPolished(QQuickItem *item, int timeout); public: // Helper functions for the C++ main() shell. diff --git a/src/qmltyperegistrar/qmltyperegistrar.cpp b/src/qmltyperegistrar/qmltyperegistrar.cpp index 49c9fccb66..697f96959f 100644 --- a/src/qmltyperegistrar/qmltyperegistrar.cpp +++ b/src/qmltyperegistrar/qmltyperegistrar.cpp @@ -368,8 +368,8 @@ int main(int argc, char **argv) qPrintable(module), qPrintable(majorVersion), qPrintable(parser.value(minorVersionOption))); fprintf(output, "\n}\n"); - fprintf(output, "\nstatic const QQmlModuleRegistration registration(\"%s\", %s, %s);\n", - qPrintable(module), qPrintable(majorVersion), qPrintable(functionName)); + fprintf(output, "\nstatic const QQmlModuleRegistration registration(\"%s\", %s);\n", + qPrintable(module), qPrintable(functionName)); if (!parser.isSet(pluginTypesOption)) return EXIT_SUCCESS; @@ -414,7 +414,7 @@ int main(int argc, char **argv) creator.setOwnTypes(std::move(types)); creator.setForeignTypes(std::move(foreignTypes)); creator.setModule(module); - creator.setMajorVersion(parser.value(majorVersionOption).toInt()); + creator.setVersion(QTypeRevision::fromVersion(parser.value(majorVersionOption).toInt(), 0)); creator.generate(parser.value(pluginTypesOption), parser.value(dependenciesOption)); return EXIT_SUCCESS; diff --git a/src/qmltyperegistrar/qmltypesclassdescription.cpp b/src/qmltyperegistrar/qmltypesclassdescription.cpp index 8189bcd52e..f1ec700c50 100644 --- a/src/qmltyperegistrar/qmltypesclassdescription.cpp +++ b/src/qmltyperegistrar/qmltypesclassdescription.cpp @@ -27,18 +27,19 @@ ****************************************************************************/ #include "qmltypesclassdescription.h" +#include "qmltypescreator.h" #include <QtCore/qjsonarray.h> static void collectExtraVersions(const QJsonObject *component, const QString &key, - QList<int> &extraVersions) + QList<QTypeRevision> &extraVersions) { const QJsonArray &items = component->value(key).toArray(); for (const QJsonValue &item : items) { const QJsonObject obj = item.toObject(); const auto revision = obj.find(QLatin1String("revision")); if (revision != obj.end()) { - const int extraVersion = revision.value().toInt(); + const auto extraVersion = QTypeRevision::fromEncodedVersion(revision.value().toInt()); if (!extraVersions.contains(extraVersion)) extraVersions.append(extraVersion); } @@ -60,7 +61,7 @@ const QJsonObject *QmlTypesClassDescription::findType(const QVector<QJsonObject> void QmlTypesClassDescription::collect(const QJsonObject *classDef, const QVector<QJsonObject> &types, const QVector<QJsonObject> &foreign, - bool topLevel) + bool topLevel, QTypeRevision defaultRevision) { const auto classInfos = classDef->value(QLatin1String("classInfos")).toArray(); for (const QJsonValue &classInfo : classInfos) { @@ -71,12 +72,13 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, if (name == QLatin1String("DefaultProperty")) { if (defaultProp.isEmpty()) defaultProp = value; - } else if (name == QLatin1String("QML.AddedInMinorVersion")) { + } else if (name == QLatin1String("QML.AddedInVersion")) { + const QTypeRevision revision = QTypeRevision::fromEncodedVersion(value.toInt()); if (topLevel) { - addedInRevision = value.toInt(); - revisions.append(value.toInt()); + addedInRevision = revision; + revisions.append(revision); } else if (!elementName.isEmpty()) { - revisions.append(value.toInt()); + revisions.append(revision); } } @@ -89,16 +91,16 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, elementName = classDef->value(QLatin1String("className")).toString(); else if (value != QLatin1String("anonymous")) elementName = value; - } else if (name == QLatin1String("QML.RemovedInMinorVersion")) { - removedInRevision = value.toInt(); + } else if (name == QLatin1String("QML.RemovedInVersion")) { + removedInRevision = QTypeRevision::fromEncodedVersion(value.toInt()); } else if (name == QLatin1String("QML.Creatable")) { isCreatable = (value != QLatin1String("false")); } else if (name == QLatin1String("QML.Attached")) { attachedType = value; if (const QJsonObject *other = findType(types, attachedType)) - collect(other, types, foreign, false); + collect(other, types, foreign, false, defaultRevision); else if (const QJsonObject *other = findType(foreign, attachedType)) - collect(other, types, foreign, false); + collect(other, types, foreign, false, defaultRevision); } else if (name == QLatin1String("QML.Singleton")) { if (value == QLatin1String("true")) isSingleton = true; @@ -141,19 +143,20 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, superClass = superName; if (const QJsonObject *other = findType(types, superName)) - collect(other, types, foreign, false); + collect(other, types, foreign, false, defaultRevision); else if (const QJsonObject *other = findType(foreign, superName)) - collect(other, types, foreign, false); + collect(other, types, foreign, false, defaultRevision); } } - if (addedInRevision == -1) { - revisions.append(0); - addedInRevision = 0; + if (!addedInRevision.isValid()) { + revisions.append(defaultRevision); + addedInRevision = defaultRevision; + } else if (addedInRevision < defaultRevision) { + revisions.append(defaultRevision); } - std::sort(revisions.begin(), revisions.end(), - [](int a, int b) { return QByteArray::number(a) < QByteArray::number(b); }); + std::sort(revisions.begin(), revisions.end()); const auto end = std::unique(revisions.begin(), revisions.end()); revisions.erase(end, revisions.end()); diff --git a/src/qmltyperegistrar/qmltypesclassdescription.h b/src/qmltyperegistrar/qmltypesclassdescription.h index 8f3a6ea124..6f391ba45c 100644 --- a/src/qmltyperegistrar/qmltypesclassdescription.h +++ b/src/qmltyperegistrar/qmltypesclassdescription.h @@ -33,6 +33,7 @@ #include <QtCore/qjsonobject.h> #include <QtCore/qvector.h> #include <QtCore/qset.h> +#include <QtCore/qversionnumber.h> struct QmlTypesClassDescription { @@ -41,16 +42,16 @@ struct QmlTypesClassDescription QString defaultProp; QString superClass; QString attachedType; - QList<int> revisions; - int addedInRevision = -1; - int removedInRevision = -1; + QList<QTypeRevision> revisions; + QTypeRevision addedInRevision; + QTypeRevision removedInRevision; bool isCreatable = true; bool isSingleton = false; bool isRootClass = false; bool isBuiltin = false; void collect(const QJsonObject *classDef, const QVector<QJsonObject> &types, - const QVector<QJsonObject> &foreign, bool topLevel); + const QVector<QJsonObject> &foreign, bool topLevel, QTypeRevision defaultRevision); static const QJsonObject *findType(const QVector<QJsonObject> &types, const QString &name); }; diff --git a/src/qmltyperegistrar/qmltypescreator.cpp b/src/qmltyperegistrar/qmltypescreator.cpp index 911120027e..d34740eaa0 100644 --- a/src/qmltyperegistrar/qmltypescreator.cpp +++ b/src/qmltyperegistrar/qmltypescreator.cpp @@ -35,6 +35,7 @@ #include <QtCore/qsavefile.h> #include <QtCore/qfile.h> #include <QtCore/qjsondocument.h> +#include <QtCore/qversionnumber.h> static QString enquote(const QString &string) { @@ -62,24 +63,24 @@ void QmlTypesCreator::writeClassProperties(const QmlTypesClassDescription &colle QStringList exports; QStringList metaObjects; + if (collector.isBuiltin) { + exports.append(enquote(QString::fromLatin1("QML/%1 1.0").arg(collector.elementName))); + metaObjects.append(QString::number(QTypeRevision::fromVersion(1, 0).toEncodedVersion<quint16>())); + } + for (auto it = collector.revisions.begin(), end = collector.revisions.end(); it != end; ++it) { - const int revision = *it; + const QTypeRevision revision = *it; if (revision < collector.addedInRevision) continue; - if (collector.removedInRevision > collector.addedInRevision - && revision >= collector.removedInRevision) { + if (collector.removedInRevision.isValid() && !(revision < collector.removedInRevision)) break; - } - - if (collector.isBuiltin) { - exports.append(enquote(QString::fromLatin1("QML/%1 1.0").arg(collector.elementName))); - metaObjects.append(QLatin1String("0")); - } exports.append(enquote(QString::fromLatin1("%1/%2 %3.%4") - .arg(m_module).arg(collector.elementName) - .arg(m_majorVersion).arg(revision))); - metaObjects.append(QString::number(revision)); + .arg(m_module).arg(collector.elementName) + .arg(revision.hasMajorVersion() ? revision.majorVersion() + : m_version.majorVersion()) + .arg(revision.minorVersion()))); + metaObjects.append(QString::number(revision.toEncodedVersion<quint16>())); } m_qml.writeArrayBinding(QLatin1String("exports"), exports); @@ -245,7 +246,7 @@ void QmlTypesCreator::writeComponents() m_qml.writeStartObject(componentElement); QmlTypesClassDescription collector; - collector.collect(&component, m_ownTypes, m_foreignTypes, true); + collector.collect(&component, m_ownTypes, m_foreignTypes, true, m_version); writeClassProperties(collector); diff --git a/src/qmltyperegistrar/qmltypescreator.h b/src/qmltyperegistrar/qmltypescreator.h index 9207a64b7e..808c189323 100644 --- a/src/qmltyperegistrar/qmltypescreator.h +++ b/src/qmltyperegistrar/qmltypescreator.h @@ -45,7 +45,7 @@ public: void setOwnTypes(QVector<QJsonObject> ownTypes) { m_ownTypes = std::move(ownTypes); } void setForeignTypes(QVector<QJsonObject> foreignTypes) { m_foreignTypes = std::move(foreignTypes); } void setModule(QString module) { m_module = std::move(module); } - void setMajorVersion(int majorVersion) { m_majorVersion = majorVersion; } + void setVersion(QTypeRevision version) { m_version = version; } private: void writeClassProperties(const QmlTypesClassDescription &collector); @@ -62,7 +62,7 @@ private: QVector<QJsonObject> m_ownTypes; QVector<QJsonObject> m_foreignTypes; QString m_module; - int m_majorVersion = 0; + QTypeRevision m_version = QTypeRevision::zero(); }; #endif // QMLTYPESCREATOR_H diff --git a/src/qmlworkerscript/qmlworkerscript.pro b/src/qmlworkerscript/qmlworkerscript.pro index 84466062e1..82b61ab12e 100644 --- a/src/qmlworkerscript/qmlworkerscript.pro +++ b/src/qmlworkerscript/qmlworkerscript.pro @@ -6,23 +6,21 @@ QMAKE_DOCS = $$PWD/doc/qtqmlworkerscript.qdocconf DEFINES += QT_NO_URL_CAST_FROM_STRING QT_NO_INTEGER_EVENT_COORDINATES QT_NO_FOREACH HEADERS += \ - qqmlworkerscriptmodule_p.h \ qquickworkerscript_p.h \ qtqmlworkerscriptglobal.h \ qtqmlworkerscriptglobal_p.h \ qv4serialize_p.h SOURCES += \ - qqmlworkerscriptmodule.cpp \ qquickworkerscript.cpp \ qv4serialize.cpp include(../3rdparty/masm/masm-defs.pri) QMLTYPES_FILENAME = plugins.qmltypes -QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQml/WorkerScript.2 +QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQml/WorkerScript QML_IMPORT_NAME = QtQml.WorkerScript -IMPORT_VERSION = 2.$$QT_MINOR_VERSION +QML_IMPORT_VERSION = $$QT_VERSION CONFIG += qmltypes install_qmltypes install_metatypes load(qt_module) diff --git a/src/qmlworkerscript/qqmlworkerscriptmodule.cpp b/src/qmlworkerscript/qqmlworkerscriptmodule.cpp deleted file mode 100644 index f6ad5b87e8..0000000000 --- a/src/qmlworkerscript/qqmlworkerscriptmodule.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qqmlworkerscriptmodule_p.h" -#include "qquickworkerscript_p.h" - -QT_BEGIN_NAMESPACE - -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - -void QQmlWorkerScriptModule::registerQuickTypes() -{ - // Don't add anything here. These are only for backwards compatibility. - // Also, don't convert to qmlRegisterTypesAndRevisions as that will add future revisions. - const char uri[] = "QtQuick"; - qmlRegisterType<QQuickWorkerScript>(uri, 2, 0, "WorkerScript"); -} - -#endif // QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - -QT_END_NAMESPACE diff --git a/src/qmlworkerscript/qqmlworkerscriptmodule_p.h b/src/qmlworkerscript/qqmlworkerscriptmodule_p.h deleted file mode 100644 index b7748d12a0..0000000000 --- a/src/qmlworkerscript/qqmlworkerscriptmodule_p.h +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQMLWORKERSCRIPTMODULE_P_H -#define QQMLWORKERSCRIPTMODULE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qtqmlworkerscriptglobal_p.h> - -QT_BEGIN_NAMESPACE - -class Q_QMLWORKERSCRIPT_PRIVATE_EXPORT QQmlWorkerScriptModule -{ -public: -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - static void registerQuickTypes(); -#endif -}; - -QT_END_NAMESPACE - -#endif // QQMLWORKERSCRIPTMODULE_P_H diff --git a/src/qmlworkerscript/qquickworkerscript_p.h b/src/qmlworkerscript/qquickworkerscript_p.h index 22a205cfe4..50eb8353b4 100644 --- a/src/qmlworkerscript/qquickworkerscript_p.h +++ b/src/qmlworkerscript/qquickworkerscript_p.h @@ -91,6 +91,7 @@ class Q_AUTOTEST_EXPORT QQuickWorkerScript : public QObject, public QQmlParserSt Q_PROPERTY(bool ready READ ready NOTIFY readyChanged) QML_NAMED_ELEMENT(WorkerScript); + QML_ADDED_IN_VERSION(2, 0) Q_INTERFACES(QQmlParserStatus) public: diff --git a/src/quick/configure.json b/src/quick/configure.json index 8d1ddaea7c..fbb70fe572 100644 --- a/src/quick/configure.json +++ b/src/quick/configure.json @@ -12,7 +12,6 @@ "commandline": { "options": { - "d3d12": "boolean", "quick-animatedimage": "boolean", "quick-canvas": "boolean", "quick-designer": "boolean", @@ -28,24 +27,7 @@ } }, - "tests": { - "d3d12": { - "label": "Direct3D 12", - "type": "compile", - "test": "d3d12" - } - }, - "features": { - "d3d12": { - "label": "Direct3D 12", - "purpose": "Provides a Direct3D 12 backend for the scenegraph.", - "section": "Qt Quick", - "condition": "tests.d3d12", - "output": [ - "publicFeature" - ] - }, "quick-animatedimage": { "label": "AnimatedImage item", "purpose": "Provides the AnimatedImage item.", @@ -202,7 +184,6 @@ { "section": "Qt Quick", "entries": [ - "d3d12", "quick-animatedimage", "quick-canvas", "quick-designer", diff --git a/src/quick/designer/qquickdesignersupportitems.cpp b/src/quick/designer/qquickdesignersupportitems.cpp index ed5fdf3a4a..4fd9158f4a 100644 --- a/src/quick/designer/qquickdesignersupportitems.cpp +++ b/src/quick/designer/qquickdesignersupportitems.cpp @@ -210,14 +210,14 @@ static bool isCrashingType(const QQmlType &type) return false; } -QObject *QQuickDesignerSupportItems::createPrimitive(const QString &typeName, int majorNumber, int minorNumber, QQmlContext *context) +QObject *QQuickDesignerSupportItems::createPrimitive(const QString &typeName, QTypeRevision version, QQmlContext *context) { ComponentCompleteDisabler disableComponentComplete; Q_UNUSED(disableComponentComplete) QObject *object = nullptr; - QQmlType type = QQmlMetaType::qmlType(typeName, majorNumber, minorNumber); + QQmlType type = QQmlMetaType::qmlType(typeName, version); if (isCrashingType(type)) { object = new QObject; @@ -242,7 +242,8 @@ QObject *QQuickDesignerSupportItems::createPrimitive(const QString &typeName, in if (!object) { qWarning() << "QuickDesigner: Cannot create an object of type" - << QString::fromLatin1("%1 %2,%3").arg(typeName).arg(majorNumber).arg(minorNumber) + << QString::fromLatin1("%1 %2,%3").arg(typeName) + .arg(version.majorVersion()).arg(version.minorVersion()) << "- type isn't known to declarative meta type system"; } diff --git a/src/quick/designer/qquickdesignersupportitems_p.h b/src/quick/designer/qquickdesignersupportitems_p.h index 8c5a44d9fe..93b4c529fa 100644 --- a/src/quick/designer/qquickdesignersupportitems_p.h +++ b/src/quick/designer/qquickdesignersupportitems_p.h @@ -58,6 +58,7 @@ #include <QVariant> #include <QList> #include <QByteArray> +#include <QTypeRevision> #include <QQmlContext> #include <QQmlListReference> @@ -66,7 +67,7 @@ QT_BEGIN_NAMESPACE class Q_QUICK_EXPORT QQuickDesignerSupportItems { public: - static QObject *createPrimitive(const QString &typeName, int majorNumber, int minorNumber, QQmlContext *context); + static QObject *createPrimitive(const QString &typeName, QTypeRevision version, QQmlContext *context); static QObject *createComponent(const QUrl &componentUrl, QQmlContext *context); static void tweakObjects(QObject *object); static bool objectWasDeleted(QObject *object); diff --git a/src/quick/designer/qquickdesignerwindowmanager_p.h b/src/quick/designer/qquickdesignerwindowmanager_p.h index 5e387ff5b9..ac9695953f 100644 --- a/src/quick/designer/qquickdesignerwindowmanager_p.h +++ b/src/quick/designer/qquickdesignerwindowmanager_p.h @@ -58,7 +58,7 @@ #include <private/qsgcontext_p.h> #if QT_CONFIG(opengl) -# include <QtGui/QOpenGLContext> +# include <QOpenGLContext> #endif QT_BEGIN_NAMESPACE diff --git a/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc b/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc index 88003b68d3..86292921a6 100644 --- a/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc +++ b/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc @@ -34,11 +34,10 @@ Originally, Qt Quick always relied on OpenGL (OpenGL ES 2.0 or OpenGL 2.0) to parse the scene graph and render the results to a render target -From Qt 5.8 onwards, Qt Quick also supports rendering in software, with OpenVG, -and with Direct3D 12. This is realized by having additional scene graph -adaptations, either in form of plugins (d3d12, openvg) or built-in to the Qt -Quick library (software). The default adaptation continues to rely directly on -OpenGL. +From Qt 5.8 onwards, Qt Quick also supports rendering in software, and with +OpenVG. This is realized by having additional scene graph adaptations, either +in form of plugins (openvg) or built-in to the Qt Quick library +(software). The default adaptation continues to rely directly on OpenGL. From Qt 5.14 onwards, the default adaptation gains the option of rendering via a graphics abstraction layer, the Qt Rendering Hardware Interface (RHI), @@ -52,7 +51,7 @@ appropriate for the various graphics APIs. \target Switching Between the Adaptation Used by the Application \section1 Switch Between Adaptations in Your Application -Unlike \c software or \c d3d12, the RHI-based renderer is not an additional +Unlike \c software, the RHI-based renderer is not an additional adaptation, and is always built-in. As of Qt 5.14 it can be enabled by setting the environment variable \c{QSG_RHI} to a non-zero value before starting the application, or via \l QQuickWindow::setSceneGraphBackend() in combination with @@ -75,8 +74,6 @@ The following backends are supported: different than the ones listed below. \li Software - Request with the \c{"software"} string or the QSGRendererInterface::Software enum value. - \li Direct3D 12 - Request with the \c{"d3d12"} string or the QSGRendererInterface::Direct3D12 - enum value. \li OpenVG - Request with the \c{"openvg"} string or the QSGRendererInterface::OpenVG enum value. \endlist @@ -111,12 +108,6 @@ The Software adaptation is an alternative renderer for \l{Qt Quick} 2 that uses engine to render the contents of the scene graph. For more details, see \l{qtquick-visualcanvas-adaptations-software.html}{Software Adaptation}. -\section1 Direct3D 12 (experimental) - -The Direct3D 12 adaptation is an alternative renderer for \l{Qt Quick} 2 when running on Windows -10, both for Win32 and UWP applications. For more details, see -\l{qtquick-visualcanvas-adaptations-d3d12.html}{Direct3D 12 Adaptation}. - \section1 OpenVG The OpenVG adaptation is an alternative renderer for \l{Qt Quick} 2 that renders the contents of @@ -172,235 +163,6 @@ behavior, which is only present in the default OpenGL adaptation. /*! -\title Qt Quick Direct3D 12 Adaptation -\page qtquick-visualcanvas-adaptations-d3d12.html - -The Direct3D 12 adaptation for Windows 10, both in Win32 (\c windows platform plugin) and in UWP -(\c winrt platform plugin), is shipped as a dynamically loaded plugin. This adaptation doesn't work -on earlier Windows versions. Building this plugin is enabled automatically, whenever the necessary -D3D and DXGI develpoment files are present. In practice, this currently means Visual Studio 2015 -and newer. - -The adaptation is available both in normal, OpenGL-enabled Qt builds, and also when Qt is -configured with \c{-no-opengl}. However, it's never the default, meaning that the user or the -application has to explicitly request it by setting the \c{QT_QUICK_BACKEND} environment variable -to \c{d3d12} or by calling QQuickWindow::setSceneGraphBackend(). - -\section2 Motivation - -This experimental adaptation is the first Qt Quick backend that focuses on a modern, lower-level -graphics API in combination with a windowing system interface that's different from the traditional -approaches used in combination with OpenGL. - -This adaptation also allows better integration with Windows, as Direct3D is the primary -vendor-supported solution. Consequently, there are fewer problems anticipated with drivers, -operations like window resizes, and special events like graphics device loss caused by device -resets or graphics driver updates. - -Performance-wise, the general expectation is a somewhat lower CPU usage compared to OpenGL, due to -lower driver overhead, and a higher GPU utilization with less idle time wastage. The backend -doesn't heavily utilize threads yet, which means there are opportunities for further improvements -in the future, for example to further optimize image loading. - -The D3D12 backend also introduces support for pre-compiled shaders. All the backend's own shaders -(used by the built-in materials on which the Rectangle, Image, Text, and other QML types are built -with) are compiled to D3D shader bytecode when you compile Qt. Applications using ShaderEffect -items can choose to ship bytecode either in regular files, via the Qt resource system, or use -High Level Shading Language for DirectX (HLSL) source strings. Unlike OpenGL, the compilation for -HLSL is properly threaded, meaning shader compilation won't block the application and its user -interface. - -\section2 Graphics Adapters - -The plugin does not necessarily require hardware acceleration. You can also use WARP, the Direct3D -software rasterizer. By default, the first adapter providing hardware acceleration is chosen. To -override this and use another graphics adapter or to force the use of the software rasterizer, set -the \c{QT_D3D_ADAPTER_INDEX} environment variable to the index of the adapter. The adapters -discovered are printed at startup when \c{QSG_INFO} or the \c{qt.scenegraph.general} logging -category is enabled. - -\section2 Troubleshooting - -If you encounter issues, always set the \c{QSG_INFO} and \c{QT_D3D_DEBUG} environment variables -to \c 1, to get debug and warning messages printed on the debug output. \c{QT_D3D_DEBUG} enables -the Direct3D debug layer. - -\note The debug layer shouldn't be enabled in production use, since it can significantly impact -performance (CPU load) due to increased API overhead. - -\section2 Render Loops - -By default, the D3D12 adaptation uses a single-threaded render loop similar to OpenGL's \c windows -render loop. A threaded variant is also available, that you can request by setting the -\c{QSG_RENDER_LOOP} environment variable to \c threaded. However, due to conceptual limitations in -DXGI, the windowing system interface, the threaded loop is prone to deadlocks when multiple -QQuickWindow or QQuickView instances are shown. Consequently, for the time being, the default is -the single-threaded loop. This means that with the D3D12 backend, applications are expected to move -their work from the main (GUI) thread out to worker threads, instead of expecting Qt to keep the -GUI thread responsive and suitable for heavy, blocking operations. - -For more information see \l{qtquick-visualcanvas-scenegraph.html}{Qt Quick Scene Graph} for -details on render loops and -\l{https://docs.microsoft.com/en-us/windows/desktop/direct3darticles/dxgi-best-practices#multithreading-and-dxgi}{Multithreading and DXGI} -regarding the issues with multithreading. - -\section2 Renderer - -The scene graph renderer in the D3D12 adaptation currently doesn't perform any batching. This is -less of an issue, unlike OpenGL, because state changes don't present any problems in the first -place. The simpler renderer logic can also lead to lower CPU overhead in some cases. The trade-offs -between the various approaches are currently under research. - -\section2 Shader Effects - -The ShaderEffect QML type is fully functional with the D3D12 adaptation as well. However, the -interpretation of the fragmentShader and vertexShader properties is different than with OpenGL. - -With D3D12, these strings can either be a URL for a local file, a file in the resource system, -or an HLSL source string. Using a URL for a local file or a file in the resource system -indicates that the file in question contains pre-compiled D3D shader bytecode generated by the -\c fxc tool, or, alternatively, HLSL source code. The type of file is detected automatically. -This means that the D3D12 backend supports all options from GraphicsInfo.shaderCompilationType -and GraphicsInfo.shaderSourceType. - -Unlike OpenGL, whenever you open a file, there is a QFileSelector with the extra \c hlsl selector -used. This provides easy creation of ShaderEffect items that are functional across both backends, -for example by placing the GLSL source code into \c{shaders/effect.frag}, the HLSL source code or -- preferably - pre-compiled bytecode into \c{shaders/+hlsl/effect.frag}, while simply writing -\c{fragmentShader: "qrc:shaders/effect.frag"} in QML. For more details, see ShaderEffect. - -\section2 Multisample Render Targets - -The Direct3D 12 adaptation ignores the QSurfaceFormat set on the QQuickWindow or QQuickView, or -set via QSurfaceFormat::setDefaultFormat(), with two exceptions: QSurfaceFormat::samples() and -QSurfaceFormat::alphaBufferSize() are still taken into account. When the sample value is greater -than 1, multisample offscreen render targets will be created with the specified sample count at -the maximum supported quality level. The backend automatically performs resolving into the -non-multisample swapchain buffers after each frame. - -\section2 Semi-transparent Windows - -When the alpha channel is enabled either via QQuickWindow::setDefaultAlphaBuffer() or by setting -alphaBufferSize to a non-zero value in the window's QSurfaceFormat or in the global format managed -by QSurfaceFormat::setDefaultFormat(), the D3D12 backend will create a swapchain for composition -and go through DirectComposition. This is necessary, because the mandatory flip model swapchain -wouldn't support transparency otherwise. - -Therefore, it's important not to unneccessarily request an alpha channel. When the alphaBufferSize -is 0 or the default -1, all these extra steps can be avoided and the traditional window-based -swapchain is sufficient. - -On WinRT, this isn't relevant because the backend there always uses a composition swapchain which -is associated with the ISwapChainPanel that backs QWindow on that platform. - -\section2 Mipmaps - -Mipmap generation is supported and handled transparently to the applications via a built-in compute -shader. However, at the moment, this feature is experimental and only supports power-of-two images. -Textures of other size will work too, but this involves a QImage-based scaling on the CPU first. -Therefore, avoid enabling mipmapping for Non-Power-Of-Two (NPOT) images whenever possible. - -\section2 Image Formats - -When creating textures via C++ scene graph APIs like QQuickWindow::createTextureFromImage(), 32-bit -formats won't involve any conversion, they'll map directly to the corresponding \c{R8G8B8A8_UNORM} -or \c{B8G8R8A8_UNORM} format. Everything else will trigger a QImage-based format conversion on the -CPU first. - -\section2 Unsupported Features - -Particles and some other OpenGL-dependent utilities, like QQuickFramebufferObject, are currently -not supported. - -Like with \l{qtquick-visualcanvas-adaptations-software.html}{Software adaptation}, text is always -rendered using the native method. Distance field-based text rendering is currently not implemented. - -The shader sources in the \l {Qt Graphical Effects} module have not been ported to any format other -than the OpenGL 2.0 compatible one, meaning that the QML types provided by that module are currently -not functional with the D3D12 backend. - -Texture atlases are currently not in use. - -The renderer may lack support for certain minor features, such as drawing points and lines with a -width other than 1. - -Custom Qt Quick items using custom scene graph nodes can be problematic because materials are -inherently tied to the graphics API. Therefore, only items that use the utility rectangle and image -nodes are functional across all adaptations. - -QQuickWidget and its underlying OpenGL-based compositing architecture is not supported. If you need -to mix with QWidget-based user interfaces, use QWidget::createWindowContainer() to embed the native -window of the QQuickWindow or QQuickView. - -Finally, rendering via QSGEngine and QSGAbstractRenderer is not feasible with the D3D12 adaptation -at the moment. - -\section2 Related APIs - -To integrate custom Direct3D 12 rendering, use QSGRenderNode in combination with -QSGRendererInterface. This approach doesn't rely on OpenGL contexts or API specifics like -framebuffers, and allows exposing the graphics device and command buffer from the adaptation. It's -not necessarily suitable for easy integration of all types of content, in particular true 3D, so -it'll likely get complemented by an alternative to QQuickFramebufferObject in future releases. - -To perform runtime decisions based on the adaptation, use QSGRendererInterface from C++ and -GraphicsInfo from QML. They can also be used to check the level of shader support: shading -language, compilation approach, and so on. - -When creating custom items, use the new QSGRectangleNode and QSGImageNode classes. These replace -the now deprecated QSGSimpleRectNode and QSGSimpleTextureNode. Unlike their predecessors, these new -classes are interfaces, and implementations are created via the QQuickWindow::createRectangleNode() -and QQuickWindow::createImageNode() factory functions. - -\section2 Advanced Configuration - -The D3D12 adaptation can keep multiple frames in flight, similar to modern game engines. This is -somewhat different from the traditional "render - swap - wait for vsync" model and allows for -better GPU utilization at the expense of higher resource use. This means that the renderer will -be a number of frames ahead of what is displayed on the screen. - -For a discussion of flip model swap chains and the typical configuration parameters, refer to -\l{https://software.intel.com/en-us/articles/sample-application-for-direct3d-12-flip-model-swap-chains} -{Sample Application for Direct3D 12 Flip Model Swap Chains}. - -Vertical synchronization is always enabled, meaning Present() is invoked with an interval of 1. - -The configuration can be changed by setting the following environment variables: - -\table - \header - \li Environment variable - \li Description - \row - \li \c{QT_D3D_BUFFER_COUNT} - \li The number of swap chain buffers in range 2 - 4. The default value is 3. - \row - \li \c{QT_D3D_FRAME_COUNT} - \li The number of frames prepared without blocking in range 1 - 4. The default value is 2. - Present() starts blocking after queuing 3 frames (regardless of - \c{QT_D3D_BUFFER_COUNT}), unless the waitable object is in use. Every additional frame - increases GPU resource usage since geometry and constant buffer data needs to be - duplicated, and involves more bookkeeping on the CPU side. - \row - \li \c{QT_D3D_WAITABLE_SWAP_CHAIN_MAX_LATENCY} - \li The frame latency in range 1 - 16. The default value is 0 (disabled). - Changes the limit for Present() and triggers a wait for an available swap chain buffer - when beginning each frame. For a detailed discussion, see the article linked above. - \note Currently, this behavior is experimental. - \row - \li \c{QT_D3D_BLOCKING_PRESENT} - \li The time the CPU should wait, a non-zero value, for the GPU to finish its work after - each call to Present(). The default value is 0 (disabled). This behavior effectively - kills all parallelism but makes the behavior resemble the traditional - swap-blocks-for-vsync model, which can be useful in some special cases. However, this - behavior is not the same as setting the frame count to 1 because that still avoids - blocking after Present(), and may only block when starting to prepare the next frame - (or may not block at all depending on the time gap between the frames). -\endtable - -*/ - -/*! \title Qt Quick OpenVG Adaptation \page qtquick-visualcanvas-adaptations-openvg.html diff --git a/src/quick/handlers/qquickdragaxis_p.h b/src/quick/handlers/qquickdragaxis_p.h index ef74902122..b3db1be620 100644 --- a/src/quick/handlers/qquickdragaxis_p.h +++ b/src/quick/handlers/qquickdragaxis_p.h @@ -63,7 +63,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickDragAxis : public QObject Q_PROPERTY(qreal maximum READ maximum WRITE setMaximum NOTIFY maximumChanged) Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) QML_NAMED_ELEMENT(DragAxis) - QML_ADDED_IN_MINOR_VERSION(12) + QML_ADDED_IN_VERSION(2, 12) QML_UNCREATABLE("DragAxis is only available as a grouped property of DragHandler.") public: diff --git a/src/quick/handlers/qquickdraghandler_p.h b/src/quick/handlers/qquickdraghandler_p.h index 22d51c78ec..1315f79114 100644 --- a/src/quick/handlers/qquickdraghandler_p.h +++ b/src/quick/handlers/qquickdraghandler_p.h @@ -62,9 +62,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickDragHandler : public QQuickMultiPointHandler Q_PROPERTY(QQuickDragAxis * xAxis READ xAxis CONSTANT) Q_PROPERTY(QQuickDragAxis * yAxis READ yAxis CONSTANT) Q_PROPERTY(QVector2D translation READ translation NOTIFY translationChanged) - Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged REVISION 14) + Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged REVISION(2, 14)) QML_NAMED_ELEMENT(DragHandler) - QML_ADDED_IN_MINOR_VERSION(12) + QML_ADDED_IN_VERSION(2, 12) public: enum SnapMode { @@ -91,7 +91,7 @@ public: Q_SIGNALS: void translationChanged(); - Q_REVISION(14) void snapModeChanged(); + Q_REVISION(2, 14) void snapModeChanged(); protected: void onActiveChanged() override; diff --git a/src/quick/handlers/qquickhoverhandler_p.h b/src/quick/handlers/qquickhoverhandler_p.h index 313b87217c..4b9d0a9f39 100644 --- a/src/quick/handlers/qquickhoverhandler_p.h +++ b/src/quick/handlers/qquickhoverhandler_p.h @@ -63,7 +63,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickHoverHandler : public QQuickSinglePointHandle Q_OBJECT Q_PROPERTY(bool hovered READ isHovered NOTIFY hoveredChanged) QML_NAMED_ELEMENT(HoverHandler) - QML_ADDED_IN_MINOR_VERSION(12) + QML_ADDED_IN_VERSION(2, 12) public: explicit QQuickHoverHandler(QQuickItem *parent = nullptr); diff --git a/src/quick/handlers/qquickpinchhandler_p.h b/src/quick/handlers/qquickpinchhandler_p.h index 708c836acf..a8f5c121ba 100644 --- a/src/quick/handlers/qquickpinchhandler_p.h +++ b/src/quick/handlers/qquickpinchhandler_p.h @@ -79,7 +79,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPinchHandler : public QQuickMultiPointHandler Q_PROPERTY(QQuickDragAxis * xAxis READ xAxis CONSTANT) Q_PROPERTY(QQuickDragAxis * yAxis READ yAxis CONSTANT) QML_NAMED_ELEMENT(PinchHandler) - QML_ADDED_IN_MINOR_VERSION(12) + QML_ADDED_IN_VERSION(2, 12) public: explicit QQuickPinchHandler(QQuickItem *parent = nullptr); diff --git a/src/quick/handlers/qquickpointerhandler_p.h b/src/quick/handlers/qquickpointerhandler_p.h index 7262f4bcd3..3e7876b3d9 100644 --- a/src/quick/handlers/qquickpointerhandler_p.h +++ b/src/quick/handlers/qquickpointerhandler_p.h @@ -71,14 +71,14 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerHandler : public QObject, public QQmlP Q_PROPERTY(QQuickItem * parent READ parentItem CONSTANT) Q_PROPERTY(GrabPermissions grabPermissions READ grabPermissions WRITE setGrabPermissions NOTIFY grabPermissionChanged) Q_PROPERTY(qreal margin READ margin WRITE setMargin NOTIFY marginChanged) - Q_PROPERTY(int dragThreshold READ dragThreshold WRITE setDragThreshold RESET resetDragThreshold NOTIFY dragThresholdChanged REVISION 15) + Q_PROPERTY(int dragThreshold READ dragThreshold WRITE setDragThreshold RESET resetDragThreshold NOTIFY dragThresholdChanged REVISION(2, 15)) #if QT_CONFIG(cursor) - Q_PROPERTY(Qt::CursorShape cursorShape READ cursorShape WRITE setCursorShape RESET resetCursorShape NOTIFY cursorShapeChanged REVISION 15) + Q_PROPERTY(Qt::CursorShape cursorShape READ cursorShape WRITE setCursorShape RESET resetCursorShape NOTIFY cursorShapeChanged REVISION(2, 15)) #endif QML_NAMED_ELEMENT(PointerHandler) QML_UNCREATABLE("PointerHandler is an abstract base class.") - QML_ADDED_IN_MINOR_VERSION(12) + QML_ADDED_IN_VERSION(2, 12) public: explicit QQuickPointerHandler(QQuickItem *parent = nullptr); @@ -134,12 +134,12 @@ Q_SIGNALS: void activeChanged(); void targetChanged(); void marginChanged(); - Q_REVISION(15) void dragThresholdChanged(); + Q_REVISION(2, 15) void dragThresholdChanged(); void grabChanged(QQuickEventPoint::GrabTransition transition, QQuickEventPoint *point); void grabPermissionChanged(); void canceled(QQuickEventPoint *point); #if QT_CONFIG(cursor) - Q_REVISION(15) void cursorShapeChanged(); + Q_REVISION(2, 15) void cursorShapeChanged(); #endif protected: diff --git a/src/quick/handlers/qquickpointhandler_p.h b/src/quick/handlers/qquickpointhandler_p.h index 42677540a7..cedbc1c539 100644 --- a/src/quick/handlers/qquickpointhandler_p.h +++ b/src/quick/handlers/qquickpointhandler_p.h @@ -60,7 +60,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointHandler : public QQuickSinglePointHandle Q_OBJECT Q_PROPERTY(QVector2D translation READ translation NOTIFY translationChanged) QML_NAMED_ELEMENT(PointHandler) - QML_ADDED_IN_MINOR_VERSION(12) + QML_ADDED_IN_VERSION(2, 12) public: explicit QQuickPointHandler(QQuickItem *parent = nullptr); diff --git a/src/quick/handlers/qquicktaphandler_p.h b/src/quick/handlers/qquicktaphandler_p.h index 07454bccb8..d5c16b071f 100644 --- a/src/quick/handlers/qquicktaphandler_p.h +++ b/src/quick/handlers/qquicktaphandler_p.h @@ -68,7 +68,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTapHandler : public QQuickSinglePointHandler Q_PROPERTY(GesturePolicy gesturePolicy READ gesturePolicy WRITE setGesturePolicy NOTIFY gesturePolicyChanged) QML_NAMED_ELEMENT(TapHandler) - QML_ADDED_IN_MINOR_VERSION(12) + QML_ADDED_IN_VERSION(2, 12) public: enum GesturePolicy { diff --git a/src/quick/handlers/qquickwheelhandler_p.h b/src/quick/handlers/qquickwheelhandler_p.h index 26b052c5b3..021cd23679 100644 --- a/src/quick/handlers/qquickwheelhandler_p.h +++ b/src/quick/handlers/qquickwheelhandler_p.h @@ -73,7 +73,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickWheelHandler : public QQuickSinglePointHandle Q_PROPERTY(bool targetTransformAroundCursor READ isTargetTransformAroundCursor WRITE setTargetTransformAroundCursor NOTIFY targetTransformAroundCursorChanged) QML_NAMED_ELEMENT(WheelHandler) - QML_ADDED_IN_MINOR_VERSION(14) + QML_ADDED_IN_VERSION(2, 14) public: explicit QQuickWheelHandler(QQuickItem *parent = nullptr); diff --git a/src/quick/items/context2d/qquickcanvasitem_p.h b/src/quick/items/context2d/qquickcanvasitem_p.h index 6575caf806..48663c2dad 100644 --- a/src/quick/items/context2d/qquickcanvasitem_p.h +++ b/src/quick/items/context2d/qquickcanvasitem_p.h @@ -100,6 +100,7 @@ class QQuickCanvasItem : public QQuickItem Q_PROPERTY(RenderTarget renderTarget READ renderTarget WRITE setRenderTarget NOTIFY renderTargetChanged) Q_PROPERTY(RenderStrategy renderStrategy READ renderStrategy WRITE setRenderStrategy NOTIFY renderStrategyChanged) QML_NAMED_ELEMENT(Canvas) + QML_ADDED_IN_VERSION(2, 0) public: enum RenderTarget { diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp index 54cda72a36..8361be7277 100644 --- a/src/quick/items/context2d/qquickcontext2d.cpp +++ b/src/quick/items/context2d/qquickcontext2d.cpp @@ -74,12 +74,12 @@ #include <QtCore/private/qnumeric_p.h> #include <QtCore/QRunnable> #include <QtGui/qguiapplication.h> -#include <QtGui/qopenglframebufferobject.h> #include <private/qguiapplication_p.h> #include <qpa/qplatformintegration.h> #if QT_CONFIG(opengl) -# include <private/qsgdefaultrendercontext_p.h> +#include <qopenglframebufferobject.h> +#include <private/qsgdefaultrendercontext_p.h> #endif #include <cmath> diff --git a/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp b/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp index 55ebbe907c..73b52d0c73 100644 --- a/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp +++ b/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp @@ -44,8 +44,8 @@ #include <QtQuick/qsgtexture.h> #include <QtGui/QPaintEngine> #if QT_CONFIG(opengl) -# include <QtGui/QOpenGLContext> -# include <QtGui/private/qopenglpaintengine_p.h> +# include <QOpenGLContext> +# include <private/qopenglpaintengine_p.h> #endif #define HAS_SHADOW(offsetX, offsetY, blur, color) (color.isValid() && color.alpha() && (blur || offsetX || offsetY)) diff --git a/src/quick/items/context2d/qquickcontext2dtexture.cpp b/src/quick/items/context2d/qquickcontext2dtexture.cpp index 0ebd1a66c9..1cf3891488 100644 --- a/src/quick/items/context2d/qquickcontext2dtexture.cpp +++ b/src/quick/items/context2d/qquickcontext2dtexture.cpp @@ -43,12 +43,12 @@ #include <private/qquickitem_p.h> #include <QtQuick/private/qsgplaintexture_p.h> #include "qquickcontext2dcommandbuffer_p.h" -#include <QOpenGLPaintDevice> #if QT_CONFIG(opengl) +#include <QOpenGLPaintDevice> #include <QOpenGLFramebufferObject> #include <QOpenGLFramebufferObjectFormat> #include <QOpenGLFunctions> -#include <QtGui/private/qopenglextensions_p.h> +#include <private/qopenglextensions_p.h> #endif #include <QtCore/QThread> #include <QtGui/QGuiApplication> diff --git a/src/quick/items/qquickaccessibleattached_p.h b/src/quick/items/qquickaccessibleattached_p.h index b7254d6686..8a71c492a3 100644 --- a/src/quick/items/qquickaccessibleattached_p.h +++ b/src/quick/items/qquickaccessibleattached_p.h @@ -91,6 +91,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickAccessibleAttached : public QObject Q_PROPERTY(bool ignored READ ignored WRITE setIgnored NOTIFY ignoredChanged FINAL) QML_NAMED_ELEMENT(Accessible) + QML_ADDED_IN_VERSION(2, 0) QML_UNCREATABLE("Accessible is only available via attached properties.") QML_ATTACHED(QQuickAccessibleAttached) diff --git a/src/quick/items/qquickanchors_p.h b/src/quick/items/qquickanchors_p.h index e0276549e9..d243f6070f 100644 --- a/src/quick/items/qquickanchors_p.h +++ b/src/quick/items/qquickanchors_p.h @@ -85,6 +85,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickAnchors : public QObject Q_PROPERTY(QQuickItem *centerIn READ centerIn WRITE setCenterIn RESET resetCenterIn NOTIFY centerInChanged) Q_PROPERTY(bool alignWhenCentered READ alignWhenCentered WRITE setAlignWhenCentered NOTIFY centerAlignedChanged) QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: QQuickAnchors(QQuickItem *item, QObject *parent=nullptr); diff --git a/src/quick/items/qquickanimatedimage_p.h b/src/quick/items/qquickanimatedimage_p.h index 7f2199fd2a..6f7a7e45d5 100644 --- a/src/quick/items/qquickanimatedimage_p.h +++ b/src/quick/items/qquickanimatedimage_p.h @@ -70,11 +70,12 @@ class Q_AUTOTEST_EXPORT QQuickAnimatedImage : public QQuickImage Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged) Q_PROPERTY(int currentFrame READ currentFrame WRITE setCurrentFrame NOTIFY frameChanged) Q_PROPERTY(int frameCount READ frameCount NOTIFY frameCountChanged) - Q_PROPERTY(qreal speed READ speed WRITE setSpeed NOTIFY speedChanged REVISION 11) + Q_PROPERTY(qreal speed READ speed WRITE setSpeed NOTIFY speedChanged REVISION(2, 11)) // read-only for AnimatedImage Q_PROPERTY(QSize sourceSize READ sourceSize NOTIFY sourceSizeChanged) QML_NAMED_ELEMENT(AnimatedImage) + QML_ADDED_IN_VERSION(2, 0) public: QQuickAnimatedImage(QQuickItem *parent=nullptr); @@ -104,7 +105,7 @@ Q_SIGNALS: void frameChanged(); void currentFrameChanged(); void frameCountChanged(); - Q_REVISION(11) void speedChanged(); + Q_REVISION(2, 11) void speedChanged(); private Q_SLOTS: void movieUpdate(); diff --git a/src/quick/items/qquickanimatedsprite_p.h b/src/quick/items/qquickanimatedsprite_p.h index c28b6ce3af..afdf8f5ea4 100644 --- a/src/quick/items/qquickanimatedsprite_p.h +++ b/src/quick/items/qquickanimatedsprite_p.h @@ -92,8 +92,9 @@ class Q_AUTOTEST_EXPORT QQuickAnimatedSprite : public QQuickItem Q_PROPERTY(int loops READ loops WRITE setLoops NOTIFY loopsChanged) Q_PROPERTY(bool paused READ paused WRITE setPaused NOTIFY pausedChanged) Q_PROPERTY(int currentFrame READ currentFrame WRITE setCurrentFrame NOTIFY currentFrameChanged) - Q_PROPERTY(FinishBehavior finishBehavior READ finishBehavior WRITE setFinishBehavior NOTIFY finishBehaviorChanged REVISION 15) + Q_PROPERTY(FinishBehavior finishBehavior READ finishBehavior WRITE setFinishBehavior NOTIFY finishBehaviorChanged REVISION(2, 15)) QML_NAMED_ELEMENT(AnimatedSprite) + QML_ADDED_IN_VERSION(2, 0) public: explicit QQuickAnimatedSprite(QQuickItem *parent = nullptr); @@ -143,9 +144,9 @@ Q_SIGNALS: void frameDurationChanged(int arg); void loopsChanged(int arg); void currentFrameChanged(int arg); - Q_REVISION(15) void finishBehaviorChanged(FinishBehavior arg); + Q_REVISION(2, 15) void finishBehaviorChanged(FinishBehavior arg); - Q_REVISION(12) void finished(); + Q_REVISION(2, 12) void finished(); public Q_SLOTS: void start(); diff --git a/src/quick/items/qquickborderimage_p.h b/src/quick/items/qquickborderimage_p.h index 515edb33da..48922147ba 100644 --- a/src/quick/items/qquickborderimage_p.h +++ b/src/quick/items/qquickborderimage_p.h @@ -68,6 +68,7 @@ class Q_AUTOTEST_EXPORT QQuickBorderImage : public QQuickImageBase // read-only for BorderImage Q_PROPERTY(QSize sourceSize READ sourceSize NOTIFY sourceSizeChanged) QML_NAMED_ELEMENT(BorderImage) + QML_ADDED_IN_VERSION(2, 0) public: QQuickBorderImage(QQuickItem *parent=nullptr); diff --git a/src/quick/items/qquickdrag.cpp b/src/quick/items/qquickdrag.cpp index 737b7ffe24..117daef924 100644 --- a/src/quick/items/qquickdrag.cpp +++ b/src/quick/items/qquickdrag.cpp @@ -61,6 +61,7 @@ class QQuickDragAttachedPrivate : public QObjectPrivate, public QQuickItemChange { Q_DECLARE_PUBLIC(QQuickDragAttached) QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: static QQuickDragAttachedPrivate *get(QQuickDragAttached *attached) { diff --git a/src/quick/items/qquickdrag_p.h b/src/quick/items/qquickdrag_p.h index 9dbaac18f9..36b0a2bfd1 100644 --- a/src/quick/items/qquickdrag_p.h +++ b/src/quick/items/qquickdrag_p.h @@ -173,6 +173,7 @@ class Q_AUTOTEST_EXPORT QQuickDrag : public QObject //### consider drag and drop QML_NAMED_ELEMENT(Drag) + QML_ADDED_IN_VERSION(2, 0) QML_UNCREATABLE("Drag is only available via attached properties.") QML_ATTACHED(QQuickDragAttached) @@ -260,6 +261,7 @@ class QQuickDragAttached : public QObject Q_PROPERTY(QQuickDrag::DragType dragType READ dragType WRITE setDragType NOTIFY dragTypeChanged) QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: QQuickDragAttached(QObject *parent); diff --git a/src/quick/items/qquickdroparea_p.h b/src/quick/items/qquickdroparea_p.h index ee2deaa97a..b1d3d78a37 100644 --- a/src/quick/items/qquickdroparea_p.h +++ b/src/quick/items/qquickdroparea_p.h @@ -81,6 +81,7 @@ class QQuickDropEvent : public QObject Q_PROPERTY(QList<QUrl> urls READ urls) Q_PROPERTY(QStringList formats READ formats) QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: QQuickDropEvent(QQuickDropAreaPrivate *d, QDropEvent *event) : d(d), event(event) {} @@ -127,6 +128,7 @@ class QQuickDropAreaDrag : public QObject Q_PROPERTY(qreal y READ y NOTIFY positionChanged) Q_PROPERTY(QObject *source READ source NOTIFY sourceChanged) QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: QQuickDropAreaDrag(QQuickDropAreaPrivate *d, QObject *parent = 0); ~QQuickDropAreaDrag(); @@ -154,6 +156,7 @@ class Q_AUTOTEST_EXPORT QQuickDropArea : public QQuickItem Q_PROPERTY(QStringList keys READ keys WRITE setKeys NOTIFY keysChanged) Q_PROPERTY(QQuickDropAreaDrag *drag READ drag CONSTANT) QML_NAMED_ELEMENT(DropArea) + QML_ADDED_IN_VERSION(2, 0) public: QQuickDropArea(QQuickItem *parent=0); diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp index 2b3ea7d63d..a598c13113 100644 --- a/src/quick/items/qquickevents.cpp +++ b/src/quick/items/qquickevents.cpp @@ -2093,7 +2093,7 @@ const QTouchEvent::TouchPoint *QQuickPointerTouchEvent::touchPointById(int point auto it = std::find_if(tps.constBegin(), tps.constEnd(), [pointId](QTouchEvent::TouchPoint const& tp) { return tp.id() == pointId; } ); // return the pointer to the actual TP in QTouchEvent::_touchPoints - return (it == tps.constEnd() ? nullptr : it.operator->()); + return (it == tps.constEnd() ? nullptr : &*it); } /*! diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h index 7004b341de..b1d8b52372 100644 --- a/src/quick/items/qquickevents_p_p.h +++ b/src/quick/items/qquickevents_p_p.h @@ -56,12 +56,14 @@ #include <QtCore/qobject.h> #include <QtCore/qpointer.h> -#include <QtGui/qvector2d.h> #include <QtGui/qevent.h> +#include <QtGui/qtouchdevice.h> +#include <QtGui/qvector2d.h> +#include <QtQuick/qquickitem.h> + #if QT_CONFIG(shortcut) # include <QtGui/qkeysequence.h> #endif -#include <QtQuick/qquickitem.h> QT_BEGIN_NAMESPACE @@ -87,6 +89,7 @@ class QQuickKeyEvent : public QObject Q_PROPERTY(quint32 nativeScanCode READ nativeScanCode CONSTANT) Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted) QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: QQuickKeyEvent() @@ -117,7 +120,7 @@ public: void setAccepted(bool accepted) { event.setAccepted(accepted); } #if QT_CONFIG(shortcut) - Q_REVISION(2) Q_INVOKABLE bool matches(QKeySequence::StandardKey key) const { return event.matches(key); } + Q_REVISION(2, 2) Q_INVOKABLE bool matches(QKeySequence::StandardKey key) const { return event.matches(key); } #endif private: @@ -133,12 +136,13 @@ class Q_QUICK_PRIVATE_EXPORT QQuickMouseEvent : public QObject Q_PROPERTY(int button READ button CONSTANT) Q_PROPERTY(int buttons READ buttons CONSTANT) Q_PROPERTY(int modifiers READ modifiers CONSTANT) - Q_PROPERTY(int source READ source CONSTANT REVISION 7) + Q_PROPERTY(int source READ source CONSTANT REVISION(2, 7)) Q_PROPERTY(bool wasHeld READ wasHeld CONSTANT) Q_PROPERTY(bool isClick READ isClick CONSTANT) Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted) - Q_PROPERTY(int flags READ flags CONSTANT REVISION 11) + Q_PROPERTY(int flags READ flags CONSTANT REVISION(2, 11)) QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: QQuickMouseEvent() @@ -205,6 +209,7 @@ class QQuickWheelEvent : public QObject Q_PROPERTY(bool inverted READ inverted CONSTANT) Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted) QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: QQuickWheelEvent() @@ -250,6 +255,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickCloseEvent : public QObject Q_OBJECT Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted) QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: QQuickCloseEvent() {} @@ -278,7 +284,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickEventPoint : public QObject QML_NAMED_ELEMENT(EventPoint) QML_UNCREATABLE("EventPoint is only available as a member of PointerEvent.") - QML_ADDED_IN_MINOR_VERSION(12) + QML_ADDED_IN_VERSION(2, 12) public: enum State { @@ -373,7 +379,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickEventTouchPoint : public QQuickEventPoint QML_NAMED_ELEMENT(EventTouchPoint) QML_UNCREATABLE("EventTouchPoint is only available as a member of PointerEvent.") - QML_ADDED_IN_MINOR_VERSION(12) + QML_ADDED_IN_VERSION(2, 12) public: QQuickEventTouchPoint(QQuickPointerTouchEvent *parent); @@ -406,7 +412,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerEvent : public QObject QML_NAMED_ELEMENT(PointerEvent) QML_UNCREATABLE("PointerEvent is only available as a parameter of several signals in PointerHandler") - QML_ADDED_IN_MINOR_VERSION(12) + QML_ADDED_IN_VERSION(2, 12) public: QQuickPointerEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr) @@ -502,7 +508,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerMouseEvent : public QQuickSinglePointE QML_NAMED_ELEMENT(PointerMouseEvent) QML_UNCREATABLE("PointerMouseEvent is only available as a parameter of several signals in PointerHandler") - QML_ADDED_IN_MINOR_VERSION(12) + QML_ADDED_IN_VERSION(2, 12) public: QQuickPointerMouseEvent(QObject *parent, QQuickPointerDevice *device); @@ -526,7 +532,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerTouchEvent : public QQuickPointerEvent QML_NAMED_ELEMENT(PointerTouchEvent) QML_UNCREATABLE("PointerTouchEvent is only available as a parameter of several signals in PointerHandler") - QML_ADDED_IN_MINOR_VERSION(12) + QML_ADDED_IN_VERSION(2, 12) public: QQuickPointerTouchEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr) @@ -578,7 +584,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickEventTabletPoint : public QQuickEventPoint QML_NAMED_ELEMENT(EventTabletPoint) QML_UNCREATABLE("EventTouchPoint is only available as a member of PointerEvent.") - QML_ADDED_IN_MINOR_VERSION(15) + QML_ADDED_IN_VERSION(2, 15) public: QQuickEventTabletPoint(QQuickPointerTabletEvent *parent); @@ -655,7 +661,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerScrollEvent : public QQuickSinglePoint QML_NAMED_ELEMENT(PointerScrollEvent) QML_UNCREATABLE("PointerScrollEvent is only available via the WheelHandler::wheel signal.") - QML_ADDED_IN_MINOR_VERSION(14) + QML_ADDED_IN_VERSION(2, 14) public: QQuickPointerScrollEvent(QObject *parent, QQuickPointerDevice *device); @@ -707,7 +713,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerDevice : public QObject QML_NAMED_ELEMENT(PointerDevice) QML_UNCREATABLE("PointerDevice is only available as a property of PointerEvent.") - QML_ADDED_IN_MINOR_VERSION(12) + QML_ADDED_IN_VERSION(2, 12) public: enum DeviceType : qint16 { diff --git a/src/quick/items/qquickflickable_p.h b/src/quick/items/qquickflickable_p.h index 2d8d4a5e9a..fe74425d57 100644 --- a/src/quick/items/qquickflickable_p.h +++ b/src/quick/items/qquickflickable_p.h @@ -80,7 +80,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickFlickable : public QQuickItem Q_PROPERTY(qreal verticalVelocity READ verticalVelocity NOTIFY verticalVelocityChanged) Q_PROPERTY(BoundsBehavior boundsBehavior READ boundsBehavior WRITE setBoundsBehavior NOTIFY boundsBehaviorChanged) - Q_PROPERTY(BoundsMovement boundsMovement READ boundsMovement WRITE setBoundsMovement NOTIFY boundsMovementChanged REVISION 10) + Q_PROPERTY(BoundsMovement boundsMovement READ boundsMovement WRITE setBoundsMovement NOTIFY boundsMovementChanged REVISION(2, 10)) Q_PROPERTY(QQuickTransition *rebound READ rebound WRITE setRebound NOTIFY reboundChanged) Q_PROPERTY(qreal maximumFlickVelocity READ maximumFlickVelocity WRITE setMaximumFlickVelocity NOTIFY maximumFlickVelocityChanged) Q_PROPERTY(qreal flickDeceleration READ flickDeceleration WRITE setFlickDeceleration NOTIFY flickDecelerationChanged) @@ -106,15 +106,16 @@ class Q_QUICK_PRIVATE_EXPORT QQuickFlickable : public QQuickItem Q_PROPERTY(QQuickFlickableVisibleArea *visibleArea READ visibleArea CONSTANT) Q_PROPERTY(bool pixelAligned READ pixelAligned WRITE setPixelAligned NOTIFY pixelAlignedChanged) - Q_PROPERTY(bool synchronousDrag READ synchronousDrag WRITE setSynchronousDrag NOTIFY synchronousDragChanged REVISION 12) + Q_PROPERTY(bool synchronousDrag READ synchronousDrag WRITE setSynchronousDrag NOTIFY synchronousDragChanged REVISION(2, 12)) - Q_PROPERTY(qreal horizontalOvershoot READ horizontalOvershoot NOTIFY horizontalOvershootChanged REVISION 9) - Q_PROPERTY(qreal verticalOvershoot READ verticalOvershoot NOTIFY verticalOvershootChanged REVISION 9) + Q_PROPERTY(qreal horizontalOvershoot READ horizontalOvershoot NOTIFY horizontalOvershootChanged REVISION(2, 9)) + Q_PROPERTY(qreal verticalOvershoot READ verticalOvershoot NOTIFY verticalOvershootChanged REVISION(2, 9)) Q_PROPERTY(QQmlListProperty<QObject> flickableData READ flickableData) Q_PROPERTY(QQmlListProperty<QQuickItem> flickableChildren READ flickableChildren) Q_CLASSINFO("DefaultProperty", "flickableData") QML_NAMED_ELEMENT(Flickable) + QML_ADDED_IN_VERSION(2, 0) public: QQuickFlickable(QQuickItem *parent=nullptr); @@ -252,7 +253,7 @@ Q_SIGNALS: void flickableDirectionChanged(); void interactiveChanged(); void boundsBehaviorChanged(); - Q_REVISION(10) void boundsMovementChanged(); + Q_REVISION(2, 10) void boundsMovementChanged(); void reboundChanged(); void maximumFlickVelocityChanged(); void flickDecelerationChanged(); @@ -264,11 +265,11 @@ Q_SIGNALS: void dragStarted(); void dragEnded(); void pixelAlignedChanged(); - Q_REVISION(12) void synchronousDragChanged(); - Q_REVISION(9) void horizontalOvershootChanged(); - Q_REVISION(9) void verticalOvershootChanged(); + Q_REVISION(2, 12) void synchronousDragChanged(); + Q_REVISION(2, 9) void horizontalOvershootChanged(); + Q_REVISION(2, 9) void verticalOvershootChanged(); - // The next four signals should be marked as Q_REVISION(12). See QTBUG-71243 + // The next four signals should be marked as Q_REVISION(2, 12). See QTBUG-71243 void atXEndChanged(); void atYEndChanged(); void atXBeginningChanged(); diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h index 3f5f11effd..0d7f27492a 100644 --- a/src/quick/items/qquickflickable_p_p.h +++ b/src/quick/items/qquickflickable_p_p.h @@ -285,6 +285,7 @@ class QQuickFlickableVisibleArea : public QObject Q_PROPERTY(qreal widthRatio READ widthRatio NOTIFY widthRatioChanged) Q_PROPERTY(qreal heightRatio READ heightRatio NOTIFY heightRatioChanged) QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: QQuickFlickableVisibleArea(QQuickFlickable *parent=nullptr); diff --git a/src/quick/items/qquickflipable_p.h b/src/quick/items/qquickflipable_p.h index 42c632a33c..8d6716ec53 100644 --- a/src/quick/items/qquickflipable_p.h +++ b/src/quick/items/qquickflipable_p.h @@ -72,6 +72,7 @@ class Q_AUTOTEST_EXPORT QQuickFlipable : public QQuickItem Q_PROPERTY(QQuickItem *back READ back WRITE setBack NOTIFY backChanged) Q_PROPERTY(Side side READ side NOTIFY sideChanged) QML_NAMED_ELEMENT(Flipable) + QML_ADDED_IN_VERSION(2, 0) //### flipAxis //### flipRotation public: diff --git a/src/quick/items/qquickfocusscope_p.h b/src/quick/items/qquickfocusscope_p.h index c32fa93cd9..d3e9197fc7 100644 --- a/src/quick/items/qquickfocusscope_p.h +++ b/src/quick/items/qquickfocusscope_p.h @@ -59,6 +59,7 @@ class Q_AUTOTEST_EXPORT QQuickFocusScope : public QQuickItem { Q_OBJECT QML_NAMED_ELEMENT(FocusScope) + QML_ADDED_IN_VERSION(2, 0) public: QQuickFocusScope(QQuickItem *parent=nullptr); virtual ~QQuickFocusScope(); diff --git a/src/quick/items/qquickframebufferobject.cpp b/src/quick/items/qquickframebufferobject.cpp index d5550e78b6..62b982340d 100644 --- a/src/quick/items/qquickframebufferobject.cpp +++ b/src/quick/items/qquickframebufferobject.cpp @@ -39,8 +39,8 @@ #include "qquickframebufferobject.h" -#include <QtGui/QOpenGLFramebufferObject> -#include <QtGui/QOpenGLFunctions> +#include <QOpenGLFramebufferObject> +#include <QOpenGLFunctions> #include <private/qquickitem_p.h> #include <private/qsgadaptationlayer_p.h> #include <qsgtextureprovider.h> diff --git a/src/quick/items/qquickgraphicsinfo.cpp b/src/quick/items/qquickgraphicsinfo.cpp index 8f6f4386fb..0e711afcf2 100644 --- a/src/quick/items/qquickgraphicsinfo.cpp +++ b/src/quick/items/qquickgraphicsinfo.cpp @@ -40,7 +40,7 @@ #include "qquickgraphicsinfo_p.h" #include "qquickwindow.h" #include "qquickitem.h" -#include <QtGui/qopenglcontext.h> +#include <qopenglcontext.h> QT_BEGIN_NAMESPACE @@ -95,7 +95,6 @@ QQuickGraphicsInfo *QQuickGraphicsInfo::qmlAttachedProperties(QObject *object) \li GraphicsInfo.Unknown - the default value when no active scenegraph is associated with the item \li GraphicsInfo.Software - Qt Quick's software renderer based on QPainter with the raster paint engine \li GraphicsInfo.OpenGL - OpenGL or OpenGL ES - \li GraphicsInfo.Direct3D12 - Direct3D 12 \li GraphicsInfo.OpenVG - OpenVG \li GraphicsInfo.OpenGLRhi - OpenGL on top of QRhi, a graphics abstraction layer \li GraphicsInfo.Direct3D11Rhi - Direct3D 11 on top of QRhi, a graphics abstraction layer diff --git a/src/quick/items/qquickgraphicsinfo_p.h b/src/quick/items/qquickgraphicsinfo_p.h index 066a419c37..c55a35ed5e 100644 --- a/src/quick/items/qquickgraphicsinfo_p.h +++ b/src/quick/items/qquickgraphicsinfo_p.h @@ -76,7 +76,7 @@ class QQuickGraphicsInfo : public QObject Q_PROPERTY(RenderableType renderableType READ renderableType NOTIFY renderableTypeChanged FINAL) QML_NAMED_ELEMENT(GraphicsInfo) - QML_ADDED_IN_MINOR_VERSION(8) + QML_ADDED_IN_VERSION(2, 8) QML_UNCREATABLE("GraphicsInfo is only available via attached properties.") QML_ATTACHED(QQuickGraphicsInfo) @@ -85,7 +85,6 @@ public: Unknown = QSGRendererInterface::Unknown, Software = QSGRendererInterface::Software, OpenGL = QSGRendererInterface::OpenGL, - Direct3D12 = QSGRendererInterface::Direct3D12, OpenVG = QSGRendererInterface::OpenVG, OpenGLRhi = QSGRendererInterface::OpenGLRhi, Direct3D11Rhi = QSGRendererInterface::Direct3D11Rhi, diff --git a/src/quick/items/qquickgridview_p.h b/src/quick/items/qquickgridview_p.h index 9072e5f269..7187eb7816 100644 --- a/src/quick/items/qquickgridview_p.h +++ b/src/quick/items/qquickgridview_p.h @@ -74,6 +74,7 @@ class Q_AUTOTEST_EXPORT QQuickGridView : public QQuickItemView Q_CLASSINFO("DefaultProperty", "data") QML_NAMED_ELEMENT(GridView) + QML_ADDED_IN_VERSION(2, 0) QML_ATTACHED(QQuickGridViewAttached) public: diff --git a/src/quick/items/qquickimage_p.h b/src/quick/items/qquickimage_p.h index e22a94c5af..1119f20e45 100644 --- a/src/quick/items/qquickimage_p.h +++ b/src/quick/items/qquickimage_p.h @@ -66,10 +66,11 @@ class Q_QUICK_PRIVATE_EXPORT QQuickImage : public QQuickImageBase Q_PROPERTY(qreal paintedHeight READ paintedHeight NOTIFY paintedGeometryChanged) Q_PROPERTY(HAlignment horizontalAlignment READ horizontalAlignment WRITE setHorizontalAlignment NOTIFY horizontalAlignmentChanged) Q_PROPERTY(VAlignment verticalAlignment READ verticalAlignment WRITE setVerticalAlignment NOTIFY verticalAlignmentChanged) - Q_PROPERTY(bool mipmap READ mipmap WRITE setMipmap NOTIFY mipmapChanged REVISION 3) - Q_PROPERTY(bool autoTransform READ autoTransform WRITE setAutoTransform NOTIFY autoTransformChanged REVISION 5) - Q_PROPERTY(QRectF sourceClipRect READ sourceClipRect WRITE setSourceClipRect RESET resetSourceClipRect NOTIFY sourceClipRectChanged REVISION 15) + Q_PROPERTY(bool mipmap READ mipmap WRITE setMipmap NOTIFY mipmapChanged REVISION(2, 3)) + Q_PROPERTY(bool autoTransform READ autoTransform WRITE setAutoTransform NOTIFY autoTransformChanged REVISION(2, 5)) + Q_PROPERTY(QRectF sourceClipRect READ sourceClipRect WRITE setSourceClipRect RESET resetSourceClipRect NOTIFY sourceClipRectChanged REVISION(2, 15)) QML_NAMED_ELEMENT(Image) + QML_ADDED_IN_VERSION(2, 0) public: QQuickImage(QQuickItem *parent=nullptr); @@ -114,8 +115,8 @@ Q_SIGNALS: void paintedGeometryChanged(); void horizontalAlignmentChanged(HAlignment alignment); void verticalAlignmentChanged(VAlignment alignment); - Q_REVISION(3) void mipmapChanged(bool); - Q_REVISION(5) void autoTransformChanged(); + Q_REVISION(2, 3) void mipmapChanged(bool); + Q_REVISION(2, 5) void autoTransformChanged(); private Q_SLOTS: void invalidateSceneGraph(); diff --git a/src/quick/items/qquickimagebase_p.h b/src/quick/items/qquickimagebase_p.h index 095547a2cf..9265792be1 100644 --- a/src/quick/items/qquickimagebase_p.h +++ b/src/quick/items/qquickimagebase_p.h @@ -69,12 +69,12 @@ class Q_QUICK_PRIVATE_EXPORT QQuickImageBase : public QQuickImplicitSizeItem Q_PROPERTY(bool cache READ cache WRITE setCache NOTIFY cacheChanged) Q_PROPERTY(QSize sourceSize READ sourceSize WRITE setSourceSize RESET resetSourceSize NOTIFY sourceSizeChanged) Q_PROPERTY(bool mirror READ mirror WRITE setMirror NOTIFY mirrorChanged) - Q_PROPERTY(int currentFrame READ currentFrame WRITE setCurrentFrame NOTIFY currentFrameChanged REVISION 14) - Q_PROPERTY(int frameCount READ frameCount NOTIFY frameCountChanged REVISION 14) - Q_PROPERTY(QColorSpace colorSpace READ colorSpace WRITE setColorSpace NOTIFY colorSpaceChanged REVISION 15) + Q_PROPERTY(int currentFrame READ currentFrame WRITE setCurrentFrame NOTIFY currentFrameChanged REVISION(2, 14)) + Q_PROPERTY(int frameCount READ frameCount NOTIFY frameCountChanged REVISION(2, 14)) + Q_PROPERTY(QColorSpace colorSpace READ colorSpace WRITE setColorSpace NOTIFY colorSpaceChanged REVISION(2, 15)) QML_NAMED_ELEMENT(ImageBase); - QML_ADDED_IN_MINOR_VERSION(14) + QML_ADDED_IN_VERSION(2, 14) QML_UNCREATABLE("ImageBase is an abstract base class.") public: @@ -141,10 +141,10 @@ Q_SIGNALS: void asynchronousChanged(); void cacheChanged(); void mirrorChanged(); - Q_REVISION(14) void currentFrameChanged(); - Q_REVISION(14) void frameCountChanged(); - Q_REVISION(15) void sourceClipRectChanged(); - Q_REVISION(15) void colorSpaceChanged(); + Q_REVISION(2, 14) void currentFrameChanged(); + Q_REVISION(2, 14) void frameCountChanged(); + Q_REVISION(2, 15) void sourceClipRectChanged(); + Q_REVISION(2, 15) void colorSpaceChanged(); protected: void loadEmptyUrl(); diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h index 8c04ced11b..ca0c2f4764 100644 --- a/src/quick/items/qquickitem.h +++ b/src/quick/items/qquickitem.h @@ -59,6 +59,7 @@ class Q_QUICK_EXPORT QQuickTransform : public QObject { Q_OBJECT QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: explicit QQuickTransform(QObject *parent = nullptr); ~QQuickTransform() override; @@ -133,7 +134,7 @@ class Q_QUICK_EXPORT QQuickItem : public QObject, public QQmlParserStatus Q_PROPERTY(bool focus READ hasFocus WRITE setFocus NOTIFY focusChanged FINAL) Q_PROPERTY(bool activeFocus READ hasActiveFocus NOTIFY activeFocusChanged FINAL) - Q_PROPERTY(bool activeFocusOnTab READ activeFocusOnTab WRITE setActiveFocusOnTab NOTIFY activeFocusOnTabChanged FINAL REVISION 1) + Q_PROPERTY(bool activeFocusOnTab READ activeFocusOnTab WRITE setActiveFocusOnTab NOTIFY activeFocusOnTabChanged FINAL REVISION(2, 1)) Q_PROPERTY(qreal rotation READ rotation WRITE setRotation NOTIFY rotationChanged) Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged) @@ -145,13 +146,14 @@ class Q_QUICK_EXPORT QQuickItem : public QObject, public QQmlParserStatus Q_PROPERTY(bool antialiasing READ antialiasing WRITE setAntialiasing NOTIFY antialiasingChanged RESET resetAntialiasing) Q_PROPERTY(qreal implicitWidth READ implicitWidth WRITE setImplicitWidth NOTIFY implicitWidthChanged) Q_PROPERTY(qreal implicitHeight READ implicitHeight WRITE setImplicitHeight NOTIFY implicitHeightChanged) - Q_PROPERTY(QObject *containmentMask READ containmentMask WRITE setContainmentMask NOTIFY containmentMaskChanged REVISION 11) + Q_PROPERTY(QObject *containmentMask READ containmentMask WRITE setContainmentMask NOTIFY containmentMaskChanged REVISION(2, 11)) Q_PRIVATE_PROPERTY(QQuickItem::d_func(), QQuickItemLayer *layer READ layer DESIGNABLE false CONSTANT FINAL) Q_CLASSINFO("DefaultProperty", "data") Q_CLASSINFO("qt_QmlJSWrapperFactoryMethod", "_q_createJSWrapper(QV4::ExecutionEngine*)") QML_NAMED_ELEMENT(Item) + QML_ADDED_IN_VERSION(2, 0) public: enum Flag { @@ -320,7 +322,7 @@ public: void setKeepTouchGrab(bool); // implemented in qquickitemgrabresult.cpp - Q_REVISION(4) Q_INVOKABLE bool grabToImage(const QJSValue &callback, const QSize &targetSize = QSize()); + Q_REVISION(2, 4) Q_INVOKABLE bool grabToImage(const QJSValue &callback, const QSize &targetSize = QSize()); QSharedPointer<QQuickItemGrabResult> grabToImage(const QSize &targetSize = QSize()); Q_INVOKABLE virtual bool contains(const QPointF &point) const; @@ -343,11 +345,11 @@ public: Q_INVOKABLE void mapFromItem(QQmlV4Function*) const; Q_INVOKABLE void mapToItem(QQmlV4Function*) const; - Q_REVISION(7) Q_INVOKABLE void mapFromGlobal(QQmlV4Function*) const; - Q_REVISION(7) Q_INVOKABLE void mapToGlobal(QQmlV4Function*) const; + Q_REVISION(2, 7) Q_INVOKABLE void mapFromGlobal(QQmlV4Function*) const; + Q_REVISION(2, 7) Q_INVOKABLE void mapToGlobal(QQmlV4Function*) const; Q_INVOKABLE void forceActiveFocus(); Q_INVOKABLE void forceActiveFocus(Qt::FocusReason reason); - Q_REVISION(1) Q_INVOKABLE QQuickItem *nextItemInFocusChain(bool forward = true); + Q_REVISION(2, 1) Q_INVOKABLE QQuickItem *nextItemInFocusChain(bool forward = true); Q_INVOKABLE QQuickItem *childAt(qreal x, qreal y) const; #if QT_CONFIG(im) @@ -373,13 +375,13 @@ Q_SIGNALS: void stateChanged(const QString &); void focusChanged(bool); void activeFocusChanged(bool); - Q_REVISION(1) void activeFocusOnTabChanged(bool); + Q_REVISION(2, 1) void activeFocusOnTabChanged(bool); void parentChanged(QQuickItem *); void transformOriginChanged(TransformOrigin); void smoothChanged(bool); void antialiasingChanged(bool); void clipChanged(bool); - Q_REVISION(1) void windowChanged(QQuickWindow* window); + Q_REVISION(2, 1) void windowChanged(QQuickWindow* window); void childrenChanged(); void opacityChanged(); @@ -396,7 +398,7 @@ Q_SIGNALS: void zChanged(); void implicitWidthChanged(); void implicitHeightChanged(); - Q_REVISION(11) void containmentMaskChanged(); + Q_REVISION(2, 11) void containmentMaskChanged(); protected: bool event(QEvent *) override; diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index 841d91bb40..a8958dfd59 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -153,6 +153,7 @@ class QQuickItemLayer : public QObject, public QQuickItemChangeListener Q_PROPERTY(QQuickShaderEffectSource::TextureMirroring textureMirroring READ textureMirroring WRITE setTextureMirroring NOTIFY textureMirroringChanged) Q_PROPERTY(int samples READ samples WRITE setSamples NOTIFY samplesChanged) QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: QQuickItemLayer(QQuickItem *item); @@ -722,6 +723,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickKeyNavigationAttached : public QObject, publi Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged) QML_NAMED_ELEMENT(KeyNavigation) + QML_ADDED_IN_VERSION(2, 0) QML_UNCREATABLE("KeyNavigation is only available via attached properties.") QML_ATTACHED(QQuickKeyNavigationAttached) @@ -771,6 +773,7 @@ class QQuickLayoutMirroringAttached : public QObject Q_PROPERTY(bool childrenInherit READ childrenInherit WRITE setChildrenInherit NOTIFY childrenInheritChanged) QML_NAMED_ELEMENT(LayoutMirroring) + QML_ADDED_IN_VERSION(2, 0) QML_UNCREATABLE("LayoutMirroring is only available via attached properties.") QML_ATTACHED(QQuickLayoutMirroringAttached) @@ -800,7 +803,7 @@ class QQuickEnterKeyAttached : public QObject QML_NAMED_ELEMENT(EnterKey) QML_UNCREATABLE("EnterKey is only available via attached properties") - QML_ADDED_IN_MINOR_VERSION(6) + QML_ADDED_IN_VERSION(2, 6) QML_ATTACHED(QQuickEnterKeyAttached) public: @@ -849,6 +852,7 @@ class QQuickKeysAttached : public QObject, public QQuickItemKeyFilter Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged) QML_NAMED_ELEMENT(Keys) + QML_ADDED_IN_VERSION(2, 0) QML_UNCREATABLE("Keys is only available via attached properties") QML_ATTACHED(QQuickKeysAttached) diff --git a/src/quick/items/qquickitemanimation_p.h b/src/quick/items/qquickitemanimation_p.h index 28c18c874d..ee4df1b6ca 100644 --- a/src/quick/items/qquickitemanimation_p.h +++ b/src/quick/items/qquickitemanimation_p.h @@ -67,6 +67,7 @@ class Q_AUTOTEST_EXPORT QQuickParentAnimation : public QQuickAnimationGroup Q_PROPERTY(QQuickItem *newParent READ newParent WRITE setNewParent NOTIFY newParentChanged) Q_PROPERTY(QQuickItem *via READ via WRITE setVia NOTIFY viaChanged) QML_NAMED_ELEMENT(ParentAnimation) + QML_ADDED_IN_VERSION(2, 0) public: QQuickParentAnimation(QObject *parent=nullptr); @@ -102,6 +103,7 @@ class Q_AUTOTEST_EXPORT QQuickAnchorAnimation : public QQuickAbstractAnimation Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged) Q_PROPERTY(QEasingCurve easing READ easing WRITE setEasing NOTIFY easingChanged) QML_NAMED_ELEMENT(AnchorAnimation) + QML_ADDED_IN_VERSION(2, 0) public: QQuickAnchorAnimation(QObject *parent=nullptr); @@ -146,6 +148,7 @@ class Q_AUTOTEST_EXPORT QQuickPathAnimation : public QQuickAbstractAnimation Q_PROPERTY(int orientationExitDuration READ orientationExitDuration WRITE setOrientationExitDuration NOTIFY orientationExitDurationChanged) Q_PROPERTY(qreal endRotation READ endRotation WRITE setEndRotation NOTIFY endRotationChanged) QML_NAMED_ELEMENT(PathAnimation) + QML_ADDED_IN_VERSION(2, 0) public: QQuickPathAnimation(QObject *parent=nullptr); diff --git a/src/quick/items/qquickitemgrabresult.h b/src/quick/items/qquickitemgrabresult.h index c92a8c52f4..48e217f61d 100644 --- a/src/quick/items/qquickitemgrabresult.h +++ b/src/quick/items/qquickitemgrabresult.h @@ -62,6 +62,7 @@ class Q_QUICK_EXPORT QQuickItemGrabResult : public QObject Q_PROPERTY(QImage image READ image CONSTANT) Q_PROPERTY(QUrl url READ url CONSTANT) QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: QImage image() const; diff --git a/src/quick/items/qquickitemsmodule_p.h b/src/quick/items/qquickitemsmodule_p.h index 28dff65dff..f7081f6ece 100644 --- a/src/quick/items/qquickitemsmodule_p.h +++ b/src/quick/items/qquickitemsmodule_p.h @@ -68,7 +68,7 @@ struct QPointingDeviceUniqueIdForeign Q_GADGET QML_FOREIGN(QPointingDeviceUniqueId) QML_NAMED_ELEMENT(PointingDeviceUniqueId) - QML_ADDED_IN_MINOR_VERSION(9) + QML_ADDED_IN_VERSION(2, 9) QML_UNCREATABLE("PointingDeviceUniqueId is only available via read-only properties.") }; diff --git a/src/quick/items/qquickitemview_p.h b/src/quick/items/qquickitemview_p.h index 521580d292..8d928aa3af 100644 --- a/src/quick/items/qquickitemview_p.h +++ b/src/quick/items/qquickitemview_p.h @@ -79,10 +79,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickItemView : public QQuickFlickable Q_PROPERTY(QQuickItem *currentItem READ currentItem NOTIFY currentItemChanged) Q_PROPERTY(bool keyNavigationWraps READ isWrapEnabled WRITE setWrapEnabled NOTIFY keyNavigationWrapsChanged) - Q_PROPERTY(bool keyNavigationEnabled READ isKeyNavigationEnabled WRITE setKeyNavigationEnabled NOTIFY keyNavigationEnabledChanged REVISION 7) + Q_PROPERTY(bool keyNavigationEnabled READ isKeyNavigationEnabled WRITE setKeyNavigationEnabled NOTIFY keyNavigationEnabledChanged REVISION(2, 7)) Q_PROPERTY(int cacheBuffer READ cacheBuffer WRITE setCacheBuffer NOTIFY cacheBufferChanged) - Q_PROPERTY(int displayMarginBeginning READ displayMarginBeginning WRITE setDisplayMarginBeginning NOTIFY displayMarginBeginningChanged REVISION 3) - Q_PROPERTY(int displayMarginEnd READ displayMarginEnd WRITE setDisplayMarginEnd NOTIFY displayMarginEndChanged REVISION 3) + Q_PROPERTY(int displayMarginBeginning READ displayMarginBeginning WRITE setDisplayMarginBeginning NOTIFY displayMarginBeginningChanged REVISION(2, 3)) + Q_PROPERTY(int displayMarginEnd READ displayMarginEnd WRITE setDisplayMarginEnd NOTIFY displayMarginEndChanged REVISION(2, 3)) Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged) Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged) @@ -110,11 +110,11 @@ class Q_QUICK_PRIVATE_EXPORT QQuickItemView : public QQuickFlickable Q_PROPERTY(qreal preferredHighlightEnd READ preferredHighlightEnd WRITE setPreferredHighlightEnd NOTIFY preferredHighlightEndChanged RESET resetPreferredHighlightEnd) Q_PROPERTY(int highlightMoveDuration READ highlightMoveDuration WRITE setHighlightMoveDuration NOTIFY highlightMoveDurationChanged) - Q_PROPERTY(bool reuseItems READ reuseItems WRITE setReuseItems NOTIFY reuseItemsChanged REVISION 15) + Q_PROPERTY(bool reuseItems READ reuseItems WRITE setReuseItems NOTIFY reuseItemsChanged REVISION(2, 15)) QML_NAMED_ELEMENT(ItemView) QML_UNCREATABLE("ItemView is an abstract base class.") - QML_ADDED_IN_MINOR_VERSION(1) + QML_ADDED_IN_VERSION(2, 1) public: // this holds all layout enum values so they can be referred to by other enums @@ -237,10 +237,10 @@ public: Q_INVOKABLE void positionViewAtIndex(int index, int mode); Q_INVOKABLE int indexAt(qreal x, qreal y) const; Q_INVOKABLE QQuickItem *itemAt(qreal x, qreal y) const; - Q_REVISION(13) Q_INVOKABLE QQuickItem *itemAtIndex(int index) const; + Q_REVISION(2, 13) Q_INVOKABLE QQuickItem *itemAtIndex(int index) const; Q_INVOKABLE void positionViewAtBeginning(); Q_INVOKABLE void positionViewAtEnd(); - Q_REVISION(1) Q_INVOKABLE void forceLayout(); + Q_REVISION(2, 1) Q_INVOKABLE void forceLayout(); void setContentX(qreal pos) override; void setContentY(qreal pos) override; @@ -255,7 +255,7 @@ Q_SIGNALS: void currentItemChanged(); void keyNavigationWrapsChanged(); - Q_REVISION(7) void keyNavigationEnabledChanged(); + Q_REVISION(2, 7) void keyNavigationEnabledChanged(); void cacheBufferChanged(); void displayMarginBeginningChanged(); void displayMarginEndChanged(); @@ -286,7 +286,7 @@ Q_SIGNALS: void preferredHighlightEndChanged(); void highlightMoveDurationChanged(); - Q_REVISION(15) void reuseItemsChanged(); + Q_REVISION(2, 15) void reuseItemsChanged(); protected: void updatePolish() override; diff --git a/src/quick/items/qquickitemviewtransition_p.h b/src/quick/items/qquickitemviewtransition_p.h index 5f4e74171e..43858db688 100644 --- a/src/quick/items/qquickitemviewtransition_p.h +++ b/src/quick/items/qquickitemviewtransition_p.h @@ -195,6 +195,7 @@ class QQuickViewTransitionAttached : public QObject Q_PROPERTY(QQmlListProperty<QObject> targetItems READ targetItems NOTIFY targetItemsChanged) QML_NAMED_ELEMENT(ViewTransition) + QML_ADDED_IN_VERSION(2, 0) QML_UNCREATABLE("ViewTransition is only available via attached properties.") QML_ATTACHED(QQuickViewTransitionAttached) diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index e75a4ccd83..b91e705ad0 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -467,7 +467,7 @@ qreal QQuickListViewPrivate::lastPosition() const // All visible items are in delayRemove state invisibleCount = model->count(); } - pos = (*(--visibleItems.constEnd()))->endPosition(); + pos = (*(visibleItems.constEnd() - 1))->endPosition(); if (invisibleCount > 0) pos += invisibleCount * (averageSize + spacing); } else if (model && model->count()) { @@ -492,7 +492,7 @@ qreal QQuickListViewPrivate::positionAt(int modelIndex) const return (*visibleItems.constBegin())->position() - count * (averageSize + spacing) - cs; } else { int count = modelIndex - findLastVisibleIndex(visibleIndex) - 1; - return (*(--visibleItems.constEnd()))->endPosition() + spacing + count * (averageSize + spacing); + return (*(visibleItems.constEnd() - 1))->endPosition() + spacing + count * (averageSize + spacing); } } return 0; @@ -508,7 +508,7 @@ qreal QQuickListViewPrivate::endPositionAt(int modelIndex) const return (*visibleItems.constBegin())->position() - (count - 1) * (averageSize + spacing) - spacing; } else { int count = modelIndex - findLastVisibleIndex(visibleIndex) - 1; - return (*(--visibleItems.constEnd()))->endPosition() + count * (averageSize + spacing); + return (*(visibleItems.constEnd() - 1))->endPosition() + count * (averageSize + spacing); } } return 0; @@ -534,7 +534,7 @@ qreal QQuickListViewPrivate::snapPosAt(qreal pos) return snapItem->itemPosition(); if (visibleItems.count()) { qreal firstPos = (*visibleItems.constBegin())->position(); - qreal endPos = (*(--visibleItems.constEnd()))->position(); + qreal endPos = (*(visibleItems.constEnd() - 1))->position(); if (pos < firstPos) { return firstPos - qRound((firstPos - pos) / averageSize) * averageSize; } else if (pos > endPos) @@ -679,7 +679,7 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal qreal itemEnd = visiblePos; if (visibleItems.count()) { visiblePos = (*visibleItems.constBegin())->position(); - itemEnd = (*(--visibleItems.constEnd()))->endPosition() + spacing; + itemEnd = (*(visibleItems.constEnd() - 1))->endPosition() + spacing; } int modelIndex = findLastVisibleIndex(); diff --git a/src/quick/items/qquicklistview_p.h b/src/quick/items/qquicklistview_p.h index be21b93155..5e3dbac3a7 100644 --- a/src/quick/items/qquicklistview_p.h +++ b/src/quick/items/qquicklistview_p.h @@ -71,6 +71,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickViewSection : public QObject Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) Q_PROPERTY(int labelPositioning READ labelPositioning WRITE setLabelPositioning NOTIFY labelPositioningChanged) QML_NAMED_ELEMENT(ViewSection) + QML_ADDED_IN_VERSION(2, 0) public: QQuickViewSection(QQuickListView *parent=nullptr); @@ -127,11 +128,12 @@ class Q_QUICK_PRIVATE_EXPORT QQuickListView : public QQuickItemView Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged) - Q_PROPERTY(HeaderPositioning headerPositioning READ headerPositioning WRITE setHeaderPositioning NOTIFY headerPositioningChanged REVISION 4) - Q_PROPERTY(FooterPositioning footerPositioning READ footerPositioning WRITE setFooterPositioning NOTIFY footerPositioningChanged REVISION 4) + Q_PROPERTY(HeaderPositioning headerPositioning READ headerPositioning WRITE setHeaderPositioning NOTIFY headerPositioningChanged REVISION(2, 4)) + Q_PROPERTY(FooterPositioning footerPositioning READ footerPositioning WRITE setFooterPositioning NOTIFY footerPositioningChanged REVISION(2, 4)) Q_CLASSINFO("DefaultProperty", "data") QML_NAMED_ELEMENT(ListView) + QML_ADDED_IN_VERSION(2, 0) QML_ATTACHED(QQuickListViewAttached) public: @@ -193,8 +195,8 @@ Q_SIGNALS: void highlightResizeVelocityChanged(); void highlightResizeDurationChanged(); void snapModeChanged(); - Q_REVISION(4) void headerPositioningChanged(); - Q_REVISION(4) void footerPositioningChanged(); + Q_REVISION(2, 4) void headerPositioningChanged(); + Q_REVISION(2, 4) void footerPositioningChanged(); protected: void viewportMoved(Qt::Orientations orient) override; diff --git a/src/quick/items/qquickloader_p.h b/src/quick/items/qquickloader_p.h index 2d560fb856..8f061d3139 100644 --- a/src/quick/items/qquickloader_p.h +++ b/src/quick/items/qquickloader_p.h @@ -68,6 +68,7 @@ class Q_AUTOTEST_EXPORT QQuickLoader : public QQuickImplicitSizeItem Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged) Q_PROPERTY(bool asynchronous READ asynchronous WRITE setAsynchronous NOTIFY asynchronousChanged) QML_NAMED_ELEMENT(Loader) + QML_ADDED_IN_VERSION(2, 0) public: QQuickLoader(QQuickItem *parent = nullptr); diff --git a/src/quick/items/qquickmousearea_p.h b/src/quick/items/qquickmousearea_p.h index 806cc41369..02ad56fd79 100644 --- a/src/quick/items/qquickmousearea_p.h +++ b/src/quick/items/qquickmousearea_p.h @@ -71,7 +71,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickMouseArea : public QQuickItem Q_PROPERTY(bool containsMouse READ hovered NOTIFY hoveredChanged) Q_PROPERTY(bool pressed READ pressed NOTIFY pressedChanged) Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged) - Q_PROPERTY(bool scrollGestureEnabled READ isScrollGestureEnabled WRITE setScrollGestureEnabled NOTIFY scrollGestureEnabledChanged REVISION 5) + Q_PROPERTY(bool scrollGestureEnabled READ isScrollGestureEnabled WRITE setScrollGestureEnabled NOTIFY scrollGestureEnabledChanged REVISION(2, 5)) Q_PROPERTY(Qt::MouseButtons pressedButtons READ pressedButtons NOTIFY pressedButtonsChanged) Q_PROPERTY(Qt::MouseButtons acceptedButtons READ acceptedButtons WRITE setAcceptedButtons NOTIFY acceptedButtonsChanged) Q_PROPERTY(bool hoverEnabled READ hoverEnabled WRITE setHoverEnabled NOTIFY hoverEnabledChanged) @@ -83,9 +83,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickMouseArea : public QQuickItem #if QT_CONFIG(cursor) Q_PROPERTY(Qt::CursorShape cursorShape READ cursorShape WRITE setCursorShape RESET unsetCursor NOTIFY cursorShapeChanged) #endif - Q_PROPERTY(bool containsPress READ containsPress NOTIFY containsPressChanged REVISION 4) - Q_PROPERTY(int pressAndHoldInterval READ pressAndHoldInterval WRITE setPressAndHoldInterval NOTIFY pressAndHoldIntervalChanged RESET resetPressAndHoldInterval REVISION 9) + Q_PROPERTY(bool containsPress READ containsPress NOTIFY containsPressChanged REVISION(2, 4)) + Q_PROPERTY(int pressAndHoldInterval READ pressAndHoldInterval WRITE setPressAndHoldInterval NOTIFY pressAndHoldIntervalChanged RESET resetPressAndHoldInterval REVISION(2, 9)) QML_NAMED_ELEMENT(MouseArea) + QML_ADDED_IN_VERSION(2, 0) public: QQuickMouseArea(QQuickItem *parent=nullptr); @@ -135,7 +136,7 @@ Q_SIGNALS: void hoveredChanged(); void pressedChanged(); void enabledChanged(); - Q_REVISION(5) void scrollGestureEnabledChanged(); + Q_REVISION(2, 5) void scrollGestureEnabledChanged(); void pressedButtonsChanged(); void acceptedButtonsChanged(); void hoverEnabledChanged(); @@ -157,8 +158,8 @@ Q_SIGNALS: void entered(); void exited(); void canceled(); - Q_REVISION(4) void containsPressChanged(); - Q_REVISION(9) void pressAndHoldIntervalChanged(); + Q_REVISION(2, 4) void containsPressChanged(); + Q_REVISION(2, 9) void pressAndHoldIntervalChanged(); protected: void setHovered(bool); diff --git a/src/quick/items/qquickmultipointtoucharea_p.h b/src/quick/items/qquickmultipointtoucharea_p.h index e34a3faad6..d37cc6df7e 100644 --- a/src/quick/items/qquickmultipointtoucharea_p.h +++ b/src/quick/items/qquickmultipointtoucharea_p.h @@ -67,13 +67,13 @@ class Q_AUTOTEST_EXPORT QQuickTouchPoint : public QObject { Q_OBJECT Q_PROPERTY(int pointId READ pointId NOTIFY pointIdChanged) - Q_PROPERTY(QPointingDeviceUniqueId uniqueId READ uniqueId NOTIFY uniqueIdChanged REVISION 9) + Q_PROPERTY(QPointingDeviceUniqueId uniqueId READ uniqueId NOTIFY uniqueIdChanged REVISION(2, 9)) Q_PROPERTY(bool pressed READ pressed NOTIFY pressedChanged) Q_PROPERTY(qreal x READ x NOTIFY xChanged) Q_PROPERTY(qreal y READ y NOTIFY yChanged) - Q_PROPERTY(QSizeF ellipseDiameters READ ellipseDiameters NOTIFY ellipseDiametersChanged REVISION 9) + Q_PROPERTY(QSizeF ellipseDiameters READ ellipseDiameters NOTIFY ellipseDiametersChanged REVISION(2, 9)) Q_PROPERTY(qreal pressure READ pressure NOTIFY pressureChanged) - Q_PROPERTY(qreal rotation READ rotation NOTIFY rotationChanged REVISION 9) + Q_PROPERTY(qreal rotation READ rotation NOTIFY rotationChanged REVISION(2, 9)) Q_PROPERTY(QVector2D velocity READ velocity NOTIFY velocityChanged) Q_PROPERTY(QRectF area READ area NOTIFY areaChanged) @@ -84,6 +84,7 @@ class Q_AUTOTEST_EXPORT QQuickTouchPoint : public QObject Q_PROPERTY(qreal sceneX READ sceneX NOTIFY sceneXChanged) Q_PROPERTY(qreal sceneY READ sceneY NOTIFY sceneYChanged) QML_NAMED_ELEMENT(TouchPoint) + QML_ADDED_IN_VERSION(2, 0) public: QQuickTouchPoint(bool qmlDefined = true) @@ -144,12 +145,12 @@ public: Q_SIGNALS: void pressedChanged(); void pointIdChanged(); - Q_REVISION(9) void uniqueIdChanged(); + Q_REVISION(2, 9) void uniqueIdChanged(); void xChanged(); void yChanged(); - Q_REVISION(9) void ellipseDiametersChanged(); + Q_REVISION(2, 9) void ellipseDiametersChanged(); void pressureChanged(); - Q_REVISION(9) void rotationChanged(); + Q_REVISION(2, 9) void rotationChanged(); void velocityChanged(); void areaChanged(); void startXChanged(); @@ -187,6 +188,7 @@ class QQuickGrabGestureEvent : public QObject Q_PROPERTY(QQmlListProperty<QObject> touchPoints READ touchPoints CONSTANT) Q_PROPERTY(qreal dragThreshold READ dragThreshold CONSTANT) QML_NAMED_ELEMENT(GestureEvent) + QML_ADDED_IN_VERSION(2, 0) QML_UNCREATABLE("GestureEvent is only available in the context of handling the gestureStarted signal from MultiPointTouchArea.") public: @@ -216,6 +218,7 @@ class Q_AUTOTEST_EXPORT QQuickMultiPointTouchArea : public QQuickItem Q_PROPERTY(int maximumTouchPoints READ maximumTouchPoints WRITE setMaximumTouchPoints NOTIFY maximumTouchPointsChanged) Q_PROPERTY(bool mouseEnabled READ mouseEnabled WRITE setMouseEnabled NOTIFY mouseEnabledChanged) QML_NAMED_ELEMENT(MultiPointTouchArea) + QML_ADDED_IN_VERSION(2, 0) public: QQuickMultiPointTouchArea(QQuickItem *parent=nullptr); diff --git a/src/quick/items/qquickopenglinfo_p.h b/src/quick/items/qquickopenglinfo_p.h index b733d205e3..e0c2572b8d 100644 --- a/src/quick/items/qquickopenglinfo_p.h +++ b/src/quick/items/qquickopenglinfo_p.h @@ -72,7 +72,7 @@ class QQuickOpenGLInfo : public QObject QML_NAMED_ELEMENT(OpenGLInfo) QML_UNCREATABLE("OpenGLInfo is only available via attached properties.") - QML_ADDED_IN_MINOR_VERSION(4) + QML_ADDED_IN_VERSION(2, 4) QML_ATTACHED(QQuickOpenGLInfo) public: diff --git a/src/quick/items/qquickopenglshadereffect.cpp b/src/quick/items/qquickopenglshadereffect.cpp index e217fdb5d0..280cdbf831 100644 --- a/src/quick/items/qquickopenglshadereffect.cpp +++ b/src/quick/items/qquickopenglshadereffect.cpp @@ -52,8 +52,9 @@ #include "qquickshadereffectmesh_p.h" #include <QtQml/qqmlfile.h> -#include <QtCore/qsignalmapper.h> +#include <QtCore/qfile.h> #include <QtCore/qfileselector.h> +#include <QtCore/qsignalmapper.h> QT_BEGIN_NAMESPACE diff --git a/src/quick/items/qquickopenglshadereffectnode.cpp b/src/quick/items/qquickopenglshadereffectnode.cpp index 5721f116e8..71cfe96462 100644 --- a/src/quick/items/qquickopenglshadereffectnode.cpp +++ b/src/quick/items/qquickopenglshadereffectnode.cpp @@ -45,7 +45,7 @@ #include <QtQuick/private/qsgshadersourcebuilder_p.h> #include <QtQuick/private/qsgtexture_p.h> #include <QtCore/qmutex.h> -#include <QtGui/qopenglfunctions.h> +#include <qopenglfunctions.h> #ifndef GL_TEXTURE_EXTERNAL_OES #define GL_TEXTURE_EXTERNAL_OES 0x8D65 diff --git a/src/quick/items/qquickpainteditem.cpp b/src/quick/items/qquickpainteditem.cpp index 386c8d8862..1eb852f6bf 100644 --- a/src/quick/items/qquickpainteditem.cpp +++ b/src/quick/items/qquickpainteditem.cpp @@ -44,6 +44,9 @@ #include <QtQuick/private/qsgcontext_p.h> #include <private/qsgadaptationlayer_p.h> #include <qsgtextureprovider.h> +#if QT_CONFIG(opengl) +#include <QOpenGLContext> +#endif // QT_CONFIG(opengl) #include <qmath.h> @@ -368,10 +371,6 @@ void QQuickPaintedItem::setTextureSize(const QSize &size) emit textureSizeChanged(); } -#if QT_VERSION >= 0x060000 -#warning "Remove: QQuickPaintedItem::contentsBoundingRect, contentsScale, contentsSize. Also remove them from qsgadaptationlayer_p.h and qsgdefaultpainternode.h/cpp." -#endif - /*! \obsolete diff --git a/src/quick/items/qquickpainteditem.h b/src/quick/items/qquickpainteditem.h index 4821a409be..a6a78f6166 100644 --- a/src/quick/items/qquickpainteditem.h +++ b/src/quick/items/qquickpainteditem.h @@ -57,6 +57,7 @@ class Q_QUICK_EXPORT QQuickPaintedItem : public QQuickItem Q_PROPERTY(QSize textureSize READ textureSize WRITE setTextureSize NOTIFY textureSizeChanged) QML_NAMED_ELEMENT(PaintedItem) + QML_ADDED_IN_VERSION(2, 0) QML_UNCREATABLE("Cannot create instance of abstract class PaintedItem.") public: diff --git a/src/quick/items/qquickpathview_p.h b/src/quick/items/qquickpathview_p.h index c12358e4f6..0c5a6578c3 100644 --- a/src/quick/items/qquickpathview_p.h +++ b/src/quick/items/qquickpathview_p.h @@ -97,10 +97,11 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathView : public QQuickItem Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) Q_PROPERTY(int pathItemCount READ pathItemCount WRITE setPathItemCount RESET resetPathItemCount NOTIFY pathItemCountChanged) Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged) - Q_PROPERTY(MovementDirection movementDirection READ movementDirection WRITE setMovementDirection NOTIFY movementDirectionChanged REVISION 7) + Q_PROPERTY(MovementDirection movementDirection READ movementDirection WRITE setMovementDirection NOTIFY movementDirectionChanged REVISION(2, 7)) Q_PROPERTY(int cacheItemCount READ cacheItemCount WRITE setCacheItemCount NOTIFY cacheItemCountChanged) QML_NAMED_ELEMENT(PathView) + QML_ADDED_IN_VERSION(2, 0) QML_ATTACHED(QQuickPathViewAttached) public: @@ -182,7 +183,7 @@ public: Q_INVOKABLE void positionViewAtIndex(int index, int mode); Q_INVOKABLE int indexAt(qreal x, qreal y) const; Q_INVOKABLE QQuickItem *itemAt(qreal x, qreal y) const; - Q_REVISION(13) Q_INVOKABLE QQuickItem *itemAtIndex(int index) const; + Q_REVISION(2, 13) Q_INVOKABLE QQuickItem *itemAtIndex(int index) const; static QQuickPathViewAttached *qmlAttachedProperties(QObject *); @@ -215,7 +216,7 @@ Q_SIGNALS: void highlightMoveDurationChanged(); void movementStarted(); void movementEnded(); - Q_REVISION(7) void movementDirectionChanged(); + Q_REVISION(2, 7) void movementDirectionChanged(); void flickStarted(); void flickEnded(); void dragStarted(); diff --git a/src/quick/items/qquickpincharea_p.h b/src/quick/items/qquickpincharea_p.h index d7f814cc8a..27f895612a 100644 --- a/src/quick/items/qquickpincharea_p.h +++ b/src/quick/items/qquickpincharea_p.h @@ -71,6 +71,7 @@ class Q_AUTOTEST_EXPORT QQuickPinch : public QObject Q_PROPERTY(qreal maximumY READ ymax WRITE setYmax NOTIFY maximumYChanged) Q_PROPERTY(bool active READ active NOTIFY activeChanged) QML_NAMED_ELEMENT(Pinch) + QML_ADDED_IN_VERSION(2, 0) public: QQuickPinch(); @@ -212,6 +213,7 @@ class Q_AUTOTEST_EXPORT QQuickPinchEvent : public QObject Q_PROPERTY(int pointCount READ pointCount) Q_PROPERTY(bool accepted READ accepted WRITE setAccepted) QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: QQuickPinchEvent(QPointF c, qreal s, qreal a, qreal r) @@ -271,6 +273,7 @@ class Q_AUTOTEST_EXPORT QQuickPinchArea : public QQuickItem Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged) Q_PROPERTY(QQuickPinch *pinch READ pinch CONSTANT) QML_NAMED_ELEMENT(PinchArea) + QML_ADDED_IN_VERSION(2, 0) public: QQuickPinchArea(QQuickItem *parent=nullptr); @@ -286,7 +289,7 @@ Q_SIGNALS: void pinchStarted(QQuickPinchEvent *pinch); void pinchUpdated(QQuickPinchEvent *pinch); void pinchFinished(QQuickPinchEvent *pinch); - Q_REVISION(5) void smartZoom(QQuickPinchEvent *pinch); + Q_REVISION(2, 5) void smartZoom(QQuickPinchEvent *pinch); protected: bool childMouseEventFilter(QQuickItem *i, QEvent *e) override; diff --git a/src/quick/items/qquickpositioners_p.h b/src/quick/items/qquickpositioners_p.h index b924cb9c12..2c3aa674c6 100644 --- a/src/quick/items/qquickpositioners_p.h +++ b/src/quick/items/qquickpositioners_p.h @@ -107,13 +107,14 @@ class Q_QUICK_PRIVATE_EXPORT QQuickBasePositioner : public QQuickImplicitSizeIte Q_PROPERTY(QQuickTransition *move READ move WRITE setMove NOTIFY moveChanged) Q_PROPERTY(QQuickTransition *add READ add WRITE setAdd NOTIFY addChanged) - Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged REVISION 6) - Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged REVISION 6) - Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION 6) - Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION 6) - Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6) + Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged REVISION(2, 6)) + Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged REVISION(2, 6)) + Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION(2, 6)) + Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION(2, 6)) + Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION(2, 6)) QML_NAMED_ELEMENT(Positioner) + QML_ADDED_IN_VERSION(2, 0) QML_UNCREATABLE("Positioner is an abstract type that is only available as an attached property.") QML_ATTACHED(QQuickPositionerAttached) @@ -159,7 +160,7 @@ public: void setBottomPadding(qreal padding); void resetBottomPadding(); - Q_REVISION(9) Q_INVOKABLE void forceLayout(); + Q_REVISION(2, 9) Q_INVOKABLE void forceLayout(); protected: QQuickBasePositioner(QQuickBasePositionerPrivate &dd, PositionerType at, QQuickItem *parent); @@ -173,12 +174,12 @@ Q_SIGNALS: void populateChanged(); void moveChanged(); void addChanged(); - Q_REVISION(6) void paddingChanged(); - Q_REVISION(6) void topPaddingChanged(); - Q_REVISION(6) void leftPaddingChanged(); - Q_REVISION(6) void rightPaddingChanged(); - Q_REVISION(6) void bottomPaddingChanged(); - Q_REVISION(9) void positioningComplete(); + Q_REVISION(2, 6) void paddingChanged(); + Q_REVISION(2, 6) void topPaddingChanged(); + Q_REVISION(2, 6) void leftPaddingChanged(); + Q_REVISION(2, 6) void rightPaddingChanged(); + Q_REVISION(2, 6) void bottomPaddingChanged(); + Q_REVISION(2, 9) void positioningComplete(); protected Q_SLOTS: void prePositioning(); @@ -236,6 +237,7 @@ class Q_AUTOTEST_EXPORT QQuickColumn : public QQuickBasePositioner { Q_OBJECT QML_NAMED_ELEMENT(Column) + QML_ADDED_IN_VERSION(2, 0) public: QQuickColumn(QQuickItem *parent=nullptr); @@ -253,6 +255,7 @@ class Q_AUTOTEST_EXPORT QQuickRow: public QQuickBasePositioner Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged) Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged) QML_NAMED_ELEMENT(Row) + QML_ADDED_IN_VERSION(2, 0) public: QQuickRow(QQuickItem *parent=nullptr); @@ -284,10 +287,11 @@ class Q_AUTOTEST_EXPORT QQuickGrid : public QQuickBasePositioner Q_PROPERTY(Flow flow READ flow WRITE setFlow NOTIFY flowChanged) Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged) Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged) - Q_PROPERTY(HAlignment horizontalItemAlignment READ hItemAlign WRITE setHItemAlign NOTIFY horizontalAlignmentChanged REVISION 1) - Q_PROPERTY(HAlignment effectiveHorizontalItemAlignment READ effectiveHAlign NOTIFY effectiveHorizontalAlignmentChanged REVISION 1) - Q_PROPERTY(VAlignment verticalItemAlignment READ vItemAlign WRITE setVItemAlign NOTIFY verticalAlignmentChanged REVISION 1) + Q_PROPERTY(HAlignment horizontalItemAlignment READ hItemAlign WRITE setHItemAlign NOTIFY horizontalAlignmentChanged REVISION(2, 1)) + Q_PROPERTY(HAlignment effectiveHorizontalItemAlignment READ effectiveHAlign NOTIFY effectiveHorizontalAlignmentChanged REVISION(2, 1)) + Q_PROPERTY(VAlignment verticalItemAlignment READ vItemAlign WRITE setVItemAlign NOTIFY verticalAlignmentChanged REVISION(2, 1)) QML_NAMED_ELEMENT(Grid) + QML_ADDED_IN_VERSION(2, 0) public: QQuickGrid(QQuickItem *parent=nullptr); @@ -339,9 +343,9 @@ Q_SIGNALS: void effectiveLayoutDirectionChanged(); void rowSpacingChanged(); void columnSpacingChanged(); - Q_REVISION(1) void horizontalAlignmentChanged(HAlignment alignment); - Q_REVISION(1) void effectiveHorizontalAlignmentChanged(HAlignment alignment); - Q_REVISION(1) void verticalAlignmentChanged(VAlignment alignment); + Q_REVISION(2, 1) void horizontalAlignmentChanged(HAlignment alignment); + Q_REVISION(2, 1) void effectiveHorizontalAlignmentChanged(HAlignment alignment); + Q_REVISION(2, 1) void verticalAlignmentChanged(VAlignment alignment); protected: void doPositioning(QSizeF *contentSize) override; @@ -369,6 +373,7 @@ class Q_AUTOTEST_EXPORT QQuickFlow: public QQuickBasePositioner Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged) Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged) QML_NAMED_ELEMENT(Flow) + QML_ADDED_IN_VERSION(2, 0) public: QQuickFlow(QQuickItem *parent=nullptr); diff --git a/src/quick/items/qquickrectangle_p.h b/src/quick/items/qquickrectangle_p.h index 934300b63b..c4f03de770 100644 --- a/src/quick/items/qquickrectangle_p.h +++ b/src/quick/items/qquickrectangle_p.h @@ -67,6 +67,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPen : public QObject Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY penChanged) Q_PROPERTY(bool pixelAligned READ pixelAligned WRITE setPixelAligned NOTIFY penChanged) QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: QQuickPen(QObject *parent=nullptr); @@ -98,6 +99,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickGradientStop : public QObject Q_PROPERTY(qreal position READ position WRITE setPosition) Q_PROPERTY(QColor color READ color WRITE setColor) QML_NAMED_ELEMENT(GradientStop) + QML_ADDED_IN_VERSION(2, 0) public: QQuickGradientStop(QObject *parent=nullptr); @@ -121,9 +123,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickGradient : public QObject Q_OBJECT Q_PROPERTY(QQmlListProperty<QQuickGradientStop> stops READ stops) - Q_PROPERTY(Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged REVISION 12) + Q_PROPERTY(Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged REVISION(2, 12)) Q_CLASSINFO("DefaultProperty", "stops") QML_NAMED_ELEMENT(Gradient) + QML_ADDED_IN_VERSION(2, 0) Q_ENUMS(QGradient::Preset) public: @@ -165,6 +168,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickRectangle : public QQuickItem Q_PROPERTY(QQuickPen * border READ border CONSTANT) Q_PROPERTY(qreal radius READ radius WRITE setRadius NOTIFY radiusChanged) QML_NAMED_ELEMENT(Rectangle) + QML_ADDED_IN_VERSION(2, 0) public: QQuickRectangle(QQuickItem *parent=nullptr); diff --git a/src/quick/items/qquickrendercontrol.cpp b/src/quick/items/qquickrendercontrol.cpp index 9f9777f199..08d04d3b11 100644 --- a/src/quick/items/qquickrendercontrol.cpp +++ b/src/quick/items/qquickrendercontrol.cpp @@ -45,7 +45,7 @@ #include <QtQuick/private/qquickanimatorcontroller_p.h> #if QT_CONFIG(opengl) -# include <QtGui/QOpenGLContext> +# include <QOpenGLContext> # include <QtQuick/private/qsgdefaultrendercontext_p.h> #if QT_CONFIG(quick_shadereffect) # include <QtQuick/private/qquickopenglshadereffectnode_p.h> diff --git a/src/quick/items/qquickrepeater_p.h b/src/quick/items/qquickrepeater_p.h index 20984fa23e..652651efb9 100644 --- a/src/quick/items/qquickrepeater_p.h +++ b/src/quick/items/qquickrepeater_p.h @@ -71,6 +71,7 @@ class Q_AUTOTEST_EXPORT QQuickRepeater : public QQuickItem Q_PROPERTY(int count READ count NOTIFY countChanged) Q_CLASSINFO("DefaultProperty", "delegate") QML_NAMED_ELEMENT(Repeater) + QML_ADDED_IN_VERSION(2, 0) public: QQuickRepeater(QQuickItem *parent=nullptr); diff --git a/src/quick/items/qquickscalegrid_p_p.h b/src/quick/items/qquickscalegrid_p_p.h index 56b0ee86ab..1eb6c05ef1 100644 --- a/src/quick/items/qquickscalegrid_p_p.h +++ b/src/quick/items/qquickscalegrid_p_p.h @@ -70,6 +70,7 @@ class Q_AUTOTEST_EXPORT QQuickScaleGrid : public QObject Q_PROPERTY(int right READ right WRITE setRight NOTIFY rightBorderChanged) Q_PROPERTY(int bottom READ bottom WRITE setBottom NOTIFY bottomBorderChanged) QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: QQuickScaleGrid(QObject *parent=nullptr); diff --git a/src/quick/items/qquickscreen_p.h b/src/quick/items/qquickscreen_p.h index b4266d78c7..dc1c820309 100644 --- a/src/quick/items/qquickscreen_p.h +++ b/src/quick/items/qquickscreen_p.h @@ -68,9 +68,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickScreenInfo : public QObject { Q_OBJECT Q_PROPERTY(QString name READ name NOTIFY nameChanged) - Q_PROPERTY(QString manufacturer READ manufacturer NOTIFY manufacturerChanged REVISION 10) - Q_PROPERTY(QString model READ model NOTIFY modelChanged REVISION 10) - Q_PROPERTY(QString serialNumber READ serialNumber NOTIFY serialNumberChanged REVISION 10) + Q_PROPERTY(QString manufacturer READ manufacturer NOTIFY manufacturerChanged REVISION(2, 10)) + Q_PROPERTY(QString model READ model NOTIFY modelChanged REVISION(2, 10)) + Q_PROPERTY(QString serialNumber READ serialNumber NOTIFY serialNumberChanged REVISION(2, 10)) Q_PROPERTY(int width READ width NOTIFY widthChanged) Q_PROPERTY(int height READ height NOTIFY heightChanged) Q_PROPERTY(int desktopAvailableWidth READ desktopAvailableWidth NOTIFY desktopGeometryChanged) @@ -83,8 +83,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickScreenInfo : public QObject // TODO Qt 6 Remove this orientation -> incomplete device orientation -> better use OrientationSensor Q_PROPERTY(Qt::ScreenOrientation orientation READ orientation NOTIFY orientationChanged) - Q_PROPERTY(int virtualX READ virtualX NOTIFY virtualXChanged REVISION 3) - Q_PROPERTY(int virtualY READ virtualY NOTIFY virtualYChanged REVISION 3) + Q_PROPERTY(int virtualX READ virtualX NOTIFY virtualXChanged REVISION(2, 3)) + Q_PROPERTY(int virtualY READ virtualY NOTIFY virtualYChanged REVISION(2, 3)) public: QQuickScreenInfo(QObject *parent = nullptr, QScreen *wrappedScreen = nullptr); @@ -110,9 +110,9 @@ public: Q_SIGNALS: void nameChanged(); - Q_REVISION(10) void manufacturerChanged(); - Q_REVISION(10) void modelChanged(); - Q_REVISION(10) void serialNumberChanged(); + Q_REVISION(2, 10) void manufacturerChanged(); + Q_REVISION(2, 10) void modelChanged(); + Q_REVISION(2, 10) void serialNumberChanged(); void widthChanged(); void heightChanged(); void desktopGeometryChanged(); @@ -121,8 +121,8 @@ Q_SIGNALS: void devicePixelRatioChanged(); void primaryOrientationChanged(); void orientationChanged(); - Q_REVISION(3) void virtualXChanged(); - Q_REVISION(3) void virtualYChanged(); + Q_REVISION(2, 3) void virtualXChanged(); + Q_REVISION(2, 3) void virtualYChanged(); protected: QPointer<QScreen> m_screen; diff --git a/src/quick/items/qquickshadereffect.cpp b/src/quick/items/qquickshadereffect.cpp index b3c8386fd9..e71e6dc698 100644 --- a/src/quick/items/qquickshadereffect.cpp +++ b/src/quick/items/qquickshadereffect.cpp @@ -179,201 +179,11 @@ QT_BEGIN_NAMESPACE is a URL with the \c file or \c qrc schema, it is treated as a file reference and the source code is read from the specified file. - \section1 Direct3D and HLSL - - Direct3D backends provide ShaderEffect support with HLSL. The Direct3D 12 - backend requires using at least Shader Model 5.0 both for vertex and pixel - shaders. When necessary, GraphicsInfo.shaderType can be used to decide - at runtime what kind of value to assign to \l fragmentShader or - \l vertexShader. - - All concepts described above for OpenGL and GLSL apply to Direct3D and HLSL - as well. There are however a number of notable practical differences, which - are the following: - - Instead of uniforms, HLSL shaders are expected to use a single constant - buffer, assigned to register \c b0. The special names \c qt_Matrix, - \c qt_Opacity, and \c qt_SubRect_<name> function the same way as with GLSL. - All other members of the buffer are expected to map to properties in the - ShaderEffect item. - - \note The buffer layout must be compatible for both shaders. This means - that application-provided shaders must make sure \c qt_Matrix and - \c qt_Opacity are included in the buffer, starting at offset 0, when custom - code is provided for one type of shader only, leading to ShaderEffect - providing the other shader. This is due to ShaderEffect's built-in shader code - declaring a constant buffer containing \c{float4x4 qt_Matrix; float qt_Opacity;}. - - Unlike GLSL's attributes, no names are used for vertex input elements. - Therefore qt_Vertex and qt_MultiTexCoord0 are not relevant. Instead, the - standard Direct3D semantics, \c POSITION and \c TEXCOORD (or \c TEXCOORD0) - are used for identifying the correct input layout. - - Unlike GLSL's samplers, texture and sampler objects are separate in HLSL. - Shaders are expected to expect 2D, non-array, non-multisample textures. - Both the texture and sampler binding points are expected to be sequential - and start from 0 (meaning registers \c{t0, t1, ...}, and \c{s0, s1, ...}, - respectively). Unlike with OpenGL, samplers are not mapped to Qt Quick item - properties and therefore the name of the sampler is not relevant. Instead, - it is the textures that map to properties referencing \l Image or - \l ShaderEffectSource items. - - Unlike OpenGL, backends for modern APIs will typically prefer offline - compilation and shipping pre-compiled bytecode with applications instead of - inlined shader source strings. In this case the string properties for - vertex and fragment shaders are treated as URLs referring to local files or - files shipped via the Qt resource system. - - To check at runtime what is supported, use the - GraphicsInfo.shaderSourceType and GraphicsInfo.shaderCompilationType - properties. Note that these are bitmasks, because some backends may support - multiple approaches. - - In case of Direct3D 12, all combinations are supported. If the vertexShader - and fragmentShader properties form a valid URL with the \c file or \c qrc - schema, the bytecode or HLSL source code is read from the specified file. - The type of the file contents is detected automatically. Otherwise, the - string is treated as HLSL source code and is compiled at runtime, assuming - Shader Model 5.0 and an entry point of \c{"main"}. This allows dynamically - constructing shader strings. However, whenever the shader source code is - static, it is strongly recommended to pre-compile to bytecode using the - \c fxc tool and refer to these files from QML. This will be a lot more - efficient at runtime and allows catching syntax errors in the shaders at - compile time. - - Unlike OpenGL, the Direct3D backend is able to perform runtime shader - compilation on dedicated threads. This is managed transparently to the - applications, and means that ShaderEffect items that contain HLSL source - strings do not block the rendering or other parts of the application until - the bytecode is ready. - - Using files with bytecode is more flexible also when it comes to the entry - point name (it can be anything, not limited to \c main) and the shader - model (it can be something newer than 5.0, for instance 5.1). - - \table 70% - \row - \li \qml - import QtQuick 2.0 - - Rectangle { - width: 200; height: 100 - Row { - Image { id: img; - sourceSize { width: 100; height: 100 } source: "qt-logo.png" } - ShaderEffect { - width: 100; height: 100 - property variant src: img - fragmentShader: "qrc:/effect_ps.cso" - } - } - } - \endqml - \row - \li where \c effect_ps.cso is the compiled bytecode for the following HLSL shader: - \code - cbuffer ConstantBuffer : register(b0) - { - float4x4 qt_Matrix; - float qt_Opacity; - }; - Texture2D src : register(t0); - SamplerState srcSampler : register(s0); - float4 ExamplePixelShader(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET - { - float4 tex = src.Sample(srcSampler, coord); - float3 col = dot(tex.rgb, float3(0.344, 0.5, 0.156)); - return float4(col, tex.a) * qt_Opacity; - } - \endcode - \endtable - - The above is equivalent to the OpenGL example presented earlier. The vertex - shader is provided implicitly by ShaderEffect. Note that the output of the - pixel shader is using premultiplied alpha and that \c qt_Matrix is present - in the constant buffer at offset 0, even though the pixel shader does not - use the value. - - If desired, the HLSL source code can be placed directly into the QML - source, similarly to how its done with GLSL. The only difference in this - case is the entry point name, which must be \c main when using inline - source strings. - - Alternatively, we could also have referred to a file containing the source - of the effect instead of the compiled bytecode version. - - Some effects will want to provide a vertex shader as well. Below is a - similar effect with both the vertex and fragment shader provided by the - application. This time the colorization factor is provided by the QML item - instead of hardcoding it in the shader. This can allow, among others, - animating the value using QML's and Qt Quick's standard facilities. - - \table 70% - \row - \li \qml - import QtQuick 2.0 - - Rectangle { - width: 200; height: 100 - Row { - Image { id: img; - sourceSize { width: 100; height: 100 } source: "qt-logo.png" } - ShaderEffect { - width: 100; height: 100 - property variant src: img - property variant color: Qt.vector3d(0.344, 0.5, 0.156) - vertexShader: "qrc:/effect_vs.cso" - fragmentShader: "qrc:/effect_ps.cso" - } - } - } - \endqml - \row - \li where \c effect_vs.cso and \c effect_ps.cso are the compiled bytecode - for \c ExampleVertexShader and \c ExamplePixelShader. The source code is - presented as one snippet here, the shaders can however be placed in - separate source files as well. - \code - cbuffer ConstantBuffer : register(b0) - { - float4x4 qt_Matrix; - float qt_Opacity; - float3 color; - }; - Texture2D src : register(t0); - SamplerState srcSampler : register(s0); - struct PSInput - { - float4 position : SV_POSITION; - float2 coord : TEXCOORD0; - }; - PSInput ExampleVertexShader(float4 position : POSITION, float2 coord : TEXCOORD0) - { - PSInput result; - result.position = mul(qt_Matrix, position); - result.coord = coord; - return result; - } - float4 ExamplePixelShader(PSInput input) : SV_TARGET - { - float4 tex = src.Sample(srcSampler, coord); - float3 col = dot(tex.rgb, color); - return float4(col, tex.a) * qt_Opacity; - } - \endcode - \endtable - - \note With OpenGL the \c y coordinate runs from bottom to top whereas with - Direct 3D it goes top to bottom. For shader effect sources Qt Quick hides - the difference by treating QtQuick::ShaderEffectSource::textureMirroring as - appropriate, meaning texture coordinates in HLSL version of the shaders - will not need any adjustments compared to the equivalent GLSL code. - \section1 Cross-platform, Cross-API ShaderEffect Items - Some applications will want to be functional with multiple accelerated - graphics backends. This has consequences for ShaderEffect items because the - supported shading languages may vary from backend to backend. + Some applications will want to be functional with multiple graphics + APIs. This has consequences for ShaderEffect items because the supported + shading languages may vary from backend to backend. There are two approaches to handle this: either write conditional property values based on GraphicsInfo.shaderType, or use file selectors. In practice @@ -404,20 +214,8 @@ QT_BEGIN_NAMESPACE gl_FragColor = vec4(vec3(dot(tex.rgb, vec3(0.344, 0.5, 0.156))), tex.a) * qt_Opacity;" - : GraphicsInfo.shaderType === GraphicsInfo.HLSL ? - "cbuffer ConstantBuffer : register(b0) - { - float4x4 qt_Matrix; - float qt_Opacity; - }; - Texture2D src : register(t0); - SamplerState srcSampler : register(s0); - float4 ExamplePixelShader(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET - { - float4 tex = src.Sample(srcSampler, coord); - float3 col = dot(tex.rgb, float3(0.344, 0.5, 0.156)); - return float4(col, tex.a) * qt_Opacity; - }" + : GraphicsInfo.shaderType === GraphicsInfo.RhiShader ? + "qrc:/shader.frag.qsb" : "" } } @@ -429,15 +227,14 @@ QT_BEGIN_NAMESPACE reported by GraphicsInfo is not up-to-date until the ShaderEffect item gets associated with a QQuickWindow. Before that, the reported value is GraphicsInfo.UnknownShadingLanguage. The alternative is to place the GLSL - source code and the compiled D3D bytecode into the files - \c{shaders/effect.frag} and \c{shaders/+hlsl/effect.frag}, include them in - the Qt resource system, and let the ShaderEffect's internal QFileSelector - do its job. The selector-less version is the GLSL source, while the \c hlsl - selector is used when running on the D3D12 backend. The file under - \c{+hlsl} can then contain either HLSL source code or compiled bytecode - from the \c fxc tool. Additionally, when using a version 3.2 or newer core - profile context with OpenGL, GLSL sources with a core profile compatible - syntax can be placed under \c{+glslcore}. + source code and the RHI-compatible shader pack into the files + \c{shaders/effect.frag} and \c{shaders/+qsb/effect.frag}, include them in + the Qt resource system, and let the ShaderEffect's internal QFileSelector do + its job. The selector-less version is the GLSL source, while the \c qsb + selector is used when running with the Qt graphics abstraction (RHI). + Additionally, when using a version 3.2 or newer core profile context with + OpenGL, GLSL sources with a core profile compatible syntax can be placed + under \c{+glslcore}. \qml import QtQuick 2.8 // for GraphicsInfo @@ -552,11 +349,7 @@ QQuickShaderEffect::~QQuickShaderEffect() With GLSL the default shader expects the texture coordinate to be passed from the vertex shader as \c{varying highp vec2 qt_TexCoord0}, and it - samples from a sampler2D named \c source. With HLSL the texture is named - \c source, while the vertex shader is expected to provide - \c{float2 coord : TEXCOORD0} in its output in addition to - \c{float4 position : SV_POSITION} (names can differ since linking is done - based on the semantics). + samples from a sampler2D named \c source. \sa vertexShader, GraphicsInfo */ @@ -593,9 +386,7 @@ void QQuickShaderEffect::setFragmentShader(const QByteArray &code) filesystem or bundled with the executable via Qt's resource system. With GLSL the default shader passes the texture coordinate along to the - fragment shader as \c{varying highp vec2 qt_TexCoord0}. With HLSL it is - enough to use the standard \c TEXCOORD0 semantic, for example - \c{float2 coord : TEXCOORD0}. + fragment shader as \c{varying highp vec2 qt_TexCoord0}. \sa fragmentShader, GraphicsInfo */ diff --git a/src/quick/items/qquickshadereffect_p.h b/src/quick/items/qquickshadereffect_p.h index c14907092c..16eb252add 100644 --- a/src/quick/items/qquickshadereffect_p.h +++ b/src/quick/items/qquickshadereffect_p.h @@ -74,8 +74,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffect : public QQuickItem Q_PROPERTY(CullMode cullMode READ cullMode WRITE setCullMode NOTIFY cullModeChanged) Q_PROPERTY(QString log READ log NOTIFY logChanged) Q_PROPERTY(Status status READ status NOTIFY statusChanged) - Q_PROPERTY(bool supportsAtlasTextures READ supportsAtlasTextures WRITE setSupportsAtlasTextures NOTIFY supportsAtlasTexturesChanged REVISION 4) + Q_PROPERTY(bool supportsAtlasTextures READ supportsAtlasTextures WRITE setSupportsAtlasTextures NOTIFY supportsAtlasTexturesChanged REVISION(2, 4)) QML_NAMED_ELEMENT(ShaderEffect) + QML_ADDED_IN_VERSION(2, 0) public: enum CullMode { diff --git a/src/quick/items/qquickshadereffectmesh_p.h b/src/quick/items/qquickshadereffectmesh_p.h index 710d37c275..4cd885a740 100644 --- a/src/quick/items/qquickshadereffectmesh_p.h +++ b/src/quick/items/qquickshadereffectmesh_p.h @@ -78,6 +78,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffectMesh : public QObject Q_OBJECT QML_NAMED_ELEMENT(ShaderEffectMesh) + QML_ADDED_IN_VERSION(2, 0) QML_UNCREATABLE("Cannot create instance of abstract class ShaderEffectMesh.") public: @@ -102,6 +103,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickGridMesh : public QQuickShaderEffectMesh Q_OBJECT Q_PROPERTY(QSize resolution READ resolution WRITE setResolution NOTIFY resolutionChanged) QML_NAMED_ELEMENT(GridMesh) + QML_ADDED_IN_VERSION(2, 0) public: QQuickGridMesh(QObject *parent = nullptr); bool validateAttributes(const QVector<QByteArray> &attributes, int *posIndex) override; @@ -131,7 +133,7 @@ class QQuickBorderImageMesh : public QQuickShaderEffectMesh Q_PROPERTY(TileMode verticalTileMode READ verticalTileMode WRITE setVerticalTileMode NOTIFY verticalTileModeChanged) QML_NAMED_ELEMENT(BorderImageMesh) - QML_ADDED_IN_MINOR_VERSION(8) + QML_ADDED_IN_VERSION(2, 8) public: QQuickBorderImageMesh(QObject *parent = nullptr); diff --git a/src/quick/items/qquickshadereffectsource_p.h b/src/quick/items/qquickshadereffectsource_p.h index c0a1ccab78..fe419e5959 100644 --- a/src/quick/items/qquickshadereffectsource_p.h +++ b/src/quick/items/qquickshadereffectsource_p.h @@ -87,9 +87,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffectSource : public QQuickItem, publi Q_PROPERTY(bool hideSource READ hideSource WRITE setHideSource NOTIFY hideSourceChanged) Q_PROPERTY(bool mipmap READ mipmap WRITE setMipmap NOTIFY mipmapChanged) Q_PROPERTY(bool recursive READ recursive WRITE setRecursive NOTIFY recursiveChanged) - Q_PROPERTY(TextureMirroring textureMirroring READ textureMirroring WRITE setTextureMirroring NOTIFY textureMirroringChanged REVISION 6) - Q_PROPERTY(int samples READ samples WRITE setSamples NOTIFY samplesChanged REVISION 9) + Q_PROPERTY(TextureMirroring textureMirroring READ textureMirroring WRITE setTextureMirroring NOTIFY textureMirroringChanged REVISION(2, 6)) + Q_PROPERTY(int samples READ samples WRITE setSamples NOTIFY samplesChanged REVISION(2, 9)) QML_NAMED_ELEMENT(ShaderEffectSource) + QML_ADDED_IN_VERSION(2, 0) public: enum WrapMode { diff --git a/src/quick/items/qquicksprite_p.h b/src/quick/items/qquicksprite_p.h index 98e5b82db8..328dc74f47 100644 --- a/src/quick/items/qquicksprite_p.h +++ b/src/quick/items/qquicksprite_p.h @@ -87,6 +87,7 @@ class Q_QUICK_EXPORT QQuickSprite : public QQuickStochasticState Q_PROPERTY(int frameDuration READ frameDuration WRITE setFrameDuration NOTIFY frameDurationChanged RESET resetFrameDuration) Q_PROPERTY(int frameDurationVariation READ frameDurationVariation WRITE setFrameDurationVariation NOTIFY frameDurationVariationChanged) QML_NAMED_ELEMENT(Sprite) + QML_ADDED_IN_VERSION(2, 0) public: explicit QQuickSprite(QObject *parent = nullptr); diff --git a/src/quick/items/qquickspriteengine.cpp b/src/quick/items/qquickspriteengine.cpp index 8c52703938..3e4ed8707b 100644 --- a/src/quick/items/qquickspriteengine.cpp +++ b/src/quick/items/qquickspriteengine.cpp @@ -45,7 +45,7 @@ #include <QPainter> #include <QRandomGenerator> #include <QSet> -#include <QtGui/qopengl.h> +#include <qopengl.h> #include <QOpenGLFunctions> QT_BEGIN_NAMESPACE diff --git a/src/quick/items/qquickspritesequence_p.h b/src/quick/items/qquickspritesequence_p.h index 8361f7832a..39b536daae 100644 --- a/src/quick/items/qquickspritesequence_p.h +++ b/src/quick/items/qquickspritesequence_p.h @@ -75,6 +75,7 @@ class Q_AUTOTEST_EXPORT QQuickSpriteSequence : public QQuickItem Q_PROPERTY(QQmlListProperty<QQuickSprite> sprites READ sprites) Q_CLASSINFO("DefaultProperty", "sprites") QML_NAMED_ELEMENT(SpriteSequence) + QML_ADDED_IN_VERSION(2, 0) public: explicit QQuickSpriteSequence(QQuickItem *parent = nullptr); diff --git a/src/quick/items/qquickstateoperations_p.h b/src/quick/items/qquickstateoperations_p.h index d451dc6f77..5ba5400367 100644 --- a/src/quick/items/qquickstateoperations_p.h +++ b/src/quick/items/qquickstateoperations_p.h @@ -75,6 +75,7 @@ class Q_AUTOTEST_EXPORT QQuickParentChange : public QQuickStateOperation, public Q_PROPERTY(QQmlScriptString scale READ scale WRITE setScale) Q_PROPERTY(QQmlScriptString rotation READ rotation WRITE setRotation) QML_NAMED_ELEMENT(ParentChange) + QML_ADDED_IN_VERSION(2, 0) public: QQuickParentChange(QObject *parent=nullptr); ~QQuickParentChange(); @@ -138,6 +139,7 @@ class Q_AUTOTEST_EXPORT QQuickAnchorSet : public QObject Q_PROPERTY(QQmlScriptString verticalCenter READ verticalCenter WRITE setVerticalCenter RESET resetVerticalCenter) Q_PROPERTY(QQmlScriptString baseline READ baseline WRITE setBaseline RESET resetBaseline) QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: QQuickAnchorSet(QObject *parent=nullptr); @@ -188,6 +190,7 @@ class Q_AUTOTEST_EXPORT QQuickAnchorChanges : public QQuickStateOperation, publi Q_PROPERTY(QQuickItem *target READ object WRITE setObject) Q_PROPERTY(QQuickAnchorSet *anchors READ anchors CONSTANT) QML_NAMED_ELEMENT(AnchorChanges) + QML_ADDED_IN_VERSION(2, 0) public: QQuickAnchorChanges(QObject *parent=nullptr); diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp index 403801b7ae..56c5bedd4d 100644 --- a/src/quick/items/qquicktableview.cpp +++ b/src/quick/items/qquicktableview.cpp @@ -520,10 +520,10 @@ int QQuickTableViewPrivate::nextVisibleEdgeIndexAroundLoadedTable(Qt::Edge edge) // visible, and should be loaded next if the content item moves. int startIndex = -1; switch (edge) { - case Qt::LeftEdge: startIndex = loadedColumns.firstKey() - 1; break; - case Qt::RightEdge: startIndex = loadedColumns.lastKey() + 1; break; - case Qt::TopEdge: startIndex = loadedRows.firstKey() - 1; break; - case Qt::BottomEdge: startIndex = loadedRows.lastKey() + 1; break; + case Qt::LeftEdge: startIndex = leftColumn() - 1; break; + case Qt::RightEdge: startIndex = rightColumn() + 1; break; + case Qt::TopEdge: startIndex = topRow() - 1; break; + case Qt::BottomEdge: startIndex = bottomRow() + 1; break; } return nextVisibleEdgeIndex(edge, startIndex); @@ -1913,7 +1913,7 @@ void QQuickTableViewPrivate::loadEdge(Qt::Edge edge, QQmlIncubator::IncubationMo const int edgeIndex = nextVisibleEdgeIndexAroundLoadedTable(edge); qCDebug(lcTableViewDelegateLifecycle) << edge << edgeIndex; - const QList<int> visibleCells = edge & (Qt::LeftEdge | Qt::RightEdge) + const auto visibleCells = edge & (Qt::LeftEdge | Qt::RightEdge) ? loadedRows.keys() : loadedColumns.keys(); loadRequest.begin(edge, edgeIndex, visibleCells, incubationMode); processLoadRequest(); @@ -2050,7 +2050,8 @@ bool QQuickTableViewPrivate::updateTableRecursive() if (!updateComplete) return false; - for (auto syncChild : qAsConst(syncChildren)) { + const auto children = syncChildren; + for (auto syncChild : children) { auto syncChild_d = syncChild->d_func(); syncChild_d->scheduledRebuildOptions |= rebuildOptions; @@ -2120,15 +2121,17 @@ void QQuickTableViewPrivate::fixup(QQuickFlickablePrivate::AxisData &data, qreal QQuickFlickablePrivate::fixup(data, minExtent, maxExtent); } -int QQuickTableViewPrivate::resolveImportVersion() +QTypeRevision QQuickTableViewPrivate::resolveImportVersion() { const auto data = QQmlData::get(q_func()); if (!data || !data->propertyCache) - return 0; + return QTypeRevision::zero(); const auto cppMetaObject = data->propertyCache->firstCppMetaObject(); const auto qmlTypeView = QQmlMetaType::qmlType(cppMetaObject); - return qmlTypeView.minorVersion(); + + // TODO: did we rather want qmlTypeView.revision() here? + return qmlTypeView.metaObjectRevision(); } void QQuickTableViewPrivate::createWrapperModel() diff --git a/src/quick/items/qquicktableview_p.h b/src/quick/items/qquicktableview_p.h index d549aaddf7..c71e74bfdc 100644 --- a/src/quick/items/qquicktableview_p.h +++ b/src/quick/items/qquicktableview_p.h @@ -79,11 +79,11 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTableView : public QQuickFlickable Q_PROPERTY(bool reuseItems READ reuseItems WRITE setReuseItems NOTIFY reuseItemsChanged) Q_PROPERTY(qreal contentWidth READ contentWidth WRITE setContentWidth NOTIFY contentWidthChanged) Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight NOTIFY contentHeightChanged) - Q_PROPERTY(QQuickTableView *syncView READ syncView WRITE setSyncView NOTIFY syncViewChanged REVISION 14) - Q_PROPERTY(Qt::Orientations syncDirection READ syncDirection WRITE setSyncDirection NOTIFY syncDirectionChanged REVISION 14) + Q_PROPERTY(QQuickTableView *syncView READ syncView WRITE setSyncView NOTIFY syncViewChanged REVISION(2, 14)) + Q_PROPERTY(Qt::Orientations syncDirection READ syncDirection WRITE setSyncDirection NOTIFY syncDirectionChanged REVISION(2, 14)) QML_NAMED_ELEMENT(TableView) - QML_ADDED_IN_MINOR_VERSION(12) + QML_ADDED_IN_VERSION(2, 12) QML_ATTACHED(QQuickTableViewAttached) public: @@ -136,8 +136,8 @@ Q_SIGNALS: void modelChanged(); void delegateChanged(); void reuseItemsChanged(); - Q_REVISION(14) void syncViewChanged(); - Q_REVISION(14) void syncDirectionChanged(); + Q_REVISION(2, 14) void syncViewChanged(); + Q_REVISION(2, 14) void syncDirectionChanged(); protected: void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; diff --git a/src/quick/items/qquicktableview_p_p.h b/src/quick/items/qquicktableview_p_p.h index 7987d8c6d8..a3cc39419f 100644 --- a/src/quick/items/qquicktableview_p_p.h +++ b/src/quick/items/qquicktableview_p_p.h @@ -54,6 +54,7 @@ #include "qquicktableview_p.h" #include <QtCore/qtimer.h> +#include <QtCore/private/qflatmap_p.h> #include <QtQmlModels/private/qqmltableinstancemodel_p.h> #include <QtQml/private/qqmlincubator_p.h> #include <QtQmlModels/private/qqmlchangeset_p.h> @@ -119,7 +120,7 @@ public: qCDebug(lcTableViewDelegateLifecycle()) << "begin top-left:" << toString(); } - void begin(Qt::Edge edgeToLoad, int edgeIndex, const QList<int> visibleCellsInEdge, QQmlIncubator::IncubationMode incubationMode) + void begin(Qt::Edge edgeToLoad, int edgeIndex, const QVector<int> visibleCellsInEdge, QQmlIncubator::IncubationMode incubationMode) { Q_ASSERT(!m_active); m_active = true; @@ -169,7 +170,7 @@ public: private: Qt::Edge m_edge = Qt::Edge(0); - QList<int> m_visibleCellsInEdge; + QVector<int> m_visibleCellsInEdge; int m_edgeIndex = 0; int m_currentIndex = 0; bool m_active = false; @@ -246,8 +247,8 @@ public: // we need to fill up with more rows/columns. loadedTableInnerRect describes the pixels // that the loaded table covers if you remove one row/column on each side of the table, and // is used to determine rows/columns that are no longer visible and can be unloaded. - QMap<int, int> loadedColumns; - QMap<int, int> loadedRows; + QFlatMap<int, int> loadedColumns; + QFlatMap<int, int> loadedRows; QRectF loadedTableOuterRect; QRectF loadedTableInnerRect; @@ -333,10 +334,10 @@ public: qreal getColumnWidth(int column); qreal getRowHeight(int row); - inline int topRow() const { return loadedRows.firstKey(); } - inline int bottomRow() const { return loadedRows.lastKey(); } - inline int leftColumn() const { return loadedColumns.firstKey(); } - inline int rightColumn() const { return loadedColumns.lastKey(); } + inline int topRow() const { return loadedRows.cbegin().key(); } + inline int bottomRow() const { return (--loadedRows.cend()).key(); } + inline int leftColumn() const { return loadedColumns.cbegin().key(); } + inline int rightColumn() const { return (--loadedColumns.cend()).key(); } QQuickTableView *rootSyncView() const; @@ -394,7 +395,7 @@ public: void scheduleRebuildTable(QQuickTableViewPrivate::RebuildOptions options); - int resolveImportVersion(); + QTypeRevision resolveImportVersion(); void createWrapperModel(); void initItemCallback(int modelIndex, QObject *item); diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index 1c7f1ca6aa..816b48b190 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -1472,11 +1472,10 @@ QQuickText::~QQuickText() */ /*! - \qmlproperty enumeration QtQuick::Text::font.weight + \qmlproperty int QtQuick::Text::font.weight - Sets the font's weight. - - The weight can be one of: + The requested weight of the font. The weight requested must be an integer + between 0 and 99, or one of the predefined values: \list \li Font.Thin \li Font.Light diff --git a/src/quick/items/qquicktext_p.h b/src/quick/items/qquicktext_p.h index d310db508e..cb6d0e260d 100644 --- a/src/quick/items/qquicktext_p.h +++ b/src/quick/items/qquicktext_p.h @@ -90,17 +90,18 @@ class Q_QUICK_PRIVATE_EXPORT QQuickText : public QQuickImplicitSizeItem Q_PROPERTY(int minimumPointSize READ minimumPointSize WRITE setMinimumPointSize NOTIFY minimumPointSizeChanged) Q_PROPERTY(FontSizeMode fontSizeMode READ fontSizeMode WRITE setFontSizeMode NOTIFY fontSizeModeChanged) Q_PROPERTY(RenderType renderType READ renderType WRITE setRenderType NOTIFY renderTypeChanged) - Q_PROPERTY(QString hoveredLink READ hoveredLink NOTIFY linkHovered REVISION 2) + Q_PROPERTY(QString hoveredLink READ hoveredLink NOTIFY linkHovered REVISION(2, 2)) - Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged REVISION 6) - Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged REVISION 6) - Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION 6) - Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION 6) - Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6) + Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged REVISION(2, 6)) + Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged REVISION(2, 6)) + Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION(2, 6)) + Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION(2, 6)) + Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION(2, 6)) - Q_PROPERTY(QJSValue fontInfo READ fontInfo NOTIFY fontInfoChanged REVISION 9) - Q_PROPERTY(QSizeF advance READ advance NOTIFY contentSizeChanged REVISION 10) + Q_PROPERTY(QJSValue fontInfo READ fontInfo NOTIFY fontInfoChanged REVISION(2, 9)) + Q_PROPERTY(QSizeF advance READ advance NOTIFY contentSizeChanged REVISION(2, 10)) QML_NAMED_ELEMENT(Text) + QML_ADDED_IN_VERSION(2, 0) public: QQuickText(QQuickItem *parent=nullptr); @@ -224,14 +225,14 @@ public: QRectF boundingRect() const override; QRectF clipRect() const override; Q_INVOKABLE void doLayout(); // ### Qt 6: remove - Q_REVISION(9) Q_INVOKABLE void forceLayout(); + Q_REVISION(2, 9) Q_INVOKABLE void forceLayout(); RenderType renderType() const; void setRenderType(RenderType renderType); QString hoveredLink() const; - Q_REVISION(3) Q_INVOKABLE QString linkAt(qreal x, qreal y) const; + Q_REVISION(2, 3) Q_INVOKABLE QString linkAt(qreal x, qreal y) const; qreal padding() const; void setPadding(qreal padding); @@ -259,7 +260,7 @@ public: Q_SIGNALS: void textChanged(const QString &text); void linkActivated(const QString &link); - Q_REVISION(2) void linkHovered(const QString &link); + Q_REVISION(2, 2) void linkHovered(const QString &link); void fontChanged(const QFont &font); void colorChanged(); void linkColorChanged(); @@ -274,7 +275,7 @@ Q_SIGNALS: void textFormatChanged(QQuickText::TextFormat textFormat); void elideModeChanged(QQuickText::TextElideMode mode); void contentSizeChanged(); - // The next two signals should be marked as Q_REVISION(12). See QTBUG-71247 + // The next two signals should be marked as Q_REVISION(2, 12). See QTBUG-71247 void contentWidthChanged(qreal contentWidth); void contentHeightChanged(qreal contentHeight); @@ -287,12 +288,12 @@ Q_SIGNALS: void lineLaidOut(QQuickTextLine *line); void baseUrlChanged(); void renderTypeChanged(); - Q_REVISION(6) void paddingChanged(); - Q_REVISION(6) void topPaddingChanged(); - Q_REVISION(6) void leftPaddingChanged(); - Q_REVISION(6) void rightPaddingChanged(); - Q_REVISION(6) void bottomPaddingChanged(); - Q_REVISION(9) void fontInfoChanged(); + Q_REVISION(2, 6) void paddingChanged(); + Q_REVISION(2, 6) void topPaddingChanged(); + Q_REVISION(2, 6) void leftPaddingChanged(); + Q_REVISION(2, 6) void rightPaddingChanged(); + Q_REVISION(2, 6) void bottomPaddingChanged(); + Q_REVISION(2, 9) void fontInfoChanged(); protected: QQuickText(QQuickTextPrivate &dd, QQuickItem *parent = nullptr); @@ -333,6 +334,7 @@ class QQuickTextLine : public QObject Q_PROPERTY(qreal implicitWidth READ implicitWidth) Q_PROPERTY(bool isLast READ isLast) QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: QQuickTextLine(); diff --git a/src/quick/items/qquicktextdocument.h b/src/quick/items/qquicktextdocument.h index bf9162755c..aadc4ca8c0 100644 --- a/src/quick/items/qquicktextdocument.h +++ b/src/quick/items/qquicktextdocument.h @@ -50,6 +50,7 @@ class Q_QUICK_EXPORT QQuickTextDocument : public QObject { Q_OBJECT QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: QQuickTextDocument(QQuickItem *parent); diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp index 650b1961a4..bb6f003ceb 100644 --- a/src/quick/items/qquicktextedit.cpp +++ b/src/quick/items/qquicktextedit.cpp @@ -233,11 +233,10 @@ QString QQuickTextEdit::text() const */ /*! - \qmlproperty enumeration QtQuick::TextEdit::font.weight + \qmlproperty int QtQuick::TextEdit::font.weight - Sets the font's weight. - - The weight can be one of: + The requested weight of the font. The weight requested must be an integer + between 0 and 99, or one of the predefined values: \list \li Font.Thin \li Font.Light diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h index 227d8cbf51..37610ed7e6 100644 --- a/src/quick/items/qquicktextedit_p.h +++ b/src/quick/items/qquicktextedit_p.h @@ -94,7 +94,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTextEdit : public QQuickImplicitSizeItem Q_PROPERTY(bool persistentSelection READ persistentSelection WRITE setPersistentSelection NOTIFY persistentSelectionChanged) Q_PROPERTY(qreal textMargin READ textMargin WRITE setTextMargin NOTIFY textMarginChanged) Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ inputMethodHints WRITE setInputMethodHints NOTIFY inputMethodHintsChanged) - Q_PROPERTY(bool selectByKeyboard READ selectByKeyboard WRITE setSelectByKeyboard NOTIFY selectByKeyboardChanged REVISION 1) + Q_PROPERTY(bool selectByKeyboard READ selectByKeyboard WRITE setSelectByKeyboard NOTIFY selectByKeyboardChanged REVISION(2, 1)) Q_PROPERTY(bool selectByMouse READ selectByMouse WRITE setSelectByMouse NOTIFY selectByMouseChanged) Q_PROPERTY(SelectionMode mouseSelectionMode READ mouseSelectionMode WRITE setMouseSelectionMode NOTIFY mouseSelectionModeChanged) Q_PROPERTY(bool canPaste READ canPaste NOTIFY canPasteChanged) @@ -103,16 +103,17 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTextEdit : public QQuickImplicitSizeItem Q_PROPERTY(bool inputMethodComposing READ isInputMethodComposing NOTIFY inputMethodComposingChanged) Q_PROPERTY(QUrl baseUrl READ baseUrl WRITE setBaseUrl RESET resetBaseUrl NOTIFY baseUrlChanged) Q_PROPERTY(RenderType renderType READ renderType WRITE setRenderType NOTIFY renderTypeChanged) - Q_PROPERTY(QQuickTextDocument *textDocument READ textDocument CONSTANT FINAL REVISION 1) - Q_PROPERTY(QString hoveredLink READ hoveredLink NOTIFY linkHovered REVISION 2) - Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged REVISION 6) - Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged REVISION 6) - Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION 6) - Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION 6) - Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6) - Q_PROPERTY(QString preeditText READ preeditText NOTIFY preeditTextChanged REVISION 7) - Q_PROPERTY(qreal tabStopDistance READ tabStopDistance WRITE setTabStopDistance NOTIFY tabStopDistanceChanged REVISION 10) + Q_PROPERTY(QQuickTextDocument *textDocument READ textDocument CONSTANT FINAL REVISION(2, 1)) + Q_PROPERTY(QString hoveredLink READ hoveredLink NOTIFY linkHovered REVISION(2, 2)) + Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged REVISION(2, 6)) + Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged REVISION(2, 6)) + Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION(2, 6)) + Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION(2, 6)) + Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION(2, 6)) + Q_PROPERTY(QString preeditText READ preeditText NOTIFY preeditTextChanged REVISION(2, 7)) + Q_PROPERTY(qreal tabStopDistance READ tabStopDistance WRITE setTabStopDistance NOTIFY tabStopDistanceChanged REVISION(2, 10)) QML_NAMED_ELEMENT(TextEdit) + QML_ADDED_IN_VERSION(2, 0) public: QQuickTextEdit(QQuickItem *parent=nullptr); @@ -162,7 +163,7 @@ public: QString text() const; void setText(const QString &); - Q_REVISION(7) QString preeditText() const; + Q_REVISION(2, 7) QString preeditText() const; TextFormat textFormat() const; void setTextFormat(TextFormat format); @@ -247,7 +248,7 @@ public: #if QT_CONFIG(im) QVariant inputMethodQuery(Qt::InputMethodQuery property) const override; - Q_REVISION(4) Q_INVOKABLE QVariant inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const; + Q_REVISION(2, 4) Q_INVOKABLE QVariant inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const; #endif qreal contentWidth() const; @@ -277,7 +278,7 @@ public: QString hoveredLink() const; - Q_REVISION(3) Q_INVOKABLE QString linkAt(qreal x, qreal y) const; + Q_REVISION(2, 3) Q_INVOKABLE QString linkAt(qreal x, qreal y) const; qreal padding() const; void setPadding(qreal padding); @@ -304,7 +305,7 @@ public: Q_SIGNALS: void textChanged(); - Q_REVISION(7) void preeditTextChanged(); + Q_REVISION(2, 7) void preeditTextChanged(); void contentSizeChanged(); void cursorPositionChanged(); void cursorRectangleChanged(); @@ -327,11 +328,11 @@ Q_SIGNALS: void activeFocusOnPressChanged(bool activeFocusOnPressed); void persistentSelectionChanged(bool isPersistentSelection); void textMarginChanged(qreal textMargin); - Q_REVISION(1) void selectByKeyboardChanged(bool selectByKeyboard); + Q_REVISION(2, 1) void selectByKeyboardChanged(bool selectByKeyboard); void selectByMouseChanged(bool selectByMouse); void mouseSelectionModeChanged(QQuickTextEdit::SelectionMode mode); void linkActivated(const QString &link); - Q_REVISION(2) void linkHovered(const QString &link); + Q_REVISION(2, 2) void linkHovered(const QString &link); void canPasteChanged(); void canUndoChanged(); void canRedoChanged(); @@ -340,13 +341,13 @@ Q_SIGNALS: void baseUrlChanged(); void inputMethodHintsChanged(); void renderTypeChanged(); - Q_REVISION(6) void editingFinished(); - Q_REVISION(6) void paddingChanged(); - Q_REVISION(6) void topPaddingChanged(); - Q_REVISION(6) void leftPaddingChanged(); - Q_REVISION(6) void rightPaddingChanged(); - Q_REVISION(6) void bottomPaddingChanged(); - Q_REVISION(10) void tabStopDistanceChanged(qreal distance); + Q_REVISION(2, 6) void editingFinished(); + Q_REVISION(2, 6) void paddingChanged(); + Q_REVISION(2, 6) void topPaddingChanged(); + Q_REVISION(2, 6) void leftPaddingChanged(); + Q_REVISION(2, 6) void rightPaddingChanged(); + Q_REVISION(2, 6) void bottomPaddingChanged(); + Q_REVISION(2, 10) void tabStopDistanceChanged(qreal distance); public Q_SLOTS: void selectAll(); @@ -363,8 +364,8 @@ public Q_SLOTS: void redo(); void insert(int position, const QString &text); void remove(int start, int end); - Q_REVISION(2) void append(const QString &text); - Q_REVISION(7) void clear(); + Q_REVISION(2, 2) void append(const QString &text); + Q_REVISION(2, 7) void clear(); private Q_SLOTS: void q_textChanged(); diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index 6e0eb4e574..b204cb3417 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -255,11 +255,10 @@ QString QQuickTextInputPrivate::realText() const */ /*! - \qmlproperty enumeration QtQuick::TextInput::font.weight + \qmlproperty int QtQuick::TextInput::font.weight - Sets the font's weight. - - The weight can be one of: + The requested weight of the font. The weight requested must be an integer + between 0 and 99, or one of the predefined values: \list \li Font.Thin \li Font.Light diff --git a/src/quick/items/qquicktextinput_p.h b/src/quick/items/qquicktextinput_p.h index 9f7b82b168..234ebc2a0a 100644 --- a/src/quick/items/qquicktextinput_p.h +++ b/src/quick/items/qquicktextinput_p.h @@ -93,9 +93,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTextInput : public QQuickImplicitSizeItem Q_PROPERTY(EchoMode echoMode READ echoMode WRITE setEchoMode NOTIFY echoModeChanged) Q_PROPERTY(bool activeFocusOnPress READ focusOnPress WRITE setFocusOnPress NOTIFY activeFocusOnPressChanged) Q_PROPERTY(QString passwordCharacter READ passwordCharacter WRITE setPasswordCharacter NOTIFY passwordCharacterChanged) - Q_PROPERTY(int passwordMaskDelay READ passwordMaskDelay WRITE setPasswordMaskDelay RESET resetPasswordMaskDelay NOTIFY passwordMaskDelayChanged REVISION 4) + Q_PROPERTY(int passwordMaskDelay READ passwordMaskDelay WRITE setPasswordMaskDelay RESET resetPasswordMaskDelay NOTIFY passwordMaskDelayChanged REVISION(2, 4)) Q_PROPERTY(QString displayText READ displayText NOTIFY displayTextChanged) - Q_PROPERTY(QString preeditText READ preeditText NOTIFY preeditTextChanged REVISION 7) + Q_PROPERTY(QString preeditText READ preeditText NOTIFY preeditTextChanged REVISION(2, 7)) Q_PROPERTY(bool autoScroll READ autoScroll WRITE setAutoScroll NOTIFY autoScrollChanged) Q_PROPERTY(bool selectByMouse READ selectByMouse WRITE setSelectByMouse NOTIFY selectByMouseChanged) Q_PROPERTY(SelectionMode mouseSelectionMode READ mouseSelectionMode WRITE setMouseSelectionMode NOTIFY mouseSelectionModeChanged) @@ -108,12 +108,13 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTextInput : public QQuickImplicitSizeItem Q_PROPERTY(qreal contentHeight READ contentHeight NOTIFY contentSizeChanged) Q_PROPERTY(RenderType renderType READ renderType WRITE setRenderType NOTIFY renderTypeChanged) - Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged REVISION 6) - Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged REVISION 6) - Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION 6) - Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION 6) - Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6) + Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged REVISION(2, 6)) + Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged REVISION(2, 6)) + Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION(2, 6)) + Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION(2, 6)) + Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION(2, 6)) QML_NAMED_ELEMENT(TextInput) + QML_ADDED_IN_VERSION(2, 0) public: QQuickTextInput(QQuickItem * parent=nullptr); @@ -242,7 +243,7 @@ public: void resetPasswordMaskDelay(); QString displayText() const; - Q_REVISION(7) QString preeditText() const; + Q_REVISION(2, 7) QString preeditText() const; QQmlComponent* cursorDelegate() const; void setCursorDelegate(QQmlComponent*); @@ -269,7 +270,7 @@ public: #if QT_CONFIG(im) QVariant inputMethodQuery(Qt::InputMethodQuery property) const override; - Q_REVISION(4) Q_INVOKABLE QVariant inputMethodQuery(Qt::InputMethodQuery query, const QVariant &argument) const; + Q_REVISION(2, 4) Q_INVOKABLE QVariant inputMethodQuery(Qt::InputMethodQuery query, const QVariant &argument) const; #endif QRectF boundingRect() const override; @@ -319,8 +320,8 @@ Q_SIGNALS: void selectedTextChanged(); void accepted(); void acceptableInputChanged(); - Q_REVISION(2) void editingFinished(); - Q_REVISION(9) void textEdited(); + Q_REVISION(2, 2) void editingFinished(); + Q_REVISION(2, 9) void textEdited(); void colorChanged(); void selectionColorChanged(); void selectedTextColorChanged(); @@ -337,9 +338,9 @@ Q_SIGNALS: void inputMaskChanged(const QString &inputMask); void echoModeChanged(QQuickTextInput::EchoMode echoMode); void passwordCharacterChanged(); - Q_REVISION(4) void passwordMaskDelayChanged(int delay); + Q_REVISION(2, 4) void passwordMaskDelayChanged(int delay); void displayTextChanged(); - Q_REVISION(7) void preeditTextChanged(); + Q_REVISION(2, 7) void preeditTextChanged(); void activeFocusOnPressChanged(bool activeFocusOnPress); void autoScrollChanged(bool autoScroll); void selectByMouseChanged(bool selectByMouse); @@ -353,11 +354,11 @@ Q_SIGNALS: void contentSizeChanged(); void inputMethodHintsChanged(); void renderTypeChanged(); - Q_REVISION(6) void paddingChanged(); - Q_REVISION(6) void topPaddingChanged(); - Q_REVISION(6) void leftPaddingChanged(); - Q_REVISION(6) void rightPaddingChanged(); - Q_REVISION(6) void bottomPaddingChanged(); + Q_REVISION(2, 6) void paddingChanged(); + Q_REVISION(2, 6) void topPaddingChanged(); + Q_REVISION(2, 6) void leftPaddingChanged(); + Q_REVISION(2, 6) void rightPaddingChanged(); + Q_REVISION(2, 6) void bottomPaddingChanged(); private: void invalidateFontCaches(); @@ -400,8 +401,8 @@ public Q_SLOTS: void redo(); void insert(int position, const QString &text); void remove(int start, int end); - Q_REVISION(4) void ensureVisible(int position); - Q_REVISION(7) void clear(); + Q_REVISION(2, 4) void ensureVisible(int position); + Q_REVISION(2, 7) void clear(); private Q_SLOTS: void selectionChanged(); diff --git a/src/quick/items/qquicktranslate.cpp b/src/quick/items/qquicktranslate.cpp index 872fe25a18..3bdcfa752e 100644 --- a/src/quick/items/qquicktranslate.cpp +++ b/src/quick/items/qquicktranslate.cpp @@ -434,14 +434,6 @@ void QQuickRotation::setAxis(Qt::Axis axis) } } -class QGraphicsRotation { -public: - static inline void projectedRotate(QMatrix4x4 *matrix, qreal angle, qreal x, qreal y, qreal z) - { - matrix->projectedRotate(angle, x, y, z); - } -}; - void QQuickRotation::applyTo(QMatrix4x4 *matrix) const { Q_D(const QQuickRotation); @@ -450,7 +442,7 @@ void QQuickRotation::applyTo(QMatrix4x4 *matrix) const return; matrix->translate(d->origin); - QGraphicsRotation::projectedRotate(matrix, d->angle, d->axis.x(), d->axis.y(), d->axis.z()); + matrix->projectedRotate(d->angle, d->axis.x(), d->axis.y(), d->axis.z()); matrix->translate(-d->origin); } diff --git a/src/quick/items/qquicktranslate_p.h b/src/quick/items/qquicktranslate_p.h index aeda6ca589..9832989e73 100644 --- a/src/quick/items/qquicktranslate_p.h +++ b/src/quick/items/qquicktranslate_p.h @@ -65,6 +65,7 @@ class Q_AUTOTEST_EXPORT QQuickTranslate : public QQuickTransform Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged) Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged) QML_NAMED_ELEMENT(Translate) + QML_ADDED_IN_VERSION(2, 0) public: QQuickTranslate(QObject *parent = nullptr); @@ -97,6 +98,7 @@ class Q_AUTOTEST_EXPORT QQuickScale : public QQuickTransform Q_PROPERTY(qreal yScale READ yScale WRITE setYScale NOTIFY yScaleChanged) Q_PROPERTY(qreal zScale READ zScale WRITE setZScale NOTIFY zScaleChanged) QML_NAMED_ELEMENT(Scale) + QML_ADDED_IN_VERSION(2, 0) public: QQuickScale(QObject *parent = nullptr); ~QQuickScale(); @@ -135,6 +137,7 @@ class Q_AUTOTEST_EXPORT QQuickRotation : public QQuickTransform Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged) Q_PROPERTY(QVector3D axis READ axis WRITE setAxis NOTIFY axisChanged) QML_NAMED_ELEMENT(Rotation) + QML_ADDED_IN_VERSION(2, 0) public: QQuickRotation(QObject *parent = nullptr); ~QQuickRotation(); @@ -167,7 +170,7 @@ class Q_AUTOTEST_EXPORT QQuickMatrix4x4 : public QQuickTransform Q_PROPERTY(QMatrix4x4 matrix READ matrix WRITE setMatrix NOTIFY matrixChanged) QML_NAMED_ELEMENT(Matrix4x4) - QML_ADDED_IN_MINOR_VERSION(3) + QML_ADDED_IN_VERSION(2, 3) public: QQuickMatrix4x4(QObject *parent = nullptr); ~QQuickMatrix4x4(); diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 426a30dfca..4b4ecd6acc 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -78,8 +78,11 @@ #include <private/qqmldebugserviceinterfaces_p.h> #include <private/qqmldebugconnector_p.h> #if QT_CONFIG(opengl) -# include <private/qopenglvertexarrayobject_p.h> -# include <private/qsgdefaultrendercontext_p.h> +#include <private/qopenglvertexarrayobject_p.h> +#include <private/qsgdefaultrendercontext_p.h> +#include <private/qopengl_p.h> +#include <QOpenGLContext> +#include <QOpenGLFramebufferObject> #endif #ifndef QT_NO_DEBUG_STREAM #include <private/qdebug_p.h> @@ -4102,7 +4105,7 @@ QImage QQuickWindow::grabWindow() Q_D(QQuickWindow); if (!isVisible() && !d->renderControl) { - // backends like software and d3d12 can grab regardless of the window state + // backends like software can grab regardless of the window state if (d->windowManager && (d->windowManager->flags() & QSGRenderLoop::SupportsGrabWithoutExpose)) return d->windowManager->grab(this); } @@ -5574,9 +5577,6 @@ void QQuickWindow::setSceneGraphBackend(QSGRendererInterface::GraphicsApi api) case QSGRendererInterface::Software: setSceneGraphBackend(QStringLiteral("software")); break; - case QSGRendererInterface::Direct3D12: - setSceneGraphBackend(QStringLiteral("d3d12")); - break; default: break; } diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h index 097627374c..bba8c014c8 100644 --- a/src/quick/items/qquickwindow.h +++ b/src/quick/items/qquickwindow.h @@ -43,7 +43,7 @@ #include <QtQuick/qtquickglobal.h> #include <QtQuick/qsgrendererinterface.h> #include <QtCore/qmetatype.h> -#include <QtGui/qopengl.h> +#include <qopengl.h> #include <QtGui/qwindow.h> #include <QtGui/qevent.h> #include <QtQml/qqml.h> @@ -74,7 +74,7 @@ class Q_QUICK_EXPORT QQuickWindow : public QWindow Q_PRIVATE_PROPERTY(QQuickWindow::d_func(), QQmlListProperty<QObject> data READ data DESIGNABLE false) Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) Q_PROPERTY(QQuickItem* contentItem READ contentItem CONSTANT) - Q_PROPERTY(QQuickItem* activeFocusItem READ activeFocusItem NOTIFY activeFocusItemChanged REVISION 1) + Q_PROPERTY(QQuickItem* activeFocusItem READ activeFocusItem NOTIFY activeFocusItemChanged REVISION(2, 1)) Q_CLASSINFO("DefaultProperty", "data") Q_DECLARE_PRIVATE(QQuickWindow) public: @@ -206,23 +206,23 @@ public: Q_SIGNALS: void frameSwapped(); - Q_REVISION(2) void openglContextCreated(QOpenGLContext *context); + Q_REVISION(2, 2) void openglContextCreated(QOpenGLContext *context); void sceneGraphInitialized(); void sceneGraphInvalidated(); void beforeSynchronizing(); - Q_REVISION(2) void afterSynchronizing(); + Q_REVISION(2, 2) void afterSynchronizing(); void beforeRendering(); void afterRendering(); - Q_REVISION(2) void afterAnimating(); - Q_REVISION(2) void sceneGraphAboutToStop(); + Q_REVISION(2, 2) void afterAnimating(); + Q_REVISION(2, 2) void sceneGraphAboutToStop(); - Q_REVISION(1) void closing(QQuickCloseEvent *close); + Q_REVISION(2, 1) void closing(QQuickCloseEvent *close); void colorChanged(const QColor &); - Q_REVISION(1) void activeFocusItemChanged(); - Q_REVISION(2) void sceneGraphError(QQuickWindow::SceneGraphError error, const QString &message); + Q_REVISION(2, 1) void activeFocusItemChanged(); + Q_REVISION(2, 2) void sceneGraphError(QQuickWindow::SceneGraphError error, const QString &message); - Q_REVISION(14) void beforeRenderPassRecording(); - Q_REVISION(14) void afterRenderPassRecording(); + Q_REVISION(2, 14) void beforeRenderPassRecording(); + Q_REVISION(2, 14) void afterRenderPassRecording(); public Q_SLOTS: void update(); diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h index 86bdaf6396..efc5e0007e 100644 --- a/src/quick/items/qquickwindow_p.h +++ b/src/quick/items/qquickwindow_p.h @@ -62,9 +62,6 @@ #include <QtCore/qwaitcondition.h> #include <QtCore/qrunnable.h> #include <private/qwindow_p.h> -#include <private/qopengl_p.h> -#include <qopenglcontext.h> -#include <QtGui/qopenglframebufferobject.h> #include <QtGui/qevent.h> #include <QtGui/qstylehints.h> #include <QtGui/qguiapplication.h> diff --git a/src/quick/items/qquickwindowmodule_p.h b/src/quick/items/qquickwindowmodule_p.h index d0bf5c29b3..2f05b987d1 100644 --- a/src/quick/items/qquickwindowmodule_p.h +++ b/src/quick/items/qquickwindowmodule_p.h @@ -67,7 +67,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickWindowQmlImpl : public QQuickWindow, public Q Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged) Q_PROPERTY(Visibility visibility READ visibility WRITE setVisibility NOTIFY visibilityChanged) - Q_PROPERTY(QObject *screen READ screen WRITE setScreen NOTIFY screenChanged REVISION 3) + Q_PROPERTY(QObject *screen READ screen WRITE setScreen NOTIFY screenChanged REVISION(2, 3)) QML_ATTACHED(QQuickWindowAttached) public: @@ -84,7 +84,7 @@ public: Q_SIGNALS: void visibleChanged(bool arg); void visibilityChanged(QWindow::Visibility visibility); - Q_REVISION(3) void screenChanged(); + Q_REVISION(2, 3) void screenChanged(); protected: void classBegin() override; diff --git a/src/quick/quick.pro b/src/quick/quick.pro index f2d49cf939..14c351a7ef 100644 --- a/src/quick/quick.pro +++ b/src/quick/quick.pro @@ -3,6 +3,8 @@ TARGET = QtQuick QT = core-private gui-private qml-private qmlmodels-private qtConfig(qml-network): \ QT_PRIVATE += network +qtConfig(opengl): \ + QT_PRIVATE += opengl-private TRACEPOINT_PROVIDER = $$PWD/qtquick.tracepoints CONFIG += qt_tracepoints @@ -49,7 +51,7 @@ INCLUDEPATH += $$PWD load(qt_module) QMLTYPES_FILENAME = plugins.qmltypes -QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQuick.2 +QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQuick QML_IMPORT_NAME = QtQuick -IMPORT_VERSION = 2.$$QT_MINOR_VERSION +QML_IMPORT_VERSION = $$QT_VERSION CONFIG += qmltypes install_qmltypes install_metatypes diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp index ca620965a8..49151551b1 100644 --- a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp @@ -77,6 +77,12 @@ QSGSoftwareRenderableNode *QSGAbstractSoftwareRenderer::renderableNode(QSGNode * return m_nodes.value(node, nullptr); } +// Used by GammaRay +const QVector<QSGSoftwareRenderableNode*> &QSGAbstractSoftwareRenderer::renderableNodes() const +{ + return m_renderableNodes; +} + void QSGAbstractSoftwareRenderer::addNodeMapping(QSGNode *node, QSGSoftwareRenderableNode *renderableNode) { m_nodes.insert(node, renderableNode); diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h index e1b477ab97..d4bfb5a9f7 100644 --- a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h @@ -87,6 +87,7 @@ protected: QRect backgroundRect(); // only known after calling optimizeRenderList() bool isOpaque() const { return m_isOpaque; } + const QVector<QSGSoftwareRenderableNode*> &renderableNodes() const; private: void nodeAdded(QSGNode *node); diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp index f07cc28827..1de9415dd0 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp @@ -423,7 +423,7 @@ void QSGSoftwareRenderThread::sync(bool inExpose) qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - sync"); mutex.lock(); - Q_ASSERT_X(renderLoop->lockedForSync, "QSGD3D12RenderThread::sync()", "sync triggered with gui not locked"); + Q_ASSERT_X(renderLoop->lockedForSync, "QSGSoftwareRenderThread::sync()", "sync triggered with gui not locked"); if (exposedWindow) { QQuickWindowPrivate *wd = QQuickWindowPrivate::get(exposedWindow); diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp index e981921c69..ac21ec2ed9 100644 --- a/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp +++ b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp @@ -43,13 +43,13 @@ #include <QtCore/QElapsedTimer> #include <QtCore/QtMath> -#include <QtGui/QOpenGLContext> +#include <QOpenGLContext> #include <QtGui/QGuiApplication> #include <QtGui/QScreen> #include <QtGui/QSurface> #include <QtGui/QWindow> -#include <QtGui/QOpenGLFunctions> -#include <QtGui/QOpenGLTexture> +#include <QOpenGLFunctions> +#include <QOpenGLTexture> #include <QDebug> #include <private/qqmlglobal_p.h> diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h index 78051778f5..aec7dbf976 100644 --- a/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h +++ b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h @@ -53,7 +53,7 @@ #include <QtCore/QSize> -#include <QtGui/qopengl.h> +#include <qopengl.h> #include <QtQuick/QSGTexture> #include <QtQuick/private/qsgareaallocator_p.h> diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index f0c57ffd80..5310e76dae 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -50,10 +50,10 @@ #include <QtCore/QtNumeric> #include <QtGui/QGuiApplication> -#include <QtGui/QOpenGLFramebufferObject> -#include <QtGui/QOpenGLVertexArrayObject> -#include <QtGui/QOpenGLFunctions_1_0> -#include <QtGui/QOpenGLFunctions_3_2_Core> +#include <QOpenGLFramebufferObject> +#include <QOpenGLVertexArrayObject> +#include <QOpenGLFunctions_1_0> +#include <QOpenGLFunctions_3_2_Core> #include <private/qnumeric_p.h> #include <private/qquickprofiler_p.h> @@ -2341,7 +2341,7 @@ void Renderer::uploadBatch(Batch *b) iDump << " -- Index Data, count:" << b->indexCount; for (int i=0; i<b->indexCount; ++i) { if ((i % 24) == 0) - iDump << endl << " --- "; + iDump << Qt::endl << " --- "; iDump << id[i]; } } diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h index 878b63fc8c..b48220fb8c 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h @@ -62,7 +62,7 @@ #include <QtCore/QBitArray> #include <QtCore/QStack> -#include <QtGui/QOpenGLFunctions> +#include <QOpenGLFunctions> #include <QtGui/private/qrhi_p.h> diff --git a/src/quick/scenegraph/coreapi/qsggeometry.h b/src/quick/scenegraph/coreapi/qsggeometry.h index d17915a842..9c60876597 100644 --- a/src/quick/scenegraph/coreapi/qsggeometry.h +++ b/src/quick/scenegraph/coreapi/qsggeometry.h @@ -41,7 +41,7 @@ #define QSGGEOMETRY_H #include <QtQuick/qtquickglobal.h> -#include <QtGui/qopengl.h> +#include <qopengl.h> #include <QtCore/QRectF> QT_BEGIN_NAMESPACE diff --git a/src/quick/scenegraph/coreapi/qsgmaterialshader.cpp b/src/quick/scenegraph/coreapi/qsgmaterialshader.cpp index d614f9be4c..9049dd5826 100644 --- a/src/quick/scenegraph/coreapi/qsgmaterialshader.cpp +++ b/src/quick/scenegraph/coreapi/qsgmaterialshader.cpp @@ -44,8 +44,8 @@ # include <private/qsgshadersourcebuilder_p.h> # include <private/qsgdefaultcontext_p.h> # include <private/qsgdefaultrendercontext_p.h> -# include <QtGui/QOpenGLFunctions> -# include <QtGui/QOpenGLContext> +# include <QOpenGLFunctions> +# include <QOpenGLContext> #endif QT_BEGIN_NAMESPACE diff --git a/src/quick/scenegraph/coreapi/qsgmaterialshader.h b/src/quick/scenegraph/coreapi/qsgmaterialshader.h index d7ee23384f..6783b3f890 100644 --- a/src/quick/scenegraph/coreapi/qsgmaterialshader.h +++ b/src/quick/scenegraph/coreapi/qsgmaterialshader.h @@ -42,7 +42,7 @@ #include <QtQuick/qtquickglobal.h> #if QT_CONFIG(opengl) -# include <QtGui/qopenglshaderprogram.h> +# include <qopenglshaderprogram.h> #endif #include <QtGui/QMatrix4x4> #include <QtCore/QRect> diff --git a/src/quick/scenegraph/coreapi/qsgrenderer.cpp b/src/quick/scenegraph/coreapi/qsgrenderer.cpp index 90090e1cc0..cd16014d41 100644 --- a/src/quick/scenegraph/coreapi/qsgrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgrenderer.cpp @@ -40,9 +40,9 @@ #include "qsgrenderer_p.h" #include "qsgnodeupdater_p.h" #if QT_CONFIG(opengl) -# include <QtGui/QOpenGLFramebufferObject> -# include <QtGui/QOpenGLContext> -# include <QtGui/QOpenGLFunctions> +# include <QOpenGLFramebufferObject> +# include <QOpenGLContext> +# include <QOpenGLFunctions> #endif #include <private/qquickprofiler_p.h> #include <qtquick_tracepoints_p.h> diff --git a/src/quick/scenegraph/coreapi/qsgrendererinterface.cpp b/src/quick/scenegraph/coreapi/qsgrendererinterface.cpp index 0fee1486cf..9b5701df5a 100644 --- a/src/quick/scenegraph/coreapi/qsgrendererinterface.cpp +++ b/src/quick/scenegraph/coreapi/qsgrendererinterface.cpp @@ -76,7 +76,6 @@ QT_BEGIN_NAMESPACE \value Unknown An unknown graphics API is in use \value Software The Qt Quick 2D Renderer is in use \value OpenGL OpenGL ES 2.0 or higher - \value Direct3D12 Direct3D 12 \value OpenVG OpenVG via EGL \value OpenGLRhi OpenGL ES 2.0 or higher via a graphics abstraction layer. This value was introduced in Qt 5.14. \value Direct3D11Rhi Direct3D 11 via a graphics abstraction layer. This value was introduced in Qt 5.14. @@ -189,10 +188,10 @@ QSGRendererInterface::~QSGRendererInterface() not supported or not available. When successful, the returned pointer is either a direct pointer to an - interface (and can be cast, for example, to \c{ID3D12Device *}) or a - pointer to an opaque handle that needs to be dereferenced first (for - example, \c{VkDevice dev = *static_cast<VkDevice *>(result)}). The latter - is necessary since such handles may have sizes different from a pointer. + interface, or a pointer to an opaque handle that needs to be dereferenced + first (for example, \c{VkDevice dev = *static_cast<VkDevice + *>(result)}). The latter is necessary since such handles may have sizes + different from a pointer. \note The ownership of the returned pointer is never transferred to the caller. diff --git a/src/quick/scenegraph/coreapi/qsgrendererinterface.h b/src/quick/scenegraph/coreapi/qsgrendererinterface.h index 7aa7d0e769..6224e08e84 100644 --- a/src/quick/scenegraph/coreapi/qsgrendererinterface.h +++ b/src/quick/scenegraph/coreapi/qsgrendererinterface.h @@ -53,7 +53,6 @@ public: Unknown, Software, OpenGL, - Direct3D12, OpenVG, OpenGLRhi, Direct3D11Rhi, diff --git a/src/quick/scenegraph/coreapi/qsgrendernode.cpp b/src/quick/scenegraph/coreapi/qsgrendernode.cpp index 63878954bf..519e3cd017 100644 --- a/src/quick/scenegraph/coreapi/qsgrendernode.cpp +++ b/src/quick/scenegraph/coreapi/qsgrendernode.cpp @@ -99,8 +99,8 @@ QSGRenderNodePrivate::QSGRenderNodePrivate() With APIs other than OpenGL, the only relevant values are the ones that correspond to dynamic state changes recorded on the command list/buffer. - For example, RSSetViewports, RSSetScissorRects, OMSetBlendFactor, - OMSetStencilRef in case of D3D12, or vkCmdSetViewport, vkCmdSetScissor, + For example, RSSetViewports, RSSetScissorRects, OMSetBlendState, + OMSetDepthStencilState in case of D3D11, or vkCmdSetViewport, vkCmdSetScissor, vkCmdSetBlendConstants, vkCmdSetStencilRef in case of Vulkan, and only when such commands were added to the scenegraph's command list queried via the QSGRendererInterface::CommandList resource enum. States set in pipeline @@ -381,11 +381,6 @@ QSGRenderNode::RenderState::~RenderState() \return the current scissor rectangle when clipping is active. x and y are the bottom left coordinates. - - \note Be aware of the differences between graphics APIs: for some the - scissor rect is only active when scissoring is enabled (for example, - OpenGL), while for others the scissor rect is equal to the viewport rect - when there is no need to scissor away anything (for example, Direct3D 12). */ /*! diff --git a/src/quick/scenegraph/coreapi/qsgtexture.cpp b/src/quick/scenegraph/coreapi/qsgtexture.cpp index 715633fdba..486fe50190 100644 --- a/src/quick/scenegraph/coreapi/qsgtexture.cpp +++ b/src/quick/scenegraph/coreapi/qsgtexture.cpp @@ -39,8 +39,8 @@ #include "qsgtexture_p.h" #if QT_CONFIG(opengl) -# include <QtGui/qopenglcontext.h> -# include <QtGui/qopenglfunctions.h> +# include <qopenglcontext.h> +# include <qopenglfunctions.h> #endif #include <private/qqmlglobal_p.h> #include <private/qsgmaterialshader_p.h> diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp index eab0369be7..e0d9d5db68 100644 --- a/src/quick/scenegraph/qsgadaptationlayer.cpp +++ b/src/quick/scenegraph/qsgadaptationlayer.cpp @@ -329,7 +329,7 @@ void QSGDistanceFieldGlyphCache::updateRhiTexture(QRhiTexture *oldTex, QRhiTextu } #if defined(QSG_DISTANCEFIELD_CACHE_DEBUG) -#include <QtGui/qopenglfunctions.h> +#include <qopenglfunctions.h> void QSGDistanceFieldGlyphCache::saveTexture(GLuint textureId, int width, int height) const { diff --git a/src/quick/scenegraph/qsgdefaultcontext.cpp b/src/quick/scenegraph/qsgdefaultcontext.cpp index ea01b0a3b4..14a0e8b7ab 100644 --- a/src/quick/scenegraph/qsgdefaultcontext.cpp +++ b/src/quick/scenegraph/qsgdefaultcontext.cpp @@ -57,8 +57,8 @@ #endif #include <QtQuick/private/qsgrhishadereffectnode_p.h> -#include <QtGui/QOpenGLContext> -#include <QtGui/QOpenGLFramebufferObject> +#include <QOpenGLContext> +#include <QOpenGLFramebufferObject> #include <QtQuick/private/qquickwindow_p.h> diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.h b/src/quick/scenegraph/qsgdefaultglyphnode_p.h index 4cff2d3d24..f70d51d1ee 100644 --- a/src/quick/scenegraph/qsgdefaultglyphnode_p.h +++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.h @@ -53,7 +53,6 @@ #include <private/qsgadaptationlayer_p.h> #include <private/qsgbasicglyphnode_p.h> -#include <qlinkedlist.h> QT_BEGIN_NAMESPACE diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p_p.h b/src/quick/scenegraph/qsgdefaultglyphnode_p_p.h index 7d2635794d..4ddef9af24 100644 --- a/src/quick/scenegraph/qsgdefaultglyphnode_p_p.h +++ b/src/quick/scenegraph/qsgdefaultglyphnode_p_p.h @@ -52,7 +52,7 @@ // #include <qcolor.h> -#include <QtGui/private/qopengltextureglyphcache_p.h> +#include <private/qopengltextureglyphcache_p.h> #include <QtQuick/qsgmaterial.h> #include <QtQuick/qsgtexture.h> #include <QtQuick/qsggeometry.h> diff --git a/src/quick/scenegraph/qsgdefaultinternalimagenode.cpp b/src/quick/scenegraph/qsgdefaultinternalimagenode.cpp index 500d4e6e95..167d2b01dd 100644 --- a/src/quick/scenegraph/qsgdefaultinternalimagenode.cpp +++ b/src/quick/scenegraph/qsgdefaultinternalimagenode.cpp @@ -41,7 +41,7 @@ #include <private/qsgdefaultrendercontext_p.h> #include <private/qsgmaterialshader_p.h> #include <private/qsgtexturematerial_p.h> -#include <QtGui/qopenglfunctions.h> +#include <qopenglfunctions.h> #include <QtCore/qmath.h> #include <QtGui/private/qrhi_p.h> diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp index e8c3ac4abb..ae227a0106 100644 --- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp +++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp @@ -40,7 +40,7 @@ #include "qsgdefaultrendercontext_p.h" #include <QtGui/QGuiApplication> -#include <QtGui/QOpenGLFramebufferObject> +#include <QOpenGLFramebufferObject> #include <QtQuick/private/qsgbatchrenderer_p.h> #include <QtQuick/private/qsgrenderer_p.h> diff --git a/src/quick/scenegraph/qsgdefaultspritenode.cpp b/src/quick/scenegraph/qsgdefaultspritenode.cpp index 6422a252d9..b2af09cc62 100644 --- a/src/quick/scenegraph/qsgdefaultspritenode.cpp +++ b/src/quick/scenegraph/qsgdefaultspritenode.cpp @@ -40,7 +40,7 @@ #include "qsgdefaultspritenode_p.h" #include <QtQuick/QSGMaterial> -#include <QtGui/QOpenGLShaderProgram> +#include <QOpenGLShaderProgram> QT_BEGIN_NAMESPACE diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp index e8e9f76d04..a25daa6070 100644 --- a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp +++ b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp @@ -39,7 +39,7 @@ #include "qsgdistancefieldglyphnode_p_p.h" #include "qsgrhidistancefieldglyphcache_p.h" -#include <QtGui/qopenglfunctions.h> +#include <qopenglfunctions.h> #include <QtGui/qsurface.h> #include <QtGui/qwindow.h> #include <qmath.h> diff --git a/src/quick/scenegraph/qsgopengldistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgopengldistancefieldglyphcache.cpp index b6b6f3b057..2f9b1e4ce6 100644 --- a/src/quick/scenegraph/qsgopengldistancefieldglyphcache.cpp +++ b/src/quick/scenegraph/qsgopengldistancefieldglyphcache.cpp @@ -45,7 +45,7 @@ #include <QtQml/qqmlfile.h> #include <QtGui/private/qdistancefield_p.h> -#include <QtGui/private/qopenglcontext_p.h> +#include <private/qopenglcontext_p.h> #include <QtQml/private/qqmlglobal_p.h> #include <qopenglfunctions.h> #include <qopenglframebufferobject.h> @@ -54,7 +54,7 @@ #if !defined(QT_OPENGL_ES_2) -#include <QtGui/qopenglfunctions_3_2_core.h> +#include <qopenglfunctions_3_2_core.h> #endif QT_BEGIN_NAMESPACE diff --git a/src/quick/scenegraph/qsgopengldistancefieldglyphcache_p.h b/src/quick/scenegraph/qsgopengldistancefieldglyphcache_p.h index 66d1b52f86..2e7b5baae2 100644 --- a/src/quick/scenegraph/qsgopengldistancefieldglyphcache_p.h +++ b/src/quick/scenegraph/qsgopengldistancefieldglyphcache_p.h @@ -52,11 +52,11 @@ // #include "qsgadaptationlayer_p.h" -#include <QtGui/qopenglfunctions.h> +#include <qopenglfunctions.h> #include <qopenglshaderprogram.h> #include <qopenglbuffer.h> #include <qopenglvertexarrayobject.h> -#include <QtGui/private/qopenglengineshadersource_p.h> +#include <private/qopenglengineshadersource_p.h> #include <private/qsgareaallocator_p.h> QT_BEGIN_NAMESPACE diff --git a/src/quick/scenegraph/qsgopengllayer.cpp b/src/quick/scenegraph/qsgopengllayer.cpp index ae5032231d..be289aeace 100644 --- a/src/quick/scenegraph/qsgopengllayer.cpp +++ b/src/quick/scenegraph/qsgopengllayer.cpp @@ -42,9 +42,9 @@ #include <private/qsgrenderer_p.h> #include <private/qsgdefaultrendercontext_p.h> -#include <QtGui/QOpenGLFramebufferObject> -#include <QtGui/QOpenGLFunctions> -#include <QtGui/private/qopenglextensions_p.h> +#include <QOpenGLFramebufferObject> +#include <QOpenGLFunctions> +#include <private/qopenglextensions_p.h> #include <QtQuick/private/qsgdepthstencilbuffer_p.h> diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index 94f15b55d4..c4f6d4457d 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -65,7 +65,7 @@ #include <private/qsgrhishadereffectnode_p.h> #if QT_CONFIG(opengl) -#include <QtGui/QOpenGLContext> +#include <QOpenGLContext> #if QT_CONFIG(quick_shadereffect) #include <private/qquickopenglshadereffectnode_p.h> #endif diff --git a/src/quick/scenegraph/qsgthreadedrenderloop_p.h b/src/quick/scenegraph/qsgthreadedrenderloop_p.h index e5e9fa8b48..d805c91d79 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop_p.h +++ b/src/quick/scenegraph/qsgthreadedrenderloop_p.h @@ -52,7 +52,7 @@ // #include <QtCore/QThread> -#include <QtGui/QOpenGLContext> +#include <QOpenGLContext> #include <private/qsgcontext_p.h> #include "qsgrenderloop_p.h" diff --git a/src/quick/scenegraph/qsgwindowsrenderloop_p.h b/src/quick/scenegraph/qsgwindowsrenderloop_p.h index a1188fed8a..4021ddb369 100644 --- a/src/quick/scenegraph/qsgwindowsrenderloop_p.h +++ b/src/quick/scenegraph/qsgwindowsrenderloop_p.h @@ -54,7 +54,7 @@ #include <QtCore/QObject> #include <QtCore/QElapsedTimer> -#include <QtGui/QOpenGLContext> +#include <QOpenGLContext> #include "qsgrenderloop_p.h" diff --git a/src/quick/scenegraph/util/qsgdefaultpainternode_p.h b/src/quick/scenegraph/util/qsgdefaultpainternode_p.h index a86f7397be..dc103648ff 100644 --- a/src/quick/scenegraph/util/qsgdefaultpainternode_p.h +++ b/src/quick/scenegraph/util/qsgdefaultpainternode_p.h @@ -159,9 +159,6 @@ private: QSize m_textureSize; QRect m_dirtyRect; QColor m_fillColor; -#if QT_VERSION >= 0x060000 -#warning "Remove m_contentsScale and assume 1 everywhere" -#endif qreal m_contentsScale; bool m_dirtyContents : 1; diff --git a/src/quick/scenegraph/util/qsgdepthstencilbuffer_p.h b/src/quick/scenegraph/util/qsgdepthstencilbuffer_p.h index f7c6923021..10c94a5954 100644 --- a/src/quick/scenegraph/util/qsgdepthstencilbuffer_p.h +++ b/src/quick/scenegraph/util/qsgdepthstencilbuffer_p.h @@ -52,8 +52,8 @@ // #include <QtCore/qsize.h> -#include <QtGui/private/qopenglcontext_p.h> -#include <QtGui/private/qopenglextensions_p.h> +#include <private/qopenglcontext_p.h> +#include <private/qopenglextensions_p.h> #include <QtCore/qsharedpointer.h> #include <QtCore/qhash.h> diff --git a/src/quick/scenegraph/util/qsgengine.cpp b/src/quick/scenegraph/util/qsgengine.cpp index 4880d98871..13c97e8615 100644 --- a/src/quick/scenegraph/util/qsgengine.cpp +++ b/src/quick/scenegraph/util/qsgengine.cpp @@ -45,7 +45,7 @@ #include <private/qsgplaintexture_p.h> #if QT_CONFIG(opengl) -# include <QtGui/QOpenGLContext> +# include <QOpenGLContext> # include <private/qsgdefaultrendercontext_p.h> #endif diff --git a/src/quick/scenegraph/util/qsgopenglatlastexture.cpp b/src/quick/scenegraph/util/qsgopenglatlastexture.cpp index 18c72286d1..b445a61940 100644 --- a/src/quick/scenegraph/util/qsgopenglatlastexture.cpp +++ b/src/quick/scenegraph/util/qsgopenglatlastexture.cpp @@ -43,9 +43,9 @@ #include <QtCore/QElapsedTimer> #include <QtCore/QtMath> -#include <QtGui/QOpenGLContext> -#include <QtGui/QOpenGLTexture> -#include <QtGui/QOpenGLFunctions> +#include <QOpenGLContext> +#include <QOpenGLTexture> +#include <QOpenGLFunctions> #include <QtGui/QGuiApplication> #include <QtGui/QScreen> #include <QtGui/QSurface> diff --git a/src/quick/scenegraph/util/qsgopenglatlastexture_p.h b/src/quick/scenegraph/util/qsgopenglatlastexture_p.h index f8dd7cdf02..379c4c7fff 100644 --- a/src/quick/scenegraph/util/qsgopenglatlastexture_p.h +++ b/src/quick/scenegraph/util/qsgopenglatlastexture_p.h @@ -53,7 +53,7 @@ #include <QtCore/QSize> -#include <QtGui/qopengl.h> +#include <qopengl.h> #include <QtQuick/QSGTexture> #include <QtQuick/private/qsgplaintexture_p.h> diff --git a/src/quick/scenegraph/util/qsgplaintexture.cpp b/src/quick/scenegraph/util/qsgplaintexture.cpp index f00918bb4e..37dc0f9138 100644 --- a/src/quick/scenegraph/util/qsgplaintexture.cpp +++ b/src/quick/scenegraph/util/qsgplaintexture.cpp @@ -45,9 +45,9 @@ #include <QtGui/qguiapplication.h> #include <QtGui/qpa/qplatformnativeinterface.h> #if QT_CONFIG(opengl) -# include <QtGui/qopenglcontext.h> -# include <QtGui/qopenglfunctions.h> -# include <QtGui/private/qopengltextureuploader_p.h> +# include <qopenglcontext.h> +# include <qopenglfunctions.h> +# include <private/qopengltextureuploader_p.h> # include <private/qsgdefaultrendercontext_p.h> #endif #include <QtGui/private/qrhi_p.h> diff --git a/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp b/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp index 93fc213f2e..77fded6c21 100644 --- a/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp +++ b/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp @@ -39,8 +39,8 @@ #include "qsgshadersourcebuilder_p.h" -#include <QtGui/qopenglcontext.h> -#include <QtGui/qopenglshaderprogram.h> +#include <qopenglcontext.h> +#include <qopenglshaderprogram.h> #include <QtCore/qdebug.h> #include <QtCore/qfile.h> diff --git a/src/quick/scenegraph/util/qsgtexturematerial.cpp b/src/quick/scenegraph/util/qsgtexturematerial.cpp index 67b8748119..b4ac0c4d1d 100644 --- a/src/quick/scenegraph/util/qsgtexturematerial.cpp +++ b/src/quick/scenegraph/util/qsgtexturematerial.cpp @@ -40,8 +40,8 @@ #include "qsgtexturematerial_p.h" #include <private/qsgtexture_p.h> #if QT_CONFIG(opengl) -# include <QtGui/qopenglshaderprogram.h> -# include <QtGui/qopenglfunctions.h> +# include <qopenglshaderprogram.h> +# include <qopenglfunctions.h> #endif #include <QtGui/private/qrhi_p.h> diff --git a/src/quick/util/qquickanimation_p.h b/src/quick/util/qquickanimation_p.h index 7bad9d50c4..b86533eb3f 100644 --- a/src/quick/util/qquickanimation_p.h +++ b/src/quick/util/qquickanimation_p.h @@ -81,6 +81,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickAbstractAnimation : public QObject, public QQ Q_CLASSINFO("DefaultMethod", "start()") QML_NAMED_ELEMENT(Animation) + QML_ADDED_IN_VERSION(2, 0) QML_UNCREATABLE("Animation is an abstract class") public: @@ -129,7 +130,7 @@ Q_SIGNALS: void pausedChanged(bool); void alwaysRunToEndChanged(bool); void loopCountChanged(int); - Q_REVISION(12) void finished(); + Q_REVISION(2, 12) void finished(); public Q_SLOTS: void restart(); @@ -169,6 +170,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPauseAnimation : public QQuickAbstractAnimati Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged) QML_NAMED_ELEMENT(PauseAnimation) + QML_ADDED_IN_VERSION(2, 0) public: QQuickPauseAnimation(QObject *parent=nullptr); @@ -196,6 +198,7 @@ class QQuickScriptAction : public QQuickAbstractAnimation Q_PROPERTY(QQmlScriptString script READ script WRITE setScript) Q_PROPERTY(QString scriptName READ stateChangeScriptName WRITE setStateChangeScriptName) QML_NAMED_ELEMENT(ScriptAction) + QML_ADDED_IN_VERSION(2, 0) public: QQuickScriptAction(QObject *parent=nullptr); @@ -227,6 +230,7 @@ class QQuickPropertyAction : public QQuickAbstractAnimation Q_PROPERTY(QQmlListProperty<QObject> exclude READ exclude) Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged) QML_NAMED_ELEMENT(PropertyAction) + QML_ADDED_IN_VERSION(2, 0) public: QQuickPropertyAction(QObject *parent=nullptr); @@ -276,6 +280,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPropertyAnimation : public QQuickAbstractAnim Q_PROPERTY(QQmlListProperty<QObject> targets READ targets) Q_PROPERTY(QQmlListProperty<QObject> exclude READ exclude) QML_NAMED_ELEMENT(PropertyAnimation) + QML_ADDED_IN_VERSION(2, 0) public: QQuickPropertyAnimation(QObject *parent=nullptr); @@ -332,6 +337,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickColorAnimation : public QQuickPropertyAnimati Q_PROPERTY(QColor from READ from WRITE setFrom) Q_PROPERTY(QColor to READ to WRITE setTo) QML_NAMED_ELEMENT(ColorAnimation) + QML_ADDED_IN_VERSION(2, 0) public: QQuickColorAnimation(QObject *parent=nullptr); @@ -352,6 +358,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickNumberAnimation : public QQuickPropertyAnimat Q_PROPERTY(qreal from READ from WRITE setFrom NOTIFY fromChanged) Q_PROPERTY(qreal to READ to WRITE setTo NOTIFY toChanged) QML_NAMED_ELEMENT(NumberAnimation) + QML_ADDED_IN_VERSION(2, 0) public: QQuickNumberAnimation(QObject *parent=nullptr); @@ -378,6 +385,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickVector3dAnimation : public QQuickPropertyAnim Q_PROPERTY(QVector3D from READ from WRITE setFrom NOTIFY fromChanged) Q_PROPERTY(QVector3D to READ to WRITE setTo NOTIFY toChanged) QML_NAMED_ELEMENT(Vector3dAnimation) + QML_ADDED_IN_VERSION(2, 0) public: QQuickVector3dAnimation(QObject *parent=nullptr); @@ -400,6 +408,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickRotationAnimation : public QQuickPropertyAnim Q_PROPERTY(qreal to READ to WRITE setTo NOTIFY toChanged) Q_PROPERTY(RotationDirection direction READ direction WRITE setDirection NOTIFY directionChanged) QML_NAMED_ELEMENT(RotationAnimation) + QML_ADDED_IN_VERSION(2, 0) public: QQuickRotationAnimation(QObject *parent=nullptr); @@ -445,6 +454,7 @@ class QQuickSequentialAnimation : public QQuickAnimationGroup Q_OBJECT Q_DECLARE_PRIVATE(QQuickAnimationGroup) QML_NAMED_ELEMENT(SequentialAnimation) + QML_ADDED_IN_VERSION(2, 0) public: QQuickSequentialAnimation(QObject *parent=nullptr); @@ -463,6 +473,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickParallelAnimation : public QQuickAnimationGro Q_OBJECT Q_DECLARE_PRIVATE(QQuickAnimationGroup) QML_NAMED_ELEMENT(ParallelAnimation) + QML_ADDED_IN_VERSION(2, 0) public: QQuickParallelAnimation(QObject *parent=nullptr); diff --git a/src/quick/util/qquickanimationcontroller_p.h b/src/quick/util/qquickanimationcontroller_p.h index da6df6038a..de308735ef 100644 --- a/src/quick/util/qquickanimationcontroller_p.h +++ b/src/quick/util/qquickanimationcontroller_p.h @@ -65,6 +65,7 @@ class Q_AUTOTEST_EXPORT QQuickAnimationController : public QObject, public QQmlP Q_DECLARE_PRIVATE(QQuickAnimationController) Q_CLASSINFO("DefaultProperty", "animation") QML_NAMED_ELEMENT(AnimationController) + QML_ADDED_IN_VERSION(2, 0) Q_PROPERTY(qreal progress READ progress WRITE setProgress NOTIFY progressChanged) Q_PROPERTY(QQuickAbstractAnimation *animation READ animation WRITE setAnimation NOTIFY animationChanged) diff --git a/src/quick/util/qquickanimator_p.h b/src/quick/util/qquickanimator_p.h index 9f7aaafcb0..0bcf4c40a4 100644 --- a/src/quick/util/qquickanimator_p.h +++ b/src/quick/util/qquickanimator_p.h @@ -70,7 +70,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickAnimator : public QQuickAbstractAnimation Q_PROPERTY(qreal from READ from WRITE setFrom NOTIFY fromChanged) QML_NAMED_ELEMENT(Animator) - QML_ADDED_IN_MINOR_VERSION(2) + QML_ADDED_IN_VERSION(2, 2) QML_UNCREATABLE("Animator is an abstract class") public: @@ -114,7 +114,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickScaleAnimator : public QQuickAnimator { Q_OBJECT QML_NAMED_ELEMENT(ScaleAnimator) - QML_ADDED_IN_MINOR_VERSION(2) + QML_ADDED_IN_VERSION(2, 2) public: QQuickScaleAnimator(QObject *parent = nullptr); protected: @@ -126,7 +126,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickXAnimator : public QQuickAnimator { Q_OBJECT QML_NAMED_ELEMENT(XAnimator) - QML_ADDED_IN_MINOR_VERSION(2) + QML_ADDED_IN_VERSION(2, 2) public: QQuickXAnimator(QObject *parent = nullptr); protected: @@ -138,7 +138,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickYAnimator : public QQuickAnimator { Q_OBJECT QML_NAMED_ELEMENT(YAnimator) - QML_ADDED_IN_MINOR_VERSION(2) + QML_ADDED_IN_VERSION(2, 2) public: QQuickYAnimator(QObject *parent = nullptr); protected: @@ -150,7 +150,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickOpacityAnimator : public QQuickAnimator { Q_OBJECT QML_NAMED_ELEMENT(OpacityAnimator) - QML_ADDED_IN_MINOR_VERSION(2) + QML_ADDED_IN_VERSION(2, 2) public: QQuickOpacityAnimator(QObject *parent = nullptr); protected: @@ -165,7 +165,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickRotationAnimator : public QQuickAnimator Q_DECLARE_PRIVATE(QQuickRotationAnimator) Q_PROPERTY(RotationDirection direction READ direction WRITE setDirection NOTIFY directionChanged) QML_NAMED_ELEMENT(RotationAnimator) - QML_ADDED_IN_MINOR_VERSION(2) + QML_ADDED_IN_VERSION(2, 2) public: enum RotationDirection { Numerical, Shortest, Clockwise, Counterclockwise }; @@ -192,7 +192,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickUniformAnimator : public QQuickAnimator Q_DECLARE_PRIVATE(QQuickUniformAnimator) Q_PROPERTY(QString uniform READ uniform WRITE setUniform NOTIFY uniformChanged) QML_NAMED_ELEMENT(UniformAnimator) - QML_ADDED_IN_MINOR_VERSION(2) + QML_ADDED_IN_VERSION(2, 2) public: QQuickUniformAnimator(QObject *parent = nullptr); diff --git a/src/quick/util/qquickanimatorjob.cpp b/src/quick/util/qquickanimatorjob.cpp index 0112a4b337..7b6b8bc878 100644 --- a/src/quick/util/qquickanimatorjob.cpp +++ b/src/quick/util/qquickanimatorjob.cpp @@ -48,6 +48,7 @@ # include <private/qquickopenglshadereffectnode_p.h> # include <private/qquickopenglshadereffect_p.h> # include <private/qquickshadereffect_p.h> +# include <QOpenGLContext> #endif #include <private/qanimationgroupjob_p.h> diff --git a/src/quick/util/qquickapplication_p.h b/src/quick/util/qquickapplication_p.h index b0eb6fa604..a740067bf3 100644 --- a/src/quick/util/qquickapplication_p.h +++ b/src/quick/util/qquickapplication_p.h @@ -72,6 +72,7 @@ class Q_AUTOTEST_EXPORT QQuickApplication : public QQmlApplication Q_PROPERTY(QQmlListProperty<QQuickScreenInfo> screens READ screens NOTIFY screensChanged) QML_NAMED_ELEMENT(Application) + QML_ADDED_IN_VERSION(2, 0) QML_UNCREATABLE("Application is an abstract class.") public: diff --git a/src/quick/util/qquickbehavior_p.h b/src/quick/util/qquickbehavior_p.h index a57a26d822..1ce687ac44 100644 --- a/src/quick/util/qquickbehavior_p.h +++ b/src/quick/util/qquickbehavior_p.h @@ -69,10 +69,11 @@ class Q_QUICK_PRIVATE_EXPORT QQuickBehavior : public QObject, public QQmlPropert Q_CLASSINFO("DefaultProperty", "animation") Q_PROPERTY(QQuickAbstractAnimation *animation READ animation WRITE setAnimation) Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) - Q_PROPERTY(QVariant targetValue READ targetValue NOTIFY targetValueChanged REVISION 13) - Q_PROPERTY(QQmlProperty targetProperty READ targetProperty NOTIFY targetPropertyChanged REVISION 15) + Q_PROPERTY(QVariant targetValue READ targetValue NOTIFY targetValueChanged REVISION(2, 13)) + Q_PROPERTY(QQmlProperty targetProperty READ targetProperty NOTIFY targetPropertyChanged REVISION(2, 15)) Q_CLASSINFO("DeferredPropertyNames", "animation") QML_NAMED_ELEMENT(Behavior) + QML_ADDED_IN_VERSION(2, 0) public: QQuickBehavior(QObject *parent=nullptr); diff --git a/src/quick/util/qquickfontloader.cpp b/src/quick/util/qquickfontloader.cpp index 505c70df7c..addf8b0c18 100644 --- a/src/quick/util/qquickfontloader.cpp +++ b/src/quick/util/qquickfontloader.cpp @@ -310,6 +310,7 @@ void QQuickFontLoader::updateFontInfo(const QString& name, QQuickFontLoader::Sta /*! \qmlproperty string QtQuick::FontLoader::name + \readonly This property holds the name of the font family. It is set automatically when a font is loaded using the \l source property. @@ -338,17 +339,6 @@ QString QQuickFontLoader::name() const return d->name; } -void QQuickFontLoader::setName(const QString &name) -{ - Q_D(QQuickFontLoader); - if (d->name == name) - return; - d->name = name; - emit nameChanged(); - d->status = Ready; - emit statusChanged(); -} - /*! \qmlproperty enumeration QtQuick::FontLoader::status diff --git a/src/quick/util/qquickfontloader_p.h b/src/quick/util/qquickfontloader_p.h index e849c52a35..8d831dac4d 100644 --- a/src/quick/util/qquickfontloader_p.h +++ b/src/quick/util/qquickfontloader_p.h @@ -65,9 +65,10 @@ class Q_AUTOTEST_EXPORT QQuickFontLoader : public QObject Q_DECLARE_PRIVATE(QQuickFontLoader) Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) - Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) + Q_PROPERTY(QString name READ name NOTIFY nameChanged) Q_PROPERTY(Status status READ status NOTIFY statusChanged) QML_NAMED_ELEMENT(FontLoader) + QML_ADDED_IN_VERSION(2, 0) public: enum Status { Null = 0, Ready, Loading, Error }; @@ -80,7 +81,6 @@ public: void setSource(const QUrl &url); QString name() const; - void setName(const QString &name); Status status() const; diff --git a/src/quick/util/qquickfontmetrics_p.h b/src/quick/util/qquickfontmetrics_p.h index ee6d679649..59f4aa8355 100644 --- a/src/quick/util/qquickfontmetrics_p.h +++ b/src/quick/util/qquickfontmetrics_p.h @@ -80,7 +80,7 @@ class Q_AUTOTEST_EXPORT QQuickFontMetrics : public QObject Q_PROPERTY(qreal strikeOutPosition READ strikeOutPosition NOTIFY fontChanged) Q_PROPERTY(qreal lineWidth READ lineWidth NOTIFY fontChanged) QML_NAMED_ELEMENT(FontMetrics) - QML_ADDED_IN_MINOR_VERSION(4) + QML_ADDED_IN_VERSION(2, 4) public: explicit QQuickFontMetrics(QObject *parent = nullptr); ~QQuickFontMetrics(); diff --git a/src/quick/util/qquickforeignutils_p.h b/src/quick/util/qquickforeignutils_p.h index 7e51bc4f82..9802420780 100644 --- a/src/quick/util/qquickforeignutils_p.h +++ b/src/quick/util/qquickforeignutils_p.h @@ -73,6 +73,7 @@ struct QValidatorForeign Q_GADGET QML_FOREIGN(QValidator) QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) }; struct QRegExpValidatorForeign @@ -80,6 +81,7 @@ struct QRegExpValidatorForeign Q_GADGET QML_FOREIGN(QRegExpValidator) QML_NAMED_ELEMENT(RegExpValidator) + QML_ADDED_IN_VERSION(2, 0) }; #if QT_CONFIG(regularexpression) @@ -88,7 +90,7 @@ struct QRegularExpressionValidatorForeign Q_GADGET QML_FOREIGN(QRegularExpressionValidator) QML_NAMED_ELEMENT(RegularExpressionValidator) - QML_ADDED_IN_MINOR_VERSION(14) + QML_ADDED_IN_VERSION(2, 14) }; #endif // QT_CONFIG(regularexpression) @@ -100,6 +102,7 @@ struct QInputMethodForeign Q_GADGET QML_FOREIGN(QInputMethod) QML_NAMED_ELEMENT(InputMethod) + QML_ADDED_IN_VERSION(2, 0) QML_UNCREATABLE("InputMethod is an abstract class.") }; #endif // QT_CONFIG(im) @@ -110,7 +113,7 @@ struct QKeySequenceForeign Q_GADGET QML_FOREIGN(QKeySequence) QML_NAMED_ELEMENT(StandardKey) - QML_ADDED_IN_MINOR_VERSION(2) + QML_ADDED_IN_VERSION(2, 2) QML_UNCREATABLE("Cannot create an instance of StandardKey.") }; #endif // QT_CONFIG(shortcut) diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp index 70256e202e..3ea2f88712 100644 --- a/src/quick/util/qquickglobal.cpp +++ b/src/quick/util/qquickglobal.cpp @@ -392,7 +392,7 @@ public: if (ok) *ok = true; } if (vweight->isInt32()) { - retn.setWeight(static_cast<QFont::Weight>(vweight->integerValue())); + retn.setWeight(vweight->integerValue()); if (ok) *ok = true; } if (vwspac->isNumber()) { diff --git a/src/quick/util/qquickimageprovider.h b/src/quick/util/qquickimageprovider.h index 82d0501697..f3dba81446 100644 --- a/src/quick/util/qquickimageprovider.h +++ b/src/quick/util/qquickimageprovider.h @@ -92,9 +92,11 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_finished()) }; +class QQuickImageProviderOptions; + class Q_QUICK_EXPORT QQuickImageProvider : public QQmlImageProviderBase { - friend class QQuickImageProviderWithOptions; // ### Qt 6 Remove + friend class QQuickImageProviderWithOptions; public: QQuickImageProvider(ImageType type, Flags flags = Flags()); ~QQuickImageProvider() override; @@ -102,15 +104,9 @@ public: ImageType imageType() const override; Flags flags() const override; -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) - virtual QImage requestImage(const QString &id, QSize *size, const QSize& requestedSize, const QQuickImageProviderOptions &options); - virtual QPixmap requestPixmap(const QString &id, QSize *size, const QSize& requestedSize, const QQuickImageProviderOptions &options); - virtual QQuickTextureFactory *requestTexture(const QString &id, QSize *size, const QSize &requestedSize, const QQuickImageProviderOptions &options); -#else virtual QImage requestImage(const QString &id, QSize *size, const QSize& requestedSize); virtual QPixmap requestPixmap(const QString &id, QSize *size, const QSize& requestedSize); virtual QQuickTextureFactory *requestTexture(const QString &id, QSize *size, const QSize &requestedSize); -#endif private: QQuickImageProviderPrivate *d; @@ -122,11 +118,7 @@ public: QQuickAsyncImageProvider(); ~QQuickAsyncImageProvider() override; -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) - virtual QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize, const QQuickImageProviderOptions &options) = 0; -#else virtual QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize) = 0; -#endif private: QQuickAsyncImageProviderPrivate *d; diff --git a/src/quick/util/qquickpath_p.h b/src/quick/util/qquickpath_p.h index 159c46d13c..8660537587 100644 --- a/src/quick/util/qquickpath_p.h +++ b/src/quick/util/qquickpath_p.h @@ -79,6 +79,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathElement : public QObject { Q_OBJECT QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: QQuickPathElement(QObject *parent=nullptr) : QObject(parent) {} Q_SIGNALS: @@ -92,6 +93,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathAttribute : public QQuickPathElement Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged) QML_NAMED_ELEMENT(PathAttribute) + QML_ADDED_IN_VERSION(2, 0) public: QQuickPathAttribute(QObject *parent=nullptr) : QQuickPathElement(parent) {} @@ -120,6 +122,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickCurve : public QQuickPathElement Q_PROPERTY(qreal relativeX READ relativeX WRITE setRelativeX NOTIFY relativeXChanged) Q_PROPERTY(qreal relativeY READ relativeY WRITE setRelativeY NOTIFY relativeYChanged) QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: QQuickCurve(QObject *parent=nullptr) : QQuickPathElement(parent) {} @@ -158,6 +161,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathLine : public QQuickCurve { Q_OBJECT QML_NAMED_ELEMENT(PathLine) + QML_ADDED_IN_VERSION(2, 0) public: QQuickPathLine(QObject *parent=nullptr) : QQuickCurve(parent) {} @@ -168,7 +172,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathMove : public QQuickCurve { Q_OBJECT QML_NAMED_ELEMENT(PathMove) - QML_ADDED_IN_MINOR_VERSION(9) + QML_ADDED_IN_VERSION(2, 9) public: QQuickPathMove(QObject *parent=nullptr) : QQuickCurve(parent) {} @@ -185,6 +189,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathQuad : public QQuickCurve Q_PROPERTY(qreal relativeControlY READ relativeControlY WRITE setRelativeControlY NOTIFY relativeControlYChanged) QML_NAMED_ELEMENT(PathQuad) + QML_ADDED_IN_VERSION(2, 0) public: QQuickPathQuad(QObject *parent=nullptr) : QQuickCurve(parent) {} @@ -230,6 +235,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathCubic : public QQuickCurve Q_PROPERTY(qreal relativeControl2X READ relativeControl2X WRITE setRelativeControl2X NOTIFY relativeControl2XChanged) Q_PROPERTY(qreal relativeControl2Y READ relativeControl2Y WRITE setRelativeControl2Y NOTIFY relativeControl2YChanged) QML_NAMED_ELEMENT(PathCubic) + QML_ADDED_IN_VERSION(2, 0) public: QQuickPathCubic(QObject *parent=nullptr) : QQuickCurve(parent) {} @@ -288,6 +294,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathCatmullRomCurve : public QQuickCurve { Q_OBJECT QML_NAMED_ELEMENT(PathCurve) + QML_ADDED_IN_VERSION(2, 0) public: QQuickPathCatmullRomCurve(QObject *parent=nullptr) : QQuickCurve(parent) {} @@ -301,8 +308,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathArc : public QQuickCurve Q_PROPERTY(qreal radiusY READ radiusY WRITE setRadiusY NOTIFY radiusYChanged) Q_PROPERTY(bool useLargeArc READ useLargeArc WRITE setUseLargeArc NOTIFY useLargeArcChanged) Q_PROPERTY(ArcDirection direction READ direction WRITE setDirection NOTIFY directionChanged) - Q_PROPERTY(qreal xAxisRotation READ xAxisRotation WRITE setXAxisRotation NOTIFY xAxisRotationChanged REVISION 9) + Q_PROPERTY(qreal xAxisRotation READ xAxisRotation WRITE setXAxisRotation NOTIFY xAxisRotationChanged REVISION(2, 9)) QML_NAMED_ELEMENT(PathArc) + QML_ADDED_IN_VERSION(2, 0) public: QQuickPathArc(QObject *parent=nullptr) @@ -333,7 +341,7 @@ Q_SIGNALS: void radiusYChanged(); void useLargeArcChanged(); void directionChanged(); - Q_REVISION(9) void xAxisRotationChanged(); + Q_REVISION(2, 9) void xAxisRotationChanged(); private: qreal _radiusX = 0; @@ -355,7 +363,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathAngleArc : public QQuickCurve Q_PROPERTY(bool moveToStart READ moveToStart WRITE setMoveToStart NOTIFY moveToStartChanged) QML_NAMED_ELEMENT(PathAngleArc) - QML_ADDED_IN_MINOR_VERSION(11) + QML_ADDED_IN_VERSION(2, 11) public: QQuickPathAngleArc(QObject *parent=nullptr) @@ -408,6 +416,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathSvg : public QQuickCurve Q_OBJECT Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged) QML_NAMED_ELEMENT(PathSvg) + QML_ADDED_IN_VERSION(2, 0) public: QQuickPathSvg(QObject *parent=nullptr) : QQuickCurve(parent) {} @@ -428,6 +437,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathPercent : public QQuickPathElement Q_OBJECT Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged) QML_NAMED_ELEMENT(PathPercent) + QML_ADDED_IN_VERSION(2, 0) public: QQuickPathPercent(QObject *parent=nullptr) : QQuickPathElement(parent) {} @@ -447,7 +457,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathPolyline : public QQuickCurve Q_PROPERTY(QPointF start READ start NOTIFY startChanged) Q_PROPERTY(QVariant path READ path WRITE setPath NOTIFY pathChanged) QML_NAMED_ELEMENT(PathPolyline) - QML_ADDED_IN_MINOR_VERSION(14) + QML_ADDED_IN_VERSION(2, 14) public: QQuickPathPolyline(QObject *parent=nullptr); @@ -471,7 +481,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathMultiline : public QQuickCurve Q_PROPERTY(QPointF start READ start NOTIFY startChanged) Q_PROPERTY(QVariant paths READ paths WRITE setPaths NOTIFY pathsChanged) QML_NAMED_ELEMENT(PathMultiline) - QML_ADDED_IN_MINOR_VERSION(14) + QML_ADDED_IN_VERSION(2, 14) public: QQuickPathMultiline(QObject *parent=nullptr); @@ -512,9 +522,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPath : public QObject, public QQmlParserStatu Q_PROPERTY(qreal startX READ startX WRITE setStartX NOTIFY startXChanged) Q_PROPERTY(qreal startY READ startY WRITE setStartY NOTIFY startYChanged) Q_PROPERTY(bool closed READ isClosed NOTIFY changed) - Q_PROPERTY(QSizeF scale READ scale WRITE setScale NOTIFY scaleChanged REVISION 14) + Q_PROPERTY(QSizeF scale READ scale WRITE setScale NOTIFY scaleChanged REVISION(2, 14)) Q_CLASSINFO("DefaultProperty", "pathElements") QML_NAMED_ELEMENT(Path) + QML_ADDED_IN_VERSION(2, 0) Q_INTERFACES(QQmlParserStatus) public: QQuickPath(QObject *parent=nullptr); @@ -535,7 +546,7 @@ public: QPainterPath path() const; QStringList attributes() const; qreal attributeAt(const QString &, qreal) const; - Q_REVISION(14) Q_INVOKABLE QPointF pointAtPercent(qreal t) const; + Q_REVISION(2, 14) Q_INVOKABLE QPointF pointAtPercent(qreal t) const; QPointF sequentialPointAt(qreal p, qreal *angle = nullptr) const; void invalidateSequentialHistory() const; @@ -546,7 +557,7 @@ Q_SIGNALS: void changed(); void startXChanged(); void startYChanged(); - Q_REVISION(14) void scaleChanged(); + Q_REVISION(2, 14) void scaleChanged(); protected: QQuickPath(QQuickPathPrivate &dd, QObject *parent = nullptr); @@ -609,7 +620,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathText : public QQuickPathElement Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged) QML_NAMED_ELEMENT(PathText) - QML_ADDED_IN_MINOR_VERSION(15) + QML_ADDED_IN_VERSION(2, 15) public: QQuickPathText(QObject *parent=nullptr) : QQuickPathElement(parent) { diff --git a/src/quick/util/qquickpathinterpolator_p.h b/src/quick/util/qquickpathinterpolator_p.h index 440ea06841..70fb0935e8 100644 --- a/src/quick/util/qquickpathinterpolator_p.h +++ b/src/quick/util/qquickpathinterpolator_p.h @@ -70,6 +70,7 @@ class Q_AUTOTEST_EXPORT QQuickPathInterpolator : public QObject Q_PROPERTY(qreal y READ y NOTIFY yChanged) Q_PROPERTY(qreal angle READ angle NOTIFY angleChanged) QML_NAMED_ELEMENT(PathInterpolator) + QML_ADDED_IN_VERSION(2, 0) public: explicit QQuickPathInterpolator(QObject *parent = nullptr); diff --git a/src/quick/util/qquickpixmapcache_p.h b/src/quick/util/qquickpixmapcache_p.h index 93dec63e94..87724d6210 100644 --- a/src/quick/util/qquickpixmapcache_p.h +++ b/src/quick/util/qquickpixmapcache_p.h @@ -197,8 +197,8 @@ private: Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickPixmap::Options) -// This class will disappear with Qt6 and will just be the regular QQuickImageProvider -// ### Qt 6: Remove this class and fold it with QQuickImageProvider +// ### Qt 6: This should be made public in Qt 6. It's functionality can't be merged into +// QQuickImageProvider without breaking source compatibility. class Q_QUICK_PRIVATE_EXPORT QQuickImageProviderWithOptions : public QQuickAsyncImageProvider { public: diff --git a/src/quick/util/qquickpropertychanges_p.h b/src/quick/util/qquickpropertychanges_p.h index 27a00420af..ff48de96c6 100644 --- a/src/quick/util/qquickpropertychanges_p.h +++ b/src/quick/util/qquickpropertychanges_p.h @@ -66,6 +66,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPropertyChanges : public QQuickStateOperation Q_PROPERTY(bool restoreEntryValues READ restoreEntryValues WRITE setRestoreEntryValues) Q_PROPERTY(bool explicit READ isExplicit WRITE setIsExplicit) QML_NAMED_ELEMENT(PropertyChanges) + QML_ADDED_IN_VERSION(2, 0) public: QQuickPropertyChanges(); diff --git a/src/quick/util/qquickshortcut_p.h b/src/quick/util/qquickshortcut_p.h index 0e66a38e75..67dab928b7 100644 --- a/src/quick/util/qquickshortcut_p.h +++ b/src/quick/util/qquickshortcut_p.h @@ -67,14 +67,14 @@ class QQuickShortcut : public QObject, public QQmlParserStatus Q_OBJECT Q_INTERFACES(QQmlParserStatus) Q_PROPERTY(QVariant sequence READ sequence WRITE setSequence NOTIFY sequenceChanged FINAL) - Q_PROPERTY(QVariantList sequences READ sequences WRITE setSequences NOTIFY sequencesChanged FINAL REVISION 9) - Q_PROPERTY(QString nativeText READ nativeText NOTIFY sequenceChanged FINAL REVISION 6) - Q_PROPERTY(QString portableText READ portableText NOTIFY sequenceChanged FINAL REVISION 6) + Q_PROPERTY(QVariantList sequences READ sequences WRITE setSequences NOTIFY sequencesChanged FINAL REVISION(2, 9)) + Q_PROPERTY(QString nativeText READ nativeText NOTIFY sequenceChanged FINAL REVISION(2, 6)) + Q_PROPERTY(QString portableText READ portableText NOTIFY sequenceChanged FINAL REVISION(2, 6)) Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged FINAL) Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat NOTIFY autoRepeatChanged FINAL) Q_PROPERTY(Qt::ShortcutContext context READ context WRITE setContext NOTIFY contextChanged FINAL) QML_NAMED_ELEMENT(Shortcut) - QML_ADDED_IN_MINOR_VERSION(5) + QML_ADDED_IN_VERSION(2, 5) public: explicit QQuickShortcut(QObject *parent = nullptr); @@ -100,7 +100,7 @@ public: Q_SIGNALS: void sequenceChanged(); - Q_REVISION(9) void sequencesChanged(); + Q_REVISION(2, 9) void sequencesChanged(); void enabledChanged(); void autoRepeatChanged(); void contextChanged(); diff --git a/src/quick/util/qquicksmoothedanimation_p.h b/src/quick/util/qquicksmoothedanimation_p.h index d7e637446d..4a53a4406f 100644 --- a/src/quick/util/qquicksmoothedanimation_p.h +++ b/src/quick/util/qquicksmoothedanimation_p.h @@ -69,6 +69,7 @@ class Q_AUTOTEST_EXPORT QQuickSmoothedAnimation : public QQuickNumberAnimation Q_PROPERTY(ReversingMode reversingMode READ reversingMode WRITE setReversingMode NOTIFY reversingModeChanged) Q_PROPERTY(qreal maximumEasingTime READ maximumEasingTime WRITE setMaximumEasingTime NOTIFY maximumEasingTimeChanged) QML_NAMED_ELEMENT(SmoothedAnimation) + QML_ADDED_IN_VERSION(2, 0) public: enum ReversingMode { Eased, Immediate, Sync }; diff --git a/src/quick/util/qquickspringanimation_p.h b/src/quick/util/qquickspringanimation_p.h index 771b746622..c09806e0ec 100644 --- a/src/quick/util/qquickspringanimation_p.h +++ b/src/quick/util/qquickspringanimation_p.h @@ -72,6 +72,7 @@ class Q_AUTOTEST_EXPORT QQuickSpringAnimation : public QQuickNumberAnimation Q_PROPERTY(qreal modulus READ modulus WRITE setModulus NOTIFY modulusChanged) Q_PROPERTY(qreal mass READ mass WRITE setMass NOTIFY massChanged) QML_NAMED_ELEMENT(SpringAnimation) + QML_ADDED_IN_VERSION(2, 0) public: QQuickSpringAnimation(QObject *parent=nullptr); diff --git a/src/quick/util/qquickstate_p.h b/src/quick/util/qquickstate_p.h index af49bb1c2f..ee9aa92bbd 100644 --- a/src/quick/util/qquickstate_p.h +++ b/src/quick/util/qquickstate_p.h @@ -126,6 +126,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickStateOperation : public QObject { Q_OBJECT QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: QQuickStateOperation(QObject *parent = nullptr) : QObject(parent) {} @@ -159,6 +160,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickState : public QObject Q_CLASSINFO("DefaultProperty", "changes") Q_CLASSINFO("DeferredPropertyNames", "changes") QML_NAMED_ELEMENT(State) + QML_ADDED_IN_VERSION(2, 0) public: QQuickState(QObject *parent=nullptr); diff --git a/src/quick/util/qquickstatechangescript_p.h b/src/quick/util/qquickstatechangescript_p.h index 931baaca4e..62f4910606 100644 --- a/src/quick/util/qquickstatechangescript_p.h +++ b/src/quick/util/qquickstatechangescript_p.h @@ -65,6 +65,7 @@ class Q_AUTOTEST_EXPORT QQuickStateChangeScript : public QQuickStateOperation, p Q_PROPERTY(QQmlScriptString script READ script WRITE setScript) Q_PROPERTY(QString name READ name WRITE setName) QML_NAMED_ELEMENT(StateChangeScript) + QML_ADDED_IN_VERSION(2, 0) public: QQuickStateChangeScript(QObject *parent=nullptr); diff --git a/src/quick/util/qquickstategroup_p.h b/src/quick/util/qquickstategroup_p.h index 11a0c5f442..c3d66fd824 100644 --- a/src/quick/util/qquickstategroup_p.h +++ b/src/quick/util/qquickstategroup_p.h @@ -66,6 +66,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickStateGroup : public QObject, public QQmlParse Q_PROPERTY(QQmlListProperty<QQuickState> states READ statesProperty DESIGNABLE false) Q_PROPERTY(QQmlListProperty<QQuickTransition> transitions READ transitionsProperty DESIGNABLE false) QML_NAMED_ELEMENT(StateGroup) + QML_ADDED_IN_VERSION(2, 0) public: QQuickStateGroup(QObject * = nullptr); diff --git a/src/quick/util/qquicksystempalette_p.h b/src/quick/util/qquicksystempalette_p.h index c6d9fc2604..43d7277bea 100644 --- a/src/quick/util/qquicksystempalette_p.h +++ b/src/quick/util/qquicksystempalette_p.h @@ -80,6 +80,7 @@ class Q_AUTOTEST_EXPORT QQuickSystemPalette : public QObject Q_PROPERTY(QColor highlight READ highlight NOTIFY paletteChanged) Q_PROPERTY(QColor highlightedText READ highlightedText NOTIFY paletteChanged) QML_NAMED_ELEMENT(SystemPalette) + QML_ADDED_IN_VERSION(2, 0) public: QQuickSystemPalette(QObject *parent=nullptr); diff --git a/src/quick/util/qquicktextmetrics_p.h b/src/quick/util/qquicktextmetrics_p.h index a1d64e3d0a..33c64073c2 100644 --- a/src/quick/util/qquicktextmetrics_p.h +++ b/src/quick/util/qquicktextmetrics_p.h @@ -75,7 +75,7 @@ class Q_AUTOTEST_EXPORT QQuickTextMetrics : public QObject Q_PROPERTY(Qt::TextElideMode elide READ elide WRITE setElide NOTIFY elideChanged FINAL) Q_PROPERTY(qreal elideWidth READ elideWidth WRITE setElideWidth NOTIFY elideWidthChanged FINAL) QML_NAMED_ELEMENT(TextMetrics) - QML_ADDED_IN_MINOR_VERSION(4) + QML_ADDED_IN_VERSION(2, 4) public: explicit QQuickTextMetrics(QObject *parent = 0); diff --git a/src/quick/util/qquicktransition_p.h b/src/quick/util/qquicktransition_p.h index 6e45143126..bfb7d75821 100644 --- a/src/quick/util/qquicktransition_p.h +++ b/src/quick/util/qquicktransition_p.h @@ -104,6 +104,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTransition : public QObject Q_CLASSINFO("DefaultProperty", "animations") Q_CLASSINFO("DeferredPropertyNames", "animations") QML_NAMED_ELEMENT(Transition) + QML_ADDED_IN_VERSION(2, 0) public: QQuickTransition(QObject *parent=nullptr); diff --git a/src/quick/util/qquickvalidator_p.h b/src/quick/util/qquickvalidator_p.h index a0dc2cd5ba..029737e10b 100644 --- a/src/quick/util/qquickvalidator_p.h +++ b/src/quick/util/qquickvalidator_p.h @@ -62,6 +62,7 @@ class Q_AUTOTEST_EXPORT QQuickIntValidator : public QIntValidator Q_OBJECT Q_PROPERTY(QString locale READ localeName WRITE setLocaleName RESET resetLocaleName NOTIFY localeNameChanged) QML_NAMED_ELEMENT(IntValidator) + QML_ADDED_IN_VERSION(2, 0) public: QQuickIntValidator(QObject *parent = nullptr); @@ -78,6 +79,7 @@ class Q_AUTOTEST_EXPORT QQuickDoubleValidator : public QDoubleValidator Q_OBJECT Q_PROPERTY(QString locale READ localeName WRITE setLocaleName RESET resetLocaleName NOTIFY localeNameChanged) QML_NAMED_ELEMENT(DoubleValidator) + QML_ADDED_IN_VERSION(2, 0) public: QQuickDoubleValidator(QObject *parent = nullptr); diff --git a/src/quick/util/qquickvaluetypes.cpp b/src/quick/util/qquickvaluetypes.cpp index 395385fa0d..517ed5da38 100644 --- a/src/quick/util/qquickvaluetypes.cpp +++ b/src/quick/util/qquickvaluetypes.cpp @@ -635,14 +635,14 @@ void QQuickFontValueType::setBold(bool b) v.setBold(b); } -QQuickFontValueType::FontWeight QQuickFontValueType::weight() const +int QQuickFontValueType::weight() const { - return (QQuickFontValueType::FontWeight)v.weight(); + return v.weight(); } -void QQuickFontValueType::setWeight(QQuickFontValueType::FontWeight w) +void QQuickFontValueType::setWeight(int w) { - v.setWeight((QFont::Weight)w); + v.setWeight(qBound(0, w, 99)); } bool QQuickFontValueType::italic() const diff --git a/src/quick/util/qquickvaluetypes_p.h b/src/quick/util/qquickvaluetypes_p.h index b6cbc37adb..ccd9eefe47 100644 --- a/src/quick/util/qquickvaluetypes_p.h +++ b/src/quick/util/qquickvaluetypes_p.h @@ -315,7 +315,7 @@ class QQuickFontValueType Q_PROPERTY(QString family READ family WRITE setFamily FINAL) Q_PROPERTY(QString styleName READ styleName WRITE setStyleName FINAL) Q_PROPERTY(bool bold READ bold WRITE setBold FINAL) - Q_PROPERTY(FontWeight weight READ weight WRITE setWeight FINAL) + Q_PROPERTY(int weight READ weight WRITE setWeight FINAL) Q_PROPERTY(bool italic READ italic WRITE setItalic FINAL) Q_PROPERTY(bool underline READ underline WRITE setUnderline FINAL) Q_PROPERTY(bool overline READ overline WRITE setOverline FINAL) @@ -330,6 +330,7 @@ class QQuickFontValueType Q_PROPERTY(bool preferShaping READ preferShaping WRITE setPreferShaping FINAL) QML_NAMED_ELEMENT(Font) + QML_ADDED_IN_VERSION(2, 0) QML_UNCREATABLE("Element is not creatable.") public: @@ -369,8 +370,8 @@ public: bool bold() const; void setBold(bool b); - FontWeight weight() const; - void setWeight(FontWeight); + int weight() const; + void setWeight(int); bool italic() const; void setItalic(bool b); @@ -420,6 +421,7 @@ class QQuickColorSpaceValueType Q_PROPERTY(float gamma READ gamma WRITE setGamma FINAL) QML_NAMED_ELEMENT(ColorSpace) + QML_ADDED_IN_VERSION(2, 15) Q_CLASSINFO("RegisterEnumClassesUnscoped", "false") public: diff --git a/src/quickshapes/qquickshape.cpp b/src/quickshapes/qquickshape.cpp index dcd331b388..563303b84a 100644 --- a/src/quickshapes/qquickshape.cpp +++ b/src/quickshapes/qquickshape.cpp @@ -600,8 +600,6 @@ void QQuickShapePath::resetFillGradient() \li The \c software backend is fully supported. The path is rendered via QPainter::strokePath() and QPainter::fillPath() in this case. - \li The Direct 3D 12 backend is not currently supported. - \li The OpenVG backend is not currently supported. \endlist diff --git a/src/quickshapes/qquickshape_p.h b/src/quickshapes/qquickshape_p.h index f86f2b03d6..ca72c628c5 100644 --- a/src/quickshapes/qquickshape_p.h +++ b/src/quickshapes/qquickshape_p.h @@ -76,6 +76,7 @@ class Q_QUICKSHAPES_PRIVATE_EXPORT QQuickShapeGradient : public QQuickGradient Q_CLASSINFO("DefaultProperty", "stops") QML_NAMED_ELEMENT(ShapeGradient) + QML_ADDED_IN_VERSION(1, 0) QML_UNCREATABLE("ShapeGradient is an abstract base class."); public: @@ -107,6 +108,7 @@ class Q_QUICKSHAPES_PRIVATE_EXPORT QQuickShapeLinearGradient : public QQuickShap Q_PROPERTY(qreal y2 READ y2 WRITE setY2 NOTIFY y2Changed) Q_CLASSINFO("DefaultProperty", "stops") QML_NAMED_ELEMENT(LinearGradient) + QML_ADDED_IN_VERSION(1, 0) public: QQuickShapeLinearGradient(QObject *parent = nullptr); @@ -142,6 +144,7 @@ class Q_QUICKSHAPES_PRIVATE_EXPORT QQuickShapeRadialGradient : public QQuickShap Q_PROPERTY(qreal focalRadius READ focalRadius WRITE setFocalRadius NOTIFY focalRadiusChanged) Q_CLASSINFO("DefaultProperty", "stops") QML_NAMED_ELEMENT(RadialGradient) + QML_ADDED_IN_VERSION(1, 0) public: QQuickShapeRadialGradient(QObject *parent = nullptr); @@ -187,6 +190,7 @@ class Q_QUICKSHAPES_PRIVATE_EXPORT QQuickShapeConicalGradient : public QQuickSha Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged) Q_CLASSINFO("DefaultProperty", "stops") QML_NAMED_ELEMENT(ConicalGradient) + QML_ADDED_IN_VERSION(1, 0) public: QQuickShapeConicalGradient(QObject *parent = nullptr); @@ -225,8 +229,9 @@ class Q_QUICKSHAPES_PRIVATE_EXPORT QQuickShapePath : public QQuickPath Q_PROPERTY(qreal dashOffset READ dashOffset WRITE setDashOffset NOTIFY dashOffsetChanged) Q_PROPERTY(QVector<qreal> dashPattern READ dashPattern WRITE setDashPattern NOTIFY dashPatternChanged) Q_PROPERTY(QQuickShapeGradient *fillGradient READ fillGradient WRITE setFillGradient RESET resetFillGradient) - Q_PROPERTY(QSizeF scale READ scale WRITE setScale NOTIFY scaleChanged REVISION 14) + Q_PROPERTY(QSizeF scale READ scale WRITE setScale NOTIFY scaleChanged REVISION(1, 14)) QML_NAMED_ELEMENT(ShapePath) + QML_ADDED_IN_VERSION(1, 0) public: enum FillRule { @@ -318,10 +323,11 @@ class Q_QUICKSHAPES_PRIVATE_EXPORT QQuickShape : public QQuickItem Q_PROPERTY(bool asynchronous READ asynchronous WRITE setAsynchronous NOTIFY asynchronousChanged) Q_PROPERTY(bool vendorExtensionsEnabled READ vendorExtensionsEnabled WRITE setVendorExtensionsEnabled NOTIFY vendorExtensionsEnabledChanged) Q_PROPERTY(Status status READ status NOTIFY statusChanged) - Q_PROPERTY(ContainsMode containsMode READ containsMode WRITE setContainsMode NOTIFY containsModeChanged REVISION 11) + Q_PROPERTY(ContainsMode containsMode READ containsMode WRITE setContainsMode NOTIFY containsModeChanged REVISION(1, 11)) Q_PROPERTY(QQmlListProperty<QObject> data READ data) Q_CLASSINFO("DefaultProperty", "data") QML_NAMED_ELEMENT(Shape) + QML_ADDED_IN_VERSION(1, 0) public: enum RendererType { @@ -377,7 +383,7 @@ Q_SIGNALS: void asynchronousChanged(); void vendorExtensionsEnabledChanged(); void statusChanged(); - Q_REVISION(11) void containsModeChanged(); + Q_REVISION(1, 11) void containsModeChanged(); private: Q_DISABLE_COPY(QQuickShape) diff --git a/src/quickshapes/qquickshapegenericrenderer.cpp b/src/quickshapes/qquickshapegenericrenderer.cpp index e0df739987..91716981d8 100644 --- a/src/quickshapes/qquickshapegenericrenderer.cpp +++ b/src/quickshapes/qquickshapegenericrenderer.cpp @@ -49,7 +49,7 @@ #if QT_CONFIG(opengl) #include <QOpenGLContext> #include <QOffscreenSurface> -#include <QtGui/private/qopenglextensions_p.h> +#include <private/qopenglextensions_p.h> #endif QT_BEGIN_NAMESPACE diff --git a/src/quickshapes/quickshapes.pro b/src/quickshapes/quickshapes.pro index 4dbd3e5e46..7b77391d92 100644 --- a/src/quickshapes/quickshapes.pro +++ b/src/quickshapes/quickshapes.pro @@ -35,5 +35,5 @@ load(qt_module) QMLTYPES_FILENAME = plugins.qmltypes QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQuick/Shapes QML_IMPORT_NAME = QtQuick.Shapes -IMPORT_VERSION = 1.$$QT_MINOR_VERSION +QML_IMPORT_VERSION = $$QT_VERSION CONFIG += qmltypes install_qmltypes install_metatypes diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp index 8ecfbf65dd..db7ae22767 100644 --- a/src/quickwidgets/qquickwidget.cpp +++ b/src/quickwidgets/qquickwidget.cpp @@ -59,9 +59,11 @@ #include <QtGui/qpa/qplatformintegration.h> #if QT_CONFIG(opengl) -#include <QtGui/QOpenGLContext> -#include <QtGui/QOpenGLFunctions> -#include <QtGui/private/qopenglextensions_p.h> +#include <private/qopenglcontext_p.h> +#include <private/qopenglextensions_p.h> +#include <QOpenGLFramebufferObject> +#include <QOpenGLContext> +#include <QOpenGLFunctions> #endif #include <QtGui/QPainter> @@ -500,7 +502,7 @@ QImage QQuickWidgetPrivate::grabFramebuffer() \section1 Support when not using OpenGL In addition to OpenGL, the \c software backend of Qt Quick also supports - QQuickWidget. Other backends, for example the Direct 3D 12 one, are not + QQuickWidget. Other backends, for example OpenVG, are not compatible however and attempting to construct a QQuickWidget will lead to problems. diff --git a/tests/auto/qml/animation/qparallelanimationgroupjob/tst_qparallelanimationgroupjob.cpp b/tests/auto/qml/animation/qparallelanimationgroupjob/tst_qparallelanimationgroupjob.cpp index a8bcadbc84..8c4c461813 100644 --- a/tests/auto/qml/animation/qparallelanimationgroupjob/tst_qparallelanimationgroupjob.cpp +++ b/tests/auto/qml/animation/qparallelanimationgroupjob/tst_qparallelanimationgroupjob.cpp @@ -432,8 +432,7 @@ void tst_QParallelAnimationGroupJob::deleteChildrenWithRunningGroup() QCOMPARE(group.state(), QAnimationGroupJob::Running); QCOMPARE(anim1->state(), QAnimationGroupJob::Running); - QTest::qWait(80); - QVERIFY(group.currentLoopTime() > 0); + QTRY_VERIFY(group.currentLoopTime() > 0); delete anim1; QVERIFY(!group.firstChild()); diff --git a/tests/auto/qml/animation/qpauseanimationjob/BLACKLIST b/tests/auto/qml/animation/qpauseanimationjob/BLACKLIST new file mode 100644 index 0000000000..33799b6528 --- /dev/null +++ b/tests/auto/qml/animation/qpauseanimationjob/BLACKLIST @@ -0,0 +1,3 @@ +[multipleSequentialGroups] +macos ci + diff --git a/tests/auto/qml/ecmascripttests/qjstest/qjstest.pro b/tests/auto/qml/ecmascripttests/qjstest/qjstest.pro index 6dec5f8f23..adead821e4 100644 --- a/tests/auto/qml/ecmascripttests/qjstest/qjstest.pro +++ b/tests/auto/qml/ecmascripttests/qjstest/qjstest.pro @@ -3,6 +3,8 @@ TARGET = qjstest QT += qml-private INCLUDEPATH += . +CONFIG += c++14 + DEFINES += QT_DEPRECATED_WARNINGS HEADERS += test262runner.h diff --git a/tests/auto/qml/ecmascripttests/testcase.pro b/tests/auto/qml/ecmascripttests/testcase.pro index 5bf7ecd696..9405095050 100644 --- a/tests/auto/qml/ecmascripttests/testcase.pro +++ b/tests/auto/qml/ecmascripttests/testcase.pro @@ -6,6 +6,8 @@ SOURCES += tst_ecmascripttests.cpp qjstest/test262runner.cpp HEADERS += qjstest/test262runner.h DEFINES += SRCDIR=\\\"$$PWD\\\" +CONFIG += c++14 + # The ES test suite takes approximately 5 mins to run, on a fairly # vanilla developer machine, so the default watchdog timer kills the # test some of the time. Fix by raising time-out to 400s when diff --git a/tests/auto/qml/qml.pro b/tests/auto/qml/qml.pro index 7a08cc805c..7a2ba10096 100644 --- a/tests/auto/qml/qml.pro +++ b/tests/auto/qml/qml.pro @@ -12,7 +12,6 @@ PUBLICTESTS += \ qqmlfileselector PUBLICTESTS += \ - qmlmin \ qqmlcomponent \ qqmlconsole \ qqmlengine \ diff --git a/tests/auto/qml/qmlformat/data/largeBindings.formatted.qml b/tests/auto/qml/qmlformat/data/largeBindings.formatted.qml new file mode 100644 index 0000000000..d8e4ffb087 --- /dev/null +++ b/tests/auto/qml/qmlformat/data/largeBindings.formatted.qml @@ -0,0 +1,9 @@ +QtObject { + small1: 3 + small2: foo + // THIS NEEDS TO BE LAST + largeBinding: { + var x = 300; + console.log(x); + } +} diff --git a/tests/auto/qml/qmlformat/data/largeBindings.qml b/tests/auto/qml/qmlformat/data/largeBindings.qml new file mode 100644 index 0000000000..a2249f6815 --- /dev/null +++ b/tests/auto/qml/qmlformat/data/largeBindings.qml @@ -0,0 +1,11 @@ +QtObject +{ + // THIS NEEDS TO BE LAST + largeBinding: { + var x = 300; + console.log(x); + } + + small1: 3 + small2: foo +} diff --git a/tests/auto/qml/qmlformat/data/statesAndTransitions.formatted.qml b/tests/auto/qml/qmlformat/data/statesAndTransitions.formatted.qml new file mode 100644 index 0000000000..bd063ac498 --- /dev/null +++ b/tests/auto/qml/qmlformat/data/statesAndTransitions.formatted.qml @@ -0,0 +1,16 @@ +QtObject { + id: foo + + // This needs to be *before* states and transitions after formatting + Item { + } + + states: [ + State { + } + ] + transitions: [ + Transition { + } + ] +} diff --git a/tests/auto/qml/qmlformat/data/statesAndTransitions.qml b/tests/auto/qml/qmlformat/data/statesAndTransitions.qml new file mode 100644 index 0000000000..648bdce6b9 --- /dev/null +++ b/tests/auto/qml/qmlformat/data/statesAndTransitions.qml @@ -0,0 +1,10 @@ +QtObject { + id: foo + + states: [ State {} ] + transitions: [ Transition {} ] + + // This needs to be *before* states and transitions after formatting + Item {} + +} diff --git a/tests/auto/qml/qmlformat/tst_qmlformat.cpp b/tests/auto/qml/qmlformat/tst_qmlformat.cpp index 47255d7745..21d5ae46a9 100644 --- a/tests/auto/qml/qmlformat/tst_qmlformat.cpp +++ b/tests/auto/qml/qmlformat/tst_qmlformat.cpp @@ -45,6 +45,8 @@ private Q_SLOTS: void testAnnotationsNoSort(); void testReadOnlyProps(); + void testStatesAndTransitions(); + void testLargeBindings(); #if !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled void testExample(); @@ -200,6 +202,16 @@ void TestQmlformat::testReadOnlyProps() QCOMPARE(runQmlformat(testFile("readOnlyProps.qml"), false, true), readTestFile("readOnlyProps.formatted.qml")); } +void TestQmlformat::testStatesAndTransitions() +{ + QCOMPARE(runQmlformat(testFile("statesAndTransitions.qml"), false, true), readTestFile("statesAndTransitions.formatted.qml")); +} + +void TestQmlformat::testLargeBindings() +{ + QCOMPARE(runQmlformat(testFile("largeBindings.qml"), false, true), readTestFile("largeBindings.formatted.qml")); +} + #if !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled void TestQmlformat::testExample_data() { diff --git a/tests/auto/qml/qmlmin/qmlmin.pro b/tests/auto/qml/qmlmin/qmlmin.pro deleted file mode 100644 index 93e5caabcf..0000000000 --- a/tests/auto/qml/qmlmin/qmlmin.pro +++ /dev/null @@ -1,12 +0,0 @@ -CONFIG += testcase -TARGET = tst_qmlmin -QT += qml testlib gui-private -macx:CONFIG -= app_bundle - -SOURCES += tst_qmlmin.cpp -DEFINES += SRCDIR=\\\"$$PWD\\\" - -# Boot2qt is cross compiled but it has sources available -!boot2qt { - cross_compile: DEFINES += QTEST_CROSS_COMPILED -} diff --git a/tests/auto/qml/qmlmin/tst_qmlmin.cpp b/tests/auto/qml/qmlmin/tst_qmlmin.cpp deleted file mode 100644 index 0501a8112a..0000000000 --- a/tests/auto/qml/qmlmin/tst_qmlmin.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qtest.h> -#include <QLibraryInfo> -#include <QDir> -#if QT_CONFIG(process) -#include <QProcess> -#endif -#include <QDebug> -#include <QQmlError> -#include <cstdlib> - -class tst_qmlmin : public QObject -{ - Q_OBJECT -public: - tst_qmlmin(); - -private slots: - void initTestCase(); -#if QT_CONFIG(process) && !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled - void qmlMinify_data(); - void qmlMinify(); -#endif - -private: - QString qmlminPath; - QStringList excludedDirs; - QStringList invalidFiles; - - QStringList findFiles(const QDir &); - bool isInvalidFile(const QFileInfo &fileName) const; -}; - -tst_qmlmin::tst_qmlmin() -{ -} - -void tst_qmlmin::initTestCase() -{ -#if QT_CONFIG(process) && !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled - qmlminPath = QLibraryInfo::location(QLibraryInfo::BinariesPath) + QLatin1String("/qmlmin"); -#ifdef Q_OS_WIN - qmlminPath += QLatin1String(".exe"); -#endif - if (!QFileInfo(qmlminPath).exists()) { - QString message = QString::fromLatin1("qmlmin executable not found (looked for %0)") - .arg(qmlminPath); - QFAIL(qPrintable(message)); - } - - // Add directories you want excluded here - - // These snippets are not expected to run on their own. - excludedDirs << "doc/src/snippets/qml/visualdatamodel_rootindex"; - excludedDirs << "doc/src/snippets/qml/qtbinding"; - excludedDirs << "doc/src/snippets/qml/imports"; - excludedDirs << "doc/src/snippets/qtquick1/visualdatamodel_rootindex"; - excludedDirs << "doc/src/snippets/qtquick1/qtbinding"; - excludedDirs << "doc/src/snippets/qtquick1/imports"; - excludedDirs << "tests/manual/v4"; - excludedDirs << "tests/auto/qml/ecmascripttests"; - excludedDirs << "tests/auto/qml/qmllint"; - - // Add invalid files (i.e. files with syntax errors) - invalidFiles << "tests/auto/quick/qquickloader/data/InvalidSourceComponent.qml"; - invalidFiles << "tests/auto/qml/qqmllanguage/data/signal.2.qml"; - invalidFiles << "tests/auto/qml/qqmllanguage/data/signal.3.qml"; - invalidFiles << "tests/auto/qml/qqmllanguage/data/signal.5.qml"; - invalidFiles << "tests/auto/qml/qqmllanguage/data/property.4.qml"; - invalidFiles << "tests/auto/qml/qqmllanguage/data/empty.qml"; - invalidFiles << "tests/auto/qml/qqmllanguage/data/missingObject.qml"; - invalidFiles << "tests/auto/qml/qqmllanguage/data/insertedSemicolon.1.qml"; - invalidFiles << "tests/auto/qml/qqmllanguage/data/nonexistantProperty.5.qml"; - invalidFiles << "tests/auto/qml/qqmllanguage/data/invalidRoot.1.qml"; - invalidFiles << "tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.1.qml"; - invalidFiles << "tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.2.qml"; - invalidFiles << "tests/auto/qml/qquickfolderlistmodel/data/dummy.qml"; - invalidFiles << "tests/auto/qml/qqmlecmascript/data/qtbug_22843.js"; - invalidFiles << "tests/auto/qml/qqmlecmascript/data/qtbug_22843.library.js"; - invalidFiles << "tests/auto/qml/qquickworkerscript/data/script_error_onLoad.js"; - invalidFiles << "tests/auto/qml/parserstress/tests/ecma_3/Unicode/regress-352044-02-n.js"; - invalidFiles << "tests/auto/qml/qqmlecmascript/data/incrDecrSemicolon_error1.qml"; - invalidFiles << "tests/auto/qml/qqmlecmascript/data/jsimportfail/malformedFileQualifier.js"; - invalidFiles << "tests/auto/qml/qqmlecmascript/data/jsimportfail/malformedFileQualifier.2.js"; - invalidFiles << "tests/auto/qml/qqmlecmascript/data/jsimportfail/malformedImport.js"; - invalidFiles << "tests/auto/qml/qqmlecmascript/data/jsimportfail/malformedModule.js"; - invalidFiles << "tests/auto/qml/qqmlecmascript/data/jsimportfail/malformedFile.js"; - invalidFiles << "tests/auto/qml/qqmlecmascript/data/jsimportfail/malformedModuleQualifier.js"; - invalidFiles << "tests/auto/qml/qqmlecmascript/data/jsimportfail/malformedModuleQualifier.2.js"; - invalidFiles << "tests/auto/qml/qqmlecmascript/data/jsimportfail/malformedModuleVersion.js"; - invalidFiles << "tests/auto/qml/qqmlecmascript/data/jsimportfail/missingFileQualifier.js"; - invalidFiles << "tests/auto/qml/qqmlecmascript/data/jsimportfail/missingModuleQualifier.js"; - invalidFiles << "tests/auto/qml/qqmlecmascript/data/jsimportfail/missingModuleVersion.js"; - invalidFiles << "tests/auto/qml/qqmlecmascript/data/stringParsing_error.1.qml"; - invalidFiles << "tests/auto/qml/qqmlecmascript/data/stringParsing_error.2.qml"; - invalidFiles << "tests/auto/qml/qqmlecmascript/data/stringParsing_error.3.qml"; - invalidFiles << "tests/auto/qml/qqmlecmascript/data/stringParsing_error.4.qml"; - invalidFiles << "tests/auto/qml/qqmlecmascript/data/stringParsing_error.5.qml"; - invalidFiles << "tests/auto/qml/qqmlecmascript/data/stringParsing_error.6.qml"; - invalidFiles << "tests/auto/qml/qqmlecmascript/data/numberParsing_error.1.qml"; - invalidFiles << "tests/auto/qml/qqmlecmascript/data/numberParsing_error.2.qml"; - invalidFiles << "tests/auto/qml/parserstress/tests/ecma_3/FunExpr/fe-001.js"; - invalidFiles << "tests/auto/qml/qjsengine/script/com/trolltech/syntaxerror/__init__.js"; - invalidFiles << "tests/auto/qml/debugger/qqmlpreview/data/broken.qml"; - invalidFiles << "tests/auto/qml/qqmllanguage/data/fuzzed.2.qml"; - invalidFiles << "tests/auto/qml/qqmllanguage/data/fuzzed.3.qml"; - invalidFiles << "tests/auto/qml/qqmllanguage/data/requiredProperties.2.qml"; - // generatorFunction.qml is not invalid per se, but the minifier cannot handle yield statements - invalidFiles << "tests/auto/qml/qqmlecmascript/data/generatorFunction.qml"; -#endif -} - -QStringList tst_qmlmin::findFiles(const QDir &d) -{ - for (int ii = 0; ii < excludedDirs.count(); ++ii) { - QString s = excludedDirs.at(ii); - if (d.absolutePath().endsWith(s)) - return QStringList(); - } - - QStringList rv; - - QStringList files = d.entryList(QStringList() << QLatin1String("*.qml") << QLatin1String("*.js"), - QDir::Files); - foreach (const QString &file, files) { - rv << d.absoluteFilePath(file); - } - - QStringList dirs = d.entryList(QDir::Dirs | QDir::NoDotAndDotDot | - QDir::NoSymLinks); - foreach (const QString &dir, dirs) { - QDir sub = d; - sub.cd(dir); - rv << findFiles(sub); - } - - return rv; -} - -bool tst_qmlmin::isInvalidFile(const QFileInfo &fileName) const -{ - foreach (const QString &invalidFile, invalidFiles) { - if (fileName.absoluteFilePath().endsWith(invalidFile)) - return true; - } - return false; -} - -/* -This test runs all the examples in the Qt QML UI source tree and ensures -that they start and exit cleanly. - -Examples are any .qml files under the examples/ directory that start -with a lower case letter. -*/ - -#if QT_CONFIG(process) && !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled -void tst_qmlmin::qmlMinify_data() -{ - QTest::addColumn<QString>("file"); - - QString examples = QLatin1String(SRCDIR) + "/../../../../examples/"; - QString tests = QLatin1String(SRCDIR) + "/../../../../tests/"; - - QStringList files; - files << findFiles(QDir(examples)); - files << findFiles(QDir(tests)); - - foreach (const QString &file, files) - QTest::newRow(qPrintable(file)) << file; -} -#endif - -#if QT_CONFIG(process) && !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled -void tst_qmlmin::qmlMinify() -{ - QFETCH(QString, file); - - QProcess qmlminify; - - // Restrict line width to 100 characters - qmlminify.start(qmlminPath, QStringList() << QLatin1String("--verify-only") << QLatin1String("-w100") << file); - qmlminify.waitForFinished(); - - QCOMPARE(qmlminify.error(), QProcess::UnknownError); - QCOMPARE(qmlminify.exitStatus(), QProcess::NormalExit); - - if (isInvalidFile(file)) - QCOMPARE(qmlminify.exitCode(), EXIT_FAILURE); // cannot minify files with syntax errors - else - QCOMPARE(qmlminify.exitCode(), 0); -} -#endif - -QTEST_MAIN(tst_qmlmin) - -#include "tst_qmlmin.moc" diff --git a/tests/auto/qml/qmlplugindump/data/dumper/ExtendedType/plugins.qmltypes b/tests/auto/qml/qmlplugindump/data/dumper/ExtendedType/plugins.qmltypes index d84eb0011a..5c5ae73ca5 100644 --- a/tests/auto/qml/qmlplugindump/data/dumper/ExtendedType/plugins.qmltypes +++ b/tests/auto/qml/qmlplugindump/data/dumper/ExtendedType/plugins.qmltypes @@ -27,9 +27,9 @@ Module { "dumper.ExtendedType/Type 1.0", "dumper.ExtendedType/Type 1.1" ] - exportMetaObjectRevisions: [0, 101] + exportMetaObjectRevisions: [0, 257] Property { name: "baseProperty"; type: "int" } - Property { name: "extendedProperty"; revision: 101; type: "int" } - Property { name: "data"; revision: 101; type: "QObject"; isList: true; isReadonly: true } + Property { name: "extendedProperty"; revision: 257; type: "int" } + Property { name: "data"; revision: 257; type: "QObject"; isList: true; isReadonly: true } } } diff --git a/tests/auto/qml/qmlplugindump/data/dumper/Versions/plugins.qmltypes b/tests/auto/qml/qmlplugindump/data/dumper/Versions/plugins.qmltypes index 3a33590139..ce003fc535 100644 --- a/tests/auto/qml/qmlplugindump/data/dumper/Versions/plugins.qmltypes +++ b/tests/auto/qml/qmlplugindump/data/dumper/Versions/plugins.qmltypes @@ -15,9 +15,9 @@ Module { "dumper.Versions/Versions 1.0", "dumper.Versions/Versions 1.1" ] - exportMetaObjectRevisions: [0, 1] + exportMetaObjectRevisions: [0, 65281] Property { name: "foo"; type: "int" } - Property { name: "bar"; revision: 1; type: "int" } - Property { name: "baz"; revision: 2; type: "int" } + Property { name: "bar"; revision: 65281; type: "int" } + Property { name: "baz"; revision: 65282; type: "int" } } } diff --git a/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp b/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp index bc4ba9437c..db79adac6c 100644 --- a/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp +++ b/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp @@ -94,7 +94,8 @@ namespace { QString toString(const QQmlDirParser::Component &c) { return c.typeName + QLatin1Char('|') + c.fileName + QLatin1Char('|') - + QString::number(c.majorVersion) + QLatin1Char('|') + QString::number(c.minorVersion) + + QString::number(c.version.majorVersion()) + QLatin1Char('|') + + QString::number(c.version.minorVersion()) + QLatin1Char('|') + (c.internal ? "true" : "false"); } @@ -112,7 +113,8 @@ namespace { QString toString(const QQmlDirParser::Script &s) { return s.nameSpace + QLatin1Char('|') + s.fileName + QLatin1Char('|') - + QString::number(s.majorVersion) + '|' + QString::number(s.minorVersion); + + QString::number(s.version.majorVersion()) + '|' + + QString::number(s.version.minorVersion()); } QStringList toStringList(const QList<QQmlDirParser::Script> &scripts) @@ -248,7 +250,7 @@ void tst_qqmldirparser::parse_data() << "unversioned-component/qmldir" << QStringList() << QStringList() - << (QStringList() << "foo|bar|-1|-1|false") + << (QStringList() << "foo|bar|255|255|false") << QStringList() << QStringList() << false; diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 2a1457d818..61dc393998 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -5771,7 +5771,7 @@ void tst_qqmlecmascript::sequenceConversionRead() QVERIFY(seq != nullptr); // we haven't registered QList<NonRegisteredType> as a sequence type. - QString warningOne = QLatin1String("QMetaProperty::read: Unable to handle unregistered datatype 'QList<NonRegisteredType>' for property 'MySequenceConversionObject::typeListProperty'"); + QString warningOne = QLatin1String("QMetaProperty::read: Unable to handle unregistered datatype 'QVector<NonRegisteredType>' for property 'MySequenceConversionObject::typeListProperty'"); QString warningTwo = qmlFile.toString() + QLatin1String(":18: TypeError: Cannot read property 'length' of undefined"); QTest::ignoreMessage(QtWarningMsg, warningOne.toLatin1().constData()); QTest::ignoreMessage(QtWarningMsg, warningTwo.toLatin1().constData()); @@ -5781,7 +5781,7 @@ void tst_qqmlecmascript::sequenceConversionRead() // QList<NonRegisteredType> has not been registered as a sequence type. QCOMPARE(object->property("pointListLength").toInt(), 0); QVERIFY(!object->property("pointList").isValid()); - QTest::ignoreMessage(QtWarningMsg, "QMetaProperty::read: Unable to handle unregistered datatype 'QList<NonRegisteredType>' for property 'MySequenceConversionObject::typeListProperty'"); + QTest::ignoreMessage(QtWarningMsg, "QMetaProperty::read: Unable to handle unregistered datatype 'QVector<NonRegisteredType>' for property 'MySequenceConversionObject::typeListProperty'"); QQmlProperty seqProp(seq, "typeListProperty", &engine); QVERIFY(!seqProp.read().isValid()); // not a valid/known sequence type @@ -5937,7 +5937,7 @@ void tst_qqmlecmascript::sequenceConversionBindings() { QUrl qmlFile = testFileUrl("sequenceConversion.bindings.error.qml"); - QString warning = QString(QLatin1String("%1:17:9: Unable to assign QList<int> to QList<bool>")).arg(qmlFile.toString()); + QString warning = QString(QLatin1String("%1:17:9: Unable to assign QVector<int> to QVector<bool>")).arg(qmlFile.toString()); QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData()); QQmlComponent component(&engine, qmlFile); QObject *object = component.create(); diff --git a/tests/auto/qml/qqmlengine/data/qtqmlModule.10.qml b/tests/auto/qml/qqmlengine/data/qtqmlModule.10.qml new file mode 100644 index 0000000000..3fc0cc217d --- /dev/null +++ b/tests/auto/qml/qqmlengine/data/qtqmlModule.10.qml @@ -0,0 +1,4 @@ +import QtQml 6.50 + +QtObject { +} diff --git a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp index cfbbd2a94c..0081243a88 100644 --- a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp +++ b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp @@ -687,9 +687,9 @@ void tst_qqmlengine::qtqmlModule_data() << QString(testFileUrl("qtqmlModule.3.qml").toString() + QLatin1String(":1 module \"QtQml\" version 1.0 is not installed\n")) << QStringList(); - QTest::newRow("import QtQml of incorrect version (2.50)") + QTest::newRow("import QtQml of old version (2.50)") << testFileUrl("qtqmlModule.4.qml") - << QString(testFileUrl("qtqmlModule.4.qml").toString() + QLatin1String(":1 module \"QtQml\" version 2.50 is not installed\n")) + << QString() << QStringList(); QTest::newRow("QtQml 2.0 module provides Component, QtObject, Connections, Binding and Timer") @@ -716,6 +716,11 @@ void tst_qqmlengine::qtqmlModule_data() << testFileUrl("qtqmlModule.9.qml") << QString(testFileUrl("qtqmlModule.9.qml").toString() + QLatin1String(":4 Item is not a type\n")) << QStringList(); + + QTest::newRow("import QtQml of incorrect version (6.50)") + << testFileUrl("qtqmlModule.10.qml") + << QString(testFileUrl("qtqmlModule.10.qml").toString() + QLatin1String(":1 module \"QtQml\" version 6.50 is not installed\n")) + << QStringList(); } // Test that the engine registers the QtQml module diff --git a/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp b/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp index 846ac842db..26b2b839ea 100644 --- a/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp +++ b/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp @@ -78,7 +78,8 @@ void tst_qqmlenginecleanup::test_qmlClearTypeRegistrations() QUrl testFile = testFileUrl("types.qml"); const auto qmlTypeForTestType = []() { - return QQmlMetaType::qmlType(QStringLiteral("TestTypeCpp"), QStringLiteral("Test"), 2, 0); + return QQmlMetaType::qmlType(QStringLiteral("TestTypeCpp"), QStringLiteral("Test"), + QTypeRevision::fromVersion(2, 0)); }; QVERIFY(!qmlTypeForTestType().isValid()); diff --git a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp index 9c865b3f73..6e95ddfdea 100644 --- a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp +++ b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp @@ -190,7 +190,9 @@ void tst_QQmlImport::completeQmldirPaths() QFETCH(int, minorVersion); QFETCH(QStringList, expectedPaths); - QCOMPARE(QQmlImports::completeQmldirPaths(uri, basePaths, majorVersion, minorVersion), expectedPaths); + QCOMPARE(QQmlImports::completeQmldirPaths( + uri, basePaths, QTypeRevision::fromVersion(majorVersion, minorVersion)), + expectedPaths); } class QmldirUrlInterceptor : public QQmlAbstractUrlInterceptor { diff --git a/tests/auto/qml/qqmlitemmodels/qtestmodel.h b/tests/auto/qml/qqmlitemmodels/qtestmodel.h index 6a022b3135..de42253708 100644 --- a/tests/auto/qml/qqmlitemmodels/qtestmodel.h +++ b/tests/auto/qml/qqmlitemmodels/qtestmodel.h @@ -31,6 +31,8 @@ #include <QtCore/qabstractitemmodel.h> +#include <limits.h> + class TestModel: public QAbstractItemModel { Q_OBJECT diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index bd23806e3a..9440fcaad4 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -324,6 +324,7 @@ private slots: void listContainingDeletedObject(); void overrideSingleton(); + void revisionedPropertyOfAttachedObjectProperty(); void arrayToContainer(); void qualifiedScopeInCustomParser(); @@ -5529,6 +5530,85 @@ void tst_qqmllanguage::overrideSingleton() check("uncreatable", "UncreatableSingleton"); } +class AttachedObject; +class InnerObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool revisionedProperty READ revisionedProperty WRITE setRevisionedProperty + NOTIFY revisionedPropertyChanged REVISION 2) + +public: + InnerObject(QObject *parent = nullptr) : QObject(parent) {} + + bool revisionedProperty() const { return m_revisionedProperty; } + void setRevisionedProperty(bool revisionedProperty) + { + if (revisionedProperty != m_revisionedProperty) { + m_revisionedProperty = revisionedProperty; + emit revisionedPropertyChanged(); + } + } + + static AttachedObject *qmlAttachedProperties(QObject *object); + +signals: + Q_REVISION(2) void revisionedPropertyChanged(); + +private: + bool m_revisionedProperty = false; +}; + +class AttachedObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(InnerObject *attached READ attached CONSTANT) + +public: + explicit AttachedObject(QObject *parent = nullptr) : + QObject(parent), + m_attached(new InnerObject(this)) + {} + + InnerObject *attached() const { return m_attached; } + +private: + InnerObject *m_attached; +}; + +class OuterObject : public QObject +{ + Q_OBJECT +public: + explicit OuterObject(QObject *parent = nullptr) : QObject(parent) {} +}; + +AttachedObject *InnerObject::qmlAttachedProperties(QObject *object) +{ + return new AttachedObject(object); +} + +QML_DECLARE_TYPE(InnerObject) +QML_DECLARE_TYPEINFO(InnerObject, QML_HAS_ATTACHED_PROPERTIES) + +void tst_qqmllanguage::revisionedPropertyOfAttachedObjectProperty() +{ + qmlRegisterAnonymousType<AttachedObject>("foo", 2); + qmlRegisterType<InnerObject>("foo", 2, 0, "InnerObject"); + qmlRegisterType<InnerObject, 2>("foo", 2, 2, "InnerObject"); + qmlRegisterType<OuterObject>("foo", 2, 2, "OuterObject"); + + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData("import foo 2.2\n" + "OuterObject {\n" + " InnerObject.attached.revisionedProperty: true\n" + "}", QUrl()); + + QVERIFY(component.isReady()); + QScopedPointer<QObject> obj(component.create()); + QVERIFY(!obj.isNull()); +} + void tst_qqmllanguage::inlineComponent() { QFETCH(QUrl, componentUrl); diff --git a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp index 296d1b14e0..c8e6e9c935 100644 --- a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp +++ b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp @@ -217,13 +217,14 @@ void tst_qqmlmetatype::qmlPropertyValueInterceptorCast() void tst_qqmlmetatype::qmlType() { - QQmlType type = QQmlMetaType::qmlType(QString("ParserStatusTestType"), QString("Test"), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("ParserStatusTestType"), QString("Test"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(type.module() == QLatin1String("Test")); QVERIFY(type.elementName() == QLatin1String("ParserStatusTestType")); QCOMPARE(type.qmlTypeName(), QLatin1String("Test/ParserStatusTestType")); - type = QQmlMetaType::qmlType("Test/ParserStatusTestType", 1, 0); + type = QQmlMetaType::qmlType("Test/ParserStatusTestType", QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(type.module() == QLatin1String("Test")); QVERIFY(type.elementName() == QLatin1String("ParserStatusTestType")); @@ -282,19 +283,22 @@ void tst_qqmlmetatype::defaultObject() void tst_qqmlmetatype::registrationType() { - QQmlType type = QQmlMetaType::qmlType(QString("TestType"), QString("Test"), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("TestType"), QString("Test"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(!type.isSingleton()); QVERIFY(!type.isComposite()); - type = QQmlMetaType::qmlType(QString("TestTypeSingleton"), QString("Test"), 1, 0); + type = QQmlMetaType::qmlType(QString("TestTypeSingleton"), QString("Test"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(type.isSingleton()); QVERIFY(!type.isComposite()); - type = QQmlMetaType::qmlType(QString("TestTypeComposite"), QString("Test"), 1, 0); + type = QQmlMetaType::qmlType(QString("TestTypeComposite"), QString("Test"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(!type.isSingleton()); @@ -310,7 +314,8 @@ void tst_qqmlmetatype::compositeType() QScopedPointer<QObject> obj(c.create()); QVERIFY(obj); - QQmlType type = QQmlMetaType::qmlType(QString("ImplicitType"), QString(""), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("ImplicitType"), QString(""), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(type.module().isEmpty()); QCOMPARE(type.elementName(), QLatin1String("ImplicitType")); @@ -380,10 +385,12 @@ void tst_qqmlmetatype::unregisterCustomType() int controllerId = 0; { QQmlEngine engine; - QQmlType type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(!type.isValid()); controllerId = qmlRegisterType<Controller1>("mytypes", 1, 0, "Controller"); - type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), 1, 0); + type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(!type.isSingleton()); @@ -403,10 +410,12 @@ void tst_qqmlmetatype::unregisterCustomType() QQmlMetaType::unregisterType(controllerId); { QQmlEngine engine; - QQmlType type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(!type.isValid()); controllerId = qmlRegisterType<Controller2>("mytypes", 1, 0, "Controller"); - type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), 1, 0); + type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(!type.isSingleton()); @@ -426,10 +435,12 @@ void tst_qqmlmetatype::unregisterCustomType() QQmlMetaType::unregisterType(controllerId); { QQmlEngine engine; - QQmlType type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(!type.isValid()); controllerId = qmlRegisterType<Controller1>("mytypes", 1, 0, "Controller"); - type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), 1, 0); + type = QQmlMetaType::qmlType(QString("Controller"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(!type.isSingleton()); @@ -480,7 +491,8 @@ void tst_qqmlmetatype::unregisterCustomSingletonType() { QQmlEngine engine; staticProviderId = qmlRegisterSingletonType<StaticProvider1>("mytypes", 1, 0, "StaticProvider", createStaticProvider1); - QQmlType type = QQmlMetaType::qmlType(QString("StaticProvider"), QString("mytypes"), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("StaticProvider"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(type.isSingleton()); @@ -496,7 +508,8 @@ void tst_qqmlmetatype::unregisterCustomSingletonType() { QQmlEngine engine; staticProviderId = qmlRegisterSingletonType<StaticProvider2>("mytypes", 1, 0, "StaticProvider", createStaticProvider2); - QQmlType type = QQmlMetaType::qmlType(QString("StaticProvider"), QString("mytypes"), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("StaticProvider"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(type.isSingleton()); @@ -512,7 +525,8 @@ void tst_qqmlmetatype::unregisterCustomSingletonType() { QQmlEngine engine; staticProviderId = qmlRegisterSingletonType<StaticProvider1>("mytypes", 1, 0, "StaticProvider", createStaticProvider1); - QQmlType type = QQmlMetaType::qmlType(QString("StaticProvider"), QString("mytypes"), 1, 0); + QQmlType type = QQmlMetaType::qmlType(QString("StaticProvider"), QString("mytypes"), + QTypeRevision::fromVersion(1, 0)); QVERIFY(type.isValid()); QVERIFY(!type.isInterface()); QVERIFY(type.isSingleton()); @@ -548,7 +562,8 @@ void tst_qqmlmetatype::unregisterAttachedProperties() QQmlComponent c(&e); c.setData("import QtQuick 2.2\n Item { }", dummy); - const QQmlType attachedType = QQmlMetaType::qmlType("QtQuick/KeyNavigation", 2, 2); + const QQmlType attachedType = QQmlMetaType::qmlType("QtQuick/KeyNavigation", + QTypeRevision::fromVersion(2, 2)); QCOMPARE(attachedType.attachedPropertiesType(QQmlEnginePrivate::get(&e)), attachedType.metaObject()); @@ -568,7 +583,8 @@ void tst_qqmlmetatype::unregisterAttachedProperties() "import QtQuick 2.2 \n" "Item { KeyNavigation.up: null }", dummy); - const QQmlType attachedType = QQmlMetaType::qmlType("QtQuick/KeyNavigation", 2, 2); + const QQmlType attachedType = QQmlMetaType::qmlType("QtQuick/KeyNavigation", + QTypeRevision::fromVersion(2, 2)); QCOMPARE(attachedType.attachedPropertiesType(QQmlEnginePrivate::get(&e)), attachedType.metaObject()); diff --git a/tests/auto/qml/qqmlmoduleplugin/data/importsMixedQmlCppPlugin.2.qml b/tests/auto/qml/qqmlmoduleplugin/data/importsMixedQmlCppPlugin.2.qml index b13b2004c2..ba6bb3d7ac 100644 --- a/tests/auto/qml/qqmlmoduleplugin/data/importsMixedQmlCppPlugin.2.qml +++ b/tests/auto/qml/qqmlmoduleplugin/data/importsMixedQmlCppPlugin.2.qml @@ -1,5 +1,6 @@ import org.qtproject.AutoTestQmlMixedPluginType 1.5 import QtQuick 2.0 +import QtQml 2.0 Item { property bool test: false diff --git a/tests/auto/qml/qqmlmoduleplugin/data/importsMixedQmlCppPlugin.qml b/tests/auto/qml/qqmlmoduleplugin/data/importsMixedQmlCppPlugin.qml index 563c0b28e3..f1268075c1 100644 --- a/tests/auto/qml/qqmlmoduleplugin/data/importsMixedQmlCppPlugin.qml +++ b/tests/auto/qml/qqmlmoduleplugin/data/importsMixedQmlCppPlugin.qml @@ -1,5 +1,6 @@ import org.qtproject.AutoTestQmlMixedPluginType 1.0 import QtQuick 2.0 +import QtQml 2.0 Item { property bool test: false diff --git a/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp b/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp index 75885bc84a..f15d53d022 100644 --- a/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp +++ b/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp @@ -34,6 +34,10 @@ #include <QtCore/qjsondocument.h> #include <QtCore/qjsonarray.h> #include <QDebug> +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +#include <QCborMap> +#include <QCborValue> +#endif #if defined(Q_OS_MAC) // For _PC_CASE_SENSITIVE @@ -131,8 +135,7 @@ QByteArray SecondStaticPlugin::metaData; template <typename PluginType> void registerStaticPlugin(const char *uri) { - QStaticPlugin plugin; - plugin.instance = []() { + auto instanceFunctor = []() { static PluginType plugin; return static_cast<QObject*>(&plugin); }; @@ -143,12 +146,28 @@ void registerStaticPlugin(const char *uri) uris.append(uri); md.insert(QStringLiteral("uri"), uris); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + PluginType::metaData.append(QLatin1String("QTMETADATA !")); + PluginType::metaData.append(char(0)); // current version + PluginType::metaData.append(char(QT_VERSION_MAJOR)); + PluginType::metaData.append(char(QT_VERSION_MINOR)); + PluginType::metaData.append(char(qPluginArchRequirements())); + PluginType::metaData.append(QCborValue(QCborMap::fromJsonObject(md)).toCbor()); + + auto rawMetaDataFunctor = []() -> QPluginMetaData { + return {reinterpret_cast<const uchar *>(PluginType::metaData.constData()), size_t(PluginType::metaData.length())}; + }; + QStaticPlugin plugin(instanceFunctor, rawMetaDataFunctor); +#else PluginType::metaData.append(QLatin1String("QTMETADATA ")); PluginType::metaData.append(QJsonDocument(md).toBinaryData()); + QStaticPlugin plugin; + plugin.instance = instanceFunctor; plugin.rawMetaData = []() { return PluginType::metaData.constData(); }; +#endif qRegisterStaticPluginFunction(plugin); }; diff --git a/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp b/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp index c7d09f9d6e..8483bd1f95 100644 --- a/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp +++ b/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp @@ -38,6 +38,7 @@ #include <qtest.h> #include <QDir> #include <QDebug> +#include <QRegularExpression> #include <cstdlib> class tst_qqmlparser : public QQmlDataTest @@ -68,6 +69,8 @@ private slots: void typeAssertion(); void annotations_data(); void annotations(); + void invalidImportVersion_data(); + void invalidImportVersion(); private: QStringList excludedDirs; @@ -585,6 +588,47 @@ void tst_qqmlparser::annotations() } } +void tst_qqmlparser::invalidImportVersion_data() +{ + QTest::addColumn<QString>("expression"); + + const QStringList segments = { + "0", "255", "500", "3030303030303030303030303" + }; + + for (const QString &major : segments) { + if (major != "0") { + QTest::addRow("%s", qPrintable(major)) + << QString::fromLatin1("import Foo %1").arg(major); + } + + for (const QString &minor : segments) { + if (major == "0" && minor == "0") + continue; + + QTest::addRow("%s.%s", qPrintable(major), qPrintable(minor)) + << QString::fromLatin1("import Foo %1.%2").arg(major).arg(minor); + } + } + + +} + +void tst_qqmlparser::invalidImportVersion() +{ + QFETCH(QString, expression); + + QQmlJS::Engine engine; + QQmlJS::Lexer lexer(&engine); + lexer.setCode(expression, 1); + QQmlJS::Parser parser(&engine); + QVERIFY(!parser.parse()); + + QRegularExpression regexp( + "^Invalid (major )?version. Version numbers must be >= 0 and < 255\\.$"); + QVERIFY(regexp.match(parser.errorMessage()).hasMatch()); +} + QTEST_MAIN(tst_qqmlparser) #include "tst_qqmlparser.moc" diff --git a/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp b/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp index c9e92cd3c9..2e040eec18 100644 --- a/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp +++ b/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp @@ -114,7 +114,8 @@ void tst_qqmlpropertycache::properties() DerivedObject object; const QMetaObject *metaObject = object.metaObject(); - QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(metaObject)); + QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(metaObject), + QQmlRefPointer<QQmlPropertyCache>::Adopt); QQmlPropertyData *data; QVERIFY((data = cacheProperty(cache, "propertyA"))); @@ -136,8 +137,11 @@ void tst_qqmlpropertycache::propertiesDerived() DerivedObject object; const QMetaObject *metaObject = object.metaObject(); - QQmlRefPointer<QQmlPropertyCache> parentCache(new QQmlPropertyCache(&BaseObject::staticMetaObject)); - QQmlRefPointer<QQmlPropertyCache> cache(parentCache->copyAndAppend(object.metaObject())); + QQmlRefPointer<QQmlPropertyCache> parentCache( + new QQmlPropertyCache(&BaseObject::staticMetaObject), + QQmlRefPointer<QQmlPropertyCache>::Adopt); + QQmlRefPointer<QQmlPropertyCache> cache(parentCache->copyAndAppend(object.metaObject()), + QQmlRefPointer<QQmlPropertyCache>::Adopt); QQmlPropertyData *data; QVERIFY((data = cacheProperty(cache, "propertyA"))); @@ -161,8 +165,11 @@ void tst_qqmlpropertycache::revisionedProperties() DerivedObject object; const QMetaObject *metaObject = object.metaObject(); - QQmlRefPointer<QQmlPropertyCache> cacheWithoutVersion(new QQmlPropertyCache(metaObject)); - QQmlRefPointer<QQmlPropertyCache> cacheWithVersion(new QQmlPropertyCache(metaObject, 1)); + QQmlRefPointer<QQmlPropertyCache> cacheWithoutVersion(new QQmlPropertyCache(metaObject), + QQmlRefPointer<QQmlPropertyCache>::Adopt); + QQmlRefPointer<QQmlPropertyCache> cacheWithVersion( + new QQmlPropertyCache(metaObject, QTypeRevision::fromMinorVersion(1)), + QQmlRefPointer<QQmlPropertyCache>::Adopt); QQmlPropertyData *data; QVERIFY((data = cacheProperty(cacheWithoutVersion, "propertyE"))); @@ -176,7 +183,8 @@ void tst_qqmlpropertycache::methods() DerivedObject object; const QMetaObject *metaObject = object.metaObject(); - QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(metaObject)); + QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(metaObject), + QQmlRefPointer<QQmlPropertyCache>::Adopt); QQmlPropertyData *data; QVERIFY((data = cacheProperty(cache, "slotA"))); @@ -210,8 +218,11 @@ void tst_qqmlpropertycache::methodsDerived() DerivedObject object; const QMetaObject *metaObject = object.metaObject(); - QQmlRefPointer<QQmlPropertyCache> parentCache(new QQmlPropertyCache(&BaseObject::staticMetaObject)); - QQmlRefPointer<QQmlPropertyCache> cache(parentCache->copyAndAppend(object.metaObject())); + QQmlRefPointer<QQmlPropertyCache> parentCache( + new QQmlPropertyCache(&BaseObject::staticMetaObject), + QQmlRefPointer<QQmlPropertyCache>::Adopt); + QQmlRefPointer<QQmlPropertyCache> cache(parentCache->copyAndAppend(object.metaObject()), + QQmlRefPointer<QQmlPropertyCache>::Adopt); QQmlPropertyData *data; QVERIFY((data = cacheProperty(cache, "slotA"))); @@ -245,7 +256,8 @@ void tst_qqmlpropertycache::signalHandlers() DerivedObject object; const QMetaObject *metaObject = object.metaObject(); - QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(metaObject)); + QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(metaObject), + QQmlRefPointer<QQmlPropertyCache>::Adopt); QQmlPropertyData *data; QVERIFY((data = cacheProperty(cache, "onSignalA"))); @@ -273,8 +285,11 @@ void tst_qqmlpropertycache::signalHandlersDerived() DerivedObject object; const QMetaObject *metaObject = object.metaObject(); - QQmlRefPointer<QQmlPropertyCache> parentCache(new QQmlPropertyCache(&BaseObject::staticMetaObject)); - QQmlRefPointer<QQmlPropertyCache> cache(parentCache->copyAndAppend(object.metaObject())); + QQmlRefPointer<QQmlPropertyCache> parentCache( + new QQmlPropertyCache(&BaseObject::staticMetaObject), + QQmlRefPointer<QQmlPropertyCache>::Adopt); + QQmlRefPointer<QQmlPropertyCache> cache(parentCache->copyAndAppend(object.metaObject()), + QQmlRefPointer<QQmlPropertyCache>::Adopt); QQmlPropertyData *data; QVERIFY((data = cacheProperty(cache, "onSignalA"))); @@ -478,7 +493,9 @@ class TestClassWithClassInfo : public QObject int(sizeof(arr) / sizeof(arr[0])) #define TEST_CLASS(Class) \ - QTest::newRow(#Class) << &Class::staticMetaObject << ARRAY_SIZE(qt_meta_data_##Class) << ARRAY_SIZE(qt_meta_stringdata_##Class.data) + QTest::newRow(#Class) \ + << &Class::staticMetaObject << ARRAY_SIZE(qt_meta_data_##Class) \ + << int(sizeof(qt_meta_stringdata_##Class.offsetsAndSize) / (sizeof(uint) * 2)) Q_DECLARE_METATYPE(const QMetaObject*); diff --git a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp index 1a54397f1a..4a2e6841e7 100644 --- a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp +++ b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp @@ -168,15 +168,13 @@ void tst_qqmlqt::initTestCase() void tst_qqmlqt::enums() { QQmlComponent component(&engine, testFileUrl("enums.qml")); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(object->property("test1").toInt(), (int)Qt::Key_Escape); QCOMPARE(object->property("test2").toInt(), (int)Qt::DescendingOrder); QCOMPARE(object->property("test3").toInt(), (int)Qt::ElideMiddle); QCOMPARE(object->property("test4").toInt(), (int)Qt::AlignRight); - - delete object; } void tst_qqmlqt::rgba() @@ -188,7 +186,7 @@ void tst_qqmlqt::rgba() QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); @@ -198,8 +196,6 @@ void tst_qqmlqt::rgba() QCOMPARE(qvariant_cast<QColor>(object->property("test4")), QColor()); QCOMPARE(qvariant_cast<QColor>(object->property("test5")), QColor::fromRgbF(1, 1, 1, 1)); QCOMPARE(qvariant_cast<QColor>(object->property("test6")), QColor::fromRgbF(0, 0, 0, 0)); - - delete object; } void tst_qqmlqt::hsla() @@ -211,7 +207,7 @@ void tst_qqmlqt::hsla() QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(qvariant_cast<QColor>(object->property("test1")), QColor::fromHslF(1, 0, 0, 0.8)); @@ -220,8 +216,6 @@ void tst_qqmlqt::hsla() QCOMPARE(qvariant_cast<QColor>(object->property("test4")), QColor()); QCOMPARE(qvariant_cast<QColor>(object->property("test5")), QColor::fromHslF(1, 1, 1, 1)); QCOMPARE(qvariant_cast<QColor>(object->property("test6")), QColor::fromHslF(0, 0, 0, 0)); - - delete object; } void tst_qqmlqt::hsva() @@ -233,7 +227,7 @@ void tst_qqmlqt::hsva() QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(qvariant_cast<QColor>(object->property("test1")), QColor::fromHsvF(1, 0, 0, 0.8)); @@ -242,8 +236,6 @@ void tst_qqmlqt::hsva() QCOMPARE(qvariant_cast<QColor>(object->property("test4")), QColor()); QCOMPARE(qvariant_cast<QColor>(object->property("test5")), QColor::fromHsvF(1, 1, 1, 1)); QCOMPARE(qvariant_cast<QColor>(object->property("test6")), QColor::fromHsvF(0, 0, 0, 0)); - - delete object; } void tst_qqmlqt::colorEqual() @@ -261,7 +253,7 @@ void tst_qqmlqt::colorEqual() QTest::ignoreMessage(QtWarningMsg, qPrintable(component.url().toString() + ":34: Error: Qt.colorEqual(): Invalid color name")); QTest::ignoreMessage(QtWarningMsg, qPrintable(component.url().toString() + ":35: Error: Qt.colorEqual(): Invalid color name")); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(object->property("test1a").toBool(), false); @@ -325,8 +317,6 @@ void tst_qqmlqt::colorEqual() QCOMPARE(object->property("test6c").toBool(), true); QCOMPARE(object->property("test6d").toBool(), false); QCOMPARE(object->property("test6e").toBool(), false); - - delete object; } void tst_qqmlqt::rect() @@ -338,7 +328,7 @@ void tst_qqmlqt::rect() QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(qvariant_cast<QRectF>(object->property("test1")), QRectF(10, 13, 100, 109)); @@ -346,8 +336,6 @@ void tst_qqmlqt::rect() QCOMPARE(qvariant_cast<QRectF>(object->property("test3")), QRectF()); QCOMPARE(qvariant_cast<QRectF>(object->property("test4")), QRectF()); QCOMPARE(qvariant_cast<QRectF>(object->property("test5")), QRectF(10, 13, 100, -109)); - - delete object; } void tst_qqmlqt::point() @@ -359,15 +347,13 @@ void tst_qqmlqt::point() QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(qvariant_cast<QPointF>(object->property("test1")), QPointF(19, 34)); QCOMPARE(qvariant_cast<QPointF>(object->property("test2")), QPointF(-3, 109.2)); QCOMPARE(qvariant_cast<QPointF>(object->property("test3")), QPointF()); QCOMPARE(qvariant_cast<QPointF>(object->property("test4")), QPointF()); - - delete object; } void tst_qqmlqt::size() @@ -379,7 +365,7 @@ void tst_qqmlqt::size() QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(qvariant_cast<QSizeF>(object->property("test1")), QSizeF(19, 34)); @@ -387,8 +373,6 @@ void tst_qqmlqt::size() QCOMPARE(qvariant_cast<QSizeF>(object->property("test3")), QSizeF(-3, 10)); QCOMPARE(qvariant_cast<QSizeF>(object->property("test4")), QSizeF()); QCOMPARE(qvariant_cast<QSizeF>(object->property("test5")), QSizeF()); - - delete object; } void tst_qqmlqt::vector2d() @@ -400,15 +384,13 @@ void tst_qqmlqt::vector2d() QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(qvariant_cast<QVector2D>(object->property("test1")), QVector2D(1, 0.9f)); QCOMPARE(qvariant_cast<QVector2D>(object->property("test2")), QVector2D(102, -982.1f)); QCOMPARE(qvariant_cast<QVector2D>(object->property("test3")), QVector2D()); QCOMPARE(qvariant_cast<QVector2D>(object->property("test4")), QVector2D()); - - delete object; } void tst_qqmlqt::vector3d() @@ -420,15 +402,13 @@ void tst_qqmlqt::vector3d() QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(qvariant_cast<QVector3D>(object->property("test1")), QVector3D(1, 0, 0.9f)); QCOMPARE(qvariant_cast<QVector3D>(object->property("test2")), QVector3D(102, -10, -982.1f)); QCOMPARE(qvariant_cast<QVector3D>(object->property("test3")), QVector3D()); QCOMPARE(qvariant_cast<QVector3D>(object->property("test4")), QVector3D()); - - delete object; } void tst_qqmlqt::vector4d() @@ -440,15 +420,13 @@ void tst_qqmlqt::vector4d() QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(qvariant_cast<QVector4D>(object->property("test1")), QVector4D(1, 0, 0.9f, 0.6f)); QCOMPARE(qvariant_cast<QVector4D>(object->property("test2")), QVector4D(102, -10, -982.1f, 10)); QCOMPARE(qvariant_cast<QVector4D>(object->property("test3")), QVector4D()); QCOMPARE(qvariant_cast<QVector4D>(object->property("test4")), QVector4D()); - - delete object; } void tst_qqmlqt::quaternion() @@ -460,15 +438,13 @@ void tst_qqmlqt::quaternion() QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(qvariant_cast<QQuaternion>(object->property("test1")), QQuaternion(2, 17, 0.9f, 0.6f)); QCOMPARE(qvariant_cast<QQuaternion>(object->property("test2")), QQuaternion(102, -10, -982.1f, 10)); QCOMPARE(qvariant_cast<QQuaternion>(object->property("test3")), QQuaternion()); QCOMPARE(qvariant_cast<QQuaternion>(object->property("test4")), QQuaternion()); - - delete object; } void tst_qqmlqt::matrix4x4() @@ -482,7 +458,7 @@ void tst_qqmlqt::matrix4x4() QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning3)); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(qvariant_cast<QMatrix4x4>(object->property("test1")), QMatrix4x4(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)); @@ -490,8 +466,6 @@ void tst_qqmlqt::matrix4x4() QCOMPARE(qvariant_cast<QMatrix4x4>(object->property("test3")), QMatrix4x4()); QCOMPARE(qvariant_cast<QMatrix4x4>(object->property("test4")), QMatrix4x4()); QCOMPARE(qvariant_cast<QMatrix4x4>(object->property("test5")), QMatrix4x4()); - - delete object; } void tst_qqmlqt::font() @@ -503,7 +477,7 @@ void tst_qqmlqt::font() QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QFont f; @@ -516,8 +490,6 @@ void tst_qqmlqt::font() QCOMPARE(qvariant_cast<QFont>(object->property("test2")), f); QCOMPARE(qvariant_cast<QFont>(object->property("test3")), QFont()); QCOMPARE(qvariant_cast<QFont>(object->property("test4")), QFont()); - - delete object; } void tst_qqmlqt::lighter() @@ -529,7 +501,7 @@ void tst_qqmlqt::lighter() QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(qvariant_cast<QColor>(object->property("test1")), QColor::fromRgbF(1, 0.8, 0.3).lighter()); @@ -538,8 +510,6 @@ void tst_qqmlqt::lighter() QCOMPARE(qvariant_cast<QColor>(object->property("test4")), QColor("red").lighter()); QCOMPARE(qvariant_cast<QColor>(object->property("test5")), QColor()); QCOMPARE(qvariant_cast<QColor>(object->property("test6")), QColor()); - - delete object; } void tst_qqmlqt::darker() @@ -551,7 +521,7 @@ void tst_qqmlqt::darker() QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(qvariant_cast<QColor>(object->property("test1")), QColor::fromRgbF(1, 0.8, 0.3).darker()); @@ -560,8 +530,6 @@ void tst_qqmlqt::darker() QCOMPARE(qvariant_cast<QColor>(object->property("test4")), QColor("red").darker()); QCOMPARE(qvariant_cast<QColor>(object->property("test5")), QColor()); QCOMPARE(qvariant_cast<QColor>(object->property("test6")), QColor()); - - delete object; } void tst_qqmlqt::tint() @@ -574,7 +542,7 @@ void tst_qqmlqt::tint() QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(qvariant_cast<QColor>(object->property("test1")), QColor::fromRgbF(0, 0, 1)); @@ -583,8 +551,6 @@ void tst_qqmlqt::tint() QCOMPARE(test3.rgba(), 0xFF7F0080); QCOMPARE(qvariant_cast<QColor>(object->property("test4")), QColor()); QCOMPARE(qvariant_cast<QColor>(object->property("test5")), QColor()); - - delete object; } class MyUrlHandler : public QObject @@ -607,7 +573,7 @@ void tst_qqmlqt::openUrlExternally() QDesktopServices::setUrlHandler("file", &handler, "noteCall"); QQmlComponent component(&engine, testFileUrl("openUrlExternally.qml")); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(handler.called,1); QCOMPARE(handler.last, QUrl("test:url")); @@ -629,7 +595,7 @@ void tst_qqmlqt::openUrlExternally_pragmaLibrary() QDesktopServices::setUrlHandler("file", &handler, "noteCall"); QQmlComponent component(&engine, testFileUrl("openUrlExternally_lib.qml")); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(handler.called,1); QCOMPARE(handler.last, QUrl("test:url")); @@ -650,42 +616,37 @@ void tst_qqmlqt::md5() QString warning1 = component.url().toString() + ":4: Error: Qt.md5(): Invalid arguments"; QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(object->property("test2").toString(), QLatin1String(QCryptographicHash::hash("Hello World", QCryptographicHash::Md5).toHex())); - - delete object; } void tst_qqmlqt::createComponent() { { - QQmlComponent component(&engine, testFileUrl("createComponent.qml")); - - QString warning1 = component.url().toString() + ":9: Error: Qt.createComponent(): Invalid arguments"; - QString warning2 = component.url().toString() + ":10: Error: Qt.createComponent(): Invalid arguments"; - QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); - QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); + QQmlComponent component(&engine, testFileUrl("createComponent.qml")); - QObject *object = component.create(); - QVERIFY(object != nullptr); + QString warning1 = component.url().toString() + ":9: Error: Qt.createComponent(): Invalid arguments"; + QString warning2 = component.url().toString() + ":10: Error: Qt.createComponent(): Invalid arguments"; + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); - QCOMPARE(object->property("absoluteUrl").toString(), QString("http://www.example.com/test.qml")); - QCOMPARE(object->property("relativeUrl").toString(), testFileUrl("createComponentData.qml").toString()); + QScopedPointer<QObject> object(component.create()); + QVERIFY(object != nullptr); - QTRY_VERIFY(object->property("asyncResult").toBool()); + QCOMPARE(object->property("absoluteUrl").toString(), QString("http://www.example.com/test.qml")); + QCOMPARE(object->property("relativeUrl").toString(), testFileUrl("createComponentData.qml").toString()); - delete object; + QTRY_VERIFY(object->property("asyncResult").toBool()); } // simultaneous sync and async compilation { - QQmlComponent component(&engine, testFileUrl("createComponent.2.qml")); - QObject *object = component.create(); - QVERIFY(object != nullptr); - QTRY_VERIFY(object->property("success").toBool()); - delete object; + QQmlComponent component(&engine, testFileUrl("createComponent.2.qml")); + QScopedPointer<QObject> object(component.create()); + QVERIFY(object != nullptr); + QTRY_VERIFY(object->property("success").toBool()); } } @@ -693,11 +654,10 @@ void tst_qqmlqt::createComponent_pragmaLibrary() { // Currently, just loading createComponent_lib.qml causes crash on some platforms QQmlComponent component(&engine, testFileUrl("createComponent_lib.qml")); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(object->property("status").toInt(), int(QQmlComponent::Ready)); QCOMPARE(object->property("readValue").toInt(), int(1913)); - delete object; } void tst_qqmlqt::createQmlObject() @@ -717,17 +677,15 @@ void tst_qqmlqt::createQmlObject() QTest::ignoreMessage(QtWarningMsg, qPrintable(warning5)); QTest::ignoreMessage(QtDebugMsg, qPrintable(warning6)); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(object->property("emptyArg").toBool(), true); QCOMPARE(object->property("success").toBool(), true); - QQuickItem *item = qobject_cast<QQuickItem *>(object); + QQuickItem *item = qobject_cast<QQuickItem *>(object.data()); QVERIFY(item != nullptr); QCOMPARE(item->childItems().count(), 1); - - delete object; } @@ -750,7 +708,7 @@ void tst_qqmlqt::dateTimeConversion() QQmlEngine eng; QQmlComponent component(&eng, testFileUrl("dateTimeConversion.qml")); - QObject *obj = component.create(); + QScopedPointer<QObject> obj(component.create()); QCOMPARE(obj->property("qdate").toDate(), date); QCOMPARE(obj->property("qtime").toTime(), time); @@ -955,7 +913,7 @@ void tst_qqmlqt::dateTimeFormattingWithLocale() void tst_qqmlqt::isQtObject() { QQmlComponent component(&engine, testFileUrl("isQtObject.qml")); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(object->property("test1").toBool(), true); @@ -963,8 +921,6 @@ void tst_qqmlqt::isQtObject() QCOMPARE(object->property("test3").toBool(), false); QCOMPARE(object->property("test4").toBool(), false); QCOMPARE(object->property("test5").toBool(), false); - - delete object; } void tst_qqmlqt::btoa() @@ -974,12 +930,10 @@ void tst_qqmlqt::btoa() QString warning1 = component.url().toString() + ":4: Error: Qt.btoa(): Invalid arguments"; QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(object->property("test2").toString(), QString("SGVsbG8gd29ybGQh")); - - delete object; } void tst_qqmlqt::atob() @@ -989,12 +943,10 @@ void tst_qqmlqt::atob() QString warning1 = component.url().toString() + ":4: Error: Qt.atob(): Invalid arguments"; QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(object->property("test2").toString(), QString("Hello world!")); - - delete object; } void tst_qqmlqt::fontFamilies() @@ -1004,13 +956,11 @@ void tst_qqmlqt::fontFamilies() QString warning1 = component.url().toString() + ":4: Error: Qt.fontFamilies(): Invalid arguments"; QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QFontDatabase database; QCOMPARE(object->property("test2"), QVariant::fromValue(database.families())); - - delete object; } void tst_qqmlqt::quit() @@ -1018,11 +968,9 @@ void tst_qqmlqt::quit() QQmlComponent component(&engine, testFileUrl("quit.qml")); QSignalSpy spy(&engine, SIGNAL(quit())); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(spy.count(), 1); - - delete object; } void tst_qqmlqt::exit() @@ -1030,26 +978,22 @@ void tst_qqmlqt::exit() QQmlComponent component(&engine, testFileUrl("exit.qml")); QSignalSpy spy(&engine, &QQmlEngine::exit); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(spy.count(), 1); QList<QVariant> arguments = spy.takeFirst(); QVERIFY(arguments.at(0).toInt() == object->property("returnCode").toInt()); - - delete object; } void tst_qqmlqt::resolvedUrl() { QQmlComponent component(&engine, testFileUrl("resolvedUrl.qml")); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QCOMPARE(object->property("result").toString(), component.url().toString()); QCOMPARE(object->property("isString").toBool(), true); - - delete object; } void tst_qqmlqt::later_data() @@ -1133,11 +1077,11 @@ void tst_qqmlqt::later() QTest::ignoreMessage(QtWarningMsg, qPrintable(w)); QQmlComponent component(&engine, testFileUrl("later.qml")); - QObject *root = component.create(); + QScopedPointer<QObject> root(component.create()); QVERIFY(root != nullptr); if (!function.isEmpty()) - QMetaObject::invokeMethod(root, qPrintable(function)); + QMetaObject::invokeMethod(root.data(), qPrintable(function)); for (int i = 0; i < propNames.size(); ++i) { if (propNames.at(i) == QLatin1String("processEvents")) { @@ -1149,21 +1093,13 @@ void tst_qqmlqt::later() QCOMPARE(root->property(qPrintable(propNames.at(i))), values.at(i)); } } - - delete root; } void tst_qqmlqt::qtObjectContents() { - struct StaticQtMetaObject : public QObject - { - static const QMetaObject *get() - { return &staticQtMetaObject; } - }; - QQmlComponent component(&engine, testFileUrl("qtObjectContents.qml")); - QObject *object = component.create(); + QScopedPointer<QObject> object(component.create()); QVERIFY(object != nullptr); QVERIFY(object->property("values").canConvert<QJSValue>()); @@ -1171,7 +1107,7 @@ void tst_qqmlqt::qtObjectContents() QSet<const char *> keys; int uniqueKeys = 0; - const QMetaObject *qtMetaObject = StaticQtMetaObject::get(); + const QMetaObject *qtMetaObject = &Qt::staticMetaObject; for (int ii = 0; ii < qtMetaObject->enumeratorCount(); ++ii) { QMetaEnum enumerator = qtMetaObject->enumerator(ii); for (int jj = 0; jj < enumerator.keyCount(); ++jj) { @@ -1194,8 +1130,6 @@ void tst_qqmlqt::qtObjectContents() QCOMPARE(values.value("Synchronous").toInt(), 1); ++uniqueKeys; QCOMPARE(values.count(), uniqueKeys); - - delete object; } class TimeProvider: public QObject @@ -1289,7 +1223,8 @@ void tst_qqmlqt::timeRoundtrip() QQmlEngine eng; //qmlRegisterSingletonInstance("Test", 1, 0, "TimeProvider", &tp); QQmlComponent component(&eng, testFileUrl("timeRoundtrip.qml")); - QObject *obj = component.createWithInitialProperties({{"tp", QVariant::fromValue(&tp)}}); + QScopedPointer<QObject> obj(component.createWithInitialProperties( + {{"tp", QVariant::fromValue(&tp)}})); QVERIFY(obj != nullptr); // QML reads m_getTime and saves the result as m_putTime; this should come out the same, without diff --git a/tests/auto/qml/qqmltimer/tst_qqmltimer.cpp b/tests/auto/qml/qqmltimer/tst_qqmltimer.cpp index 4e42d02514..0168663cf2 100644 --- a/tests/auto/qml/qqmltimer/tst_qqmltimer.cpp +++ b/tests/auto/qml/qqmltimer/tst_qqmltimer.cpp @@ -311,7 +311,7 @@ void tst_qqmltimer::restart() { QQmlEngine engine; QQmlComponent component(&engine); - component.setData(QByteArray("import QtQml 2.0\nTimer { interval: 500; repeat: true; running: true }"), QUrl::fromLocalFile("")); + component.setData(QByteArray("import QtQml 2.0\nTimer { interval: 1000; repeat: true; running: true }"), QUrl::fromLocalFile("")); QQmlTimer *timer = qobject_cast<QQmlTimer*>(component.create()); QVERIFY(timer != nullptr); @@ -319,14 +319,16 @@ void tst_qqmltimer::restart() connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); QCOMPARE(helper.count, 0); - consistentWait(600); + consistentWait(1200); QCOMPARE(helper.count, 1); - consistentWait(300); + consistentWait(500); + QCOMPARE(helper.count, 1); timer->restart(); + QCOMPARE(helper.count, 1); - consistentWait(700); + consistentWait(1400); QCOMPARE(helper.count, 2); QVERIFY(timer->isRunning()); diff --git a/tests/auto/qml/qqmltypeloader/dummy_imports.qml b/tests/auto/qml/qqmltypeloader/dummy_imports.qml new file mode 100644 index 0000000000..a4684b2007 --- /dev/null +++ b/tests/auto/qml/qqmltypeloader/dummy_imports.qml @@ -0,0 +1,9 @@ +// This file exists for the sole purpose for qmlimportscanner to find +// which modules it needs to extract for deployment. +// Otherwise, it fails to find the imports that are expressed in the +// C++ code belonging to the test. + +import QtQml 2.0 +import QtQuick 2.6 + +QtObject { } // This is needed in order to keep importscanner happy diff --git a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp index 266a4e97d6..9ec3e9557b 100644 --- a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp +++ b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp @@ -63,10 +63,15 @@ private slots: void implicitImport(); void compositeSingletonCycle(); void declarativeCppType(); +private: + void checkSingleton(const QString & dataDirectory); }; void tst_QQMLTypeLoader::testLoadComplete() { +#ifdef Q_OS_ANDROID + QSKIP("Loading dynamic plugins does not work on Android"); +#endif QQuickView *window = new QQuickView(); window->engine()->addImportPath(QT_TESTCASE_BUILDDIR); qDebug() << window->engine()->importPathList(); @@ -170,7 +175,7 @@ void tst_QQMLTypeLoader::trimCache3() QCOMPARE(loader.isTypeLoaded(testFileUrl("ComponentWithIncubator.qml")), false); } -static void checkSingleton(const QString &dataDirectory) +void tst_QQMLTypeLoader::checkSingleton(const QString &dataDirectory) { QQmlEngine engine; engine.addImportPath(dataDirectory); @@ -179,8 +184,8 @@ static void checkSingleton(const QString &dataDirectory) "import QtQuick 2.6\n" "import \"..\"\n" "Item { property int t: ValueSource.something }", - QUrl::fromLocalFile(dataDirectory + "/abc/Xyz.qml")); - QCOMPARE(component.status(), QQmlComponent::Ready); + testFileUrl("abc/Xyz.qml")); + QVERIFY2(component.status() == QQmlComponent::Ready, qPrintable(component.errorString())); QScopedPointer<QObject> o(component.create()); QVERIFY(o.data()); QCOMPARE(o->property("t").toInt(), 10); @@ -402,6 +407,9 @@ public: void tst_QQMLTypeLoader::intercept() { +#ifdef Q_OS_ANDROID + QSKIP("Loading dynamic plugins does not work on Android"); +#endif qmlClearTypeRegistrations(); QQmlEngine engine; @@ -491,6 +499,9 @@ static void checkCleanCacheLoad(const QString &testCase) void tst_QQMLTypeLoader::multiSingletonModule() { +#ifdef Q_OS_ANDROID + QSKIP("Android seems to have problems with QProcess"); +#endif qmlClearTypeRegistrations(); QQmlEngine engine; engine.addImportPath(testFile("imports")); @@ -511,6 +522,9 @@ void tst_QQMLTypeLoader::multiSingletonModule() void tst_QQMLTypeLoader::implicitComponentModule() { +#ifdef Q_OS_ANDROID + QSKIP("Android seems to have problems with QProcess"); +#endif QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("implicitcomponent.qml")); QCOMPARE(component.status(), QQmlComponent::Ready); diff --git a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.pro b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.pro index 19834ff537..c868474b5b 100644 --- a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.pro +++ b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.pro @@ -15,3 +15,5 @@ QML_IMPORT_VERSION = 3.2 QML_IMPORT_NAME = "declarative.import.for.typeloader.test" include (../../shared/util.pri) + +TESTDATA = data/* diff --git a/tests/auto/qml/qqmlvaluetypes/data/font_write.qml b/tests/auto/qml/qqmlvaluetypes/data/font_write.qml index ff4d0a1004..4d3ae32025 100644 --- a/tests/auto/qml/qqmlvaluetypes/data/font_write.qml +++ b/tests/auto/qml/qqmlvaluetypes/data/font_write.qml @@ -3,7 +3,7 @@ import Test 1.0 MyTypeObject { font.family: if(1) "Helvetica" font.bold: if(1) false - font.weight: "Normal" + font.weight: 50 font.italic: if(1) false font.underline: if(1) false font.overline: if(1) false diff --git a/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp b/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp index ae794e76a9..2c08c33fc8 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp +++ b/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp @@ -1133,15 +1133,16 @@ void tst_qqmlxmlhttprequest::sendFileRequest() #if QT_CONFIG(process) void tst_qqmlxmlhttprequest::sendFileRequestNotSet() { if (qEnvironmentVariableIsSet("TEST_CUSTOM_PERMISSIONS")) { - // Test with no settings - // Should just result in warnings in Qt 5 - doFileRequest([](QObject* object, QTemporaryFile &writeFile) { - QTRY_COMPARE(object->property("readResult").toString(), testString); + // Test with no settings, neither reading nor writing should work + doFileRequest([](QObject *object, QTemporaryFile &writeFile) { + QTest::qWait(1000); - QTRY_VERIFY(object->property("writeDone").toBool()); + // Verify that the read has not yielded any value + QVERIFY(object->property("readResult").isNull()); + // Check that the file stays empty QVERIFY(writeFile.open()); - QCOMPARE(QString::fromUtf8(writeFile.readAll()), testString); + QCOMPARE(QString::fromUtf8(writeFile.readAll()), ""); writeFile.close(); }); return; @@ -1161,22 +1162,25 @@ void tst_qqmlxmlhttprequest::sendFileRequestNotSet() { // Check exit code QCOMPARE(child.exitCode(), 0); - // Check if all warnings were printed + // Check if all errors were printed QString output = QString::fromUtf8(child.readAllStandardOutput()); + // Due to differences in line endings on Windows, check for the error lines individually + const QStringList readingError = { + QLatin1String("XMLHttpRequest: Using GET on a local file is disabled by default."), + QLatin1String("Set QML_XHR_ALLOW_FILE_READ to 1 to enable this feature.") + }; - const QString readingWarning = QLatin1String( - "XMLHttpRequest: Using GET on a local file is dangerous " - "and will be disabled by default in a future Qt version." - "Set QML_XHR_ALLOW_FILE_READ to 1 if you wish to continue using this feature."); + const QStringList writingError = { + QLatin1String("XMLHttpRequest: Using PUT on a local file is disabled by default."), + QLatin1String("Set QML_XHR_ALLOW_FILE_WRITE to 1 to enable this feature.") + }; - const QString writingWarning = QLatin1String( - "XMLHttpRequest: Using PUT on a local file is dangerous " - "and will be disabled by default in a future Qt version." - "Set QML_XHR_ALLOW_FILE_WRITE to 1 if you wish to continue using this feature."); + for (const auto &readingErrorLine : readingError) + QVERIFY(output.contains(readingErrorLine)); - QVERIFY(output.contains(readingWarning)); - QVERIFY(output.contains(writingWarning)); + for (const auto &writingErrorLine : writingError) + QVERIFY(output.contains(writingErrorLine)); } #endif diff --git a/tests/auto/qmltest/fontloader/daniel.ttf b/tests/auto/qmltest/fontloader/daniel.ttf Binary files differnew file mode 100644 index 0000000000..aae50d5035 --- /dev/null +++ b/tests/auto/qmltest/fontloader/daniel.ttf diff --git a/tests/auto/qmltest/fontloader/tst_fontloader.qml b/tests/auto/qmltest/fontloader/tst_fontloader.qml index 0d1831230e..48b92e02ba 100644 --- a/tests/auto/qmltest/fontloader/tst_fontloader.qml +++ b/tests/auto/qmltest/fontloader/tst_fontloader.qml @@ -81,10 +81,6 @@ Item { fontloader.source = "dummy.ttf"; tryCompare(fontloader, 'status', FontLoader.Error) compare(testinput.font.family, "") - fontloader.source = ""; - fontloader.name = "Courier"; - tryCompare(fontloader, 'status', FontLoader.Ready) - compare(testinput.font.family, "Courier") } function test_fontswitching() { @@ -92,10 +88,9 @@ Item { fontswitch.source = "tarzeau_ocr_a.ttf"; tryCompare(fontswitch, 'status', FontLoader.Ready) compare(fontswitch.name, "OCRA") - fontswitch.source = ""; - fontswitch.name = "Courier"; + fontswitch.source = "daniel.ttf"; tryCompare(fontswitch, 'status', FontLoader.Ready) - compare(fontswitch.name, "Courier") + compare(fontswitch.name, "Daniel") fontswitch.source = "tarzeau_ocr_a.ttf"; tryCompare(fontswitch, 'status', FontLoader.Ready) compare(fontswitch.name, "OCRA") diff --git a/tests/auto/quick/drawingmodes/tst_drawingmodes.cpp b/tests/auto/quick/drawingmodes/tst_drawingmodes.cpp index 9bcc21c77d..39f4c3c70a 100644 --- a/tests/auto/quick/drawingmodes/tst_drawingmodes.cpp +++ b/tests/auto/quick/drawingmodes/tst_drawingmodes.cpp @@ -34,7 +34,7 @@ #include <QtQuick/qsggeometry.h> #include <QtQuick/qsgflatcolormaterial.h> #include <QtGui/qscreen.h> -#include <QtGui/qopenglcontext.h> +#include <qopenglcontext.h> #include "../../shared/util.h" diff --git a/tests/auto/quick/nodes/tst_nodestest.cpp b/tests/auto/quick/nodes/tst_nodestest.cpp index 249ecd5aa5..1b2b355596 100644 --- a/tests/auto/quick/nodes/tst_nodestest.cpp +++ b/tests/auto/quick/nodes/tst_nodestest.cpp @@ -30,7 +30,7 @@ #include <QtTest/QtTest> #include <QtGui/QOffscreenSurface> -#include <QtGui/QOpenGLContext> +#include <QOpenGLContext> #include <QtQuick/qsgnode.h> #include <QtQuick/private/qsgbatchrenderer_p.h> #include <QtQuick/private/qsgnodeupdater_p.h> diff --git a/tests/auto/quick/nokeywords/nokeywords.pro b/tests/auto/quick/nokeywords/nokeywords.pro index 6872dac22a..69e1abe43e 100644 --- a/tests/auto/quick/nokeywords/nokeywords.pro +++ b/tests/auto/quick/nokeywords/nokeywords.pro @@ -7,3 +7,5 @@ SOURCES += tst_nokeywords.cpp CONFIG+=parallel_test QT += quick core-private gui-private qml-private quick-private testlib +qtConfig(opengl): \ + QT_PRIVATE += opengl-private diff --git a/tests/auto/quick/pointerhandlers/qquickhoverhandler/BLACKLIST b/tests/auto/quick/pointerhandlers/qquickhoverhandler/BLACKLIST new file mode 100644 index 0000000000..9bb35c4770 --- /dev/null +++ b/tests/auto/quick/pointerhandlers/qquickhoverhandler/BLACKLIST @@ -0,0 +1,3 @@ +[movingItemWithHoverHandler] +macos # Can't move cursor (QTBUG-76312) + diff --git a/tests/auto/quick/pointerhandlers/qquickwheelhandler/BLACKLIST b/tests/auto/quick/pointerhandlers/qquickwheelhandler/BLACKLIST new file mode 100644 index 0000000000..2949d3371f --- /dev/null +++ b/tests/auto/quick/pointerhandlers/qquickwheelhandler/BLACKLIST @@ -0,0 +1,3 @@ +# QTBUG-81993 +[singleHandler] +macos ci diff --git a/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp b/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp index 9f616c56e2..47d6008c28 100644 --- a/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp +++ b/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp @@ -34,8 +34,8 @@ #include <private/qquickitem_p.h> #include <QtCore/qscopedpointer.h> #include <QtGui/qpainter.h> -#include <QtGui/qopenglcontext.h> -#include <QtGui/qopenglfunctions.h> +#include <qopenglcontext.h> +#include <qopenglfunctions.h> #include <QtGui/qoffscreensurface.h> #include <QtQml/qqmlproperty.h> diff --git a/tests/auto/quick/qquickanimations/BLACKLIST b/tests/auto/quick/qquickanimations/BLACKLIST new file mode 100644 index 0000000000..a1b8557128 --- /dev/null +++ b/tests/auto/quick/qquickanimations/BLACKLIST @@ -0,0 +1,2 @@ +[simplePath] +macos ci diff --git a/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp b/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp index b44977bd5a..062a8b5c9a 100644 --- a/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp +++ b/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp @@ -76,7 +76,10 @@ void tst_qquickdesignersupport::customData() QVERIFY(rootItem); - QScopedPointer<QObject> newItemScopedPointer(QQuickDesignerSupportItems::createPrimitive(QLatin1String("QtQuick/Item"), 2, 6, view->rootContext())); + QScopedPointer<QObject> newItemScopedPointer(QQuickDesignerSupportItems::createPrimitive( + QLatin1String("QtQuick/Item"), + QTypeRevision::fromVersion(2, 6), + view->rootContext())); QObject *newItem = newItemScopedPointer.data(); QVERIFY(newItem); diff --git a/tests/auto/quick/qquickfontloader/data/qtbug-20268.qml b/tests/auto/quick/qquickfontloader/data/qtbug-20268.qml index 0eafdfa17b..e9282bf2c7 100644 --- a/tests/auto/quick/qquickfontloader/data/qtbug-20268.qml +++ b/tests/auto/quick/qquickfontloader/data/qtbug-20268.qml @@ -4,7 +4,7 @@ Rectangle { id: test property variant fontloader: fontloaderelement height: 100; width: 100 - property bool usename: false + property bool useotherfont: false property int statenum: 1 property alias name: fontloaderelement.name property alias source: fontloaderelement.source @@ -15,11 +15,11 @@ Rectangle { } states: [ - State { name: "start"; when: !usename + State { name: "start"; when: !useotherfont PropertyChanges { target: fontloaderelement; source: "tarzeau_ocr_a.ttf" } }, - State { name: "changefont"; when: usename - PropertyChanges { target: fontloaderelement; name: "Tahoma" } + State { name: "changefont"; when: useotherfont + PropertyChanges { target: fontloaderelement; source: "daniel.ttf" } } ] diff --git a/tests/auto/quick/qquickfontloader/tst_qquickfontloader.cpp b/tests/auto/quick/qquickfontloader/tst_qquickfontloader.cpp index 87a5bd469a..8f6910bee4 100644 --- a/tests/auto/quick/qquickfontloader/tst_qquickfontloader.cpp +++ b/tests/auto/quick/qquickfontloader/tst_qquickfontloader.cpp @@ -45,7 +45,6 @@ public: private slots: void initTestCase(); void noFont(); - void namedFont(); void localFont(); void failLocalFont(); void webFont(); @@ -85,19 +84,6 @@ void tst_qquickfontloader::noFont() delete fontObject; } -void tst_qquickfontloader::namedFont() -{ - QString componentStr = "import QtQuick 2.0\nFontLoader { name: \"Helvetica\" }"; - QQmlComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickFontLoader *fontObject = qobject_cast<QQuickFontLoader*>(component.create()); - - QVERIFY(fontObject != nullptr); - QCOMPARE(fontObject->source(), QUrl("")); - QCOMPARE(fontObject->name(), QString("Helvetica")); - QTRY_COMPARE(fontObject->status(), QQuickFontLoader::Ready); -} - void tst_qquickfontloader::localFont() { QString componentStr = "import QtQuick 2.0\nFontLoader { source: \"" + testFileUrl("tarzeau_ocr_a.ttf").toString() + "\" }"; @@ -223,16 +209,10 @@ void tst_qquickfontloader::changeFontSourceViaState() QVERIFY(fontObject->source() != QUrl("")); QTRY_COMPARE(fontObject->name(), QString("OCRA")); - window.rootObject()->setProperty("usename", true); - - // This warning should probably not be printed once QTBUG-20268 is fixed - QString warning = QString(testFileUrl("qtbug-20268.qml").toString()) + - QLatin1String(":13:5: QML FontLoader: Cannot load font: \"\""); - QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); + window.rootObject()->setProperty("useotherfont", true); - QEXPECT_FAIL("", "QTBUG-20268", Abort); QTRY_COMPARE(fontObject->status(), QQuickFontLoader::Ready); - QCOMPARE(window.rootObject()->property("name").toString(), QString("Tahoma")); + QCOMPARE(window.rootObject()->property("name").toString(), QString("Daniel")); } QTEST_MAIN(tst_qquickfontloader) diff --git a/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp b/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp index 6aff66d61e..2327270b0f 100644 --- a/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp +++ b/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp @@ -30,9 +30,9 @@ #include <QtQuick/qquickitem.h> #include <QtQuick/qquickview.h> -#include <QtGui/qopenglcontext.h> -#include <QtGui/qopenglframebufferobject.h> -#include <QtGui/qopenglfunctions.h> +#include <qopenglcontext.h> +#include <qopenglframebufferobject.h> +#include <qopenglfunctions.h> #include <QtQuick/QQuickFramebufferObject> diff --git a/tests/auto/quick/qquickgraphicsinfo/tst_qquickgraphicsinfo.cpp b/tests/auto/quick/qquickgraphicsinfo/tst_qquickgraphicsinfo.cpp index 4da6da6043..aff081c4a8 100644 --- a/tests/auto/quick/qquickgraphicsinfo/tst_qquickgraphicsinfo.cpp +++ b/tests/auto/quick/qquickgraphicsinfo/tst_qquickgraphicsinfo.cpp @@ -36,7 +36,7 @@ #include "../../shared/util.h" #if QT_CONFIG(opengl) -#include <QtGui/qopenglcontext.h> +#include <qopenglcontext.h> #include <QtGui/qsurfaceformat.h> #endif diff --git a/tests/auto/quick/qquickitem/tst_qquickitem.cpp b/tests/auto/quick/qquickitem/tst_qquickitem.cpp index 8aab13e095..ac8c599cc9 100644 --- a/tests/auto/quick/qquickitem/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem/tst_qquickitem.cpp @@ -34,6 +34,9 @@ #include "private/qquickfocusscope_p.h" #include "private/qquickitem_p.h" #include <qpa/qwindowsysteminterface.h> +#ifdef Q_OS_WIN +#include <QOpenGLContext> +#endif #include <QDebug> #include <QTimer> #include <QQmlEngine> diff --git a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp index 2f90632841..b45aa5d61c 100644 --- a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp +++ b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp @@ -31,8 +31,8 @@ #include <QtQuick/qquickitem.h> #include <QtQuick/qquickview.h> #include <QtQuick/qsgrendererinterface.h> -#include <QtGui/qopenglcontext.h> -#include <QtGui/qopenglfunctions.h> +#include <qopenglcontext.h> +#include <qopenglfunctions.h> #include "../../shared/util.h" diff --git a/tests/auto/quick/qquickmousearea/BLACKLIST b/tests/auto/quick/qquickmousearea/BLACKLIST index 6e0665271c..089bb3a873 100644 --- a/tests/auto/quick/qquickmousearea/BLACKLIST +++ b/tests/auto/quick/qquickmousearea/BLACKLIST @@ -1,3 +1,6 @@ +[pressAndHold] +macos ci + # QTBUG-78153 [nestedStopAtBounds] opensuse-leap @@ -5,4 +8,3 @@ opensuse-leap # QTBUG-82282 [pressOneAndTapAnother] opensuse-leap - diff --git a/tests/auto/quick/qquickopenglinfo/tst_qquickopenglinfo.cpp b/tests/auto/quick/qquickopenglinfo/tst_qquickopenglinfo.cpp index 3bf61e8f17..a4cbaa453d 100644 --- a/tests/auto/quick/qquickopenglinfo/tst_qquickopenglinfo.cpp +++ b/tests/auto/quick/qquickopenglinfo/tst_qquickopenglinfo.cpp @@ -32,7 +32,7 @@ #include <QtQuick/qquickitem.h> #include <QtQuick/qquickview.h> -#include <QtGui/qopenglcontext.h> +#include <qopenglcontext.h> #include <QtGui/qsurfaceformat.h> #include "../../shared/util.h" diff --git a/tests/auto/quick/qquicktext/BLACKLIST b/tests/auto/quick/qquicktext/BLACKLIST index 08a5249e2e..b551575e9d 100644 --- a/tests/auto/quick/qquicktext/BLACKLIST +++ b/tests/auto/quick/qquicktext/BLACKLIST @@ -4,3 +4,5 @@ qemu macos [fontSizeMode] opensuse-42.1 +[contentSize] +windows gcc diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp index a64c9372da..19a33f1861 100644 --- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp +++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp @@ -1506,7 +1506,7 @@ void tst_qquicktext::weight() delete textObject; } { - QString componentStr = "import QtQuick 2.0\nText { font.weight: \"Bold\"; text: \"Hello world!\" }"; + QString componentStr = "import QtQuick 2.0\nText { font.weight: Font.Bold; text: \"Hello world!\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); diff --git a/tests/auto/quick/qquicktextedit/BLACKLIST b/tests/auto/quick/qquicktextedit/BLACKLIST index 36c7f0042f..b8147a0ef9 100644 --- a/tests/auto/quick/qquicktextedit/BLACKLIST +++ b/tests/auto/quick/qquicktextedit/BLACKLIST @@ -4,3 +4,7 @@ opensuse-leap # QTBUG-78846 [mouseSelectionMode] opensuse-leap + +# QTBUG-82052 +[linkHover] +macos ci diff --git a/tests/auto/quick/qquicktextinput/BLACKLIST b/tests/auto/quick/qquicktextinput/BLACKLIST index ada7c57c75..6cd24de9a9 100644 --- a/tests/auto/quick/qquicktextinput/BLACKLIST +++ b/tests/auto/quick/qquicktextinput/BLACKLIST @@ -1,3 +1,7 @@ # QTBUG-78162 [mouseSelectionMode] opensuse-leap + +# QTBUG-82058 +[setInputMask] +macos ci diff --git a/tests/auto/quick/rendernode/tst_rendernode.cpp b/tests/auto/quick/rendernode/tst_rendernode.cpp index 6ca5231343..961531db6d 100644 --- a/tests/auto/quick/rendernode/tst_rendernode.cpp +++ b/tests/auto/quick/rendernode/tst_rendernode.cpp @@ -30,8 +30,8 @@ #include <QtQuick/qquickitem.h> #include <QtQuick/qquickview.h> -#include <QtGui/qopenglcontext.h> -#include <QtGui/qopenglfunctions.h> +#include <qopenglcontext.h> +#include <qopenglfunctions.h> #include <QtGui/qscreen.h> #include <private/qsgrendernode_p.h> @@ -194,7 +194,7 @@ static bool fuzzyCompareColor(QRgb x, QRgb y, QByteArray *errorMessage) enum { fuzz = 4 }; if (qAbs(qRed(x) - qRed(y)) >= fuzz || qAbs(qGreen(x) - qGreen(y)) >= fuzz || qAbs(qBlue(x) - qBlue(y)) >= fuzz) { QString s; - QDebug(&s).nospace() << hex << "Color mismatch 0x" << x << " 0x" << y << dec << " (fuzz=" << fuzz << ")."; + QDebug(&s).nospace() << Qt::hex << "Color mismatch 0x" << x << " 0x" << y << Qt::dec << " (fuzz=" << fuzz << ")."; *errorMessage = s.toLocal8Bit(); return false; } diff --git a/tests/auto/quick/shared/visualtestutil.cpp b/tests/auto/quick/shared/visualtestutil.cpp index de2cf2bd5b..06f7386902 100644 --- a/tests/auto/quick/shared/visualtestutil.cpp +++ b/tests/auto/quick/shared/visualtestutil.cpp @@ -95,7 +95,7 @@ bool QQuickVisualTestUtil::compareImages(const QImage &ia, const QImage &ib, QSt || qAbs(qRed(a) - qRed(b)) > tolerance || qAbs(qRed(a) - qRed(b)) > tolerance) { QDebug(errorMessage) << "Mismatch at:" << x << y << ':' - << hex << showbase << a << b; + << Qt::hex << Qt::showbase << a << b; return false; } } diff --git a/tests/auto/shared/qqmljsastdumper.cpp b/tests/auto/shared/qqmljsastdumper.cpp index 8a50e021f6..bc21d8d4e5 100644 --- a/tests/auto/shared/qqmljsastdumper.cpp +++ b/tests/auto/shared/qqmljsastdumper.cpp @@ -347,7 +347,9 @@ bool AstDumper::visit(AST::UiEnumMemberList *el) { bool AstDumper::visit(AST::UiVersionSpecifier *el) { start(QLatin1String("UiVersionSpecifier majorVersion=%1 minorVersion=%2 majorToken=%3 minorToken=%4") - .arg(qs(QString::number(el->majorVersion)), qs(QString::number(el->minorVersion)), loc(el->majorToken), loc(el->minorToken))); + .arg(qs(QString::number(el->version.majorVersion())), + qs(QString::number(el->version.minorVersion())), + loc(el->majorToken), loc(el->minorToken))); return true; } diff --git a/tests/auto/toolsupport/tst_toolsupport.cpp b/tests/auto/toolsupport/tst_toolsupport.cpp index f743a6f5c6..0c87d1a00c 100644 --- a/tests/auto/toolsupport/tst_toolsupport.cpp +++ b/tests/auto/toolsupport/tst_toolsupport.cpp @@ -87,7 +87,7 @@ void tst_toolsupport::offsets_data() { QTestData &data = QTest::newRow("sizeof(QObjectData)") << sizeof(QObjectData); - data << 28 << 48; // vptr + 3 ptr + 2 int + ptr + data << 36 << 64; // vptr + 4 ptr + 3 int + (padding) + ptr } { @@ -115,8 +115,8 @@ void tst_toolsupport::offsets_data() { QTestData &data - = QTest::newRow("Heap::String::text") - << pmm_to_offsetof(&QV4::Heap::String::text); + = QTest::newRow("Heap::String::textStorage") + << pmm_to_offsetof(&QV4::Heap::String::textStorage); data << 4 << 8; } diff --git a/tests/benchmarks/qml/creation/tst_creation.cpp b/tests/benchmarks/qml/creation/tst_creation.cpp index ed2e52f869..2044360b3d 100644 --- a/tests/benchmarks/qml/creation/tst_creation.cpp +++ b/tests/benchmarks/qml/creation/tst_creation.cpp @@ -196,7 +196,7 @@ void tst_creation::qobject_10tree_cpp() void tst_creation::qobject_qmltype() { - QQmlType t = QQmlMetaType::qmlType("QtQuick/QtObject", 2, 0); + QQmlType t = QQmlMetaType::qmlType("QtQuick/QtObject", QTypeRevision::fromVersion(2, 0)); QBENCHMARK { QObject *obj = t.create(); diff --git a/tests/benchmarks/qml/painting/paintbenchmark.cpp b/tests/benchmarks/qml/painting/paintbenchmark.cpp index 1500f39c9a..e1659d6837 100644 --- a/tests/benchmarks/qml/painting/paintbenchmark.cpp +++ b/tests/benchmarks/qml/painting/paintbenchmark.cpp @@ -31,7 +31,7 @@ #include <QImage> #include <QPainter> #include <QPainterPath> -#include <QGLWidget> +#include <QOpenGLWidget> #include <QTextLayout> #include <QVBoxLayout> #include <QElapsedTimer> @@ -46,7 +46,7 @@ const int spacing = 36; QSizeF size(1000, 800); const qreal lineWidth = 1000; QString strings[lines]; -QGLWidget *testWidget = 0; +QOpenGLWidget *testWidget = 0; void paint_QTextLayout(QPainter &p, bool useCache) { @@ -151,8 +151,8 @@ void paint_RoundedRect(QPainter &p) static bool first = true; if (first) { if (testWidget) { - QGLFormat format = testWidget->format(); - if (!format.sampleBuffers()) + QSurfaceFormat format = testWidget->format(); + if (format.samples() == -1) qWarning() << "Cannot paint antialiased rounded rect without sampleBuffers"; } first = false; @@ -314,10 +314,11 @@ struct { PaintFunc testFunc = 0; -class MyGLWidget : public QGLWidget +class MyGLWidget : public QOpenGLWidget { public: - MyGLWidget(const QGLFormat &format) : QGLWidget(format), frames(0) { + MyGLWidget(const QSurfaceFormat &format) : frames(0) { + setFormat(format); const char chars[] = "abcd efgh ijkl mnop qrst uvwx yz!$. ABCD 1234"; int len = strlen(chars); for (int i = 0; i < lines; ++i) { @@ -394,8 +395,11 @@ int main(int argc, char *argv[]) } QWidget w; - QGLFormat format = QGLFormat::defaultFormat(); - format.setSampleBuffers(sampleBuffers); + QSurfaceFormat format = QSurfaceFormat::defaultFormat(); + if (!sampleBuffers) + format.setSamples(-1); + else if (format.samples() == -1) + format.setSamples(4); testWidget = new MyGLWidget(format); testWidget->setAutoFillBackground(false); QVBoxLayout *layout = new QVBoxLayout(&w); diff --git a/tests/benchmarks/qml/painting/painting.pro b/tests/benchmarks/qml/painting/painting.pro index 7e97915f43..633be76e30 100644 --- a/tests/benchmarks/qml/painting/painting.pro +++ b/tests/benchmarks/qml/painting/painting.pro @@ -1,6 +1,7 @@ requires(qtHaveModule(opengl)) +requires(qtHaveModule(widgets)) -QT += opengl +QT += opengl widgets CONFIG += console macx:CONFIG -= app_bundle diff --git a/tests/manual/nodetypes/Animators.qml b/tests/manual/nodetypes/Animators.qml deleted file mode 100644 index c582106c5d..0000000000 --- a/tests/manual/nodetypes/Animators.qml +++ /dev/null @@ -1,190 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.5 - -Item { - id: window - - Rectangle { - anchors.fill: parent - gradient: Gradient { - GradientStop { position: 0.0; color: "#14148c" } - GradientStop { position: 0.499; color: "#14aaff" } - GradientStop { position: 0.5; color: "#80c342" } - GradientStop { position: 1.0; color: "#006325" } - } - } - - SequentialAnimation { - id: plainAnim - SequentialAnimation { - ParallelAnimation { - PropertyAnimation { - property: "y" - target: smiley - from: smiley.minHeight - to: smiley.maxHeight - easing.type: Easing.OutExpo - duration: 300 - } - PropertyAnimation { - property: "scale" - target: shadow - from: 1 - to: 0.5 - easing.type: Easing.OutExpo - duration: 300 - } - } - ParallelAnimation { - PropertyAnimation { - property: "y" - target: smiley - from: smiley.maxHeight - to: smiley.minHeight - easing.type: Easing.OutBounce - duration: 1000 - } - PropertyAnimation { - property: "scale" - target: shadow - from: 0.5 - to: 1 - easing.type: Easing.OutBounce - duration: 1000 - } - } - } - running: false - } - - SequentialAnimation { - id: renderThreadAnim - SequentialAnimation { - ParallelAnimation { - YAnimator { - target: smiley - from: smiley.minHeight - to: smiley.maxHeight - easing.type: Easing.OutExpo - duration: 300 - } - ScaleAnimator { - target: shadow - from: 1 - to: 0.5 - easing.type: Easing.OutExpo - duration: 300 - } - } - ParallelAnimation { - YAnimator { - target: smiley - from: smiley.maxHeight - to: smiley.minHeight - easing.type: Easing.OutBounce - duration: 1000 - } - ScaleAnimator { - target: shadow - from: 0.5 - to: 1 - easing.type: Easing.OutBounce - duration: 1000 - } - } - } - running: false - } - - Image { - id: shadow - anchors.horizontalCenter: parent.horizontalCenter - y: smiley.minHeight + smiley.height - source: "qrc:/shadow.png" - } - - Image { - id: smiley - property int maxHeight: window.height / 3 - property int minHeight: 2 * window.height / 3 - - anchors.horizontalCenter: parent.horizontalCenter - y: minHeight - source: "qrc:/face-smile.png" - } - - Text { - text: "click left for plain animation, right for render thread Animators, middle to sleep for 2 sec on the main (gui) thread" - color: "white" - } - - Text { - text: plainAnim.running ? "NORMAL ANIMATION" : (renderThreadAnim.running ? "RENDER THREAD ANIMATION" : "NO ANIMATION") - color: "red" - font.pointSize: 20 - anchors.bottom: parent.bottom - } - - MouseArea { - anchors.fill: parent - acceptedButtons: Qt.AllButtons - onClicked: if (mouse.button === Qt.LeftButton) { - renderThreadAnim.running = false; - plainAnim.running = true; - } else if (mouse.button === Qt.RightButton) { - plainAnim.running = false; - renderThreadAnim.running = true; - } else if (mouse.button === Qt.MiddleButton) { - helper.sleep(2000); - } - } -} diff --git a/tests/manual/nodetypes/Effects.qml b/tests/manual/nodetypes/Effects.qml deleted file mode 100644 index 90a30c40d3..0000000000 --- a/tests/manual/nodetypes/Effects.qml +++ /dev/null @@ -1,231 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// Use QtQuick 2.8 to get GraphicsInfo and the other new properties -import QtQuick 2.8 - -Item { - Rectangle { - color: "gray" - anchors.margins: 10 - anchors.fill: parent - Image { - id: image1 - source: "qrc:/qt.png" - } - ShaderEffectSource { - id: effectSource1 - sourceItem: image1 - hideSource: true - } - ShaderEffect { // wobble - id: eff - width: image1.width - height: image1.height - anchors.centerIn: parent - - property variant source: effectSource1 - property real amplitude: 0.04 * 0.2 - property real frequency: 20 - property real time: 0 - - NumberAnimation on time { loops: Animation.Infinite; from: 0; to: Math.PI * 2; duration: 600 } - - property bool customVertexShader: false // the effect is fine with the default vs, but toggle this to test - property bool useHLSLSourceString: false // toggle to provide HLSL shaders as strings instead of bytecode in files - - property string glslVertexShader: - "uniform highp mat4 qt_Matrix;" + - "attribute highp vec4 qt_Vertex;" + - "attribute highp vec2 qt_MultiTexCoord0;" + - "varying highp vec2 qt_TexCoord0;" + - "void main() {" + - " qt_TexCoord0 = qt_MultiTexCoord0;" + - " gl_Position = qt_Matrix * qt_Vertex;" + - "}" - - property string glslFragmentShader: - "uniform sampler2D source;" + - "uniform highp float amplitude;" + - "uniform highp float frequency;" + - "uniform highp float time;" + - "uniform lowp float qt_Opacity;" + - "varying highp vec2 qt_TexCoord0;" + - "void main() {" + - " highp vec2 p = sin(time + frequency * qt_TexCoord0);" + - " gl_FragColor = texture2D(source, qt_TexCoord0 + amplitude * vec2(p.y, -p.x)) * qt_Opacity;" + - "}" - - property string hlslVertexShader: "cbuffer ConstantBuffer : register(b0) {" + - " float4x4 qt_Matrix;" + - " float qt_Opacity; }" + - "struct PSInput {" + - " float4 position : SV_POSITION;" + - " float2 coord : TEXCOORD0; };" + - "PSInput main(float4 position : POSITION, float2 coord : TEXCOORD0) {" + - " PSInput result;" + - " result.position = mul(qt_Matrix, position);" + - " result.coord = coord;" + - " return result;" + - "}"; - - property string hlslPixelShader:"cbuffer ConstantBuffer : register(b0) {" + - " float4x4 qt_Matrix;" + - " float qt_Opacity;" + - " float amplitude;" + - " float frequency;" + - " float time; }" + - "Texture2D source : register(t0);" + - "SamplerState sourceSampler : register(s0);" + - "float4 main(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET" + - "{" + - " float2 p = sin(time + frequency * coord);" + - " return source.Sample(sourceSampler, coord + amplitude * float2(p.y, -p.x)) * qt_Opacity;" + - "}"; - - property string hlslVertexShaderByteCode: "qrc:/vs_wobble.cso" - property string hlslPixelShaderByteCode: "qrc:/ps_wobble.cso" - - vertexShader: customVertexShader ? (GraphicsInfo.shaderType === GraphicsInfo.HLSL - ? (useHLSLSourceString ? hlslVertexShader : hlslVertexShaderByteCode) - : (GraphicsInfo.shaderType === GraphicsInfo.GLSL ? glslVertexShader : "")) : "" - - fragmentShader: GraphicsInfo.shaderType === GraphicsInfo.HLSL - ? (useHLSLSourceString ? hlslPixelShader : hlslPixelShaderByteCode) - : (GraphicsInfo.shaderType === GraphicsInfo.GLSL ? glslFragmentShader : "") - } - - Image { - id: image2 - source: "qrc:/face-smile.png" - } - ShaderEffectSource { - id: effectSource2 - sourceItem: image2 - hideSource: true - } - ShaderEffect { // dropshadow - id: eff2 - width: image2.width - height: image2.height - scale: 2 - x: 40 - y: 40 - - property variant source: effectSource2 - - property string glslShaderPass1: " - uniform lowp float qt_Opacity; - uniform sampler2D source; - uniform highp vec2 delta; - varying highp vec2 qt_TexCoord0; - void main() { - gl_FragColor = (0.0538 * texture2D(source, qt_TexCoord0 - 3.182 * delta) - + 0.3229 * texture2D(source, qt_TexCoord0 - 1.364 * delta) - + 0.2466 * texture2D(source, qt_TexCoord0) - + 0.3229 * texture2D(source, qt_TexCoord0 + 1.364 * delta) - + 0.0538 * texture2D(source, qt_TexCoord0 + 3.182 * delta)) * qt_Opacity; - }" - property string glslShaderPass2: " - uniform lowp float qt_Opacity; - uniform highp vec2 offset; - uniform sampler2D source; - uniform sampler2D shadow; - uniform highp float darkness; - uniform highp vec2 delta; - varying highp vec2 qt_TexCoord0; - void main() { - lowp vec4 fg = texture2D(source, qt_TexCoord0); - lowp vec4 bg = texture2D(shadow, qt_TexCoord0 + delta); - gl_FragColor = (fg + vec4(0., 0., 0., darkness * bg.a) * (1. - fg.a)) * qt_Opacity; - }" - - property variant shadow: ShaderEffectSource { - sourceItem: ShaderEffect { - width: eff2.width - height: eff2.height - property variant delta: Qt.size(0.0, 1.0 / height) - property variant source: ShaderEffectSource { - sourceItem: ShaderEffect { - id: innerEff - width: eff2.width - height: eff2.height - property variant delta: Qt.size(1.0 / width, 0.0) - property variant source: effectSource2 - fragmentShader: GraphicsInfo.shaderType === GraphicsInfo.HLSL ? "qrc:/ps_shadow1.cso" : (GraphicsInfo.shaderType === GraphicsInfo.GLSL ? eff2.glslShaderPass1 : "") - } - } - fragmentShader: GraphicsInfo.shaderType === GraphicsInfo.HLSL ? "qrc:/ps_shadow1.cso" : (GraphicsInfo.shaderType === GraphicsInfo.GLSL ? eff2.glslShaderPass1: "") - } - } - property real angle: 0 - property variant offset: Qt.point(5.0 * Math.cos(angle), 5.0 * Math.sin(angle)) - NumberAnimation on angle { loops: Animation.Infinite; from: 0; to: Math.PI * 2; duration: 6000 } - property variant delta: Qt.size(offset.x / width, offset.y / height) - property real darkness: 0.5 - fragmentShader: GraphicsInfo.shaderType === GraphicsInfo.HLSL ? "qrc:/ps_shadow2.cso" : (GraphicsInfo.shaderType === GraphicsInfo.GLSL ? glslShaderPass2 : "") - } - - Column { - anchors.bottom: parent.bottom - Text { - color: "yellow" - font.pointSize: 24 - text: "Shader effect is " + (GraphicsInfo.shaderType === GraphicsInfo.HLSL ? "HLSL" : (GraphicsInfo.shaderType === GraphicsInfo.GLSL ? "GLSL" : "UNKNOWN")) + " based"; - } - Text { - text: GraphicsInfo.shaderType + " " + GraphicsInfo.shaderCompilationType + " " + GraphicsInfo.shaderSourceType - } - Text { - text: eff.status + " " + eff.log - } - } - } -} diff --git a/tests/manual/nodetypes/Images.qml b/tests/manual/nodetypes/Images.qml deleted file mode 100644 index 95e8442690..0000000000 --- a/tests/manual/nodetypes/Images.qml +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.3 - -Item { - Rectangle { - width: 100 - height: 100 - anchors.centerIn: parent - color: "red" - NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; } - } - - Image { - id: im - source: "qrc:/qt.png" - mipmap: true - - // changing the mipmap property results in the creation of a brand new - // texture resource. enable the following to test. -// Timer { -// interval: 2000 -// onTriggered: im.mipmap = false -// running: true -// } - - SequentialAnimation on scale { - loops: Animation.Infinite - NumberAnimation { - from: 1.0 - to: 4.0 - duration: 2000 - } - NumberAnimation { - from: 4.0 - to: 0.1 - duration: 3000 - } - NumberAnimation { - from: 0.1 - to: 1.0 - duration: 1000 - } - } - - Image { - anchors.centerIn: parent - source: "qrc:/face-smile.png" - } - } - - Image { - source: "qrc:/face-smile.png" - anchors.bottom: parent.bottom - anchors.right: parent.right - antialiasing: true - NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; } - } -} diff --git a/tests/manual/nodetypes/Layers.qml b/tests/manual/nodetypes/Layers.qml deleted file mode 100644 index 755d00d41a..0000000000 --- a/tests/manual/nodetypes/Layers.qml +++ /dev/null @@ -1,116 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -Item { - Rectangle { - color: "lightGray" - anchors.fill: parent - anchors.margins: 10 - - Row { - anchors.fill: parent - anchors.margins: 10 - Rectangle { - color: "red" -// ColorAnimation on color { -// from: "black" -// to: "white" -// duration: 2000 -// loops: Animation.Infinite -// } - width: 300 - height: 100 - layer.enabled: true - Text { text: "this is in a layer, going through an offscreen render target" } - clip: true - Rectangle { - color: "lightGreen" - width: 50 - height: 50 - x: 275 - y: 75 - } - } - Rectangle { - color: "white" - width: 300 - height: 100 - Text { text: "this is not a layer" } - } - Rectangle { - color: "green" - width: 300 - height: 100 - layer.enabled: true - Text { text: "this is another layer" } - Rectangle { - border.width: 4 - border.color: "black" - anchors.centerIn: parent - width: 150 - height: 50 - layer.enabled: true - Text { - anchors.centerIn: parent - text: "layer in a layer" - } - } - Image { - source: "qrc:/face-smile.png" - anchors.bottom: parent.bottom - anchors.right: parent.right - NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; } - } - } - } - } -} diff --git a/tests/manual/nodetypes/LotsOfImages.qml b/tests/manual/nodetypes/LotsOfImages.qml deleted file mode 100644 index 72c36aba01..0000000000 --- a/tests/manual/nodetypes/LotsOfImages.qml +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.3 - -Item { - Grid { - columns: 20 - spacing: 4 - anchors.centerIn: parent - - Repeater { - model: 500 - - Image { - source: "qrc:/qt.png" - - // async true, cache false -> there is a separate, new texture for each and every image - // and the pixel data reading is done over and over again on a separate thread. - asynchronous: true - cache: false - - width: 20 - height: 20 - } - } - } - - Rectangle { - width: 100 - height: 100 - anchors.centerIn: parent - color: "red" - NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; } - } -} diff --git a/tests/manual/nodetypes/LotsOfRects.qml b/tests/manual/nodetypes/LotsOfRects.qml deleted file mode 100644 index e54174f10c..0000000000 --- a/tests/manual/nodetypes/LotsOfRects.qml +++ /dev/null @@ -1,260 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -Item { - Rectangle { - anchors.margins: 4 - anchors.fill: parent - - // Background - gradient: Gradient { - GradientStop { position: 0; color: "steelblue" } - GradientStop { position: 1; color: "black" } - } - - // Animated gradient stops. - // NB! Causes a full buffer rebuild on every animated change due to the geometry change! - Row { - spacing: 10 - Repeater { - model: 20 - Rectangle { - width: 20 - height: 20 - gradient: Gradient { - GradientStop { position: 0.0; color: "red" } - GradientStop { NumberAnimation on position { from: 0.01; to: 0.99; duration: 5000; loops: Animation.Infinite } color: "yellow" } - GradientStop { position: 1.0; color: "green" } - } - } - } - } - - // Rounded rects with border (smooth material) - Row { - spacing: 10 - Repeater { - model: 5 - Rectangle { - color: "blue" - width: 100 - height: 50 - y: 50 - radius: 16 - border.color: "red" - border.width: 4 - - SequentialAnimation on y { - loops: Animation.Infinite - NumberAnimation { - from: 50 - to: 150 - duration: 7000 - } - NumberAnimation { - from: 150 - to: 50 - duration: 3000 - } - } - } - } - } - - // Clip using scissor - Row { - spacing: 10 - Repeater { - model: 5 - Rectangle { - color: "green" - width: 100 - height: 100 - y: 150 - NumberAnimation on y { - from: 150 - to: 200 - duration: 2000 - loops: Animation.Infinite - } - clip: true - Rectangle { - color: "lightGreen" - width: 50 - height: 50 - x: 75 - y: 75 - } - } - } - } - - // Clip using scissor - Row { - spacing: 10 - Repeater { - model: 5 - Rectangle { - color: "green" - width: 100 - height: 100 - y: 300 - NumberAnimation on y { - from: 300 - to: 400 - duration: 2000 - loops: Animation.Infinite - } - clip: true - Rectangle { - color: "lightGreen" - width: 50 - height: 50 - x: 75 - y: 75 - NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; } - } - } - } - } - - // Clip using stencil - Row { - spacing: 10 - Repeater { - model: 5 - Rectangle { - color: "green" - width: 100 - height: 100 - y: 450 - NumberAnimation on y { - from: 450 - to: 550 - duration: 2000 - loops: Animation.Infinite - } - NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; } - clip: true - Rectangle { - color: "lightGreen" - width: 50 - height: 50 - x: 75 - y: 75 - } - } - } - } - - // The signature red square with another item with animated opacity blended on top - Rectangle { - width: 100 - height: 100 - anchors.centerIn: parent - color: "red" - NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; } - - Rectangle { - color: "gray" - width: 50 - height: 50 - anchors.centerIn: parent - - SequentialAnimation on opacity { - loops: Animation.Infinite - NumberAnimation { - from: 1.0 - to: 0.0 - duration: 4000 - } - NumberAnimation { - from: 0.0 - to: 1.0 - duration: 4000 - easing.type: Easing.InOutQuad - } - } - } - } - - // Animated size and color. - // NB! Causes a full buffer rebuild on every animated change due to the geometry change! - Rectangle { - anchors.right: parent.right - anchors.bottom: parent.bottom - width: 10 - height: 100 - ColorAnimation on color { - from: "blue" - to: "purple" - duration: 5000 - loops: Animation.Infinite - } - NumberAnimation on width { - from: 10 - to: 300 - duration: 5000 - loops: Animation.Infinite - } - } - - // Semi-transparent rect on top. - Rectangle { - anchors.centerIn: parent - opacity: 0.2 - color: "black" - anchors.fill: parent - anchors.margins: 10 - } - } -} diff --git a/tests/manual/nodetypes/Painter.qml b/tests/manual/nodetypes/Painter.qml deleted file mode 100644 index c5db3496f8..0000000000 --- a/tests/manual/nodetypes/Painter.qml +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 -import Stuff 1.0 - -Item { - ListModel { - id: balloonModel - ListElement { - balloonWidth: 200 - } - ListElement { - balloonWidth: 120 - } - ListElement { - balloonWidth: 120 - } - ListElement { - balloonWidth: 120 - } - ListElement { - balloonWidth: 120 - } - } - - ListView { - anchors.fill: parent - anchors.margins: 10 - id: balloonView - model: balloonModel - spacing: 5 - delegate: TextBalloon { - anchors.right: index % 2 == 0 ? undefined : parent.right - height: 60 - rightAligned: index % 2 == 0 ? false : true - width: balloonWidth - innerAnim: model.index === 1 - NumberAnimation on width { - from: 200 - to: 300 - duration: 5000 - running: model.index === 0 - } - } - } -} diff --git a/tests/manual/nodetypes/Rects.qml b/tests/manual/nodetypes/Rects.qml deleted file mode 100644 index 7f12d118dd..0000000000 --- a/tests/manual/nodetypes/Rects.qml +++ /dev/null @@ -1,147 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -Item { - Rectangle { - width: 100 - height: 100 - anchors.centerIn: parent - color: "red" - NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; } - - Rectangle { - color: "gray" - width: 50 - height: 50 - anchors.centerIn: parent - - SequentialAnimation on opacity { - loops: Animation.Infinite - NumberAnimation { - from: 1.0 - to: 0.0 - duration: 4000 - } - NumberAnimation { - from: 0.0 - to: 1.0 - duration: 4000 - easing.type: Easing.InOutQuad - } - } - } - } - - Rectangle { - color: "green" - width: 100 - height: 200 - x: 0 - y: 0 - - NumberAnimation on x { - from: 0 - to: 300 - duration: 5000 - } - NumberAnimation on y { - from: 0 - to: 50 - duration: 2000 - } - - clip: true - Rectangle { - color: "lightGreen" - width: 50 - height: 50 - x: 75 - y: 175 - } - } - - Rectangle { - color: "blue" - width: 200 - height: 100 - x: 100 - y: 300 - radius: 16 - border.color: "red" - border.width: 4 - - SequentialAnimation on y { - loops: Animation.Infinite - NumberAnimation { - from: 300 - to: 500 - duration: 7000 - } - NumberAnimation { - from: 500 - to: 300 - duration: 3000 - } - } - } - - Rectangle { - anchors.right: parent.right - width: 100 - height: 100 - gradient: Gradient { - GradientStop { position: 0.0; color: "red" } - GradientStop { position: 0.33; color: "yellow" } - GradientStop { position: 1.0; color: "green" } - } - } -} diff --git a/tests/manual/nodetypes/Text.qml b/tests/manual/nodetypes/Text.qml deleted file mode 100644 index 58befe8c49..0000000000 --- a/tests/manual/nodetypes/Text.qml +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -Item { - Text { - id: text1 - anchors.top: parent.top - text: "árvíztűrő tükörfúrógép\nÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP" - } - Text { - anchors.bottom: parent.bottom - text: "the quick brown fox jumps over the lazy dog\nTHE QUICK BROWN FOX JUMPS OVER THE LAZY DOG" - color: "red" - } - Text { - anchors.centerIn: parent - text: "rotate rotate rotate" - font.bold: true - font.pointSize: 20 - color: "green" - NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; } - } - - Row { - anchors.top: text1.bottom - anchors.margins: 10 - Text { font.pointSize: 24; text: "Normal" } - Text { font.pointSize: 24; text: "Raised"; style: Text.Raised; styleColor: "#AAAAAA" } - Text { font.pointSize: 24; text: "Outline"; style: Text.Outline; styleColor: "red" } - Text { font.pointSize: 24; text: "Sunken"; style: Text.Sunken; styleColor: "#AAAAAA" } - } -} diff --git a/tests/manual/nodetypes/face-smile.png b/tests/manual/nodetypes/face-smile.png Binary files differdeleted file mode 100644 index 3d66d72578..0000000000 --- a/tests/manual/nodetypes/face-smile.png +++ /dev/null diff --git a/tests/manual/nodetypes/hlslcompile.bat b/tests/manual/nodetypes/hlslcompile.bat deleted file mode 100644 index b24824e324..0000000000 --- a/tests/manual/nodetypes/hlslcompile.bat +++ /dev/null @@ -1,4 +0,0 @@ -fxc /E VS_Wobble /T vs_5_0 /Fo vs_wobble.cso wobble.hlsl -fxc /E PS_Wobble /T ps_5_0 /Fo ps_wobble.cso wobble.hlsl -fxc /E PS_Shadow1 /T ps_5_0 /Fo ps_shadow1.cso shadow1.hlsl -fxc /E PS_Shadow2 /T ps_5_0 /Fo ps_shadow2.cso shadow2.hlsl diff --git a/tests/manual/nodetypes/main.qml b/tests/manual/nodetypes/main.qml deleted file mode 100644 index 9f1a5c5e9c..0000000000 --- a/tests/manual/nodetypes/main.qml +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -Item { - focus: true - - Loader { - anchors.fill: parent - id: loader - } - - Keys.onPressed: { - if (event.key === Qt.Key_S) - loader.source = ""; - - if (event.key === Qt.Key_R) - loader.source = "qrc:/Rects.qml"; - if (event.key === Qt.Key_4) - loader.source = "qrc:/LotsOfRects.qml"; - - if (event.key === Qt.Key_I) - loader.source = "qrc:/Images.qml"; - if (event.key === Qt.Key_5) - loader.source = "qrc:/LotsOfImages.qml"; - - if (event.key === Qt.Key_T) - loader.source = "qrc:/Text.qml"; - - if (event.key === Qt.Key_A) - loader.source = "qrc:/Animators.qml"; - - if (event.key === Qt.Key_L) - loader.source = "qrc:/Layers.qml"; - - if (event.key === Qt.Key_E) - loader.source = "qrc:/Effects.qml"; - - if (event.key === Qt.Key_P) - loader.source = "qrc:/Painter.qml"; - - if (event.key === Qt.Key_G) - helper.testGrab() - } -} diff --git a/tests/manual/nodetypes/nodetypes.cpp b/tests/manual/nodetypes/nodetypes.cpp deleted file mode 100644 index 287574f25c..0000000000 --- a/tests/manual/nodetypes/nodetypes.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QGuiApplication> -#include <QThread> -#include <QQuickView> -#include <QQmlEngine> -#include <QQmlContext> -#include <QQuickPaintedItem> -#include <QPainter> -#include <QTimer> - -class TextBalloon : public QQuickPaintedItem -{ - Q_OBJECT - Q_PROPERTY(bool rightAligned READ isRightAligned WRITE setRightAligned NOTIFY rightAlignedChanged) - Q_PROPERTY(bool innerAnim READ innerAnimEnabled WRITE setInnerAnimEnabled NOTIFY innerAnimChanged) - -public: - TextBalloon(QQuickItem *parent = nullptr) : QQuickPaintedItem(parent) { - connect(&m_timer, &QTimer::timeout, this, &TextBalloon::onAnim); - m_timer.setInterval(500); - } - void paint(QPainter *painter); - - bool isRightAligned() { return m_rightAligned; } - void setRightAligned(bool rightAligned); - - bool innerAnimEnabled() const { return m_innerAnim; } - void setInnerAnimEnabled(bool b); - -signals: - void rightAlignedChanged(); - void innerAnimChanged(); - -private slots: - void onAnim(); - -private: - bool m_rightAligned = false; - bool m_innerAnim = false; - QTimer m_timer; - QRect m_animRect = QRect(10, 10, 50, 20); - int m_anim = 0; -}; - -void TextBalloon::paint(QPainter *painter) -{ - QBrush brush(QColor("#007430")); - - painter->setBrush(brush); - painter->setPen(Qt::NoPen); - painter->setRenderHint(QPainter::Antialiasing); - - painter->drawRoundedRect(0, 0, boundingRect().width(), boundingRect().height() - 10, 10, 10); - - if (m_rightAligned) { - const QPointF points[3] = { - QPointF(boundingRect().width() - 10.0, boundingRect().height() - 10.0), - QPointF(boundingRect().width() - 20.0, boundingRect().height()), - QPointF(boundingRect().width() - 30.0, boundingRect().height() - 10.0), - }; - painter->drawConvexPolygon(points, 3); - } else { - const QPointF points[3] = { - QPointF(10.0, boundingRect().height() - 10.0), - QPointF(20.0, boundingRect().height()), - QPointF(30.0, boundingRect().height() - 10.0), - }; - painter->drawConvexPolygon(points, 3); - } - - if (m_innerAnim) { - painter->fillRect(m_animRect, Qt::lightGray); - const int x = m_animRect.x() + m_anim; - const int y = m_animRect.y() + m_animRect.height() / 2; - painter->setPen(QPen(QBrush(Qt::SolidLine), 4)); - painter->drawLine(x + 4, y, x + 10, y); - m_anim += 10; - if (m_anim > m_animRect.width()) - m_anim = 0; - } -} - -void TextBalloon::setRightAligned(bool rightAligned) -{ - if (m_rightAligned == rightAligned) - return; - - m_rightAligned = rightAligned; - emit rightAlignedChanged(); -} - -void TextBalloon::setInnerAnimEnabled(bool b) -{ - if (m_innerAnim == b) - return; - - m_innerAnim = b; - if (!b) - m_timer.stop(); - else - m_timer.start(); - emit innerAnimChanged(); -} - -void TextBalloon::onAnim() -{ - update(m_animRect); -} - -class Helper : public QObject -{ - Q_OBJECT - -public: - Helper(QQuickWindow *w) : m_window(w) { } - - Q_INVOKABLE void sleep(int ms) { - QThread::msleep(ms); - } - - Q_INVOKABLE void testGrab() { - QImage img = m_window->grabWindow(); - qDebug() << "Saving image to grab_result.png" << img; - img.save("grab_result.png"); - } - - QQuickWindow *m_window; -}; - -int main(int argc, char **argv) -{ - qputenv("QT_QUICK_BACKEND", "d3d12"); - - QGuiApplication app(argc, argv); - - qDebug("Available tests:"); - qDebug(" [R] - Rectangles"); - qDebug(" [4] - A lot of rectangles"); - qDebug(" [I] - Images"); - qDebug(" [5] - A lot of async images"); - qDebug(" [T] - Text"); - qDebug(" [A] - Render thread Animator"); - qDebug(" [L] - Layers"); - qDebug(" [E] - Effects"); - qDebug(" [P] - QQuickPaintedItem"); - qDebug(" [G] - Grab current window"); - qDebug("\nPress S to stop the currently running test\n"); - - QQuickView view; - Helper helper(&view); - if (app.arguments().contains(QLatin1String("--multisample"))) { - qDebug("Requesting sample count 4"); - QSurfaceFormat fmt; - fmt.setSamples(4); - view.setFormat(fmt); - } - view.engine()->rootContext()->setContextProperty(QLatin1String("helper"), &helper); - qmlRegisterType<TextBalloon>("Stuff", 1, 0, "TextBalloon"); - view.setResizeMode(QQuickView::SizeRootObjectToView); - view.resize(1024, 768); - view.setSource(QUrl("qrc:/main.qml")); - view.show(); - - return app.exec(); -} - -#include "nodetypes.moc" diff --git a/tests/manual/nodetypes/nodetypes.pro b/tests/manual/nodetypes/nodetypes.pro deleted file mode 100644 index 959b43cf18..0000000000 --- a/tests/manual/nodetypes/nodetypes.pro +++ /dev/null @@ -1,9 +0,0 @@ -QT += qml quick - -SOURCES += nodetypes.cpp - -RESOURCES += nodetypes.qrc - -OTHER_FILES += main.qml Rects.qml LotsOfRects.qml \ - Images.qml LotsOfImages.qml Text.qml Animators.qml Layers.qml Effects.qml Painter.qml \ - wobble.hlsl shadow1.hlsl shadow2.hlsl diff --git a/tests/manual/nodetypes/nodetypes.qrc b/tests/manual/nodetypes/nodetypes.qrc deleted file mode 100644 index 78c0d085a1..0000000000 --- a/tests/manual/nodetypes/nodetypes.qrc +++ /dev/null @@ -1,21 +0,0 @@ -<RCC> - <qresource prefix="/"> - <file>main.qml</file> - <file>Rects.qml</file> - <file>LotsOfRects.qml</file> - <file>Images.qml</file> - <file>LotsOfImages.qml</file> - <file>Text.qml</file> - <file>Animators.qml</file> - <file>Layers.qml</file> - <file>Effects.qml</file> - <file>Painter.qml</file> - <file>qt.png</file> - <file>face-smile.png</file> - <file>shadow.png</file> - <file>vs_wobble.cso</file> - <file>ps_wobble.cso</file> - <file>ps_shadow1.cso</file> - <file>ps_shadow2.cso</file> - </qresource> -</RCC> diff --git a/tests/manual/nodetypes/ps_shadow1.cso b/tests/manual/nodetypes/ps_shadow1.cso Binary files differdeleted file mode 100644 index b6fbe3f3c2..0000000000 --- a/tests/manual/nodetypes/ps_shadow1.cso +++ /dev/null diff --git a/tests/manual/nodetypes/ps_shadow2.cso b/tests/manual/nodetypes/ps_shadow2.cso Binary files differdeleted file mode 100644 index ab8cb63f34..0000000000 --- a/tests/manual/nodetypes/ps_shadow2.cso +++ /dev/null diff --git a/tests/manual/nodetypes/ps_wobble.cso b/tests/manual/nodetypes/ps_wobble.cso Binary files differdeleted file mode 100644 index 4e5b6a27f4..0000000000 --- a/tests/manual/nodetypes/ps_wobble.cso +++ /dev/null diff --git a/tests/manual/nodetypes/qt.png b/tests/manual/nodetypes/qt.png Binary files differdeleted file mode 100644 index f30eec0d4d..0000000000 --- a/tests/manual/nodetypes/qt.png +++ /dev/null diff --git a/tests/manual/nodetypes/shadow.png b/tests/manual/nodetypes/shadow.png Binary files differdeleted file mode 100644 index 8270565e87..0000000000 --- a/tests/manual/nodetypes/shadow.png +++ /dev/null diff --git a/tests/manual/nodetypes/shadow1.hlsl b/tests/manual/nodetypes/shadow1.hlsl deleted file mode 100644 index ff3f4b6fd5..0000000000 --- a/tests/manual/nodetypes/shadow1.hlsl +++ /dev/null @@ -1,18 +0,0 @@ -cbuffer ConstantBuffer : register(b0) -{ - float4x4 qt_Matrix; - float qt_Opacity; - float2 delta; -}; - -Texture2D source : register(t0); -SamplerState sourceSampler : register(s0); - -float4 PS_Shadow1(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET -{ - return (0.0538 * source.Sample(sourceSampler, coord - 3.182 * delta) - + 0.3229 * source.Sample(sourceSampler, coord - 1.364 * delta) - + 0.2466 * source.Sample(sourceSampler, coord) - + 0.3229 * source.Sample(sourceSampler, coord + 1.364 * delta) - + 0.0538 * source.Sample(sourceSampler, coord + 3.182 * delta)) * qt_Opacity; -} diff --git a/tests/manual/nodetypes/shadow2.hlsl b/tests/manual/nodetypes/shadow2.hlsl deleted file mode 100644 index eaa30cd988..0000000000 --- a/tests/manual/nodetypes/shadow2.hlsl +++ /dev/null @@ -1,22 +0,0 @@ -cbuffer ConstantBuffer : register(b0) -{ - float4x4 qt_Matrix; - float qt_Opacity; - float2 offset; - float darkness; - float2 delta; -}; - -Texture2D source : register(t0); -Texture2D shadow : register(t1); -SamplerState samp : register(s0); -// Use the same sampler for both textures. In fact the engine will create an extra static sampler -// in any case (to match the number of textures) due to some internals, but that won't hurt, the -// shader works either way. - -float4 PS_Shadow2(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET -{ - float4 fg = source.Sample(samp, coord); - float4 bg = shadow.Sample(samp, coord + delta); - return (fg + float4(0.0, 0.0, 0.0, darkness * bg.a) * (1.0 - fg.a)) * qt_Opacity; -} diff --git a/tests/manual/nodetypes/vs_wobble.cso b/tests/manual/nodetypes/vs_wobble.cso Binary files differdeleted file mode 100644 index f3a2596457..0000000000 --- a/tests/manual/nodetypes/vs_wobble.cso +++ /dev/null diff --git a/tests/manual/nodetypes/wobble.hlsl b/tests/manual/nodetypes/wobble.hlsl deleted file mode 100644 index 203dbda7f2..0000000000 --- a/tests/manual/nodetypes/wobble.hlsl +++ /dev/null @@ -1,32 +0,0 @@ -cbuffer ConstantBuffer : register(b0) -{ - float4x4 qt_Matrix; - float qt_Opacity; - - float amplitude; - float frequency; - float time; -}; - -struct PSInput -{ - float4 position : SV_POSITION; - float2 coord : TEXCOORD0; -}; - -PSInput VS_Wobble(float4 position : POSITION, float2 coord : TEXCOORD0) -{ - PSInput result; - result.position = mul(qt_Matrix, position); - result.coord = coord; - return result; -} - -Texture2D source : register(t0); -SamplerState sourceSampler : register(s0); - -float4 PS_Wobble(PSInput input) : SV_TARGET -{ - float2 p = sin(time + frequency * input.coord); - return source.Sample(sourceSampler, input.coord + amplitude * float2(p.y, -p.x)) * qt_Opacity; -} diff --git a/tools/qml/conf.h b/tools/qml/conf.h index 4ad45428ed..84167c9134 100644 --- a/tools/qml/conf.h +++ b/tools/qml/conf.h @@ -40,6 +40,7 @@ class PartialScene : public QObject Q_PROPERTY(QUrl container READ container WRITE setContainer NOTIFY containerChanged) Q_PROPERTY(QString itemType READ itemType WRITE setItemType NOTIFY itemTypeChanged) QML_ELEMENT + QML_ADDED_IN_VERSION(1, 0) public: PartialScene(QObject *parent = 0) : QObject(parent) {} @@ -75,6 +76,7 @@ class Config : public QObject Q_PROPERTY(QQmlListProperty<PartialScene> sceneCompleters READ sceneCompleters) Q_CLASSINFO("DefaultProperty", "sceneCompleters") QML_NAMED_ELEMENT(Configuration) + QML_ADDED_IN_VERSION(1, 0) public: Config (QObject* parent=0) : QObject(parent) {} diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp index beeec88f07..e8c471e22e 100644 --- a/tools/qml/main.cpp +++ b/tools/qml/main.cpp @@ -622,7 +622,7 @@ int main(int argc, char *argv[]) } if (files.count() <= 0) { -#if defined(Q_OS_DARWIN) +#if defined(Q_OS_DARWIN) && defined(QT_GUI_LIB) if (applicationType == QmlApplicationTypeGui) exitTimerId = static_cast<LoaderApplication *>(app.get())->startTimer(FILE_OPEN_EVENT_WAIT_TIME); else diff --git a/tools/qmlcachegen/generateloader.cpp b/tools/qmlcachegen/generateloader.cpp index 71286137eb..a8ec527299 100644 --- a/tools/qmlcachegen/generateloader.cpp +++ b/tools/qmlcachegen/generateloader.cpp @@ -155,7 +155,7 @@ bool generateLoader(const QStringList &compiledFiles, const QString &outputFileN } stream << " QQmlPrivate::RegisterQmlUnitCacheHook registration;\n"; - stream << " registration.version = 0;\n"; + stream << " registration.structVersion = 0;\n"; stream << " registration.lookupCachedQmlUnit = &lookupCachedUnit;\n"; stream << " QQmlPrivate::qmlregister(QQmlPrivate::QmlUnitCacheHookRegistration, ®istration);\n"; diff --git a/tools/qmlformat/dumpastvisitor.cpp b/tools/qmlformat/dumpastvisitor.cpp index 7f1e285423..75712975cc 100644 --- a/tools/qmlformat/dumpastvisitor.cpp +++ b/tools/qmlformat/dumpastvisitor.cpp @@ -1229,8 +1229,8 @@ bool DumpAstVisitor::visit(UiImport *node) { result += parseUiQualifiedId(node->importUri); if (node->version) { - result += " " + QString::number(node->version->majorVersion) + "." - + QString::number(node->version->minorVersion); + result += " " + QString::number(node->version->version.majorVersion()) + "." + + QString::number(node->version->version.minorVersion()); } if (node->asToken.isValid()) { diff --git a/tools/qmlformat/restructureastvisitor.cpp b/tools/qmlformat/restructureastvisitor.cpp index f9ac2a20c2..7cce0e8034 100644 --- a/tools/qmlformat/restructureastvisitor.cpp +++ b/tools/qmlformat/restructureastvisitor.cpp @@ -110,6 +110,11 @@ void RestructureAstVisitor::endVisit(UiObjectMemberList *node) { QList<UiObjectMember*> correctOrder; + QList<UiScriptBinding*> largeScriptBinding; + + UiObjectMember *states = nullptr; + UiObjectMember *transitions = nullptr; + auto enumDeclarations = findKind<UiEnumDeclaration>(node); auto scriptBindings = findKind<UiScriptBinding>(node); auto arrayBindings = findKind<UiArrayBinding>(node); @@ -117,11 +122,47 @@ void RestructureAstVisitor::endVisit(UiObjectMemberList *node) auto sourceElements = findKind<UiSourceElement>(node); auto objectDefinitions = findKind<UiObjectDefinition>(node); + // Look for transitions and states + for (auto *binding : findKind<UiObjectBinding>(node)) { + const QString name = parseUiQualifiedId(binding->qualifiedId); + + if (name == "transitions") + transitions = binding; + else if (name == "states") + states = binding; + } + + for (auto it = arrayBindings.begin(); it != arrayBindings.end();) { + const QString name = parseUiQualifiedId((*it)->qualifiedId); + + if (name == "transitions") { + transitions = *it; + it = arrayBindings.erase(it); + } else if (name == "states") { + states = *it; + it = arrayBindings.erase(it); + } else { + it++; + } + } + + // Find large script bindings + for (auto it = scriptBindings.begin(); it != scriptBindings.end();) { + // A binding is considered large if it uses a block + if ((*it)->statement->kind != Node::Kind_Block) { + it++; + continue; + } + + largeScriptBinding.push_back(*it); + it = scriptBindings.erase(it); + } + // This structure is based on https://doc.qt.io/qt-5/qml-codingconventions.html // 1st id for (auto *binding : scriptBindings) { - if (binding->qualifiedId->name == "id") { + if (parseUiQualifiedId(binding->qualifiedId) == "id") { correctOrder.append(binding); scriptBindings.removeOne(binding); @@ -154,9 +195,14 @@ void RestructureAstVisitor::endVisit(UiObjectMemberList *node) correctOrder.append(source); // 6th properties + // small script bindings... for (auto *binding : scriptBindings) correctOrder.append(binding); + // ...then large ones + for (auto *binding : largeScriptBinding) + correctOrder.append(binding); + for (auto *binding : arrayBindings) correctOrder.append(binding); @@ -170,6 +216,13 @@ void RestructureAstVisitor::endVisit(UiObjectMemberList *node) correctOrder.append(item->member); } + // 9th states and transitions + if (states != nullptr) + correctOrder.append(states); + + if (transitions != nullptr) + correctOrder.append(transitions); + // Rebuild member list from correctOrder for (auto *item = node; item != nullptr; item = item->next) { item->member = correctOrder.front(); diff --git a/tools/qmlimportscanner/main.cpp b/tools/qmlimportscanner/main.cpp index b563d7df95..1059f12b54 100644 --- a/tools/qmlimportscanner/main.cpp +++ b/tools/qmlimportscanner/main.cpp @@ -123,7 +123,11 @@ QVariantList findImportsInAst(QQmlJS::AST::UiHeaderItemList *headerItemList, con if (!name.isEmpty()) import[nameLiteral()] = name; import[typeLiteral()] = moduleLiteral(); - auto versionString = importNode->version ? QString::number(importNode->version->majorVersion) + QLatin1Char('.') + QString::number(importNode->version->minorVersion) : QString(); + auto versionString = importNode->version + ? QString::number(importNode->version->version.majorVersion()) + + QLatin1Char('.') + + QString::number(importNode->version->version.minorVersion()) + : QString(); import[versionLiteral()] = versionString; } diff --git a/tools/qmllint/componentversion.cpp b/tools/qmllint/componentversion.cpp index e5047b8302..95403ec15f 100644 --- a/tools/qmllint/componentversion.cpp +++ b/tools/qmllint/componentversion.cpp @@ -41,21 +41,21 @@ ComponentVersion::ComponentVersion(const QString &versionString) const int maybeMinor = versionString.midRef(dotIdx + 1).toInt(&ok); if (!ok) return; - m_major = maybeMajor; - m_minor = maybeMinor; + m_version = QTypeRevision::fromVersion(maybeMajor, maybeMinor); } bool operator<(const ComponentVersion &lhs, const ComponentVersion &rhs) { - return lhs.majorVersion() < rhs.majorVersion() - || (lhs.majorVersion() == rhs.majorVersion() && lhs.minorVersion() < rhs.minorVersion()); + return lhs.version().majorVersion() < rhs.version().majorVersion() + || (lhs.version().majorVersion() == rhs.version().majorVersion() + && lhs.version().minorVersion() < rhs.version().minorVersion()); } bool operator<=(const ComponentVersion &lhs, const ComponentVersion &rhs) { - return lhs.majorVersion() < rhs.majorVersion() - || (lhs.majorVersion() == rhs.majorVersion() - && lhs.minorVersion() <= rhs.minorVersion()); + return lhs.version().majorVersion() < rhs.version().majorVersion() + || (lhs.version().majorVersion() == rhs.version().majorVersion() + && lhs.version().minorVersion() <= rhs.version().minorVersion()); } bool operator>(const ComponentVersion &lhs, const ComponentVersion &rhs) @@ -70,8 +70,8 @@ bool operator>=(const ComponentVersion &lhs, const ComponentVersion &rhs) bool operator==(const ComponentVersion &lhs, const ComponentVersion &rhs) { - return lhs.majorVersion() == rhs.majorVersion() - && lhs.minorVersion() == rhs.minorVersion(); + return lhs.version().majorVersion() == rhs.version().majorVersion() + && lhs.version().minorVersion() == rhs.version().minorVersion(); } bool operator!=(const ComponentVersion &lhs, const ComponentVersion &rhs) diff --git a/tools/qmllint/componentversion.h b/tools/qmllint/componentversion.h index 9c4604b9a3..bbb039fc40 100644 --- a/tools/qmllint/componentversion.h +++ b/tools/qmllint/componentversion.h @@ -40,24 +40,20 @@ // We mean it. #include <QtCore/qglobal.h> +#include <QtCore/qversionnumber.h> class ComponentVersion { public: - static const int NoVersion = -1; - ComponentVersion() = default; - ComponentVersion(int major, int minor) : m_major(major), m_minor(minor) {} + ComponentVersion(QTypeRevision version) : m_version(version) {} explicit ComponentVersion(const QString &versionString); - int majorVersion() const { return m_major; } - int minorVersion() const { return m_minor; } - - bool isValid() const { return m_major >= 0 && m_minor >= 0; } + QTypeRevision version() const { return m_version; } + bool isValid() const { return m_version.hasMajorVersion() && m_version.hasMinorVersion(); } private: - int m_major = NoVersion; - int m_minor = NoVersion; + QTypeRevision m_version; }; bool operator<(const ComponentVersion &lhs, const ComponentVersion &rhs); diff --git a/tools/qmllint/findunqualified.cpp b/tools/qmllint/findunqualified.cpp index 88466cfae9..187471125a 100644 --- a/tools/qmllint/findunqualified.cpp +++ b/tools/qmllint/findunqualified.cpp @@ -92,8 +92,7 @@ void FindUnqualifiedIDVisitor::parseHeaders(QQmlJS::AST::UiHeaderItemList *heade if (import->asToken.isValid()) { prefix += import->importId + QLatin1Char('.'); } - importHelper(path, prefix, import->version->majorVersion, - import->version->minorVersion); + importHelper(path, prefix, import->version->version); } } header = header->next; @@ -119,7 +118,7 @@ ScopeTree *FindUnqualifiedIDVisitor::parseProgram(QQmlJS::AST::Program *program, enum ImportVersion { FullyVersioned, PartiallyVersioned, Unversioned, BasePath }; -QStringList completeImportPaths(const QString &uri, const QString &basePath, int vmaj, int vmin) +QStringList completeImportPaths(const QString &uri, const QString &basePath, QTypeRevision version) { static const QLatin1Char Slash('/'); static const QLatin1Char Backslash('\\'); @@ -130,15 +129,16 @@ QStringList completeImportPaths(const QString &uri, const QString &basePath, int // fully & partially versioned parts + 1 unversioned for each base path qmlDirPathsPaths.reserve(2 * parts.count() + 1); - auto versionString = [](int vmaj, int vmin, ImportVersion version) + auto versionString = [](QTypeRevision version, ImportVersion mode) { - if (version == FullyVersioned) { + if (mode == FullyVersioned) { // extension with fully encoded version number (eg. MyModule.3.2) - return QString::fromLatin1(".%1.%2").arg(vmaj).arg(vmin); + return QString::fromLatin1(".%1.%2").arg(version.majorVersion()) + .arg(version.minorVersion()); } - if (version == PartiallyVersioned) { + if (mode == PartiallyVersioned) { // extension with encoded version major (eg. MyModule.3) - return QString::fromLatin1(".%1").arg(vmaj); + return QString::fromLatin1(".%1").arg(version.majorVersion()); } // else extension without version number (eg. MyModule) return QString(); @@ -153,24 +153,24 @@ QStringList completeImportPaths(const QString &uri, const QString &basePath, int return str; }; - const ImportVersion initial = (vmin >= 0) + const ImportVersion initial = (version.hasMinorVersion()) ? FullyVersioned - : (vmaj >= 0 ? PartiallyVersioned : Unversioned); - for (int version = initial; version <= BasePath; ++version) { - const QString ver = versionString(vmaj, vmin, static_cast<ImportVersion>(version)); + : (version.hasMajorVersion() ? PartiallyVersioned : Unversioned); + for (int mode = initial; mode <= BasePath; ++mode) { + const QString ver = versionString(version, ImportVersion(mode)); QString dir = basePath; if (!dir.endsWith(Slash) && !dir.endsWith(Backslash)) dir += Slash; - if (version == BasePath) { + if (mode == BasePath) { qmlDirPathsPaths += dir; } else { // append to the end qmlDirPathsPaths += dir + joinStringRefs(parts, Slash) + ver; } - if (version < Unversioned) { + if (mode < Unversioned) { // insert in the middle for (int index = parts.count() - 2; index >= 0; --index) { qmlDirPathsPaths += dir + joinStringRefs(parts.mid(0, index + 1), Slash) @@ -222,7 +222,7 @@ FindUnqualifiedIDVisitor::Import FindUnqualifiedIDVisitor::readQmldir(const QStr (*mo)->addExport( it.key(), reader.typeNamespace(), - ComponentVersion(it->majorVersion, it->minorVersion)); + ComponentVersion(it->version)); } for (auto it = qmlComponents.begin(), end = qmlComponents.end(); it != end; ++it) result.objects.insert( it.key(), ScopeTree::ConstPtr(it.value())); @@ -240,11 +240,11 @@ void FindUnqualifiedIDVisitor::processImport(const QString &prefix, const FindUn auto const &id = split.at(0); if (split.length() > 1) { const auto version = split.at(1).split('.'); - importHelper(id, QString(), - version.at(0).toInt(), - version.length() > 1 ? version.at(1).toInt() : -1); + importHelper(id, QString(), QTypeRevision::fromVersion( + version.at(0).toInt(), + version.length() > 1 ? version.at(1).toInt() : -1)); } else { - importHelper(id, QString(), -1, -1); + importHelper(id, QString(), QTypeRevision()); } @@ -267,7 +267,7 @@ void FindUnqualifiedIDVisitor::processImport(const QString &prefix, const FindUn } void FindUnqualifiedIDVisitor::importHelper(const QString &module, const QString &prefix, - int major, int minor) + QTypeRevision version) { const QString id = QString(module).replace(QLatin1Char('/'), QLatin1Char('.')); QPair<QString, QString> importId { id, prefix }; @@ -276,7 +276,7 @@ void FindUnqualifiedIDVisitor::importHelper(const QString &module, const QString m_alreadySeenImports.insert(importId); for (const QString &qmltypeDir : m_qmltypeDirs) { - auto qmltypesPaths = completeImportPaths(id, qmltypeDir, major, minor); + auto qmltypesPaths = completeImportPaths(id, qmltypeDir, version); for (auto const &qmltypesPath : qmltypesPaths) { if (QFile::exists(qmltypesPath + SlashQmldir)) { @@ -540,12 +540,12 @@ void FindUnqualifiedIDVisitor::endVisit(QQmlJS::AST::WithStatement *) leaveEnvironment(); } -static QString signalName(const QStringRef &handlerName) +static QString signalName(QStringView handlerName) { - if (handlerName.startsWith("on") && handlerName.size() > 2) { + if (handlerName.startsWith(u"on") && handlerName.size() > 2) { QString signal = handlerName.mid(2).toString(); for (int i = 0; i < signal.length(); ++i) { - QCharRef ch = signal[i]; + QChar &ch = signal[i]; if (ch.isLower()) return QString(); if (ch.isUpper()) { @@ -764,7 +764,7 @@ bool FindUnqualifiedIDVisitor::visit(QQmlJS::AST::UiImport *import) } path.chop(1); - importHelper(path, prefix, import->version->majorVersion, import->version->minorVersion); + importHelper(path, prefix, import->version->version); } return true; } diff --git a/tools/qmllint/findunqualified.h b/tools/qmllint/findunqualified.h index 6668b53b08..1c351e4fd9 100644 --- a/tools/qmllint/findunqualified.h +++ b/tools/qmllint/findunqualified.h @@ -91,7 +91,7 @@ private: void enterEnvironment(ScopeType type, const QString &name); void leaveEnvironment(); void importHelper(const QString &module, const QString &prefix = QString(), - int major = -1, int minor = -1); + QTypeRevision version = QTypeRevision()); void readQmltypes(const QString &filename, Import &result); Import readQmldir(const QString &dirname); diff --git a/tools/qmllint/typedescriptionreader.cpp b/tools/qmllint/typedescriptionreader.cpp index 3dc87ffc8d..8734f349d5 100644 --- a/tools/qmllint/typedescriptionreader.cpp +++ b/tools/qmllint/typedescriptionreader.cpp @@ -102,7 +102,7 @@ void TypeDescriptionReader::readDocument(UiProgram *ast) return; } - if (import->version->majorVersion != 1) { + if (import->version->version.majorVersion() != 1) { addError(import->version->firstSourceLocation(), tr("Major version different from 1 not supported.")); return; diff --git a/tools/qmlmin/main.cpp b/tools/qmlmin/main.cpp deleted file mode 100644 index 3c9b3c7251..0000000000 --- a/tools/qmlmin/main.cpp +++ /dev/null @@ -1,700 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <private/qqmljsengine_p.h> -#include <private/qqmljslexer_p.h> -#include <private/qqmljsparser_p.h> -#include <QtCore/QCoreApplication> -#include <QtCore/QStringList> -#include <QtCore/QFile> -#include <QtCore/QFileInfo> -#include <QtCore/QDir> -#include <iostream> -#include <cstdlib> - -QT_BEGIN_NAMESPACE - -// -// QML/JS minifier -// -namespace QQmlJS { - -enum RegExpFlag { - Global = 0x01, - IgnoreCase = 0x02, - Multiline = 0x04 -}; - - -class QmlminLexer: protected Lexer, public Directives -{ - QQmlJS::Engine _engine; - QString _fileName; - QString _directives; - -protected: - QVector<int> _stateStack; - QList<int> _tokens; - QList<QString> _tokenStrings; - int yytoken = -1; - QString yytokentext; - - void lex() { - if (_tokens.isEmpty()) { - _tokens.append(Lexer::lex()); - _tokenStrings.append(tokenText()); - } - - yytoken = _tokens.takeFirst(); - yytokentext = _tokenStrings.takeFirst(); - } - - int lookaheadToken() - { - if (yytoken < 0) - lex(); - return yytoken; - } - - void pushToken(int token) - { - _tokens.prepend(yytoken); - _tokenStrings.prepend(yytokentext); - yytoken = token; - yytokentext = QString(); - } - -public: - QmlminLexer() - : Lexer(&_engine), _stateStack(128) {} - virtual ~QmlminLexer() {} - - QString fileName() const { return _fileName; } - - bool operator()(const QString &fileName, const QString &code) - { - int startToken = T_FEED_JS_SCRIPT; - const QFileInfo fileInfo(fileName); - if (fileInfo.suffix().toLower() == QLatin1String("qml")) - startToken = T_FEED_UI_PROGRAM; - setCode(code, /*line = */ 1, /*qmlMode = */ startToken == T_FEED_UI_PROGRAM); - _fileName = fileName; - _directives.clear(); - return parse(startToken); - } - - QString directives() - { - return _directives; - } - - // - // Handle the .pragma/.import directives - // - void pragmaLibrary() override - { - _directives += QLatin1String(".pragma library\n"); - } - - void importFile(const QString &jsfile, const QString &module, int line, int column) override - { - _directives += QLatin1String(".import"); - _directives += QLatin1Char('"'); - _directives += quote(jsfile); - _directives += QLatin1Char('"'); - _directives += QLatin1String("as "); - _directives += module; - _directives += QLatin1Char('\n'); - Q_UNUSED(line); - Q_UNUSED(column); - } - - void importModule(const QString &uri, const QString &version, const QString &module, int line, int column) override - { - _directives += QLatin1String(".import "); - _directives += uri; - _directives += QLatin1Char(' '); - _directives += version; - _directives += QLatin1String(" as "); - _directives += module; - _directives += QLatin1Char('\n'); - Q_UNUSED(line); - Q_UNUSED(column); - } - -protected: - virtual bool parse(int startToken) = 0; - - static QString quote(const QString &string) - { - QString quotedString; - for (const QChar &ch : string) { - if (ch == QLatin1Char('"')) - quotedString += QLatin1String("\\\""); - else { - if (ch == QLatin1Char('\\')) quotedString += QLatin1String("\\\\"); - else if (ch == QLatin1Char('\"')) quotedString += QLatin1String("\\\""); - else if (ch == QLatin1Char('\b')) quotedString += QLatin1String("\\b"); - else if (ch == QLatin1Char('\f')) quotedString += QLatin1String("\\f"); - else if (ch == QLatin1Char('\n')) quotedString += QLatin1String("\\n"); - else if (ch == QLatin1Char('\r')) quotedString += QLatin1String("\\r"); - else if (ch == QLatin1Char('\t')) quotedString += QLatin1String("\\t"); - else if (ch == QLatin1Char('\v')) quotedString += QLatin1String("\\v"); - else if (ch == QLatin1Char('\0')) quotedString += QLatin1String("\\0"); - else quotedString += ch; - } - } - return quotedString; - } - - bool isIdentChar(const QChar &ch) const - { - if (ch.isLetterOrNumber()) - return true; - else if (ch == QLatin1Char('_') || ch == QLatin1Char('$')) - return true; - return false; - } - - bool isRegExpRule(int ruleno) const - { - return ruleno == J_SCRIPT_REGEXPLITERAL_RULE1 || - ruleno == J_SCRIPT_REGEXPLITERAL_RULE2; - } - - void handleLookaheads(int ruleno) { - if (ruleno == J_SCRIPT_EXPRESSIONSTATEMENTLOOKAHEAD_RULE) { - int token = lookaheadToken(); - if (token == T_LBRACE) - pushToken(T_FORCE_BLOCK); - else if (token == T_FUNCTION || token == T_CLASS || token == T_LET || token == T_CONST) - pushToken(T_FORCE_DECLARATION); - } else if (ruleno == J_SCRIPT_CONCISEBODYLOOKAHEAD_RULE) { - int token = lookaheadToken(); - if (token == T_LBRACE) - pushToken(T_FORCE_BLOCK); - } else if (ruleno == J_SCRIPT_EXPORTDECLARATIONLOOKAHEAD_RULE) { - int token = lookaheadToken(); - if (token == T_FUNCTION || token == T_CLASS) - pushToken(T_FORCE_DECLARATION); - } - } - - bool scanRestOfRegExp(int ruleno, QString *restOfRegExp) - { - if (! scanRegExp(ruleno == J_SCRIPT_REGEXPLITERAL_RULE1 ? Lexer::NoPrefix : Lexer::EqualPrefix)) - return false; - - *restOfRegExp = regExpPattern(); - if (ruleno == J_SCRIPT_REGEXPLITERAL_RULE2) { - Q_ASSERT(! restOfRegExp->isEmpty()); - Q_ASSERT(restOfRegExp->at(0) == QLatin1Char('=')); - *restOfRegExp = restOfRegExp->mid(1); // strip the prefix - } - *restOfRegExp += QLatin1Char('/'); - const RegExpFlag flags = (RegExpFlag) regExpFlags(); - if (flags & Global) - *restOfRegExp += QLatin1Char('g'); - if (flags & IgnoreCase) - *restOfRegExp += QLatin1Char('i'); - if (flags & Multiline) - *restOfRegExp += QLatin1Char('m'); - - if (regExpFlags() == 0) { - // Add an extra space after the regexp literal delimiter (aka '/'). - // This will avoid possible problems when pasting tokens like `instanceof' - // after the regexp literal. - *restOfRegExp += QLatin1Char(' '); - } - return true; - } -}; - - -class Minify: public QmlminLexer -{ - QString _minifiedCode; - int _maxWidth; - int _width; - -public: - Minify(int maxWidth); - - QString minifiedCode() const; - -protected: - void append(const QString &s); - bool parse(int startToken) override; - void escape(const QChar &ch, QString *out); -}; - -Minify::Minify(int maxWidth) - : _maxWidth(maxWidth), _width(0) -{ -} - -QString Minify::minifiedCode() const -{ - return _minifiedCode; -} - -void Minify::append(const QString &s) -{ - if (!s.isEmpty()) { - if (_maxWidth) { - // Prefer not to exceed the maximum chars per line (but don't break up segments) - int segmentLength = s.count(); - if (_width && ((_width + segmentLength) > _maxWidth)) { - _minifiedCode.append(QLatin1Char('\n')); - _width = 0; - } - - _width += segmentLength; - } - - _minifiedCode.append(s); - } -} - -void Minify::escape(const QChar &ch, QString *out) -{ - out->append(QLatin1String("\\u")); - const QString hx = QString::number(ch.unicode(), 16); - switch (hx.length()) { - case 1: out->append(QLatin1String("000")); break; - case 2: out->append(QLatin1String("00")); break; - case 3: out->append(QLatin1Char('0')); break; - case 4: break; - default: Q_ASSERT(!"unreachable"); - } - out->append(hx); -} - -bool Minify::parse(int startToken) -{ - int yyaction = 0; - int yytos = -1; - QString assembled; - - _minifiedCode.clear(); - _tokens.append(startToken); - _tokenStrings.append(QString()); - - if (startToken == T_FEED_JS_SCRIPT) { - // parse optional pragma directive - DiagnosticMessage error; - if (scanDirectives(this, &error)) { - // append the scanned directives to the minifier code. - append(directives()); - - _tokens.append(tokenKind()); - _tokenStrings.append(tokenText()); - } else { - std::cerr << qPrintable(fileName()) << ':' << tokenStartLine() << ':' - << tokenStartColumn() << ": syntax error" << std::endl; - return false; - } - } - - do { - if (++yytos == _stateStack.size()) - _stateStack.resize(_stateStack.size() * 2); - - _stateStack[yytos] = yyaction; - - again: - if (yytoken == -1 && action_index[yyaction] != -TERMINAL_COUNT) - lex(); - - yyaction = t_action(yyaction, yytoken); - if (yyaction > 0) { - if (yyaction == ACCEPT_STATE) { - --yytos; - if (!assembled.isEmpty()) - append(assembled); - return true; - } - - const QChar lastChar = assembled.isEmpty() ? (_minifiedCode.isEmpty() ? QChar() - : _minifiedCode.at(_minifiedCode.length() - 1)) - : assembled.at(assembled.length() - 1); - - if (yytoken == T_SEMICOLON) { - assembled += QLatin1Char(';'); - - append(assembled); - assembled.clear(); - - } else if (yytoken == T_PLUS || yytoken == T_MINUS || yytoken == T_PLUS_PLUS || yytoken == T_MINUS_MINUS) { - if (lastChar == QLatin1Char(spell[yytoken][0])) { - // don't merge unary signs, additive expressions and postfix/prefix increments. - assembled += QLatin1Char(' '); - } - - assembled += QLatin1String(spell[yytoken]); - - } else if (yytoken == T_NUMERIC_LITERAL) { - if (isIdentChar(lastChar)) - assembled += QLatin1Char(' '); - - if (yytokentext.startsWith('.')) - assembled += QLatin1Char('0'); - - assembled += yytokentext; - - if (assembled.endsWith(QLatin1Char('.'))) - assembled += QLatin1Char('0'); - - } else if (yytoken == T_IDENTIFIER) { - QString identifier = yytokentext; - - if (classify(identifier.constData(), identifier.size(), qmlMode()) != T_IDENTIFIER) { - // the unescaped identifier is a keyword. In this case just replace - // the last character of the identifier with it escape sequence. - const QChar ch = identifier.at(identifier.length() - 1); - identifier.chop(1); - escape(ch, &identifier); - } - - if (isIdentChar(lastChar)) - assembled += QLatin1Char(' '); - - assembled += identifier; - - } else if (yytoken == T_STRING_LITERAL || yytoken == T_MULTILINE_STRING_LITERAL) { - assembled += QLatin1Char('"'); - assembled += quote(yytokentext); - assembled += QLatin1Char('"'); - } else { - if (isIdentChar(lastChar)) { - if (! yytokentext.isEmpty()) { - const QChar ch = yytokentext.at(0); - if (isIdentChar(ch)) - assembled += QLatin1Char(' '); - } - } - assembled += yytokentext; - } - yytoken = -1; - } else if (yyaction < 0) { - const int ruleno = -yyaction - 1; - yytos -= rhs[ruleno]; - - handleLookaheads(ruleno); - - if (isRegExpRule(ruleno)) { - QString restOfRegExp; - - if (! scanRestOfRegExp(ruleno, &restOfRegExp)) - break; // break the loop, it wil report a syntax error - - assembled += restOfRegExp; - } - yyaction = nt_action(_stateStack[yytos], lhs[ruleno] - TERMINAL_COUNT); - } - } while (yyaction); - - const int yyerrorstate = _stateStack[yytos]; - - // automatic insertion of `;' - if (yytoken != -1 && ((t_action(yyerrorstate, T_AUTOMATIC_SEMICOLON) && canInsertAutomaticSemicolon(yytoken)) - || t_action(yyerrorstate, T_COMPATIBILITY_SEMICOLON))) { - _tokens.prepend(yytoken); - _tokenStrings.prepend(yytokentext); - yyaction = yyerrorstate; - yytoken = T_SEMICOLON; - goto again; - } - - std::cerr << qPrintable(fileName()) << ':' << tokenStartLine() << ':' << tokenStartColumn() - << ": syntax error" << std::endl; - return false; -} - - -class Tokenize: public QmlminLexer -{ - QStringList _minifiedCode; - -public: - Tokenize() {} - - QStringList tokenStream() const; - -protected: - bool parse(int startToken) override; -}; - -QStringList Tokenize::tokenStream() const -{ - return _minifiedCode; -} - -bool Tokenize::parse(int startToken) -{ - int yyaction = 0; - int yytos = -1; - - _minifiedCode.clear(); - _tokens.append(startToken); - _tokenStrings.append(QString()); - - if (startToken == T_FEED_JS_SCRIPT) { - // parse optional pragma directive - DiagnosticMessage error; - if (scanDirectives(this, &error)) { - // append the scanned directives as one token to - // the token stream. - _minifiedCode.append(directives()); - - _tokens.append(tokenKind()); - _tokenStrings.append(tokenText()); - } else { - std::cerr << qPrintable(fileName()) << ':' << tokenStartLine() << ':' - << tokenStartColumn() << ": syntax error" << std::endl; - return false; - } - } - - do { - if (++yytos == _stateStack.size()) - _stateStack.resize(_stateStack.size() * 2); - - _stateStack[yytos] = yyaction; - - again: - if (yytoken == -1 && action_index[yyaction] != -TERMINAL_COUNT) - lex(); - - yyaction = t_action(yyaction, yytoken); - if (yyaction > 0) { - if (yyaction == ACCEPT_STATE) { - --yytos; - return true; - } - - if (yytoken == T_SEMICOLON) - _minifiedCode += QLatin1String(";"); - else - _minifiedCode += yytokentext; - - yytoken = -1; - } else if (yyaction < 0) { - const int ruleno = -yyaction - 1; - yytos -= rhs[ruleno]; - - handleLookaheads(ruleno); - - if (isRegExpRule(ruleno)) { - QString restOfRegExp; - - if (! scanRestOfRegExp(ruleno, &restOfRegExp)) - break; // break the loop, it wil report a syntax error - - _minifiedCode.last().append(restOfRegExp); - } - - yyaction = nt_action(_stateStack[yytos], lhs[ruleno] - TERMINAL_COUNT); - } - } while (yyaction); - - const int yyerrorstate = _stateStack[yytos]; - - // automatic insertion of `;' - if (yytoken != -1 && ((t_action(yyerrorstate, T_AUTOMATIC_SEMICOLON) && canInsertAutomaticSemicolon(yytoken)) - || t_action(yyerrorstate, T_COMPATIBILITY_SEMICOLON))) { - _tokens.prepend(yytoken); - _tokenStrings.prepend(yytokentext); - yyaction = yyerrorstate; - yytoken = T_SEMICOLON; - goto again; - } - - std::cerr << qPrintable(fileName()) << ':' << tokenStartLine() << ':' - << tokenStartColumn() << ": syntax error" << std::endl; - return false; -} - -} // end of QQmlJS namespace - -static void usage(bool showHelp = false) -{ - std::cerr << "Usage: qmlmin [options] file" << std::endl; - - if (showHelp) { - std::cerr << " Removes comments and layout characters" << std::endl - << " The options are:" << std::endl - << " -o<file> write output to file rather than stdout" << std::endl - << " -v --verify-only just run the verifier, no output" << std::endl - << " -w<width> restrict line characters to width" << std::endl - << " -h display this output" << std::endl; - } -} - -int runQmlmin(int argc, char *argv[]) -{ - QCoreApplication app(argc, argv); - QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR)); - - const QStringList args = app.arguments(); - - QString fileName; - QString outputFile; - bool verifyOnly = false; - - // By default ensure the output character width is less than 16-bits (pass 0 to disable) - int width = USHRT_MAX; - - int index = 1; - while (index < args.size()) { - const QString arg = args.at(index++); - const QString next = index < args.size() ? args.at(index) : QString(); - - if (arg == QLatin1String("-h") || arg == QLatin1String("--help")) { - usage(/*showHelp*/ true); - return 0; - } else if (arg == QLatin1String("-v") || arg == QLatin1String("--verify-only")) { - verifyOnly = true; - } else if (arg == QLatin1String("-o")) { - if (next.isEmpty()) { - std::cerr << "qmlmin: argument to '-o' is missing" << std::endl; - return EXIT_FAILURE; - } else { - outputFile = next; - ++index; // consume the next argument - } - } else if (arg.startsWith(QLatin1String("-o"))) { - outputFile = arg.mid(2); - - if (outputFile.isEmpty()) { - std::cerr << "qmlmin: argument to '-o' is missing" << std::endl; - return EXIT_FAILURE; - } - } else if (arg == QLatin1String("-w")) { - if (next.isEmpty()) { - std::cerr << "qmlmin: argument to '-w' is missing" << std::endl; - return EXIT_FAILURE; - } else { - bool ok; - width = next.toInt(&ok); - - if (!ok) { - std::cerr << "qmlmin: argument to '-w' is invalid" << std::endl; - return EXIT_FAILURE; - } - - ++index; // consume the next argument - } - } else if (arg.startsWith(QLatin1String("-w"))) { - bool ok; - width = arg.midRef(2).toInt(&ok); - - if (!ok) { - std::cerr << "qmlmin: argument to '-w' is invalid" << std::endl; - return EXIT_FAILURE; - } - } else { - const bool isInvalidOpt = arg.startsWith(QLatin1Char('-')); - if (! isInvalidOpt && fileName.isEmpty()) - fileName = arg; - else { - usage(/*show help*/ isInvalidOpt); - if (isInvalidOpt) - std::cerr << "qmlmin: invalid option '" << qPrintable(arg) << '\'' << std::endl; - else - std::cerr << "qmlmin: too many input files specified" << std::endl; - return EXIT_FAILURE; - } - } - } - - if (fileName.isEmpty()) { - usage(); - return 0; - } - - std::cerr << "qmlmin: This tool is deprecated and will be removed in Qt 6. It is not needed anymore due to QtQml's built-in caching." << std::endl; - - QFile file(fileName); - if (! file.open(QFile::ReadOnly)) { - std::cerr << "qmlmin: '" << qPrintable(fileName) << "' no such file or directory" << std::endl; - return EXIT_FAILURE; - } - - const QString code = QString::fromUtf8(file.readAll()); // QML files are UTF-8 encoded. - file.close(); - - QQmlJS::Minify minify(width); - if (! minify(fileName, code)) { - std::cerr << "qmlmin: cannot minify '" << qPrintable(fileName) << "' (not a valid QML/JS file)" << std::endl; - return EXIT_FAILURE; - } - - // - // verify the output - // - QQmlJS::Minify secondMinify(width); - if (! secondMinify(fileName, minify.minifiedCode()) || secondMinify.minifiedCode() != minify.minifiedCode()) { - std::cerr << "qmlmin: cannot minify '" << qPrintable(fileName) << '\'' << std::endl; - return EXIT_FAILURE; - } - - QQmlJS::Tokenize originalTokens, minimizedTokens; - originalTokens(fileName, code); - minimizedTokens(fileName, minify.minifiedCode()); - - if (originalTokens.tokenStream().size() != minimizedTokens.tokenStream().size()) { - std::cerr << "qmlmin: cannot minify '" << qPrintable(fileName) << '\'' << std::endl; - return EXIT_FAILURE; - } - - if (! verifyOnly) { - if (outputFile.isEmpty()) { - const QByteArray chars = minify.minifiedCode().toUtf8(); - std::cout << chars.constData(); - } else { - QFile file(outputFile); - if (! file.open(QFile::WriteOnly)) { - std::cerr << "qmlmin: cannot minify '" << qPrintable(fileName) << "' (permission denied)" << std::endl; - return EXIT_FAILURE; - } - - file.write(minify.minifiedCode().toUtf8()); - file.close(); - } - } - - return 0; -} - -QT_END_NAMESPACE - -int main(int argc, char **argv) -{ - return QT_PREPEND_NAMESPACE(runQmlmin(argc, argv)); -} diff --git a/tools/qmlmin/qmlmin.pro b/tools/qmlmin/qmlmin.pro deleted file mode 100644 index 32d9e3343b..0000000000 --- a/tools/qmlmin/qmlmin.pro +++ /dev/null @@ -1,7 +0,0 @@ -option(host_build) -QT = core qmldevtools-private -SOURCES += main.cpp - -QMAKE_TARGET_DESCRIPTION = QML/JS Minifier - -load(qt_tool) diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp index 1556718471..3efa4dc605 100644 --- a/tools/qmlplugindump/main.cpp +++ b/tools/qmlplugindump/main.cpp @@ -103,15 +103,15 @@ static QString enquote(const QString &string) struct QmlVersionInfo { QString pluginImportUri; - int majorVersion; - int minorVersion; + QTypeRevision version; bool strict; }; static bool matchingImportUri(const QQmlType &ty, const QmlVersionInfo& versionInfo) { if (versionInfo.strict) { return (versionInfo.pluginImportUri == ty.module() - && (ty.majorVersion() == versionInfo.majorVersion || ty.majorVersion() == -1)) + && (ty.version().majorVersion() == versionInfo.version.majorVersion() + || !ty.version().hasMajorVersion())) || ty.module().isEmpty(); } return ty.module().isEmpty() @@ -179,15 +179,6 @@ void collectReachableMetaObjects(QQmlEnginePrivate *engine, const QQmlType &ty, } } -/* We want to add the MetaObject for 'Qt' to the list, this is a - simple way to access it. -*/ -class FriendlyQObject: public QObject -{ -public: - static const QMetaObject *qtMeta() { return &staticQtMetaObject; } -}; - /* When we dump a QMetaObject, we want to list all the types it is exported as. To do this, we need to find the QQmlTypes associated with this QMetaObject. @@ -258,7 +249,7 @@ QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine, ) { QSet<const QMetaObject *> metas; - metas.insert(FriendlyQObject::qtMeta()); + metas.insert(&Qt::staticMetaObject); const auto qmlTypes = QQmlMetaType::qmlTypes(); for (const QQmlType &ty : qmlTypes) { @@ -344,23 +335,23 @@ QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine, } class KnownAttributes { - QHash<QByteArray, int> m_properties; - QHash<QByteArray, QHash<int, int> > m_methods; + QHash<QByteArray, QTypeRevision> m_properties; + QHash<QByteArray, QHash<int, QTypeRevision> > m_methods; public: - bool knownMethod(const QByteArray &name, int nArgs, int revision) + bool knownMethod(const QByteArray &name, int nArgs, QTypeRevision revision) { if (m_methods.contains(name)) { - QHash<int, int> overloads = m_methods.value(name); - if (overloads.contains(nArgs) && overloads.value(nArgs) <= revision) + QHash<int, QTypeRevision> overloads = m_methods.value(name); + if (overloads.contains(nArgs) && overloads.value(nArgs).toEncodedVersion<quint16>() <= revision.toEncodedVersion<quint16>()) return true; } m_methods[name][nArgs] = revision; return false; } - bool knownProperty(const QByteArray &name, int revision) + bool knownProperty(const QByteArray &name, QTypeRevision revision) { - if (m_properties.contains(name) && m_properties.value(name) <= revision) + if (m_properties.contains(name) && m_properties.value(name).toEncodedVersion<quint16>() <= revision.toEncodedVersion<quint16>()) return true; m_properties[name] = revision; return false; @@ -384,13 +375,14 @@ public: { const QString module = type.module().isEmpty() ? versionInfo.pluginImportUri : type.module(); - const int majorVersion = type.majorVersion() >= 0 ? type.majorVersion() - : versionInfo.majorVersion; - const int minorVersion = type.minorVersion() >= 0 ? type.minorVersion() - : versionInfo.minorVersion; + QTypeRevision version = QTypeRevision::fromVersion( + type.version().hasMajorVersion() ? type.version().majorVersion() + : versionInfo.version.majorVersion(), + type.version().hasMinorVersion() ? type.version().minorVersion() + : versionInfo.version.minorVersion()); const QString versionedElement = type.elementName() - + QString::fromLatin1(" %1.%2").arg(majorVersion).arg(minorVersion); + + QString::fromLatin1(" %1.%2").arg(version.majorVersion()).arg(version.minorVersion()); return enquote((module == relocatableModuleUri) ? versionedElement @@ -399,7 +391,7 @@ public: void writeMetaContent(const QMetaObject *meta, KnownAttributes *knownAttributes = nullptr) { - QSet<QString> implicitSignals = dumpMetaProperties(meta, 0, knownAttributes); + QSet<QString> implicitSignals = dumpMetaProperties(meta, QTypeRevision::zero(), knownAttributes); if (meta == &QObject::staticMetaObject) { // for QObject, hide deleteLater() and onDestroyed @@ -414,17 +406,17 @@ public: } // and add toString(), destroy() and destroy(int) - if (!knownAttributes || !knownAttributes->knownMethod(QByteArray("toString"), 0, 0)) { + if (!knownAttributes || !knownAttributes->knownMethod(QByteArray("toString"), 0, QTypeRevision::zero())) { qml->writeStartObject(QLatin1String("Method")); qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("toString"))); qml->writeEndObject(); } - if (!knownAttributes || !knownAttributes->knownMethod(QByteArray("destroy"), 0, 0)) { + if (!knownAttributes || !knownAttributes->knownMethod(QByteArray("destroy"), 0, QTypeRevision::zero())) { qml->writeStartObject(QLatin1String("Method")); qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("destroy"))); qml->writeEndObject(); } - if (!knownAttributes || !knownAttributes->knownMethod(QByteArray("destroy"), 1, 0)) { + if (!knownAttributes || !knownAttributes->knownMethod(QByteArray("destroy"), 1, QTypeRevision::zero())) { qml->writeStartObject(QLatin1String("Method")); qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("destroy"))); qml->writeStartObject(QLatin1String("Parameter")); @@ -507,7 +499,12 @@ public: qml->writeScriptBinding(QLatin1String("name"), exportString); qml->writeArrayBinding(QLatin1String("exports"), QStringList() << exportString); - qml->writeArrayBinding(QLatin1String("exportMetaObjectRevisions"), QStringList() << QString::number(compositeType.minorVersion())); + + // TODO: shouldn't this be metaObjectRevision().value<quint16>() + // rather than version().minorVersion() + qml->writeArrayBinding(QLatin1String("exportMetaObjectRevisions"), QStringList() + << QString::number(compositeType.version().minorVersion())); + qml->writeBooleanBinding(QLatin1String("isComposite"), true); if (compositeType.isSingleton()) { @@ -546,10 +543,10 @@ public: struct QmlTypeInfo { QmlTypeInfo() {} - QmlTypeInfo(const QString &exportString, int revision, const QMetaObject *extendedObject, QByteArray attachedTypeId) + QmlTypeInfo(const QString &exportString, QTypeRevision revision, const QMetaObject *extendedObject, QByteArray attachedTypeId) : exportString(exportString), revision(revision), extendedObject(extendedObject), attachedTypeId(attachedTypeId) {} QString exportString; - int revision = 0; + QTypeRevision revision = QTypeRevision::zero(); const QMetaObject *extendedObject = nullptr; QByteArray attachedTypeId; }; @@ -572,11 +569,11 @@ public: if (attachedType != meta) attachedTypeId = convertToId(attachedType); } - const QString exportString = getExportString(type, { QString(), -1, -1, false }); - int metaObjectRevision = type.metaObjectRevision(); + const QString exportString = getExportString(type, { QString(), QTypeRevision(), false }); + QTypeRevision metaObjectRevision = type.metaObjectRevision(); if (extendedObject) { // emulate custom metaobjectrevision out of import - metaObjectRevision = type.majorVersion() * 100 + type.minorVersion(); + metaObjectRevision = type.version(); } QmlTypeInfo info = { exportString, metaObjectRevision, extendedObject, attachedTypeId }; @@ -585,7 +582,7 @@ public: // sort to ensure stable output std::sort(typeInfo.begin(), typeInfo.end(), [](const QmlTypeInfo &i1, const QmlTypeInfo &i2) { - return i1.revision < i2.revision; + return i1.revision.toEncodedVersion<quint16>() < i2.revision.toEncodedVersion<quint16>(); }); // determine default property @@ -609,7 +606,7 @@ public: if (!typeInfo.isEmpty()) { QMap<QString, QString> exports; // sort exports for (const QmlTypeInfo &iter : typeInfo) - exports.insert(iter.exportString, QString::number(iter.revision)); + exports.insert(iter.exportString, QString::number(iter.revision.toEncodedVersion<quint16>())); QStringList exportStrings = exports.keys(); QStringList metaObjectRevisions = exports.values(); @@ -690,22 +687,27 @@ private: qml->writeScriptBinding(QLatin1String("isPointer"), QLatin1String("true")); } - void dump(const QMetaProperty &prop, int metaRevision = -1, KnownAttributes *knownAttributes = nullptr) + void dump(const QMetaProperty &prop, QTypeRevision metaRevision = QTypeRevision(), + KnownAttributes *knownAttributes = nullptr) { - int revision = metaRevision ? metaRevision : prop.revision(); + // TODO: should that not be metaRevision.isValid() rather than comparing to zero()? + QTypeRevision revision = (metaRevision == QTypeRevision::zero()) + ? QTypeRevision::fromEncodedVersion(prop.revision()) + : metaRevision; QByteArray propName = prop.name(); if (knownAttributes && knownAttributes->knownProperty(propName, revision)) return; qml->writeStartObject("Property"); qml->writeScriptBinding(QLatin1String("name"), enquote(QString::fromUtf8(prop.name()))); - if (revision) - qml->writeScriptBinding(QLatin1String("revision"), QString::number(revision)); + if (revision != QTypeRevision::zero()) + qml->writeScriptBinding(QLatin1String("revision"), QString::number(revision.toEncodedVersion<quint16>())); writeTypeProperties(prop.typeName(), prop.isWritable()); qml->writeEndObject(); } - QSet<QString> dumpMetaProperties(const QMetaObject *meta, int metaRevision = -1, KnownAttributes *knownAttributes = nullptr) + QSet<QString> dumpMetaProperties(const QMetaObject *meta, QTypeRevision metaRevision = QTypeRevision(), + KnownAttributes *knownAttributes = nullptr) { QSet<QString> implicitSignals; for (int index = meta->propertyOffset(); index < meta->propertyCount(); ++index) { @@ -713,7 +715,7 @@ private: dump(property, metaRevision, knownAttributes); if (knownAttributes) knownAttributes->knownMethod(QByteArray(property.name()).append("Changed"), - 0, property.revision()); + 0, QTypeRevision::fromEncodedVersion(property.revision())); implicitSignals.insert(QString("%1Changed").arg(QString::fromUtf8(property.name()))); } return implicitSignals; @@ -741,7 +743,7 @@ private: return; } - int revision = meth.revision(); + QTypeRevision revision = QTypeRevision::fromEncodedVersion(meth.revision()); if (knownAttributes && knownAttributes->knownMethod(name, meth.parameterNames().size(), revision)) return; if (meth.methodType() == QMetaMethod::Signal) @@ -751,8 +753,8 @@ private: qml->writeScriptBinding(QLatin1String("name"), enquote(name)); - if (revision) - qml->writeScriptBinding(QLatin1String("revision"), QString::number(revision)); + if (revision != QTypeRevision::zero()) + qml->writeScriptBinding(QLatin1String("revision"), QString::number(revision.toEncodedVersion<quint16>())); if (typeName != QLatin1String("void")) qml->writeScriptBinding(QLatin1String("type"), enquote(typeName)); @@ -1010,9 +1012,9 @@ static bool operator<(const QQmlType &a, const QQmlType &b) { return a.qmlTypeName() < b.qmlTypeName() || (a.qmlTypeName() == b.qmlTypeName() - && ((a.majorVersion() < b.majorVersion()) - || (a.majorVersion() == b.majorVersion() - && a.minorVersion() < b.minorVersion()))); + && ((a.version().majorVersion() < b.version().majorVersion()) + || (a.version().majorVersion() == b.version().majorVersion() + && a.version().minorVersion() < b.version().minorVersion()))); } QT_END_NAMESPACE @@ -1252,11 +1254,13 @@ int main(int argc, char *argv[]) // composite types we want to dump information of QMap<QString, QList<QQmlType>> compositeTypes; - int majorVersion = qtQmlMajorVersion, minorVersion = qtQmlMinorVersion; + QTypeRevision version = QTypeRevision::fromVersion(qtQmlMajorVersion, qtQmlMinorVersion); QmlVersionInfo info; if (action == Builtins) { QMap<QString, QList<QQmlType>> defaultCompositeTypes; - QSet<const QMetaObject *> builtins = collectReachableMetaObjects(&engine, uncreatableMetas, singletonMetas, defaultCompositeTypes, {QLatin1String("Qt"), majorVersion, minorVersion, strict}); + QSet<const QMetaObject *> builtins = collectReachableMetaObjects( + &engine, uncreatableMetas, singletonMetas, defaultCompositeTypes, + {QLatin1String("Qt"), version, strict}); Q_ASSERT(builtins.size() == 1); metas.insert(*builtins.begin()); } else { @@ -1265,12 +1269,13 @@ int main(int argc, char *argv[]) if (!ok) qCritical("Invalid version number"); else { - majorVersion = versionSplitted.at(0).toInt(&ok); + const int majorVersion = versionSplitted.at(0).toInt(&ok); if (!ok) qCritical("Invalid major version"); - minorVersion = versionSplitted.at(1).toInt(&ok); + const int minorVersion = versionSplitted.at(1).toInt(&ok); if (!ok) qCritical("Invalid minor version"); + version = QTypeRevision::fromVersion(majorVersion, minorVersion); } QList<QQmlType> defaultTypes = QQmlMetaType::qmlTypes(); // find a valid QtQuick import @@ -1282,9 +1287,9 @@ int main(int argc, char *argv[]) } else { QString module = qtObjectType.qmlTypeName(); module = module.mid(0, module.lastIndexOf(QLatin1Char('/'))); - importCode = QString("import %1 %2.%3").arg(module, - QString::number(qtObjectType.majorVersion()), - QString::number(qtObjectType.minorVersion())).toUtf8(); + importCode = QString("import %1 %2.%3").arg( + module, QString::number(qtObjectType.version().majorVersion()), + QString::number(qtObjectType.version().minorVersion())).toUtf8(); } // avoid importing dependencies? for (const QString &moduleToImport : qAsConst(dependencies)) { @@ -1316,7 +1321,7 @@ int main(int argc, char *argv[]) return EXIT_IMPORTERROR; } } - info = {pluginImportUri, majorVersion, minorVersion, strict}; + info = {pluginImportUri, version, strict}; QSet<const QMetaObject *> candidates = collectReachableMetaObjects(&engine, uncreatableMetas, singletonMetas, compositeTypes, info, defaultTypes); for (auto it = compositeTypes.begin(), end = compositeTypes.end(); it != end; ++it) { diff --git a/tools/qmlscene/main.cpp b/tools/qmlscene/main.cpp index b14166ad8d..b0635a7e87 100644 --- a/tools/qmlscene/main.cpp +++ b/tools/qmlscene/main.cpp @@ -36,7 +36,7 @@ #include <QtCore/qregularexpression.h> #include <QtGui/QGuiApplication> -#include <QtGui/QOpenGLFunctions> +#include <QOpenGLFunctions> #include <QtQml/qqml.h> #include <QtQml/qqmlengine.h> diff --git a/tools/tools.pro b/tools/tools.pro index 2e04f9330c..d16f78071c 100644 --- a/tools/tools.pro +++ b/tools/tools.pro @@ -4,7 +4,6 @@ QT_FOR_CONFIG += qml-private qtConfig(qml-devtools) { SUBDIRS += \ qmllint \ - qmlmin \ qmlimportscanner \ qmlformat @@ -12,8 +11,7 @@ qtConfig(qml-devtools) { } qtConfig(thread):!android|android_app:!wasm:!rtems { - SUBDIRS += \ - qml + qtConfig(commandlineparser): SUBDIRS += qml qtConfig(qml-profiler): SUBDIRS += qmlprofiler qtConfig(qml-preview): SUBDIRS += qmlpreview @@ -46,7 +44,7 @@ qtConfig(qml-devtools) { qmleasing.depends = qmlimportscanner } -# qmlmin, qmlimportscanner & qmlcachegen are build tools. +# qmlimportscanner & qmlcachegen are build tools. # qmlscene is needed by the autotests. # qmltestrunner may be useful for manual testing. # qmlplugindump cannot be a build tool, because it loads target plugins. |