Merge remote-tracking branch 'origin/5.15' into dev

Change-Id: Ibb3be39cbdaf363f017fdfd62e4647acbc3443cb
This commit is contained in:
Qt Forward Merge Bot 2019-11-15 01:02:20 +01:00
commit 0ee087f5a5
16 changed files with 185 additions and 36 deletions

View File

@ -58,7 +58,7 @@ GetForm
mouseArea.onClicked: Utils.makeRequest()
button.border.width: button.pressed ? 2 : 1
button.border.width: mouseArea.pressed ? 2 : 1
text.text: "Request data.xml"
}

View File

@ -1,5 +1,7 @@
<RCC>
<qresource prefix="/scenegraph/fboitem">
<file>main.qml</file>
<file>shaders/checker.frag</file>
<file>shaders/+qsb/checker.frag</file>
</qresource>
</RCC>

View File

@ -67,20 +67,7 @@ Item {
property size pixelSize: Qt.size(width / tileSize, height / tileSize);
fragmentShader:
"
uniform lowp vec4 color1;
uniform lowp vec4 color2;
uniform highp vec2 pixelSize;
varying highp vec2 qt_TexCoord0;
void main() {
highp vec2 tc = sign(sin(3.14159265358979323846 * qt_TexCoord0 * pixelSize));
if (tc.x != tc.y)
gl_FragColor = color1;
else
gl_FragColor = color2;
}
"
fragmentShader: "qrc:/scenegraph/fboitem/shaders/checker.frag"
}
Renderer {

View File

@ -0,0 +1,14 @@
uniform lowp vec4 color1;
uniform lowp vec4 color2;
uniform highp vec2 pixelSize;
varying highp vec2 qt_TexCoord0;
void main()
{
highp vec2 tc = sign(sin(3.14159265358979323846 * qt_TexCoord0 * pixelSize));
if (tc.x != tc.y)
gl_FragColor = color1;
else
gl_FragColor = color2;
}

View File

@ -0,0 +1,22 @@
#version 440
layout(std140, binding = 0) uniform buf {
mat4 qt_Matrix;
float qt_Opacity;
vec4 color1;
vec4 color2;
vec2 pixelSize;
} ubuf;
layout(location = 0) in vec2 qt_TexCoord0;
layout(location = 0) out vec4 fragColor;
void main()
{
vec2 tc = sign(sin(3.14159265358979323846 * qt_TexCoord0 * ubuf.pixelSize));
if (tc.x != tc.y)
fragColor = ubuf.color1;
else
fragColor = ubuf.color2;
}

View File

@ -18,7 +18,15 @@ HEADERS += \
build_integration.files = qmltypes.prf
build_integration.path = $$[QT_HOST_DATA]/mkspecs/features
prefix_build: INSTALLS += build_integration
else: COPIES += build_integration
prefix_build {
load(qt_build_paths)
qmltypes_to_builddir.files = qmltypes.prf
qmltypes_to_builddir.path = $$MODULE_BASE_OUTDIR/mkspecs/features
COPIES += qmltypes_to_builddir
INSTALLS += build_integration
} else {
COPIES += build_integration
}
load(qt_tool)

View File

@ -39,8 +39,17 @@ qt_module_deps += $$replace(QT_PRIVATE, -private$, '')
qt_module_deps = $$replace(qt_module_deps, _private$, '')
all_qt_module_deps = $$resolve_depends(qt_module_deps, "QT.", ".depends" ".run_depends")
foreign_types =
for(dep, all_qt_module_deps): \
foreign_types += $$[QT_INSTALL_LIBS]/metatypes/$$lower($$eval(QT.$${dep}.module))_metatypes.json
for(dep, all_qt_module_deps) {
METATYPES_FILENAME = $$lower($$eval(QT.$${dep}.module))_metatypes.json
INSTALLED_METATYPES = $$[QT_INSTALL_LIBS]/metatypes/$$METATYPES_FILENAME
isEmpty(MODULE_BASE_OUTDIR) {
foreign_types += $$INSTALLED_METATYPES
} else {
MODULE_BASE_METATYPES = $$MODULE_BASE_OUTDIR/lib/metatypes/$$METATYPES_FILENAME
exists($$MODULE_BASE_METATYPES): foreign_types += $$MODULE_BASE_METATYPES
else: foreign_types += $$INSTALLED_METATYPES
}
}
QML_TYPEREGISTRAR_FLAGS = \
--generate-plugintypes=$$QMLTYPES_FILENAME \

View File

@ -262,6 +262,19 @@ QT_BEGIN_NAMESPACE
*/
/*!
\qmlproperty enumeration QtQuick::AnimatedSprite::finishBehavior
The behavior when the animation finishes on its own.
\value FinishAtInitialFrame
When the animation finishes it returns to the initial frame.
This is the default behavior.
\value FinishAtFinalFrame
When the animation finishes it stays on the final frame.
*/
/*!
\qmlmethod int QtQuick::AnimatedSprite::restart()
@ -381,6 +394,12 @@ int QQuickAnimatedSprite::currentFrame() const
return d->m_curFrame;
}
QQuickAnimatedSprite::FinishBehavior QQuickAnimatedSprite::finishBehavior() const
{
Q_D(const QQuickAnimatedSprite);
return d->m_finishBehavior;
}
bool QQuickAnimatedSprite::isCurrentFrameChangedConnected()
{
IS_SIGNAL_CONNECTED(this, QQuickAnimatedSprite, currentFrameChanged, (int));
@ -704,6 +723,16 @@ void QQuickAnimatedSprite::setCurrentFrame(int arg) //TODO-C: Probably only work
}
}
void QQuickAnimatedSprite::setFinishBehavior(FinishBehavior arg)
{
Q_D(QQuickAnimatedSprite);
if (d->m_finishBehavior != arg) {
d->m_finishBehavior = arg;
Q_EMIT finishBehaviorChanged(arg);
}
}
void QQuickAnimatedSprite::createEngine()
{
Q_D(QQuickAnimatedSprite);
@ -838,7 +867,11 @@ void QQuickAnimatedSprite::prepareNextFrame(QSGSpriteNode *node)
progress = 0;
}
if (d->m_loops > 0 && d->m_curLoop >= d->m_loops) {
frameAt = 0;
if (d->m_finishBehavior == FinishAtInitialFrame)
frameAt = 0;
else
frameAt = frameCount() - 1;
d->m_curFrame = frameAt;
d->m_running = false;
emit runningChanged(false);
emit finished();

View File

@ -92,6 +92,7 @@ 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)
QML_NAMED_ELEMENT(AnimatedSprite)
public:
@ -101,6 +102,12 @@ public:
};
Q_ENUM(LoopParameters)
enum FinishBehavior {
FinishAtInitialFrame,
FinishAtFinalFrame
};
Q_ENUM(FinishBehavior)
bool running() const;
bool interpolate() const;
QUrl source() const;
@ -116,6 +123,7 @@ public:
int loops() const;
bool paused() const;
int currentFrame() const;
FinishBehavior finishBehavior() const;
Q_SIGNALS:
@ -135,6 +143,7 @@ Q_SIGNALS:
void frameDurationChanged(int arg);
void loopsChanged(int arg);
void currentFrameChanged(int arg);
Q_REVISION(15) void finishBehaviorChanged(FinishBehavior arg);
Q_REVISION(12) void finished();
@ -163,7 +172,7 @@ public Q_SLOTS:
void resetFrameDuration();
void setLoops(int arg);
void setCurrentFrame(int arg);
void setFinishBehavior(FinishBehavior arg);
private Q_SLOTS:
void createEngine();

View File

@ -57,11 +57,10 @@ QT_REQUIRE_CONFIG(quick_sprite);
#include "qquickitem_p.h"
#include "qquicksprite_p.h"
#include "qquickanimatedsprite_p.h"
QT_BEGIN_NAMESPACE
class QQuickAnimatedSprite;
class QQuickAnimatedSpritePrivate : public QQuickItemPrivate
{
Q_DECLARE_PUBLIC(QQuickAnimatedSprite)
@ -78,6 +77,7 @@ public:
, m_loops(-1)
, m_curLoop(0)
, m_pauseOffset(0)
, m_finishBehavior(QQuickAnimatedSprite::FinishAtInitialFrame)
{
}
@ -93,6 +93,7 @@ public:
int m_loops;
int m_curLoop;
int m_pauseOffset;
QQuickAnimatedSprite::FinishBehavior m_finishBehavior;
};
QT_END_NAMESPACE

View File

@ -83,6 +83,11 @@ public:
* Everything that relates to rendering must be located in the
* QQuickFramebufferObject::Renderer class.
*
* \warning This class is only functional when Qt Quick is rendering
* via OpenGL, either directly or through the \l{Scene Graph
* Adaptations}{RHI-based rendering path}. It is not compatible with
* other RHI backends, such as, Vulkan or Metal.
*
* To avoid race conditions and read/write issues from two threads
* it is important that the renderer and the item never read or
* write shared variables. Communication between the item and the renderer
@ -109,10 +114,6 @@ public:
* and can be used directly in \l {ShaderEffect}{ShaderEffects} and other
* classes that consume texture providers.
*
* \warning This class is only suitable when working directly with OpenGL. It
* is not compatible with the \l{Scene Graph Adaptations}{RHI-based rendering
* path}.
*
* \sa {Scene Graph - Rendering FBOs}, {Scene Graph and Rendering}
*/
@ -233,6 +234,13 @@ public Q_SLOTS:
{
if (renderPending) {
renderPending = false;
const bool needsWrap = QSGRendererInterface::isApiRhiBased(window->rendererInterface()->graphicsApi());
if (needsWrap) {
window->beginExternalCommands();
window->resetOpenGLState();
}
fbo->bind();
QOpenGLContext::currentContext()->functions()->glViewport(0, 0, fbo->width(), fbo->height());
renderer->render();
@ -241,6 +249,9 @@ public Q_SLOTS:
if (msDisplayFbo)
QOpenGLFramebufferObject::blitFramebuffer(msDisplayFbo, fbo);
if (needsWrap)
window->endExternalCommands();
markDirty(QSGNode::DirtyMaterial);
emit textureChanged();
}
@ -270,7 +281,8 @@ public:
static inline bool isOpenGL(QSGRenderContext *rc)
{
QSGRendererInterface *rif = rc->sceneGraphContext()->rendererInterface(rc);
return !rif || rif->graphicsApi() == QSGRendererInterface::OpenGL;
return rif && (rif->graphicsApi() == QSGRendererInterface::OpenGL
|| rif->graphicsApi() == QSGRendererInterface::OpenGLRhi);
}
/*!
@ -335,9 +347,11 @@ QSGNode *QQuickFramebufferObject::updatePaintNode(QSGNode *node, UpdatePaintNode
displayTexture = n->msDisplayFbo->texture();
}
n->setTexture(window()->createTextureFromId(displayTexture,
n->fbo->size(),
QQuickWindow::TextureHasAlphaChannel));
QSGTexture *wrapper = window()->createTextureFromNativeObject(QQuickWindow::NativeObjectTexture,
&displayTexture, 0,
n->fbo->size(),
QQuickWindow::TextureHasAlphaChannel);
n->setTexture(wrapper);
}
n->setTextureCoordinatesTransform(d->mirrorVertically ? QSGSimpleTextureNode::MirrorVertically : QSGSimpleTextureNode::NoTransform);

View File

@ -48,7 +48,8 @@ class QOpenGLFramebufferObject;
class QQuickFramebufferObjectPrivate;
class QSGFramebufferObjectNode;
// ### Qt 6: To be removed. To be seen if an alternative will need to be introduced.
// ### Qt 6: Consider what to do here. QQuickFbo supports both direct OpenGL and
// OpenGL via QRhi, but it cannot function when running with another rhi backend.
class Q_QUICK_EXPORT QQuickFramebufferObject : public QQuickItem
{

View File

@ -4735,8 +4735,7 @@ void QQuickWindow::setDefaultAlphaBuffer(bool useAlpha)
adaptation.
\note This function has no effect when running on the RHI graphics
abstraction. With the RHI, the functions to call when enqueuing native
graphics commands are beginExternalCommands() and endExternalCommands().
abstraction and the underlying RHI backend is not OpenGL.
\sa QQuickWindow::beforeRendering(), beginExternalCommands(), endExternalCommands()
*/
@ -4744,7 +4743,7 @@ void QQuickWindow::resetOpenGLState()
{
Q_D(QQuickWindow);
if (d->rhi || !openglContext())
if (!openglContext())
return;
QOpenGLContext *ctx = openglContext();
@ -4859,7 +4858,13 @@ const QQuickWindow::GraphicsStateInfo &QQuickWindow::graphicsStateInfo()
directly and the RHI graphics abstraction layer is not in use. Refer to
resetOpenGLState() in that case.
\sa endExternalCommands()
\note When the scenegraph is using the RHI graphics abstraction layer with
the OpenGL backend underneath, pay attention to the fact that the OpenGL
state in the context can have arbitrary settings, and this function does not
perform any resetting of the state back to defaults. Call
resetOpenGLState() if that is seen necessary.
\sa endExternalCommands(), resetOpenGLState()
\since 5.14
*/

View File

@ -0,0 +1,18 @@
import QtQuick 2.15
Rectangle {
color: "black"
width: 320
height: 320
AnimatedSprite {
objectName: "sprite"
loops: 1
source: "squarefacesprite.png"
frameCount: 6
frameDuration: 64
width: 160
height: 160
finishBehavior: AnimatedSprite.FinishAtFinalFrame
}
}

View File

@ -57,6 +57,7 @@ private slots:
void test_changeSourceToSmallerImgKeepingBigFrameSize();
void test_infiniteLoops();
void test_implicitSize();
void test_finishBehavior();
};
void tst_qquickanimatedsprite::initTestCase()
@ -428,6 +429,31 @@ void tst_qquickanimatedsprite::test_infiniteLoops()
QCOMPARE(finishedSpy.count(), 0);
}
void tst_qquickanimatedsprite::test_finishBehavior()
{
QQuickView window;
window.setSource(testFileUrl("finishBehavior.qml"));
window.show();
QVERIFY(QTest::qWaitForWindowExposed(&window));
QVERIFY(window.rootObject());
QQuickAnimatedSprite* sprite = window.rootObject()->findChild<QQuickAnimatedSprite*>("sprite");
QVERIFY(sprite);
QTRY_VERIFY(sprite->running());
// correctly stops at last frame
QSignalSpy finishedSpy(sprite, SIGNAL(finished()));
QVERIFY(finishedSpy.wait(2000));
QCOMPARE(sprite->running(), false);
QCOMPARE(sprite->currentFrame(), 5);
// correctly starts a second time
sprite->start();
QTRY_VERIFY(sprite->running());
QTRY_COMPARE(sprite->currentFrame(), 5);
}
QTEST_MAIN(tst_qquickanimatedsprite)
#include "tst_qquickanimatedsprite.moc"