aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/scenegraph
diff options
context:
space:
mode:
authorAndy Nichols <andy.nichols@qt.io>2016-04-03 18:06:46 +0200
committerAndy Nichols <andy.nichols@qt.io>2016-12-13 15:43:15 +0000
commit3f57f2b7cc3899af154257a3c858bd23d9f03a62 (patch)
tree45ba7f7a37110c81963bf644b8830201504e117f /src/plugins/scenegraph
parentbff7302fc277d18b5bd4ad95d35b9e1bbc2be001 (diff)
OpenVG Scenegraph Adaptation
This is an OpenVG backend for the Qt Quick 2 scenegraph. Should be feature complete now, but there are still some issues that could be improved in future commits: If Rectangle nodes are rendered with a non-affine transform, they will be rendered incorrectly. This is because paths expect affine transformations. The Glyph cache is a bit cheeky in that it's caching paths, but doing so per font size. It shoudln't need to, but right now I've not though up a good way of getting the transform/scale needed when rendering yet. Change-Id: Ie3c4f2df35d14279b0f9f55e0e10a873328c025b Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Diffstat (limited to 'src/plugins/scenegraph')
-rw-r--r--src/plugins/scenegraph/openvg/openvg.json3
-rw-r--r--src/plugins/scenegraph/openvg/openvg.pro54
-rw-r--r--src/plugins/scenegraph/openvg/qopenvgcontext.cpp218
-rw-r--r--src/plugins/scenegraph/openvg/qopenvgcontext_p.h88
-rw-r--r--src/plugins/scenegraph/openvg/qopenvgmatrix.cpp325
-rw-r--r--src/plugins/scenegraph/openvg/qopenvgmatrix.h99
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgadaptation.cpp78
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgadaptation_p.h68
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp219
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgcontext_p.h104
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgfontglyphcache.cpp185
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgfontglyphcache.h99
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgglyphnode.cpp191
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgglyphnode_p.h95
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvghelpers.cpp433
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvghelpers.h64
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvginternalimagenode.cpp233
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvginternalimagenode.h92
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvginternalrectanglenode.cpp613
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvginternalrectanglenode.h96
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvglayer.cpp360
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvglayer.h115
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.cpp283
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.h104
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgpainternode.cpp249
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgpainternode.h97
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.cpp266
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.h143
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgrenderable.cpp77
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgrenderable.h69
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgrenderer.cpp90
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgrenderer_p.h61
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgrenderloop.cpp257
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgrenderloop_p.h94
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgspritenode.cpp153
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgspritenode.h78
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgtexture.cpp123
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgtexture.h67
-rw-r--r--src/plugins/scenegraph/scenegraph.pro2
39 files changed, 6045 insertions, 0 deletions
diff --git a/src/plugins/scenegraph/openvg/openvg.json b/src/plugins/scenegraph/openvg/openvg.json
new file mode 100644
index 0000000000..224afbf784
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/openvg.json
@@ -0,0 +1,3 @@
+{
+ "Keys": ["openvg"]
+}
diff --git a/src/plugins/scenegraph/openvg/openvg.pro b/src/plugins/scenegraph/openvg/openvg.pro
new file mode 100644
index 0000000000..fb9b3b93f5
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/openvg.pro
@@ -0,0 +1,54 @@
+TARGET = qsgopenvgbackend
+
+QT += gui-private core-private qml-private quick-private
+
+PLUGIN_TYPE = scenegraph
+PLUGIN_CLASS_NAME = QSGOpenVGAdaptation
+load(qt_plugin)
+
+QMAKE_TARGET_PRODUCT = "Qt Quick OpenVG Renderer (Qt $$QT_VERSION)"
+QMAKE_TARGET_DESCRIPTION = "Quick OpenVG Renderer for Qt."
+
+QMAKE_USE += openvg
+
+OTHER_FILES += $$PWD/openvg.json
+
+HEADERS += \
+ qsgopenvgadaptation_p.h \
+ qsgopenvgcontext_p.h \
+ qsgopenvgrenderloop_p.h \
+ qsgopenvgglyphnode_p.h \
+ qopenvgcontext_p.h \
+ qsgopenvgrenderer_p.h \
+ qsgopenvginternalrectanglenode.h \
+ qsgopenvgnodevisitor.h \
+ qopenvgmatrix.h \
+ qsgopenvgpublicnodes.h \
+ qsgopenvginternalimagenode.h \
+ qsgopenvgtexture.h \
+ qsgopenvglayer.h \
+ qsgopenvghelpers.h \
+ qsgopenvgfontglyphcache.h \
+ qsgopenvgpainternode.h \
+ qsgopenvgspritenode.h \
+ qsgopenvgrenderable.h
+
+SOURCES += \
+ qsgopenvgadaptation.cpp \
+ qsgopenvgcontext.cpp \
+ qsgopenvgrenderloop.cpp \
+ qsgopenvgglyphnode.cpp \
+ qopenvgcontext.cpp \
+ qsgopenvgrenderer.cpp \
+ qsgopenvginternalrectanglenode.cpp \
+ qsgopenvgnodevisitor.cpp \
+ qopenvgmatrix.cpp \
+ qsgopenvgpublicnodes.cpp \
+ qsgopenvginternalimagenode.cpp \
+ qsgopenvgtexture.cpp \
+ qsgopenvglayer.cpp \
+ qsgopenvghelpers.cpp \
+ qsgopenvgfontglyphcache.cpp \
+ qsgopenvgpainternode.cpp \
+ qsgopenvgspritenode.cpp \
+ qsgopenvgrenderable.cpp
diff --git a/src/plugins/scenegraph/openvg/qopenvgcontext.cpp b/src/plugins/scenegraph/openvg/qopenvgcontext.cpp
new file mode 100644
index 0000000000..ea2c24afdb
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qopenvgcontext.cpp
@@ -0,0 +1,218 @@
+/****************************************************************************
+**
+** 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 <qpa/qplatformnativeinterface.h>
+#include <QtGui/QGuiApplication>
+#include <QtCore/QVector>
+#include <QtCore/QDebug>
+
+#include "qopenvgcontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QOpenVGContext::QOpenVGContext(QWindow *window)
+ : m_window(window)
+{
+ QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
+ m_display = reinterpret_cast<EGLDisplay>(nativeInterface->nativeResourceForWindow("EglDisplay", window));
+ m_surface = reinterpret_cast<EGLSurface>(nativeInterface->nativeResourceForWindow("EglSurface", window));
+
+ if (m_display == 0)
+ qFatal("QOpenVGContext: failed to get EGLDisplay");
+ if (m_surface == 0)
+ qFatal("QOpenVGContext: failed to get EGLSurface");
+
+ EGLint configID = 0;
+ if (eglQuerySurface(m_display, m_surface, EGL_CONFIG_ID, &configID)) {
+ EGLint numConfigs;
+ const EGLint configAttribs[] = {
+ EGL_CONFIG_ID, configID,
+ EGL_NONE
+ };
+ eglChooseConfig(m_display, configAttribs, &m_config, 1, &numConfigs);
+ } else {
+ qFatal("QOpenVGContext: failed to get surface config");
+ }
+
+ // Create an EGL Context
+ eglBindAPI(EGL_OPENVG_API);
+ m_context = eglCreateContext(m_display, m_config, EGL_NO_CONTEXT, 0);
+ if (!m_context)
+ qFatal("QOpenVGContext: eglCreateContext failed");
+}
+
+QOpenVGContext::~QOpenVGContext()
+{
+ doneCurrent();
+ eglDestroyContext(m_display, m_context);
+}
+
+void QOpenVGContext::makeCurrent()
+{
+ makeCurrent(m_surface);
+}
+
+void QOpenVGContext::makeCurrent(EGLSurface surface)
+{
+ eglMakeCurrent(m_display, surface, surface, m_context);
+}
+
+void QOpenVGContext::doneCurrent()
+{
+ eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+}
+
+void QOpenVGContext::swapBuffers()
+{
+ swapBuffers(m_surface);
+}
+
+void QOpenVGContext::swapBuffers(EGLSurface surface)
+{
+ eglSwapBuffers(m_display, surface);
+}
+
+QWindow *QOpenVGContext::window() const
+{
+ return m_window;
+}
+
+QImage QOpenVGContext::readFramebuffer(const QSize &size)
+{
+ QImage framebufferImage(size, QImage::Format_RGB32);
+ vgReadPixels(framebufferImage.bits(), framebufferImage.bytesPerLine(), VG_sXRGB_8888, 0, 0, size.width(), size.height());
+ return framebufferImage.mirrored(false, true);
+}
+
+void QOpenVGContext::getConfigs()
+{
+ EGLint configsAvailable = 0;
+ eglGetConfigs(m_display, 0, 0, &configsAvailable);
+
+ QVector<EGLConfig> configs(configsAvailable);
+ eglGetConfigs(m_display, configs.data(), configs.size(), &configsAvailable);
+
+ for (EGLConfig config : configs) {
+ EGLint value;
+ eglGetConfigAttrib(m_display, config, EGL_CONFIG_ID, &value);
+ qDebug() << "#################\n" << "EGL_CONFIG_ID:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_BUFFER_SIZE, &value);
+ qDebug() << "EGL_BUFFER_SIZE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_ALPHA_SIZE, &value);
+ qDebug() << "EGL_ALPHA_SIZE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_RED_SIZE, &value);
+ qDebug() << "EGL_RED_SIZE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_GREEN_SIZE, &value);
+ qDebug() << "EGL_GREEN_SIZE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_BLUE_SIZE, &value);
+ qDebug() << "EGL_BLUE_SIZE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_DEPTH_SIZE, &value);
+ qDebug() << "EGL_DEPTH_SIZE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_STENCIL_SIZE, &value);
+ qDebug() << "EGL_STENCIL_SIZE:" << value;
+
+ eglGetConfigAttrib(m_display, config, EGL_ALPHA_MASK_SIZE, &value);
+ qDebug() << "EGL_ALPHA_MASK_SIZE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_BIND_TO_TEXTURE_RGB, &value);
+ qDebug() << "EGL_BIND_TO_TEXTURE_RGB:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_BIND_TO_TEXTURE_RGBA, &value);
+ qDebug() << "EGL_BIND_TO_TEXTURE_RGBA:" << value;
+
+
+ eglGetConfigAttrib(m_display, config, EGL_COLOR_BUFFER_TYPE, &value);
+ qDebug() << "EGL_COLOR_BUFFER_TYPE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_CONFIG_CAVEAT, &value);
+ qDebug() << "EGL_CONFIG_CAVEAT:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_CONFORMANT, &value);
+ qDebug() << "EGL_CONFORMANT:" << value;
+
+
+ eglGetConfigAttrib(m_display, config, EGL_LEVEL, &value);
+ qDebug() << "EGL_LEVEL:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_LUMINANCE_SIZE, &value);
+ qDebug() << "EGL_LUMINANCE_SIZE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_MAX_PBUFFER_WIDTH, &value);
+ qDebug() << "EGL_MAX_PBUFFER_WIDTH:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_MAX_PBUFFER_HEIGHT, &value);
+ qDebug() << "EGL_MAX_PBUFFER_HEIGHT:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_MAX_PBUFFER_PIXELS, &value);
+ qDebug() << "EGL_MAX_PBUFFER_PIXELS:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_MAX_SWAP_INTERVAL, &value);
+ qDebug() << "EGL_MAX_SWAP_INTERVAL:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_MIN_SWAP_INTERVAL, &value);
+ qDebug() << "EGL_MIN_SWAP_INTERVAL:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_NATIVE_RENDERABLE, &value);
+ qDebug() << "EGL_NATIVE_RENDERABLE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_NATIVE_VISUAL_ID, &value);
+ qDebug() << "EGL_NATIVE_VISUAL_ID:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_NATIVE_VISUAL_TYPE, &value);
+ qDebug() << "EGL_NATIVE_VISUAL_TYPE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_RENDERABLE_TYPE, &value);
+ qDebug() << "EGL_RENDERABLE_TYPE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_SAMPLE_BUFFERS, &value);
+ qDebug() << "EGL_SAMPLE_BUFFERS:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_SAMPLES, &value);
+ qDebug() << "EGL_SAMPLES:" << value;
+
+ eglGetConfigAttrib(m_display, config, EGL_SURFACE_TYPE, &value);
+ qDebug() << "EGL_SURFACE_TYPE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_TRANSPARENT_TYPE, &value);
+ qDebug() << "EGL_TRANSPARENT_TYPE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_TRANSPARENT_RED_VALUE, &value);
+ qDebug() << "EGL_TRANSPARENT_RED_VALUE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_TRANSPARENT_GREEN_VALUE, &value);
+ qDebug() << "EGL_TRANSPARENT_GREEN_VALUE:" << value;
+ eglGetConfigAttrib(m_display, config, EGL_TRANSPARENT_BLUE_VALUE, &value);
+ qDebug() << "EGL_TRANSPARENT_BLUE_VALUE:" << value;
+ }
+}
+
+void QOpenVGContext::checkErrors()
+{
+ VGErrorCode error;
+ EGLint eglError;
+ do {
+ error = vgGetError();
+ eglError = eglGetError();
+ qDebug() << "error: " << QString::number(error, 16);
+ qDebug() << "eglError: " << QString::number(eglError, 16);
+ } while (error != VG_NO_ERROR && eglError != EGL_SUCCESS);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qopenvgcontext_p.h b/src/plugins/scenegraph/openvg/qopenvgcontext_p.h
new file mode 100644
index 0000000000..a1ba73957f
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qopenvgcontext_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** 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 QOPENVGCONTEXT_H
+#define QOPENVGCONTEXT_H
+
+#include <QtGui/QWindow>
+#include <QtGui/QImage>
+
+#include <EGL/egl.h>
+#include <VG/openvg.h>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenVGContext
+{
+public:
+ QOpenVGContext(QWindow *window);
+ ~QOpenVGContext();
+
+ void makeCurrent();
+ void makeCurrent(EGLSurface surface);
+ void doneCurrent();
+ void swapBuffers();
+ void swapBuffers(EGLSurface surface);
+
+
+ QWindow *window() const;
+
+ EGLDisplay eglDisplay() { return m_display; }
+ EGLConfig eglConfig() { return m_config; }
+ EGLContext eglContext() { return m_context; }
+
+ QImage readFramebuffer(const QSize &size);
+
+ void getConfigs();
+
+ static void checkErrors();
+
+private:
+ EGLSurface m_surface;
+ EGLDisplay m_display;
+ EGLConfig m_config;
+ EGLContext m_context;
+
+ QWindow *m_window;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QOPENVGCONTEXT_H
diff --git a/src/plugins/scenegraph/openvg/qopenvgmatrix.cpp b/src/plugins/scenegraph/openvg/qopenvgmatrix.cpp
new file mode 100644
index 0000000000..e55de2ce0d
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qopenvgmatrix.cpp
@@ -0,0 +1,325 @@
+/****************************************************************************
+**
+** 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 "qopenvgmatrix.h"
+
+QT_BEGIN_NAMESPACE
+
+// QOpenVGMatrix: Because Qt will never have enough matrix classes
+// Internally the data is stored as column-major format
+// So this is a 3x3 version of QMatrix4x4 for optimal
+// OpenVG usage.
+
+QOpenVGMatrix::QOpenVGMatrix()
+{
+ setToIdentity();
+}
+
+QOpenVGMatrix::QOpenVGMatrix(const float *values)
+{
+ for (int col = 0; col < 3; ++col)
+ for (int row = 0; row < 3; ++row)
+ m[col][row] = values[col * 3 + row];
+}
+
+const float &QOpenVGMatrix::operator()(int row, int column) const
+{
+ Q_ASSERT(row >= 0 && row < 4 && column >= 0 && column < 4);
+ return m[column][row];
+}
+
+float &QOpenVGMatrix::operator()(int row, int column)
+{
+ Q_ASSERT(row >= 0 && row < 4 && column >= 0 && column < 4);
+ return m[column][row];
+}
+
+bool QOpenVGMatrix::isIdentity() const
+{
+ if (m[0][0] != 1.0f || m[0][1] != 0.0f || m[0][2] != 0.0f)
+ return false;
+ if ( m[1][0] != 0.0f || m[1][1] != 1.0f)
+ return false;
+ if (m[1][2] != 0.0f || m[2][0] != 0.0f)
+ return false;
+ if (m[2][1] != 0.0f || m[2][2] != 1.0f)
+ return false;
+
+ return true;
+}
+
+void QOpenVGMatrix::setToIdentity()
+{
+ m[0][0] = 1.0f;
+ m[0][1] = 0.0f;
+ m[0][2] = 0.0f;
+ m[1][0] = 0.0f;
+ m[1][1] = 1.0f;
+ m[1][2] = 0.0f;
+ m[2][0] = 0.0f;
+ m[2][1] = 0.0f;
+ m[2][2] = 1.0f;
+}
+
+void QOpenVGMatrix::fill(float value)
+{
+ m[0][0] = value;
+ m[0][1] = value;
+ m[0][2] = value;
+ m[1][0] = value;
+ m[1][1] = value;
+ m[1][2] = value;
+ m[2][0] = value;
+ m[2][1] = value;
+ m[2][2] = value;
+}
+
+QOpenVGMatrix QOpenVGMatrix::transposed() const
+{
+ QOpenVGMatrix result;
+ for (int row = 0; row < 3; ++row) {
+ for (int col = 0; col < 3; ++col)
+ result.m[col][row] = m[row][col];
+ }
+ return result;
+}
+
+QOpenVGMatrix &QOpenVGMatrix::operator+=(const QOpenVGMatrix &other)
+{
+ m[0][0] += other.m[0][0];
+ m[0][1] += other.m[0][1];
+ m[0][2] += other.m[0][2];
+ m[1][0] += other.m[1][0];
+ m[1][1] += other.m[1][1];
+ m[1][2] += other.m[1][2];
+ m[2][0] += other.m[2][0];
+ m[2][1] += other.m[2][1];
+ m[2][2] += other.m[2][2];
+ return *this;
+}
+
+QOpenVGMatrix &QOpenVGMatrix::operator-=(const QOpenVGMatrix &other)
+{
+ m[0][0] -= other.m[0][0];
+ m[0][1] -= other.m[0][1];
+ m[0][2] -= other.m[0][2];
+ m[1][0] -= other.m[1][0];
+ m[1][1] -= other.m[1][1];
+ m[1][2] -= other.m[1][2];
+ m[2][0] -= other.m[2][0];
+ m[2][1] -= other.m[2][1];
+ m[2][2] -= other.m[2][2];
+ return *this;
+}
+
+QOpenVGMatrix &QOpenVGMatrix::operator*=(const QOpenVGMatrix &other)
+{
+ float m0, m1;
+ m0 = m[0][0] * other.m[0][0]
+ + m[1][0] * other.m[0][1]
+ + m[2][0] * other.m[0][2];
+ m1 = m[0][0] * other.m[1][0]
+ + m[1][0] * other.m[1][1]
+ + m[2][0] * other.m[1][2];
+ m[2][0] = m[0][0] * other.m[2][0]
+ + m[1][0] * other.m[2][1]
+ + m[2][0] * other.m[2][2];
+ m[0][0] = m0;
+ m[1][0] = m1;
+
+ m0 = m[0][1] * other.m[0][0]
+ + m[1][1] * other.m[0][1]
+ + m[2][1] * other.m[0][2];
+ m1 = m[0][1] * other.m[1][0]
+ + m[1][1] * other.m[1][1]
+ + m[2][1] * other.m[1][2];
+ m[2][1] = m[0][1] * other.m[2][0]
+ + m[1][1] * other.m[2][1]
+ + m[2][1] * other.m[2][2];
+ m[0][1] = m0;
+ m[1][1] = m1;
+
+ m0 = m[0][2] * other.m[0][0]
+ + m[1][2] * other.m[0][1]
+ + m[2][2] * other.m[0][2];
+ m1 = m[0][2] * other.m[1][0]
+ + m[1][2] * other.m[1][1]
+ + m[2][2] * other.m[1][2];
+ m[2][2] = m[0][2] * other.m[2][0]
+ + m[1][2] * other.m[2][1]
+ + m[2][2] * other.m[2][2];
+ m[0][2] = m0;
+ m[1][2] = m1;
+ return *this;
+}
+
+QOpenVGMatrix &QOpenVGMatrix::operator*=(float factor)
+{
+ m[0][0] *= factor;
+ m[0][1] *= factor;
+ m[0][2] *= factor;
+ m[1][0] *= factor;
+ m[1][1] *= factor;
+ m[1][2] *= factor;
+ m[2][0] *= factor;
+ m[2][1] *= factor;
+ m[2][2] *= factor;
+ return *this;
+}
+
+QOpenVGMatrix &QOpenVGMatrix::operator/=(float divisor)
+{
+ m[0][0] /= divisor;
+ m[0][1] /= divisor;
+ m[0][2] /= divisor;
+ m[1][0] /= divisor;
+ m[1][1] /= divisor;
+ m[1][2] /= divisor;
+ m[2][0] /= divisor;
+ m[2][1] /= divisor;
+ m[2][2] /= divisor;
+ return *this;
+}
+
+bool QOpenVGMatrix::operator==(const QOpenVGMatrix &other) const
+{
+ return m[0][0] == other.m[0][0] &&
+ m[0][1] == other.m[0][1] &&
+ m[0][2] == other.m[0][2] &&
+ m[1][0] == other.m[1][0] &&
+ m[1][1] == other.m[1][1] &&
+ m[1][2] == other.m[1][2] &&
+ m[2][0] == other.m[2][0] &&
+ m[2][1] == other.m[2][1] &&
+ m[2][2] == other.m[2][2];
+}
+
+bool QOpenVGMatrix::operator!=(const QOpenVGMatrix &other) const
+{
+ return m[0][0] != other.m[0][0] ||
+ m[0][1] != other.m[0][1] ||
+ m[0][2] != other.m[0][2] ||
+ m[1][0] != other.m[1][0] ||
+ m[1][1] != other.m[1][1] ||
+ m[1][2] != other.m[1][2] ||
+ m[2][0] != other.m[2][0] ||
+ m[2][1] != other.m[2][1] ||
+ m[2][2] != other.m[2][2];
+}
+
+void QOpenVGMatrix::copyDataTo(float *values) const
+{
+ // Row-Major?
+ for (int row = 0; row < 3; ++row) {
+ for (int col = 0; col < 3; ++col)
+ values[row * 3 + col] = float(m[col][row]);
+ }
+}
+
+QOpenVGMatrix operator*(const QOpenVGMatrix &m1, const QOpenVGMatrix &m2)
+{
+ QOpenVGMatrix matrix;
+ matrix.m[0][0] = m1.m[0][0] * m2.m[0][0]
+ + m1.m[1][0] * m2.m[0][1]
+ + m1.m[2][0] * m2.m[0][2];
+ matrix.m[0][1] = m1.m[0][1] * m2.m[0][0]
+ + m1.m[1][1] * m2.m[0][1]
+ + m1.m[2][1] * m2.m[0][2];
+ matrix.m[0][2] = m1.m[0][2] * m2.m[0][0]
+ + m1.m[1][2] * m2.m[0][1]
+ + m1.m[2][2] * m2.m[0][2];
+
+ matrix.m[1][0] = m1.m[0][0] * m2.m[1][0]
+ + m1.m[1][0] * m2.m[1][1]
+ + m1.m[2][0] * m2.m[1][2];
+ matrix.m[1][1] = m1.m[0][1] * m2.m[1][0]
+ + m1.m[1][1] * m2.m[1][1]
+ + m1.m[2][1] * m2.m[1][2];
+ matrix.m[1][2] = m1.m[0][2] * m2.m[1][0]
+ + m1.m[1][2] * m2.m[1][1]
+ + m1.m[2][2] * m2.m[1][2];
+
+ matrix.m[2][0] = m1.m[0][0] * m2.m[2][0]
+ + m1.m[1][0] * m2.m[2][1]
+ + m1.m[2][0] * m2.m[2][2];
+ matrix.m[2][1] = m1.m[0][1] * m2.m[2][0]
+ + m1.m[1][1] * m2.m[2][1]
+ + m1.m[2][1] * m2.m[2][2];
+ matrix.m[2][2] = m1.m[0][2] * m2.m[2][0]
+ + m1.m[1][2] * m2.m[2][1]
+ + m1.m[2][2] * m2.m[2][2];
+ return matrix;
+}
+
+QDebug operator<<(QDebug dbg, const QOpenVGMatrix &m)
+{
+ QDebugStateSaver saver(dbg);
+ // Output in row-major order because it is more human-readable.
+ dbg.nospace() << "QOpenVGMatrix:(" << endl
+ << qSetFieldWidth(10)
+ << m(0, 0) << m(0, 1) << m(0, 2) << endl
+ << m(1, 0) << m(1, 1) << m(1, 2) << endl
+ << m(2, 0) << m(2, 1) << m(2, 2) << endl
+ << qSetFieldWidth(0) << ')';
+ return dbg;
+}
+
+QDataStream &operator<<(QDataStream &stream, const QOpenVGMatrix &matrix)
+{
+ for (int row = 0; row < 3; ++row)
+ for (int col = 0; col < 3; ++col)
+ stream << matrix(row, col);
+ return stream;
+}
+
+
+QDataStream &operator>>(QDataStream &stream, QOpenVGMatrix &matrix)
+{
+ float x;
+ for (int row = 0; row < 4; ++row) {
+ for (int col = 0; col < 4; ++col) {
+ stream >> x;
+ matrix(row, col) = x;
+ }
+ }
+ return stream;
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qopenvgmatrix.h b/src/plugins/scenegraph/openvg/qopenvgmatrix.h
new file mode 100644
index 0000000000..644c9da5bc
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qopenvgmatrix.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** 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 QOPENVGMATRIX_H
+#define QOPENVGMATRIX_H
+
+#include <QtCore/qdebug.h>
+#include <QtCore/QDataStream>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenVGMatrix
+{
+public:
+ QOpenVGMatrix();
+ explicit QOpenVGMatrix(const float *values);
+
+ const float& operator()(int row, int column) const;
+ float& operator()(int row, int column);
+
+ bool isIdentity() const;
+ void setToIdentity();
+
+ void fill(float value);
+
+ QOpenVGMatrix transposed() const;
+
+ QOpenVGMatrix& operator+=(const QOpenVGMatrix& other);
+ QOpenVGMatrix& operator-=(const QOpenVGMatrix& other);
+ QOpenVGMatrix& operator*=(const QOpenVGMatrix& other);
+ QOpenVGMatrix& operator*=(float factor);
+ QOpenVGMatrix& operator/=(float divisor);
+ friend QOpenVGMatrix operator*(const QOpenVGMatrix& m1, const QOpenVGMatrix& m2);
+#ifndef QT_NO_DEBUG_STREAM
+ friend QDebug operator<<(QDebug dbg, const QOpenVGMatrix &m);
+#endif
+ bool operator==(const QOpenVGMatrix& other) const;
+ bool operator!=(const QOpenVGMatrix& other) const;
+
+ void copyDataTo(float *values) const;
+
+ float *data() { return *m; }
+ const float *data() const { return *m; }
+ const float *constData() const { return *m; }
+
+private:
+ float m[3][3];
+};
+
+QOpenVGMatrix operator*(const QOpenVGMatrix& m1, const QOpenVGMatrix& m2);
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QOpenVGMatrix &m);
+#endif
+
+#ifndef QT_NO_DATASTREAM
+QDataStream &operator<<(QDataStream &, const QOpenVGMatrix &);
+QDataStream &operator>>(QDataStream &, QOpenVGMatrix &);
+#endif
+
+QT_END_NAMESPACE
+
+#endif // QOPENVGMATRIX_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgadaptation.cpp b/src/plugins/scenegraph/openvg/qsgopenvgadaptation.cpp
new file mode 100644
index 0000000000..1a26522459
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgadaptation.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** 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 "qsgopenvgadaptation_p.h"
+
+#include "qsgopenvgcontext_p.h"
+#include "qsgopenvgrenderloop_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGAdaptation::QSGOpenVGAdaptation(QObject *parent)
+ : QSGContextPlugin(parent)
+{
+}
+
+QStringList QSGOpenVGAdaptation::keys() const
+{
+ return QStringList() << QLatin1String("openvg");
+}
+
+QSGContext *QSGOpenVGAdaptation::create(const QString &key) const
+{
+ Q_UNUSED(key)
+ if (!instance)
+ instance = new QSGOpenVGContext();
+ return instance;
+}
+
+QSGRenderLoop *QSGOpenVGAdaptation::createWindowManager()
+{
+ return new QSGOpenVGRenderLoop();
+}
+
+QSGContextFactoryInterface::Flags QSGOpenVGAdaptation::flags(const QString &key) const
+{
+ Q_UNUSED(key)
+ return 0;
+}
+
+QSGOpenVGContext *QSGOpenVGAdaptation::instance = nullptr;
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgadaptation_p.h b/src/plugins/scenegraph/openvg/qsgopenvgadaptation_p.h
new file mode 100644
index 0000000000..77f79af9ac
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgadaptation_p.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGADAPTATION_H
+#define QSGOPENVGADAPTATION_H
+
+#include <private/qsgcontextplugin_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSGContext;
+class QSGRenderLoop;
+class QSGOpenVGContext;
+
+class QSGOpenVGAdaptation : public QSGContextPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QSGContextFactoryInterface" FILE "openvg.json")
+public:
+ QSGOpenVGAdaptation(QObject *parent = nullptr);
+
+ QStringList keys() const override;
+ QSGContext *create(const QString &key) const override;
+ QSGRenderLoop *createWindowManager() override;
+ Flags flags(const QString &key) const override;
+private:
+ static QSGOpenVGContext *instance;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGADAPTATION_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp b/src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp
new file mode 100644
index 0000000000..22a80c62e8
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp
@@ -0,0 +1,219 @@
+/****************************************************************************
+**
+** 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 "qsgopenvgcontext_p.h"
+#include "qsgopenvgrenderer_p.h"
+#include "qsgopenvginternalrectanglenode.h"
+#include "qsgopenvginternalimagenode.h"
+#include "qsgopenvgpublicnodes.h"
+#include "qsgopenvgtexture.h"
+#include "qsgopenvglayer.h"
+#include "qsgopenvgglyphnode_p.h"
+#include "qsgopenvgfontglyphcache.h"
+#include "qsgopenvgpainternode.h"
+#include "qsgopenvgspritenode.h"
+
+#include "qopenvgcontext_p.h"
+
+#include <private/qsgrenderer_p.h>
+
+// polish, animations, sync, render and swap in the render loop
+Q_LOGGING_CATEGORY(QSG_OPENVG_LOG_TIME_RENDERLOOP, "qt.scenegraph.time.renderloop")
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGRenderContext::QSGOpenVGRenderContext(QSGContext *context)
+ : QSGRenderContext(context)
+ , m_vgContext(nullptr)
+ , m_glyphCacheManager(nullptr)
+{
+
+}
+
+void QSGOpenVGRenderContext::initialize(void *context)
+{
+ m_vgContext = static_cast<QOpenVGContext*>(context);
+ QSGRenderContext::initialize(context);
+}
+
+void QSGOpenVGRenderContext::invalidate()
+{
+ m_vgContext = nullptr;
+ delete m_glyphCacheManager;
+ m_glyphCacheManager = nullptr;
+ QSGRenderContext::invalidate();
+}
+
+void QSGOpenVGRenderContext::renderNextFrame(QSGRenderer *renderer, uint fboId)
+{
+ renderer->renderScene(fboId);
+}
+
+QSGTexture *QSGOpenVGRenderContext::createTexture(const QImage &image, uint flags) const
+{
+ QImage tmp = image;
+
+ // Make sure image is not larger than maxTextureSize
+ int maxSize = maxTextureSize();
+ if (tmp.width() > maxSize || tmp.height() > maxSize) {
+ tmp = tmp.scaled(qMin(maxSize, tmp.width()), qMin(maxSize, tmp.height()), Qt::IgnoreAspectRatio, Qt::FastTransformation);
+ }
+
+ return new QSGOpenVGTexture(tmp, flags);
+}
+
+QSGRenderer *QSGOpenVGRenderContext::createRenderer()
+{
+ return new QSGOpenVGRenderer(this);
+}
+
+QSGOpenVGContext::QSGOpenVGContext(QObject *parent)
+{
+ Q_UNUSED(parent)
+}
+
+QSGRenderContext *QSGOpenVGContext::createRenderContext()
+{
+ return new QSGOpenVGRenderContext(this);
+}
+
+QSGRectangleNode *QSGOpenVGContext::createRectangleNode()
+{
+ return new QSGOpenVGRectangleNode;
+}
+
+QSGImageNode *QSGOpenVGContext::createImageNode()
+{
+ return new QSGOpenVGImageNode;
+}
+
+QSGPainterNode *QSGOpenVGContext::createPainterNode(QQuickPaintedItem *item)
+{
+ Q_UNUSED(item)
+ return new QSGOpenVGPainterNode(item);
+}
+
+QSGGlyphNode *QSGOpenVGContext::createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode)
+{
+ Q_UNUSED(preferNativeGlyphNode)
+ return new QSGOpenVGGlyphNode(rc);
+}
+
+QSGNinePatchNode *QSGOpenVGContext::createNinePatchNode()
+{
+ return new QSGOpenVGNinePatchNode;
+}
+
+QSGLayer *QSGOpenVGContext::createLayer(QSGRenderContext *renderContext)
+{
+ return new QSGOpenVGLayer(renderContext);
+}
+
+QSurfaceFormat QSGOpenVGContext::defaultSurfaceFormat() const
+{
+ QSurfaceFormat format = QSurfaceFormat::defaultFormat();
+ format.setRenderableType(QSurfaceFormat::OpenVG);
+ format.setMajorVersion(1);
+ return format;
+}
+
+QSGInternalRectangleNode *QSGOpenVGContext::createInternalRectangleNode()
+{
+ return new QSGOpenVGInternalRectangleNode();
+}
+
+QSGInternalImageNode *QSGOpenVGContext::createInternalImageNode()
+{
+ return new QSGOpenVGInternalImageNode();
+}
+
+int QSGOpenVGRenderContext::maxTextureSize() const
+{
+ VGint width = vgGeti(VG_MAX_IMAGE_WIDTH);
+ VGint height = vgGeti(VG_MAX_IMAGE_HEIGHT);
+
+ return qMin(width, height);
+}
+
+
+QSGSpriteNode *QSGOpenVGContext::createSpriteNode()
+{
+ return new QSGOpenVGSpriteNode();
+}
+
+QSGRendererInterface *QSGOpenVGContext::rendererInterface(QSGRenderContext *renderContext)
+{
+ return static_cast<QSGOpenVGRenderContext *>(renderContext);
+}
+
+QSGRendererInterface::GraphicsApi QSGOpenVGRenderContext::graphicsApi() const
+{
+ return OpenVG;
+}
+
+QSGRendererInterface::ShaderType QSGOpenVGRenderContext::shaderType() const
+{
+ return UnknownShadingLanguage;
+}
+
+QSGRendererInterface::ShaderCompilationTypes QSGOpenVGRenderContext::shaderCompilationType() const
+{
+ return 0;
+}
+
+QSGRendererInterface::ShaderSourceTypes QSGOpenVGRenderContext::shaderSourceType() const
+{
+ return 0;
+}
+
+QSGOpenVGFontGlyphCache *QSGOpenVGRenderContext::glyphCache(const QRawFont &rawFont)
+{
+ if (!m_glyphCacheManager)
+ m_glyphCacheManager = new QSGOpenVGFontGlyphCacheManager;
+
+ QSGOpenVGFontGlyphCache *cache = m_glyphCacheManager->cache(rawFont);
+ if (!cache) {
+ cache = new QSGOpenVGFontGlyphCache(m_glyphCacheManager, rawFont);
+ m_glyphCacheManager->insertCache(rawFont, cache);
+ }
+
+ return cache;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgcontext_p.h b/src/plugins/scenegraph/openvg/qsgopenvgcontext_p.h
new file mode 100644
index 0000000000..fa9939a253
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgcontext_p.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGCONTEXT_H
+#define QSGOPENVGCONTEXT_H
+
+#include <private/qsgcontext_p.h>
+#include <qsgrendererinterface.h>
+
+Q_DECLARE_LOGGING_CATEGORY(QSG_OPENVG_LOG_TIME_RENDERLOOP)
+
+QT_BEGIN_NAMESPACE
+
+class QOpenVGContext;
+class QSGOpenVGFontGlyphCache;
+class QSGOpenVGFontGlyphCacheManager;
+
+class QSGOpenVGRenderContext : public QSGRenderContext, public QSGRendererInterface
+{
+ Q_OBJECT
+public:
+ QSGOpenVGRenderContext(QSGContext *context);
+
+ void initialize(void *context) override;
+ void invalidate() override;
+ void renderNextFrame(QSGRenderer *renderer, uint fboId) override;
+ QSGTexture *createTexture(const QImage &image, uint flags) const override;
+ QSGRenderer *createRenderer() override;
+ int maxTextureSize() const override;
+
+ // QSGRendererInterface interface
+ GraphicsApi graphicsApi() const override;
+ ShaderType shaderType() const override;
+ ShaderCompilationTypes shaderCompilationType() const override;
+ ShaderSourceTypes shaderSourceType() const override;
+
+ QOpenVGContext* vgContext() { return m_vgContext; }
+ QSGOpenVGFontGlyphCache* glyphCache(const QRawFont &rawFont);
+
+private:
+ QOpenVGContext *m_vgContext;
+ QSGOpenVGFontGlyphCacheManager *m_glyphCacheManager;
+
+};
+
+class QSGOpenVGContext : public QSGContext
+{
+ Q_OBJECT
+public:
+ QSGOpenVGContext(QObject *parent = nullptr);
+
+ QSGRenderContext *createRenderContext() override;
+ QSGRectangleNode *createRectangleNode() override;
+ QSGImageNode *createImageNode() override;
+ QSGPainterNode *createPainterNode(QQuickPaintedItem *item) override;
+ QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode) override;
+ QSGNinePatchNode *createNinePatchNode() override;
+ QSGLayer *createLayer(QSGRenderContext *renderContext) override;
+ QSurfaceFormat defaultSurfaceFormat() const override;
+ QSGInternalRectangleNode *createInternalRectangleNode() override;
+ QSGInternalImageNode *createInternalImageNode() override;
+ QSGSpriteNode *createSpriteNode() override;
+ QSGRendererInterface *rendererInterface(QSGRenderContext *renderContext) override;
+};
+
+#endif // QSGOPENVGCONTEXT_H
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgfontglyphcache.cpp b/src/plugins/scenegraph/openvg/qsgopenvgfontglyphcache.cpp
new file mode 100644
index 0000000000..1ed54f7b6a
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgfontglyphcache.cpp
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** 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 "qsgopenvgfontglyphcache.h"
+#include "qsgopenvghelpers.h"
+#include <private/qfontengine_p.h>
+#include <private/qrawfont_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGFontGlyphCacheManager::QSGOpenVGFontGlyphCacheManager()
+{
+
+}
+
+QSGOpenVGFontGlyphCacheManager::~QSGOpenVGFontGlyphCacheManager()
+{
+ qDeleteAll(m_caches);
+}
+
+QSGOpenVGFontGlyphCache *QSGOpenVGFontGlyphCacheManager::cache(const QRawFont &font)
+{
+ return m_caches.value(fontKey(font), nullptr);
+}
+
+void QSGOpenVGFontGlyphCacheManager::insertCache(const QRawFont &font, QSGOpenVGFontGlyphCache *cache)
+{
+ m_caches.insert(fontKey(font), cache);
+}
+
+QString QSGOpenVGFontGlyphCacheManager::fontKey(const QRawFont &font)
+{
+ QFontEngine *fe = QRawFontPrivate::get(font)->fontEngine;
+ if (!fe->faceId().filename.isEmpty()) {
+ QByteArray keyName = fe->faceId().filename;
+ if (font.style() != QFont::StyleNormal)
+ keyName += QByteArray(" I");
+ if (font.weight() != QFont::Normal)
+ keyName += ' ' + QByteArray::number(font.weight());
+ keyName += " " + QString::number(font.pixelSize());
+ keyName += QByteArray(" DF");
+ return QString::fromUtf8(keyName);
+ } else {
+ return QString::fromLatin1("%1_%2_%3_%4_%5")
+ .arg(font.familyName())
+ .arg(font.styleName())
+ .arg(font.weight())
+ .arg(font.style())
+ .arg(font.pixelSize());
+ }
+}
+
+
+QSGOpenVGFontGlyphCache::QSGOpenVGFontGlyphCache(QSGOpenVGFontGlyphCacheManager *manager, const QRawFont &font)
+ : m_manager(manager)
+{
+ m_referenceFont = font;
+ QRawFontPrivate *fontD = QRawFontPrivate::get(font);
+ m_glyphCount = fontD->fontEngine->glyphCount();
+ m_font = vgCreateFont(0);
+}
+
+QSGOpenVGFontGlyphCache::~QSGOpenVGFontGlyphCache()
+{
+ if (m_font != VG_INVALID_HANDLE)
+ vgDestroyFont(m_font);
+}
+
+void QSGOpenVGFontGlyphCache::populate(const QVector<quint32> &glyphs)
+{
+ QSet<quint32> referencedGlyphs;
+ QSet<quint32> newGlyphs;
+ int count = glyphs.count();
+ for (int i = 0; i < count; ++i) {
+ quint32 glyphIndex = glyphs.at(i);
+ if ((int) glyphIndex >= glyphCount()) {
+ qWarning("Warning: glyph is not available with index %d", glyphIndex);
+ continue;
+ }
+
+ referencedGlyphs.insert(glyphIndex);
+
+
+ if (!m_cachedGlyphs.contains(glyphIndex)) {
+ newGlyphs.insert(glyphIndex);
+ }
+ }
+
+ referenceGlyphs(referencedGlyphs);
+ if (!newGlyphs.isEmpty())
+ requestGlyphs(newGlyphs);
+}
+
+void QSGOpenVGFontGlyphCache::release(const QVector<quint32> &glyphs)
+{
+ QSet<quint32> unusedGlyphs;
+ int count = glyphs.count();
+ for (int i = 0; i < count; ++i) {
+ quint32 glyphIndex = glyphs.at(i);
+ unusedGlyphs.insert(glyphIndex);
+ }
+ releaseGlyphs(unusedGlyphs);
+}
+
+void QSGOpenVGFontGlyphCache::requestGlyphs(const QSet<quint32> &glyphs)
+{
+ VGfloat origin[2];
+ VGfloat escapement[2];
+ QRectF metrics;
+ QRawFont rawFont = m_referenceFont;
+
+ // Before adding any new glyphs, remove any unused glyphs
+ for (auto glyph : qAsConst(m_unusedGlyphs)) {
+ vgClearGlyph(m_font, glyph);
+ }
+
+ for (auto glyph : glyphs) {
+ m_cachedGlyphs.insert(glyph);
+
+ // Calculate the path for the glyph and cache it.
+ QPainterPath path = rawFont.pathForGlyph(glyph);
+ VGPath vgPath;
+ if (!path.isEmpty()) {
+ vgPath = QSGOpenVGHelpers::qPainterPathToVGPath(path);
+ } else {
+ // Probably a "space" character with no visible outline.
+ vgPath = VG_INVALID_HANDLE;
+ }
+ origin[0] = 0;
+ origin[1] = 0;
+ escapement[0] = 0;
+ escapement[1] = 0;
+ vgSetGlyphToPath(m_font, glyph, vgPath, VG_FALSE, origin, escapement);
+ vgDestroyPath(vgPath); // Reduce reference count.
+ }
+
+}
+
+void QSGOpenVGFontGlyphCache::referenceGlyphs(const QSet<quint32> &glyphs)
+{
+ m_unusedGlyphs -= glyphs;
+}
+
+void QSGOpenVGFontGlyphCache::releaseGlyphs(const QSet<quint32> &glyphs)
+{
+ m_unusedGlyphs += glyphs;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgfontglyphcache.h b/src/plugins/scenegraph/openvg/qsgopenvgfontglyphcache.h
new file mode 100644
index 0000000000..a4a51cd2b6
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgfontglyphcache.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGFONTGLYPHCACHE_H
+#define QSGOPENVGFONTGLYPHCACHE_H
+
+#include <QtGui/QGlyphRun>
+#include <QtCore/QSet>
+#include <QtCore/QLinkedList>
+#include <VG/openvg.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSGOpenVGFontGlyphCache;
+
+class QSGOpenVGFontGlyphCacheManager
+{
+public:
+ QSGOpenVGFontGlyphCacheManager();
+ ~QSGOpenVGFontGlyphCacheManager();
+
+ QSGOpenVGFontGlyphCache *cache(const QRawFont &font);
+ void insertCache(const QRawFont &font, QSGOpenVGFontGlyphCache *cache);
+
+private:
+ static QString fontKey(const QRawFont &font);
+
+ QHash<QString, QSGOpenVGFontGlyphCache *> m_caches;
+};
+
+class QSGOpenVGFontGlyphCache
+{
+public:
+ QSGOpenVGFontGlyphCache(QSGOpenVGFontGlyphCacheManager *manager, const QRawFont &font);
+ ~QSGOpenVGFontGlyphCache();
+
+ const QSGOpenVGFontGlyphCacheManager *manager() const { return m_manager; }
+ const QRawFont &referenceFont() const { return m_referenceFont; }
+ int glyphCount() const { return m_glyphCount; }
+
+ void populate(const QVector<quint32> &glyphs);
+ void release(const QVector<quint32> &glyphs);
+
+ VGFont font() { return m_font; }
+
+private:
+ void requestGlyphs(const QSet<quint32> &glyphs);
+ void referenceGlyphs(const QSet<quint32> &glyphs);
+ void releaseGlyphs(const QSet<quint32> &glyphs);
+
+ QSGOpenVGFontGlyphCacheManager *m_manager;
+ QRawFont m_referenceFont;
+ int m_glyphCount;
+
+ VGFont m_font;
+ QSet<quint32> m_cachedGlyphs;
+ QSet<quint32> m_unusedGlyphs;
+};
+
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGFONTGLYPHCACHE_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgglyphnode.cpp b/src/plugins/scenegraph/openvg/qsgopenvgglyphnode.cpp
new file mode 100644
index 0000000000..c90f0f0bbe
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgglyphnode.cpp
@@ -0,0 +1,191 @@
+/****************************************************************************
+**
+** 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 "qsgopenvgglyphnode_p.h"
+#include "qopenvgcontext_p.h"
+#include "qsgopenvgcontext_p.h"
+#include "qsgopenvghelpers.h"
+#include "qsgopenvgfontglyphcache.h"
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGGlyphNode::QSGOpenVGGlyphNode(QSGRenderContext *rc)
+ : m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 0)
+ , m_style(QQuickText::Normal)
+ , m_glyphCache(nullptr)
+{
+ // Set Dummy material to avoid asserts
+ setMaterial((QSGMaterial*)1);
+ setGeometry(&m_geometry);
+ m_fontColorPaint = vgCreatePaint();
+ m_styleColorPaint = vgCreatePaint();
+
+ // Get handle to Glyph Cache
+ m_renderContext = static_cast<QSGOpenVGRenderContext*>(rc);
+}
+
+QSGOpenVGGlyphNode::~QSGOpenVGGlyphNode()
+{
+ if (m_glyphCache)
+ m_glyphCache->release(m_glyphRun.glyphIndexes());
+
+ vgDestroyPaint(m_fontColorPaint);
+ vgDestroyPaint(m_styleColorPaint);
+}
+
+void QSGOpenVGGlyphNode::setGlyphs(const QPointF &position, const QGlyphRun &glyphs)
+{
+ // Obtain glyph cache for font
+ auto oldGlyphCache = m_glyphCache;
+ m_glyphCache = m_renderContext->glyphCache(glyphs.rawFont());
+ if (m_glyphCache != oldGlyphCache) {
+ if (oldGlyphCache)
+ oldGlyphCache->release(m_glyphRun.glyphIndexes());
+ }
+ m_glyphCache->populate(glyphs.glyphIndexes());
+
+ m_position = position;
+ m_glyphRun = glyphs;
+
+ // Recreate ajustments
+ m_xAdjustments.clear();
+ m_yAdjustments.clear();
+
+ for (int i = 1; i < glyphs.positions().count(); ++i) {
+ m_xAdjustments.append(glyphs.positions().at(i).x() - glyphs.positions().at(i-1).x());
+ m_yAdjustments.append(glyphs.positions().at(i).y() - glyphs.positions().at(i-1).y());
+ }
+}
+
+void QSGOpenVGGlyphNode::setColor(const QColor &color)
+{
+ m_color = color;
+ vgSetParameteri(m_fontColorPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
+ vgSetParameterfv(m_fontColorPaint, VG_PAINT_COLOR, 4, QSGOpenVGHelpers::qColorToVGColor(m_color, opacity()).constData());
+}
+
+void QSGOpenVGGlyphNode::setStyle(QQuickText::TextStyle style)
+{
+ m_style = style;
+}
+
+void QSGOpenVGGlyphNode::setStyleColor(const QColor &color)
+{
+ m_styleColor = color;
+ vgSetParameteri(m_styleColorPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
+ vgSetParameterfv(m_styleColorPaint, VG_PAINT_COLOR, 4, QSGOpenVGHelpers::qColorToVGColor(m_styleColor, opacity()).constData());
+}
+
+QPointF QSGOpenVGGlyphNode::baseLine() const
+{
+ return QPointF();
+}
+
+void QSGOpenVGGlyphNode::setPreferredAntialiasingMode(QSGGlyphNode::AntialiasingMode)
+{
+}
+
+void QSGOpenVGGlyphNode::update()
+{
+}
+
+void QSGOpenVGGlyphNode::render()
+{
+ if (m_glyphRun.positions().count() == 0)
+ return;
+
+ // Rendering Style
+ qreal offset = 1.0;
+
+ vgSeti(VG_RENDERING_QUALITY, VG_RENDERING_QUALITY_BETTER);
+
+ switch (m_style) {
+ case QQuickText::Normal: break;
+ case QQuickText::Outline:
+ // Set the correct fill state
+ vgSetPaint(m_styleColorPaint, VG_FILL_PATH);
+ drawGlyphsAtOffset(QPointF(0, offset));
+ drawGlyphsAtOffset(QPointF(0, -offset));
+ drawGlyphsAtOffset(QPointF(offset, 0));
+ drawGlyphsAtOffset(QPointF(-offset, 0));
+ break;
+ case QQuickText::Raised:
+ vgSetPaint(m_styleColorPaint, VG_FILL_PATH);
+ drawGlyphsAtOffset(QPointF(0, offset));
+ break;
+ case QQuickText::Sunken:
+ vgSetPaint(m_styleColorPaint, VG_FILL_PATH);
+ drawGlyphsAtOffset(QPointF(0, -offset));
+ break;
+ }
+
+ // Set the correct fill state
+ vgSetPaint(m_fontColorPaint, VG_FILL_PATH);
+ drawGlyphsAtOffset(QPointF(0.0, 0.0));
+
+}
+
+void QSGOpenVGGlyphNode::setOpacity(float opacity)
+{
+ if (QSGOpenVGRenderable::opacity() != opacity) {
+ QSGOpenVGRenderable::setOpacity(opacity);
+ // Update Colors
+ setColor(m_color);
+ setStyleColor(m_styleColor);
+ }
+}
+
+void QSGOpenVGGlyphNode::drawGlyphsAtOffset(const QPointF &offset)
+{
+ QPointF firstPosition = m_glyphRun.positions()[0] + (m_position - QPointF(0, m_glyphRun.rawFont().ascent()));
+ VGfloat origin[2];
+ origin[0] = firstPosition.x() + offset.x();
+ origin[1] = firstPosition.y() + offset.y();
+ vgSetfv(VG_GLYPH_ORIGIN, 2, origin);
+
+ vgDrawGlyphs(m_glyphCache->font(),
+ m_glyphRun.glyphIndexes().count(),
+ (VGuint*)m_glyphRun.glyphIndexes().constData(),
+ m_xAdjustments.constData(),
+ m_yAdjustments.constData(),
+ VG_FILL_PATH,
+ VG_TRUE);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgglyphnode_p.h b/src/plugins/scenegraph/openvg/qsgopenvgglyphnode_p.h
new file mode 100644
index 0000000000..205e3dcbc8
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgglyphnode_p.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGGLYPHNODE_H
+#define QSGOPENVGGLYPHNODE_H
+
+#include <private/qsgadaptationlayer_p.h>
+#include <QtCore/QVector>
+
+#include <VG/openvg.h>
+
+#include "qsgopenvgrenderable.h"
+#include "qsgopenvgfontglyphcache.h"
+
+QT_BEGIN_NAMESPACE
+
+class QSGOpenVGFontGlyphCache;
+class QSGOpenVGRenderContext;
+class QSGRenderContext;
+
+class QSGOpenVGGlyphNode : public QSGGlyphNode, public QSGOpenVGRenderable
+{
+public:
+ QSGOpenVGGlyphNode(QSGRenderContext *rc);
+ ~QSGOpenVGGlyphNode();
+
+ void setGlyphs(const QPointF &position, const QGlyphRun &glyphs) override;
+ void setColor(const QColor &color) override;
+ void setStyle(QQuickText::TextStyle style) override;
+ void setStyleColor(const QColor &color) override;
+ QPointF baseLine() const override;
+ void setPreferredAntialiasingMode(AntialiasingMode) override;
+ void update() override;
+
+ void render() override;
+ void setOpacity(float opacity) override;
+
+private:
+ void drawGlyphsAtOffset(const QPointF &offset);
+
+ QPointF m_position;
+ QGlyphRun m_glyphRun;
+ QColor m_color;
+ QSGGeometry m_geometry;
+ QQuickText::TextStyle m_style;
+ QColor m_styleColor;
+
+ QSGOpenVGFontGlyphCache *m_glyphCache;
+ QVector<VGfloat> m_xAdjustments;
+ QVector<VGfloat> m_yAdjustments;
+ VGPaint m_fontColorPaint;
+ VGPaint m_styleColorPaint;
+
+ QSGOpenVGRenderContext *m_renderContext;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGGLYPHNODE_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvghelpers.cpp b/src/plugins/scenegraph/openvg/qsgopenvghelpers.cpp
new file mode 100644
index 0000000000..6bc99d32a1
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvghelpers.cpp
@@ -0,0 +1,433 @@
+/****************************************************************************
+**
+** 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 "qsgopenvghelpers.h"
+#include <cmath>
+
+QT_BEGIN_NAMESPACE
+
+namespace QSGOpenVGHelpers {
+
+VGPath qPainterPathToVGPath(const QPainterPath &path)
+{
+ int count = path.elementCount();
+
+ VGPath vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD,
+ VG_PATH_DATATYPE_F,
+ 1.0f, // scale
+ 0.0f, // bias
+ count + 1, // segmentCapacityHint
+ count * 2, // coordCapacityHint
+ VG_PATH_CAPABILITY_ALL);
+
+ if (count == 0)
+ return vgpath;
+
+ QVector<VGfloat> coords;
+ QVector<VGubyte> segments;
+
+ int curvePos = 0;
+ QPointF temp;
+
+ // Keep track of the start and end of each sub-path. QPainterPath
+ // does not have an "implicit close" flag like QVectorPath does.
+ // We therefore have to detect closed paths by looking for a LineTo
+ // element that connects back to the initial MoveTo element.
+ qreal startx = 0.0;
+ qreal starty = 0.0;
+ qreal endx = 0.0;
+ qreal endy = 0.0;
+ bool haveStart = false;
+ bool haveEnd = false;
+
+ for (int i = 0; i < count; ++i) {
+ const QPainterPath::Element element = path.elementAt(i);
+ switch (element.type) {
+
+ case QPainterPath::MoveToElement:
+ {
+ if (haveStart && haveEnd && startx == endx && starty == endy) {
+ // Implicitly close the previous sub-path.
+ segments.append(VG_CLOSE_PATH);
+ }
+ temp = QPointF(element.x, element.y);
+ startx = temp.x();
+ starty = temp.y();
+ coords.append(startx);
+ coords.append(starty);
+ haveStart = true;
+ haveEnd = false;
+ segments.append(VG_MOVE_TO_ABS);
+ }
+ break;
+
+ case QPainterPath::LineToElement:
+ {
+ temp = QPointF(element.x, element.y);
+ endx = temp.x();
+ endy = temp.y();
+ coords.append(endx);
+ coords.append(endy);
+ haveEnd = true;
+ segments.append(VG_LINE_TO_ABS);
+ }
+ break;
+
+ case QPainterPath::CurveToElement:
+ {
+ temp = QPointF(element.x, element.y);
+ coords.append(temp.x());
+ coords.append(temp.y());
+ haveEnd = false;
+ curvePos = 2;
+ }
+ break;
+
+ case QPainterPath::CurveToDataElement:
+ {
+ temp = QPointF(element.x, element.y);
+ coords.append(temp.x());
+ coords.append(temp.y());
+ haveEnd = false;
+ curvePos += 2;
+ if (curvePos == 6) {
+ curvePos = 0;
+ segments.append(VG_CUBIC_TO_ABS);
+ }
+ }
+ break;
+
+ }
+ }
+
+ if (haveStart && haveEnd && startx == endx && starty == endy) {
+ // Implicitly close the last sub-path.
+ segments.append(VG_CLOSE_PATH);
+ }
+
+ vgAppendPathData(vgpath, segments.count(),
+ segments.constData(), coords.constData());
+
+ return vgpath;
+}
+
+
+void qDrawTiled(VGImage image, const QSize imageSize, const QRectF &targetRect, const QPointF offset, float scaleX, float scaleY) {
+
+ //Check for valid image size and targetRect
+ if (imageSize.width() <= 0 || imageSize.height() <= 0)
+ return;
+ if (targetRect.width() <= 0 || targetRect.height() <= 0)
+ return;
+
+ // This logic is mostly from the Qt Raster PaintEngine's qt_draw_tile
+ qreal drawH;
+ qreal drawW;
+ qreal xPos;
+ qreal xOff;
+ qreal yPos = targetRect.y();
+ qreal yOff;
+
+ if (offset.y() < 0)
+ yOff = imageSize.height() - qRound(-offset.y()) % imageSize.height();
+ else
+ yOff = qRound(offset.y()) % imageSize.height();
+
+
+ // Save the current image transform matrix
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+ QVector<float> originalMatrix(9);
+ vgGetMatrix(originalMatrix.data());
+
+ while (!qFuzzyCompare(yPos, targetRect.y() + targetRect.height()) &&
+ yPos < targetRect.y() + targetRect.height()) {
+ drawH = imageSize.height() - yOff; // Cropping first row
+ if (yPos + drawH * scaleY > targetRect.y() + targetRect.height()) { // Cropping last row
+ // Check that values aren't equal
+ if (!qFuzzyCompare((float)(yPos + drawH * scaleY), (float)(targetRect.y() + targetRect.height())))
+ drawH = targetRect.y() + targetRect.height() - yPos;
+ }
+ xPos = targetRect.x();
+ if (offset.x() < 0)
+ xOff = imageSize.width() - qRound(-offset.x()) % imageSize.width();
+ else
+ xOff = qRound(offset.x()) % imageSize.width();
+
+ while (!qFuzzyCompare(xPos, targetRect.x() + targetRect.width()) &&
+ xPos < targetRect.x() + targetRect.width()) {
+ drawW = imageSize.width() - xOff; // Cropping first column
+ if (xPos + drawW * scaleX > targetRect.x() + targetRect.width()) {
+ // Check that values aren't equal
+ if (!qFuzzyCompare((float)(xPos + drawW * scaleX), (float)(targetRect.x() + targetRect.width())))
+ drawW = targetRect.x() + targetRect.width() - xPos;
+ }
+ if (round(drawW) > 0 && round(drawH) > 0) { // Can't source image less than 1 width or height
+ //Draw here
+ VGImage childRectImage = vgChildImage(image, xOff, yOff, round(drawW), round(drawH));
+ vgTranslate(xPos, yPos);
+ vgScale(scaleX, scaleY);
+ vgDrawImage(childRectImage);
+ vgDestroyImage(childRectImage);
+ vgLoadMatrix(originalMatrix.constData());
+ }
+ if ( drawW > 0)
+ xPos += drawW * scaleX;
+ xOff = 0;
+ }
+ if ( drawH > 0)
+ yPos += drawH * scaleY;
+ yOff = 0;
+
+ }
+}
+
+void qDrawBorderImage(VGImage image, const QSizeF &textureSize, const QRectF &targetRect, const QRectF &innerTargetRect, const QRectF &subSourceRect)
+{
+ // Create normalized margins
+ QMarginsF margins(qMax(innerTargetRect.left() - targetRect.left(), 0.0),
+ qMax(innerTargetRect.top() - targetRect.top(), 0.0),
+ qMax(targetRect.right() - innerTargetRect.right(), 0.0),
+ qMax(targetRect.bottom() - innerTargetRect.bottom(), 0.0));
+
+ QRectF sourceRect(0, 0, textureSize.width(), textureSize.height());
+
+ // Create all the subRects
+ QRectF topLeftSourceRect(sourceRect.topLeft(), QSizeF(margins.left(), margins.top()));
+ QRectF topRightSourceRect(sourceRect.width() - margins.right(), sourceRect.top(), margins.right(), margins.top());
+ QRectF bottomLeftSourceRect(sourceRect.left(), sourceRect.height() - margins.bottom(), margins.left(), margins.bottom());
+ QRectF bottomRightSourceRect(sourceRect.width() - margins.right(), sourceRect.height() - margins.bottom(), margins.right(), margins.bottom());
+
+ QRectF topSourceRect(margins.left(), 0.0, sourceRect.width() - (margins.right() + margins.left()), margins.top());
+ QRectF topTargetRect(margins.left(), 0.0, innerTargetRect.width(), margins.top());
+ QRectF bottomSourceRect(margins.left(), sourceRect.height() - margins.bottom(), sourceRect.width() - (margins.right() + margins.left()), margins.bottom());
+ QRectF bottomTargetRect(margins.left(), targetRect.height() - margins.bottom(), innerTargetRect.width(), margins.bottom());
+ QRectF leftSourceRect(0.0, margins.top(), margins.left(), sourceRect.height() - (margins.bottom() + margins.top()));
+ QRectF leftTargetRect(0.0, margins.top(), margins.left(), innerTargetRect.height());
+ QRectF rightSourceRect(sourceRect.width() - margins.right(), margins.top(), margins.right(), sourceRect.height() - (margins.bottom() + margins.top()));
+ QRectF rightTargetRect(targetRect.width() - margins.right(), margins.top(), margins.right(), innerTargetRect.height());
+
+ QRectF centerSourceRect(margins.left(), margins.top(), sourceRect.width() - (margins.right() + margins.left()), sourceRect.height() - (margins.top() + margins.bottom()));
+
+ // Draw the 9 different sections
+ // (1) Top Left (unscaled)
+ qDrawSubImage(image,
+ topLeftSourceRect,
+ targetRect.topLeft());
+
+ // (3) Top Right (unscaled)
+ qDrawSubImage(image,
+ topRightSourceRect,
+ QPointF(targetRect.width() - margins.right(), 0.0));
+
+ // (7) Bottom Left (unscaled)
+ qDrawSubImage(image,
+ bottomLeftSourceRect,
+ QPointF(targetRect.left(), targetRect.height() - margins.bottom()));
+
+ // (9) Bottom Right (unscaled)
+ qDrawSubImage(image,
+ bottomRightSourceRect,
+ QPointF(targetRect.width() - margins.right(), targetRect.height() - margins.bottom()));
+
+ double scaledWidth = 1.0;
+ double scaledHeight = 1.0;
+
+ // (2) Top (scaled via horizontalTileRule)
+ VGImage topImage = vgChildImage(image, topSourceRect.x(), topSourceRect.y(), topSourceRect.width(), topSourceRect.height());
+ scaledWidth = (topTargetRect.width() / subSourceRect.width()) / topSourceRect.width();
+
+ QSGOpenVGHelpers::qDrawTiled(topImage, topSourceRect.size().toSize(), topTargetRect, QPoint(0.0, 0.0), scaledWidth, 1);
+
+ vgDestroyImage(topImage);
+
+ // (8) Bottom (scaled via horizontalTileRule)
+ VGImage bottomImage = vgChildImage(image, bottomSourceRect.x(), bottomSourceRect.y(), bottomSourceRect.width(), bottomSourceRect.height());
+ scaledWidth = (bottomTargetRect.width() / subSourceRect.width()) / bottomSourceRect.width();
+
+ QSGOpenVGHelpers::qDrawTiled(bottomImage, bottomSourceRect.size().toSize(), bottomTargetRect, QPoint(0.0, 0.0), scaledWidth, 1);
+
+ vgDestroyImage(bottomImage);
+
+ // (4) Left (scaled via verticalTileRule)
+ VGImage leftImage = vgChildImage(image, leftSourceRect.x(), leftSourceRect.y(), leftSourceRect.width(), leftSourceRect.height());
+ scaledHeight = (leftTargetRect.height() / subSourceRect.height()) / leftSourceRect.height();
+ QSGOpenVGHelpers::qDrawTiled(leftImage, leftSourceRect.size().toSize(), leftTargetRect, QPointF(0.0, 0.0), 1, scaledHeight);
+
+ vgDestroyImage(leftImage);
+
+ // (6) Right (scaled via verticalTileRule)
+ VGImage rightImage = vgChildImage(image, rightSourceRect.x(), rightSourceRect.y(), rightSourceRect.width(), rightSourceRect.height());
+ scaledHeight = (rightTargetRect.height() / subSourceRect.height()) / rightSourceRect.height();
+
+ QSGOpenVGHelpers::qDrawTiled(rightImage, rightSourceRect.size().toSize(), rightTargetRect, QPointF(0, 0), 1, scaledHeight);
+
+ vgDestroyImage(rightImage);
+
+ // (5) Center (saled via verticalTileRule and horizontalTileRule)
+ VGImage centerImage = vgChildImage(image, centerSourceRect.x(), centerSourceRect.y(), centerSourceRect.width(), centerSourceRect.height());
+
+ scaledWidth = (innerTargetRect.width() / subSourceRect.width()) / centerSourceRect.width();
+ scaledHeight = (innerTargetRect.height() / subSourceRect.height()) / centerSourceRect.height();
+
+ QSGOpenVGHelpers::qDrawTiled(centerImage, centerSourceRect.size().toSize(), innerTargetRect, QPointF(0, 0), scaledWidth, scaledHeight);
+
+ vgDestroyImage(centerImage);
+}
+
+void qDrawSubImage(VGImage image, const QRectF &sourceRect, const QPointF &destOffset)
+{
+ // Check for valid source size
+ if (sourceRect.width() <= 0 || sourceRect.height() <= 0)
+ return;
+
+ // Save the current image transform matrix
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+ QVector<float> originalMatrix(9);
+ vgGetMatrix(originalMatrix.data());
+
+ // Get the child Image
+ VGImage childRectImage = vgChildImage(image, sourceRect.x(), sourceRect.y(), sourceRect.width(), sourceRect.height());
+ vgTranslate(destOffset.x(), destOffset.y());
+ vgDrawImage(childRectImage);
+ vgDestroyImage(childRectImage);
+
+ // Pop Matrix
+ vgLoadMatrix(originalMatrix.constData());
+}
+
+const QVector<VGfloat> qColorToVGColor(const QColor &color, float opacity)
+{
+ QVector<VGfloat> vgColor(4);
+ vgColor[0] = color.redF();
+ vgColor[1] = color.greenF();
+ vgColor[2] = color.blueF();
+ vgColor[3] = color.alphaF() * opacity;
+ return vgColor;
+}
+
+VGImageFormat qImageFormatToVGImageFormat(QImage::Format format)
+{
+ VGImageFormat vgFormat;
+
+ switch (format) {
+ case QImage::Format_Mono:
+ case QImage::Format_MonoLSB:
+ vgFormat = VG_BW_1;
+ break;
+ case QImage::Format_RGB32:
+ vgFormat = VG_sXRGB_8888;
+ break;
+ case QImage::Format_ARGB32:
+ vgFormat = VG_sARGB_8888;
+ break;
+ case QImage::Format_ARGB32_Premultiplied:
+ vgFormat = VG_sARGB_8888_PRE;
+ break;
+ case QImage::Format_RGB16:
+ vgFormat = VG_sRGB_565;
+ break;
+ case QImage::Format_RGBX8888:
+ vgFormat = VG_sRGBX_8888;
+ break;
+ case QImage::Format_RGBA8888:
+ vgFormat = VG_sRGBA_8888;
+ break;
+ case QImage::Format_RGBA8888_Premultiplied:
+ vgFormat = VG_sRGBA_8888_PRE;
+ break;
+ case QImage::Format_Alpha8:
+ vgFormat = VG_A_8;
+ break;
+ case QImage::Format_Grayscale8:
+ vgFormat = VG_sL_8;
+ break;
+ default:
+ //Invalid
+ vgFormat = (VGImageFormat)-1;
+ break;
+ }
+
+ return vgFormat;
+}
+
+QImage::Format qVGImageFormatToQImageFormat(VGImageFormat format)
+{
+ QImage::Format qImageFormat;
+
+ switch (format) {
+ case VG_BW_1:
+ qImageFormat = QImage::Format_Mono;
+ break;
+ case VG_sXRGB_8888:
+ qImageFormat = QImage::Format_RGB32;
+ break;
+ case VG_sARGB_8888:
+ qImageFormat = QImage::Format_ARGB32;
+ break;
+ case VG_sARGB_8888_PRE:
+ qImageFormat = QImage::Format_ARGB32_Premultiplied;
+ break;
+ case VG_sRGB_565:
+ qImageFormat = QImage::Format_RGB16;
+ break;
+ case VG_sRGBX_8888:
+ qImageFormat = QImage::Format_RGBX8888;
+ break;
+ case VG_sRGBA_8888:
+ qImageFormat = QImage::Format_RGBA8888;
+ break;
+ case VG_sRGBA_8888_PRE:
+ qImageFormat = QImage::Format_RGBA8888_Premultiplied;
+ break;
+ case VG_A_8:
+ qImageFormat = QImage::Format_Alpha8;
+ break;
+ case VG_sL_8:
+ qImageFormat = QImage::Format_Grayscale8;
+ default:
+ qImageFormat = QImage::Format_ARGB32;
+ break;
+ }
+
+ return qImageFormat;
+}
+
+} // end namespace QSGOpenVGHelpers
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvghelpers.h b/src/plugins/scenegraph/openvg/qsgopenvghelpers.h
new file mode 100644
index 0000000000..ee8ff73ca8
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvghelpers.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGHELPERS_H
+#define QSGOPENVGHELPERS_H
+
+#include <QtGui/QPainterPath>
+#include <QtGui/QColor>
+#include <QtGui/QImage>
+#include <VG/openvg.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QSGOpenVGHelpers {
+
+VGPath qPainterPathToVGPath(const QPainterPath &path);
+void qDrawTiled(VGImage image, const QSize imageSize, const QRectF &targetRect, const QPointF offset, float scaleX, float scaleY);
+void qDrawBorderImage(VGImage image, const QSizeF &textureSize, const QRectF &targetRect, const QRectF &innerTargetRect, const QRectF &subSourceRect);
+void qDrawSubImage(VGImage image, const QRectF &sourceRect, const QPointF &destOffset);
+const QVector<VGfloat> qColorToVGColor(const QColor &color, float opacity = 1.0f);
+VGImageFormat qImageFormatToVGImageFormat(QImage::Format format);
+QImage::Format qVGImageFormatToQImageFormat(VGImageFormat format);
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGHELPERS_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvginternalimagenode.cpp b/src/plugins/scenegraph/openvg/qsgopenvginternalimagenode.cpp
new file mode 100644
index 0000000000..2ab477f116
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvginternalimagenode.cpp
@@ -0,0 +1,233 @@
+/****************************************************************************
+**
+** 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 "qsgopenvginternalimagenode.h"
+#include "qsgopenvghelpers.h"
+
+#include <VG/openvg.h>
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGInternalImageNode::QSGOpenVGInternalImageNode()
+{
+ // Set Dummy material and geometry to avoid asserts
+ setMaterial((QSGMaterial*)1);
+ setGeometry((QSGGeometry*)1);
+}
+
+QSGOpenVGInternalImageNode::~QSGOpenVGInternalImageNode()
+{
+ if (m_subSourceRectImage != 0)
+ vgDestroyImage(m_subSourceRectImage);
+}
+
+void QSGOpenVGInternalImageNode::render()
+{
+ if (!m_texture) {
+ return;
+ }
+
+ // Set Draw Mode
+ if (opacity() < 1.0) {
+ //Transparent
+ vgSetPaint(opacityPaint(), VG_FILL_PATH);
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_MULTIPLY);
+ } else {
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL);
+ }
+
+
+ VGImage image = static_cast<VGImage>(m_texture->textureId());
+ QSize textureSize = m_texture->textureSize();
+
+
+ // If Mirrored
+ if (m_mirror) {
+ vgTranslate(m_targetRect.width(), 0.0f);
+ vgScale(-1.0, 1.0);
+ }
+
+ if (m_smooth)
+ vgSeti(VG_IMAGE_QUALITY, VG_IMAGE_QUALITY_BETTER);
+ else
+ vgSeti(VG_IMAGE_QUALITY, VG_IMAGE_QUALITY_NONANTIALIASED);
+
+
+ if (m_innerTargetRect != m_targetRect) {
+ // border image
+ QSGOpenVGHelpers::qDrawBorderImage(image, textureSize, m_targetRect, m_innerTargetRect, m_subSourceRect);
+ } else if (m_tileHorizontal || m_tileVertical) {
+ // Tilled Image
+
+ float sx = m_targetRect.width() / (m_subSourceRect.width() * textureSize.width());
+ float sy = m_targetRect.height() / (m_subSourceRect.height() * textureSize.height());
+ QPointF offset(m_subSourceRect.left() * textureSize.width(), m_subSourceRect.top() * textureSize.height());
+
+ QSGOpenVGHelpers::qDrawTiled(image, textureSize, m_targetRect, offset, sx, sy);
+
+ } else {
+ // Regular BLIT
+
+ QRectF sr(m_subSourceRect.left() * textureSize.width(), m_subSourceRect.top() * textureSize.height(),
+ m_subSourceRect.width() * textureSize.width(), m_subSourceRect.height() * textureSize.height());
+
+ if (m_subSourceRectImageDirty) {
+ if (m_subSourceRectImage != 0)
+ vgDestroyImage(m_subSourceRectImage);
+ m_subSourceRectImage = vgChildImage(image, sr.x(), sr.y(), sr.width(), sr.height());
+ m_subSourceRectImageDirty = false;
+ }
+
+ // If the the source rect is the same as the target rect
+ if (sr == m_targetRect) {
+ vgDrawImage(image);
+ } else {
+ // Scale
+ float scaleX = m_targetRect.width() / sr.width();
+ float scaleY = m_targetRect.height() / sr.height();
+ vgTranslate(m_targetRect.x(), m_targetRect.y());
+ vgScale(scaleX, scaleY);
+ vgDrawImage(m_subSourceRectImage);
+ }
+ }
+}
+
+void QSGOpenVGInternalImageNode::setTargetRect(const QRectF &rect)
+{
+ if (rect == m_targetRect)
+ return;
+ m_targetRect = rect;
+ markDirty(DirtyGeometry);
+}
+
+void QSGOpenVGInternalImageNode::setInnerTargetRect(const QRectF &rect)
+{
+ if (rect == m_innerTargetRect)
+ return;
+ m_innerTargetRect = rect;
+ markDirty(DirtyGeometry);
+}
+
+void QSGOpenVGInternalImageNode::setInnerSourceRect(const QRectF &rect)
+{
+ if (rect == m_innerSourceRect)
+ return;
+ m_innerSourceRect = rect;
+ markDirty(DirtyGeometry);
+}
+
+void QSGOpenVGInternalImageNode::setSubSourceRect(const QRectF &rect)
+{
+ if (rect == m_subSourceRect)
+ return;
+ m_subSourceRect = rect;
+ m_subSourceRectImageDirty = true;
+ markDirty(DirtyGeometry);
+}
+
+void QSGOpenVGInternalImageNode::setTexture(QSGTexture *texture)
+{
+ m_texture = texture;
+ m_subSourceRectImageDirty = true;
+ markDirty(DirtyMaterial);
+}
+
+void QSGOpenVGInternalImageNode::setMirror(bool mirror)
+{
+ if (m_mirror != mirror) {
+ m_mirror = mirror;
+ markDirty(DirtyMaterial);
+ }
+}
+
+void QSGOpenVGInternalImageNode::setMipmapFiltering(QSGTexture::Filtering)
+{
+}
+
+void QSGOpenVGInternalImageNode::setFiltering(QSGTexture::Filtering filtering)
+{
+ bool smooth = (filtering == QSGTexture::Linear);
+ if (smooth == m_smooth)
+ return;
+
+ m_smooth = smooth;
+ markDirty(DirtyMaterial);
+}
+
+void QSGOpenVGInternalImageNode::setHorizontalWrapMode(QSGTexture::WrapMode wrapMode)
+{
+ bool tileHorizontal = (wrapMode == QSGTexture::Repeat);
+ if (tileHorizontal == m_tileHorizontal)
+ return;
+
+ m_tileHorizontal = tileHorizontal;
+ markDirty(DirtyMaterial);
+}
+
+void QSGOpenVGInternalImageNode::setVerticalWrapMode(QSGTexture::WrapMode wrapMode)
+{
+ bool tileVertical = (wrapMode == QSGTexture::Repeat);
+ if (tileVertical == m_tileVertical)
+ return;
+
+ m_tileVertical = (wrapMode == QSGTexture::Repeat);
+ markDirty(DirtyMaterial);
+}
+
+void QSGOpenVGInternalImageNode::update()
+{
+}
+
+void QSGOpenVGInternalImageNode::preprocess()
+{
+ bool doDirty = false;
+ QSGLayer *t = qobject_cast<QSGLayer *>(m_texture);
+ if (t) {
+ doDirty = t->updateTexture();
+ markDirty(DirtyGeometry);
+ }
+ if (doDirty)
+ markDirty(DirtyMaterial);
+}
+
+QT_END_NAMESPACE
+
+
+
+
diff --git a/src/plugins/scenegraph/openvg/qsgopenvginternalimagenode.h b/src/plugins/scenegraph/openvg/qsgopenvginternalimagenode.h
new file mode 100644
index 0000000000..2361aa4892
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvginternalimagenode.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGINTERNALIMAGENODE_H
+#define QSGOPENVGINTERNALIMAGENODE_H
+
+#include <private/qsgadaptationlayer_p.h>
+#include "qsgopenvgrenderable.h"
+
+#include <VG/openvg.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSGOpenVGInternalImageNode : public QSGInternalImageNode, public QSGOpenVGRenderable
+{
+public:
+ QSGOpenVGInternalImageNode();
+ ~QSGOpenVGInternalImageNode();
+
+ void render() override;
+
+ void setTargetRect(const QRectF &rect) override;
+ void setInnerTargetRect(const QRectF &rect) override;
+ void setInnerSourceRect(const QRectF &rect) override;
+ void setSubSourceRect(const QRectF &rect) override;
+ void setTexture(QSGTexture *texture) override;
+ void setMirror(bool mirror) override;
+ 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 update() override;
+
+ void preprocess() override;
+
+private:
+
+ QRectF m_targetRect;
+ QRectF m_innerTargetRect;
+ QRectF m_innerSourceRect = QRectF(0, 0, 1, 1);
+ QRectF m_subSourceRect = QRectF(0, 0, 1, 1);
+
+ bool m_mirror = false;
+ bool m_smooth = true;
+ bool m_tileHorizontal = false;
+ bool m_tileVertical = false;
+
+ QSGTexture *m_texture = nullptr;
+
+ VGImage m_subSourceRectImage = 0;
+ bool m_subSourceRectImageDirty = true;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGINTERNALIMAGENODE_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvginternalrectanglenode.cpp b/src/plugins/scenegraph/openvg/qsgopenvginternalrectanglenode.cpp
new file mode 100644
index 0000000000..372dffbbc2
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvginternalrectanglenode.cpp
@@ -0,0 +1,613 @@
+/****************************************************************************
+**
+** 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 "qsgopenvginternalrectanglenode.h"
+#include "qsgopenvghelpers.h"
+
+#include <VG/vgu.h>
+
+QSGOpenVGInternalRectangleNode::QSGOpenVGInternalRectangleNode()
+{
+ // Set Dummy material and geometry to avoid asserts
+ setMaterial((QSGMaterial*)1);
+ setGeometry((QSGGeometry*)1);
+ createVGResources();
+}
+
+QSGOpenVGInternalRectangleNode::~QSGOpenVGInternalRectangleNode()
+{
+ destroyVGResources();
+}
+
+
+void QSGOpenVGInternalRectangleNode::setRect(const QRectF &rect)
+{
+ m_rect = rect;
+ m_pathDirty = true;
+}
+
+void QSGOpenVGInternalRectangleNode::setColor(const QColor &color)
+{
+ m_fillColor = color;
+ m_fillDirty = true;
+}
+
+void QSGOpenVGInternalRectangleNode::setPenColor(const QColor &color)
+{
+ m_strokeColor = color;
+ m_strokeDirty = true;
+}
+
+void QSGOpenVGInternalRectangleNode::setPenWidth(qreal width)
+{
+ m_penWidth = width;
+ m_strokeDirty = true;
+ m_pathDirty = true;
+}
+
+//Move first stop by pos relative to seconds
+static QGradientStop interpolateStop(const QGradientStop &firstStop, const QGradientStop &secondStop, double newPos)
+{
+ double distance = secondStop.first - firstStop.first;
+ double distanceDelta = newPos - firstStop.first;
+ double modifierValue = distanceDelta / distance;
+ int redDelta = (secondStop.second.red() - firstStop.second.red()) * modifierValue;
+ int greenDelta = (secondStop.second.green() - firstStop.second.green()) * modifierValue;
+ int blueDelta = (secondStop.second.blue() - firstStop.second.blue()) * modifierValue;
+ int alphaDelta = (secondStop.second.alpha() - firstStop.second.alpha()) * modifierValue;
+
+ QGradientStop newStop;
+ newStop.first = newPos;
+ newStop.second = QColor(firstStop.second.red() + redDelta,
+ firstStop.second.green() + greenDelta,
+ firstStop.second.blue() + blueDelta,
+ firstStop.second.alpha() + alphaDelta);
+
+ return newStop;
+}
+
+void QSGOpenVGInternalRectangleNode::setGradientStops(const QGradientStops &stops)
+{
+
+ //normalize stops
+ bool needsNormalization = false;
+ for (const QGradientStop &stop : qAsConst(stops)) {
+ if (stop.first < 0.0 || stop.first > 1.0) {
+ needsNormalization = true;
+ continue;
+ }
+ }
+
+ if (needsNormalization) {
+ QGradientStops normalizedStops;
+ if (stops.count() == 1) {
+ //If there is only one stop, then the position does not matter
+ //It is just treated as a color
+ QGradientStop stop = stops.at(0);
+ stop.first = 0.0;
+ normalizedStops.append(stop);
+ } else {
+ //Clip stops to only the first below 0.0 and above 1.0
+ int below = -1;
+ int above = -1;
+ QVector<int> between;
+ for (int i = 0; i < stops.count(); ++i) {
+ if (stops.at(i).first < 0.0) {
+ below = i;
+ } else if (stops.at(i).first > 1.0) {
+ above = i;
+ break;
+ } else {
+ between.append(i);
+ }
+ }
+
+ //Interpoloate new color values for above and below
+ if (below != -1 ) {
+ //If there are more than one stops left, interpolate
+ if (below + 1 < stops.count()) {
+ normalizedStops.append(interpolateStop(stops.at(below), stops.at(below + 1), 0.0));
+ } else {
+ QGradientStop singleStop;
+ singleStop.first = 0.0;
+ singleStop.second = stops.at(below).second;
+ normalizedStops.append(singleStop);
+ }
+ }
+
+ for (int i = 0; i < between.count(); ++i)
+ normalizedStops.append(stops.at(between.at(i)));
+
+ if (above != -1) {
+ //If there stops before above, interpolate
+ if (above >= 1) {
+ normalizedStops.append(interpolateStop(stops.at(above), stops.at(above - 1), 1.0));
+ } else {
+ QGradientStop singleStop;
+ singleStop.first = 1.0;
+ singleStop.second = stops.at(above).second;
+ normalizedStops.append(singleStop);
+ }
+ }
+ }
+
+ m_gradientStops = normalizedStops;
+
+ } else {
+ m_gradientStops = stops;
+ }
+
+ m_fillDirty = true;
+}
+
+void QSGOpenVGInternalRectangleNode::setRadius(qreal radius)
+{
+ m_radius = radius;
+ m_pathDirty = true;
+}
+
+void QSGOpenVGInternalRectangleNode::setAligned(bool aligned)
+{
+ m_aligned = aligned;
+}
+
+void QSGOpenVGInternalRectangleNode::update()
+{
+}
+
+void QSGOpenVGInternalRectangleNode::render()
+{
+ // If path is dirty
+ if (m_pathDirty) {
+ vgClearPath(m_rectanglePath, VG_PATH_CAPABILITY_APPEND_TO);
+ vgClearPath(m_borderPath, VG_PATH_CAPABILITY_APPEND_TO);
+
+ if (m_penWidth == 0) {
+ generateRectanglePath(m_rect, m_radius, m_rectanglePath);
+ } else {
+ generateRectangleAndBorderPaths(m_rect, m_penWidth, m_radius, m_rectanglePath, m_borderPath);
+ }
+
+ m_pathDirty = false;
+ }
+
+ //If fill is drity
+ if (m_fillDirty) {
+ if (m_gradientStops.isEmpty()) {
+ vgSetParameteri(m_rectanglePaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
+ vgSetParameterfv(m_rectanglePaint, VG_PAINT_COLOR, 4, QSGOpenVGHelpers::qColorToVGColor(m_fillColor, opacity()).constData());
+ } else {
+ // Linear Gradient
+ vgSetParameteri(m_rectanglePaint, VG_PAINT_TYPE, VG_PAINT_TYPE_LINEAR_GRADIENT);
+ const VGfloat verticalLinearGradient[] = {
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ static_cast<VGfloat>(m_rect.height())
+ };
+ vgSetParameterfv(m_rectanglePaint, VG_PAINT_LINEAR_GRADIENT, 4, verticalLinearGradient);
+ vgSetParameteri(m_rectanglePaint, VG_PAINT_COLOR_RAMP_SPREAD_MODE, VG_COLOR_RAMP_SPREAD_PAD);
+ vgSetParameteri(m_rectanglePaint, VG_PAINT_COLOR_RAMP_PREMULTIPLIED, false);
+
+ QVector<VGfloat> stops;
+ for (const QGradientStop &stop : qAsConst(m_gradientStops)) {
+ // offset
+ stops.append(stop.first);
+ // color
+ stops.append(QSGOpenVGHelpers::qColorToVGColor(stop.second, opacity()));
+ }
+
+ vgSetParameterfv(m_rectanglePaint, VG_PAINT_COLOR_RAMP_STOPS, stops.length(), stops.constData());
+ }
+
+ m_fillDirty = false;
+ }
+
+ //If stroke is dirty
+ if (m_strokeDirty) {
+ vgSetParameteri(m_borderPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
+ vgSetParameterfv(m_borderPaint, VG_PAINT_COLOR, 4, QSGOpenVGHelpers::qColorToVGColor(m_strokeColor, opacity()).constData());
+
+ m_strokeDirty = false;
+ }
+
+ //Draw
+ if (m_penWidth > 0) {
+ vgSetPaint(m_borderPaint, VG_FILL_PATH);
+ vgDrawPath(m_borderPath, VG_FILL_PATH);
+ vgSetPaint(m_rectanglePaint, VG_FILL_PATH);
+ vgDrawPath(m_rectanglePath, VG_FILL_PATH);
+ } else {
+ vgSetPaint(m_rectanglePaint, VG_FILL_PATH);
+ vgDrawPath(m_rectanglePath, VG_FILL_PATH);
+ }
+}
+
+void QSGOpenVGInternalRectangleNode::setOpacity(float opacity)
+{
+ if (opacity != QSGOpenVGRenderable::opacity()) {
+ QSGOpenVGRenderable::setOpacity(opacity);
+ m_strokeDirty = true;
+ m_fillDirty = true;
+ }
+}
+
+void QSGOpenVGInternalRectangleNode::createVGResources()
+{
+ m_rectanglePaint = vgCreatePaint();
+ m_borderPaint = vgCreatePaint();
+ m_rectanglePath = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1, 0, 0, 0,
+ VG_PATH_CAPABILITY_APPEND_TO);
+ m_borderPath = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1, 0, 0, 0,
+ VG_PATH_CAPABILITY_APPEND_TO);
+}
+
+void QSGOpenVGInternalRectangleNode::destroyVGResources()
+{
+ vgDestroyPaint(m_rectanglePaint);
+ vgDestroyPaint(m_borderPaint);
+ vgDestroyPath(m_rectanglePath);
+ vgDestroyPath(m_borderPath);
+}
+
+void QSGOpenVGInternalRectangleNode::generateRectanglePath(const QRectF &rect, float radius, VGPath path) const
+{
+ if (radius == 0) {
+ // Generate a rectangle
+
+ // Create command list
+ static const VGubyte rectCommands[] = {
+ VG_MOVE_TO_ABS,
+ VG_HLINE_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_HLINE_TO_REL,
+ VG_CLOSE_PATH
+ };
+
+ // Create command data
+ QVector<VGfloat> coordinates(5);
+ coordinates[0] = rect.x();
+ coordinates[1] = rect.y();
+ coordinates[2] = rect.width();
+ coordinates[3] = rect.height();
+ coordinates[4] = -rect.width();
+
+ vgAppendPathData(path, 5, rectCommands, coordinates.constData());
+ } else {
+ // Generate a rounded rectangle
+ //Radius should never exceeds half of the width or half of the height
+ float adjustedRadius = qMin((float)qMin(rect.width(), rect.height()) * 0.5f, radius);
+
+ // OpenVG expectes radius to be 2x what we expect
+ adjustedRadius *= 2;
+
+ // Create command list
+ static const VGubyte roundedRectCommands[] = {
+ VG_MOVE_TO_ABS,
+ VG_HLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ VG_HLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ VG_CLOSE_PATH
+ };
+
+ // Create command data
+ QVector<VGfloat> coordinates(26);
+
+ coordinates[0] = rect.x() + adjustedRadius / 2;
+ coordinates[1] = rect.y();
+
+ coordinates[2] = rect.width() - adjustedRadius;
+
+ coordinates[3] = adjustedRadius / 2;
+ coordinates[4] = adjustedRadius / 2;
+ coordinates[5] = 0;
+ coordinates[6] = adjustedRadius / 2;
+ coordinates[7] = adjustedRadius / 2;
+
+ coordinates[8] = rect.height() - adjustedRadius;
+
+ coordinates[9] = adjustedRadius / 2;
+ coordinates[10] = adjustedRadius / 2;
+ coordinates[11] = 0;
+ coordinates[12] = -adjustedRadius / 2;
+ coordinates[13] = adjustedRadius / 2;
+
+ coordinates[14] = -(rect.width() - adjustedRadius);
+
+ coordinates[15] = adjustedRadius / 2;
+ coordinates[16] = adjustedRadius / 2;
+ coordinates[17] = 0;
+ coordinates[18] = -adjustedRadius / 2;
+ coordinates[19] = -adjustedRadius / 2;
+
+ coordinates[20] = -(rect.height() - adjustedRadius);
+
+ coordinates[21] = adjustedRadius / 2;
+ coordinates[22] = adjustedRadius / 2;
+ coordinates[23] = 0;
+ coordinates[24] = adjustedRadius / 2;
+ coordinates[25] = -adjustedRadius / 2;
+
+ vgAppendPathData(path, 10, roundedRectCommands, coordinates.constData());
+ }
+}
+
+void QSGOpenVGInternalRectangleNode::generateBorderPath(const QRectF &rect, float borderWidth, float borderHeight, float radius, VGPath path) const
+{
+ if (radius == 0) {
+ // squared frame
+ // Create command list
+ static const VGubyte squaredBorderCommands[] = {
+ VG_MOVE_TO_ABS,
+ VG_HLINE_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_HLINE_TO_REL,
+ VG_MOVE_TO_ABS,
+ VG_VLINE_TO_REL,
+ VG_HLINE_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_CLOSE_PATH
+ };
+
+ // Create command data
+ QVector<VGfloat> coordinates(10);
+ // Outside Square
+ coordinates[0] = rect.x();
+ coordinates[1] = rect.y();
+ coordinates[2] = rect.width();
+ coordinates[3] = rect.height();
+ coordinates[4] = -rect.width();
+ // Inside Square (opposite direction)
+ coordinates[5] = rect.x() + borderWidth;
+ coordinates[6] = rect.y() + borderHeight;
+ coordinates[7] = rect.height() - (borderHeight * 2);
+ coordinates[8] = rect.width() - (borderWidth * 2);
+ coordinates[9] = -(rect.height() - (borderHeight * 2));
+
+ vgAppendPathData(path, 9, squaredBorderCommands, coordinates.constData());
+ } else if (radius < qMax(borderWidth, borderHeight)){
+ // rounded outside, squared inside
+ // Create command list
+ static const VGubyte roundedRectCommands[] = {
+ VG_MOVE_TO_ABS,
+ VG_HLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ VG_HLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ VG_MOVE_TO_ABS,
+ VG_VLINE_TO_REL,
+ VG_HLINE_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_CLOSE_PATH
+ };
+
+ // Ajust for OpenVG's usage or radius
+ float adjustedRadius = radius * 2;
+
+ // Create command data
+ QVector<VGfloat> coordinates(31);
+ // Outside Rounded Rect
+ coordinates[0] = rect.x() + adjustedRadius / 2;
+ coordinates[1] = rect.y();
+
+ coordinates[2] = rect.width() - adjustedRadius;
+
+ coordinates[3] = adjustedRadius / 2;
+ coordinates[4] = adjustedRadius / 2;
+ coordinates[5] = 0;
+ coordinates[6] = adjustedRadius / 2;
+ coordinates[7] = adjustedRadius / 2;
+
+ coordinates[8] = rect.height() - adjustedRadius;
+
+ coordinates[9] = adjustedRadius / 2;
+ coordinates[10] = adjustedRadius / 2;
+ coordinates[11] = 0;
+ coordinates[12] = -adjustedRadius / 2;
+ coordinates[13] = adjustedRadius / 2;
+
+ coordinates[14] = -(rect.width() - adjustedRadius);
+
+ coordinates[15] = adjustedRadius / 2;
+ coordinates[16] = adjustedRadius / 2;
+ coordinates[17] = 0;
+ coordinates[18] = -adjustedRadius / 2;
+ coordinates[19] = -adjustedRadius / 2;
+
+ coordinates[20] = -(rect.height() - adjustedRadius);
+
+ coordinates[21] = adjustedRadius / 2;
+ coordinates[22] = adjustedRadius / 2;
+ coordinates[23] = 0;
+ coordinates[24] = adjustedRadius / 2;
+ coordinates[25] = -adjustedRadius / 2;
+
+ // Inside Square (opposite direction)
+ coordinates[26] = rect.x() + borderWidth;
+ coordinates[27] = rect.y() + borderHeight;
+ coordinates[28] = rect.height() - (borderHeight * 2);
+ coordinates[29] = rect.width() - (borderWidth * 2);
+ coordinates[30] = -(rect.height() - (borderHeight * 2));
+
+ vgAppendPathData(path, 14, roundedRectCommands, coordinates.constData());
+ } else {
+ // rounded outside, rounded inside
+
+ static const VGubyte roundedBorderCommands[] = {
+ // Outer
+ VG_MOVE_TO_ABS,
+ VG_HLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ VG_HLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ // Inner
+ VG_MOVE_TO_ABS,
+ VG_SCWARC_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_SCWARC_TO_REL,
+ VG_HLINE_TO_REL,
+ VG_SCWARC_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_SCWARC_TO_REL,
+ VG_HLINE_TO_REL,
+ VG_CLOSE_PATH
+ };
+
+ // Adjust for OpenVG's usage or radius
+ float adjustedRadius = radius * 2;
+ float adjustedInnerRadius = (radius - qMax(borderWidth, borderHeight)) * 2;
+
+ // Create command data
+ QVector<VGfloat> coordinates(52);
+
+ // Outer
+ coordinates[0] = rect.x() + adjustedRadius / 2;
+ coordinates[1] = rect.y();
+
+ coordinates[2] = rect.width() - adjustedRadius;
+
+ coordinates[3] = adjustedRadius / 2;
+ coordinates[4] = adjustedRadius / 2;
+ coordinates[5] = 0;
+ coordinates[6] = adjustedRadius / 2;
+ coordinates[7] = adjustedRadius / 2;
+
+ coordinates[8] = rect.height() - adjustedRadius;
+
+ coordinates[9] = adjustedRadius / 2;
+ coordinates[10] = adjustedRadius / 2;
+ coordinates[11] = 0;
+ coordinates[12] = -adjustedRadius / 2;
+ coordinates[13] = adjustedRadius / 2;
+
+ coordinates[14] = -(rect.width() - adjustedRadius);
+
+ coordinates[15] = adjustedRadius / 2;
+ coordinates[16] = adjustedRadius / 2;
+ coordinates[17] = 0;
+ coordinates[18] = -adjustedRadius / 2;
+ coordinates[19] = -adjustedRadius / 2;
+
+ coordinates[20] = -(rect.height() - adjustedRadius);
+
+ coordinates[21] = adjustedRadius / 2;
+ coordinates[22] = adjustedRadius / 2;
+ coordinates[23] = 0;
+ coordinates[24] = adjustedRadius / 2;
+ coordinates[25] = -adjustedRadius / 2;
+
+ // Inner
+ coordinates[26] = rect.width() - (adjustedInnerRadius / 2 + borderWidth);
+ coordinates[27] = rect.height() - borderHeight;
+
+ coordinates[28] = adjustedInnerRadius / 2;
+ coordinates[29] = adjustedInnerRadius / 2;
+ coordinates[30] = 0;
+ coordinates[31] = adjustedInnerRadius / 2;
+ coordinates[32] = -adjustedInnerRadius / 2;
+
+ coordinates[33] = -((rect.height() - borderHeight * 2) - adjustedInnerRadius);
+
+ coordinates[34] = adjustedInnerRadius / 2;
+ coordinates[35] = adjustedInnerRadius / 2;
+ coordinates[36] = 0;
+ coordinates[37] = -adjustedInnerRadius / 2;
+ coordinates[38] = -adjustedInnerRadius / 2;
+
+ coordinates[39] = -((rect.width() - borderWidth * 2) - adjustedInnerRadius);
+
+ coordinates[40] = adjustedInnerRadius / 2;
+ coordinates[41] = adjustedInnerRadius / 2;
+ coordinates[42] = 0;
+ coordinates[43] = -adjustedInnerRadius / 2;
+ coordinates[44] = adjustedInnerRadius / 2;
+
+ coordinates[45] = (rect.height() - borderHeight * 2) - adjustedInnerRadius;
+
+ coordinates[46] = adjustedInnerRadius / 2;
+ coordinates[47] = adjustedInnerRadius / 2;
+ coordinates[48] = 0;
+ coordinates[49] = adjustedInnerRadius / 2;
+ coordinates[50] = adjustedInnerRadius / 2;
+
+ coordinates[51] = (rect.width() - borderWidth * 2) - adjustedInnerRadius;
+
+ vgAppendPathData(path, 19, roundedBorderCommands, coordinates.constData());
+ }
+}
+
+void QSGOpenVGInternalRectangleNode::generateRectangleAndBorderPaths(const QRectF &rect, float penWidth, float radius, VGPath inside, VGPath outside) const
+{
+ //Borders can not be more than half the height/width of a rect
+ float borderWidth = qMin(penWidth, (float)rect.width() * 0.5f);
+ float borderHeight = qMin(penWidth, (float)rect.height() * 0.5f);
+
+ //Radius should never exceeds half of the width or half of the height
+ float adjustedRadius = qMin((float)qMin(rect.width(), rect.height()) * 0.5f, radius);
+
+ QRectF innerRect = rect;
+ innerRect.adjust(borderWidth, borderHeight, -borderWidth, -borderHeight);
+
+ if (radius == 0) {
+ // Regular rect with border
+ generateRectanglePath(innerRect, 0, inside);
+ generateBorderPath(rect, borderWidth, borderHeight, 0, outside);
+ } else {
+ // Rounded Rect with border
+ float innerRadius = radius - qMax(borderWidth, borderHeight);
+ if (innerRadius < 0)
+ innerRadius = 0.0f;
+
+ generateRectanglePath(innerRect, innerRadius, inside);
+ generateBorderPath(rect, borderWidth, borderHeight, adjustedRadius, outside);
+ }
+}
diff --git a/src/plugins/scenegraph/openvg/qsgopenvginternalrectanglenode.h b/src/plugins/scenegraph/openvg/qsgopenvginternalrectanglenode.h
new file mode 100644
index 0000000000..0d5283773f
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvginternalrectanglenode.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGINTERNALRECTANGLENODE_H
+#define QSGOPENVGINTERNALRECTANGLENODE_H
+
+#include <private/qsgadaptationlayer_p.h>
+#include "qsgopenvgrenderable.h"
+
+#include <VG/openvg.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSGOpenVGInternalRectangleNode : public QSGInternalRectangleNode, public QSGOpenVGRenderable
+{
+public:
+ QSGOpenVGInternalRectangleNode();
+ ~QSGOpenVGInternalRectangleNode();
+
+ void setRect(const QRectF &rect) override;
+ void setColor(const QColor &color) override;
+ void setPenColor(const QColor &color) override;
+ void setPenWidth(qreal width) override;
+ void setGradientStops(const QGradientStops &stops) override;
+ void setRadius(qreal radius) override;
+ void setAligned(bool aligned) override;
+ void update() override;
+
+ void render() override;
+ void setOpacity(float opacity) override;
+
+private:
+ void createVGResources();
+ void destroyVGResources();
+
+ void generateRectanglePath(const QRectF &rect, float radius, VGPath path) const;
+ void generateRectangleAndBorderPaths(const QRectF &rect, float penWidth, float radius, VGPath inside, VGPath outside) const;
+ void generateBorderPath(const QRectF &rect, float borderWidth, float borderHeight, float radius, VGPath path) const;
+
+ bool m_pathDirty = true;
+ bool m_fillDirty = true;
+ bool m_strokeDirty = true;
+
+ QRectF m_rect;
+ QColor m_fillColor;
+ QColor m_strokeColor;
+ qreal m_penWidth = 0.0;
+ qreal m_radius = 0.0;
+ bool m_aligned = false;
+ QGradientStops m_gradientStops;
+
+ VGPath m_rectanglePath;
+ VGPath m_borderPath;
+ VGPaint m_rectanglePaint;
+ VGPaint m_borderPaint;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGINTERNALRECTANGLENODE_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvglayer.cpp b/src/plugins/scenegraph/openvg/qsgopenvglayer.cpp
new file mode 100644
index 0000000000..03a82ca4ee
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvglayer.cpp
@@ -0,0 +1,360 @@
+/****************************************************************************
+**
+** 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 "qsgopenvglayer.h"
+#include "qsgopenvgrenderer_p.h"
+#include "qsgopenvgcontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGLayer::QSGOpenVGLayer(QSGRenderContext *renderContext)
+ : m_item(nullptr)
+ , m_renderer(nullptr)
+ , m_device_pixel_ratio(1)
+ , m_mirrorHorizontal(false)
+ , m_mirrorVertical(false)
+ , m_live(true)
+ , m_grab(true)
+ , m_recursive(false)
+ , m_dirtyTexture(true)
+ , m_image(0)
+ , m_renderTarget(0)
+ , m_layerContext(0)
+{
+ m_context = static_cast<QSGOpenVGRenderContext*>(renderContext);
+ m_vgContext = m_context->vgContext();
+}
+
+QSGOpenVGLayer::~QSGOpenVGLayer()
+{
+ invalidated();
+}
+
+int QSGOpenVGLayer::textureId() const
+{
+ return static_cast<int>(m_image);
+}
+
+QSize QSGOpenVGLayer::textureSize() const
+{
+ if (m_image != 0) {
+ VGint imageWidth = vgGetParameteri(m_image, VG_IMAGE_WIDTH);
+ VGint imageHeight = vgGetParameteri(m_image, VG_IMAGE_HEIGHT);
+ return QSize(imageWidth, imageHeight);
+ }
+
+ return QSize();
+}
+
+bool QSGOpenVGLayer::hasAlphaChannel() const
+{
+ VGImageFormat format = static_cast<VGImageFormat>(vgGetParameteri(m_image, VG_IMAGE_FORMAT));
+
+ switch (format) {
+ case VG_sRGBA_8888:
+ case VG_sRGBA_8888_PRE:
+ case VG_sRGBA_5551:
+ case VG_sRGBA_4444:
+ case VG_lRGBA_8888:
+ case VG_lRGBA_8888_PRE:
+ case VG_A_8:
+ case VG_A_1:
+ case VG_A_4:
+ case VG_sARGB_8888:
+ case VG_sARGB_8888_PRE:
+ case VG_sARGB_1555:
+ case VG_sARGB_4444:
+ case VG_lARGB_8888:
+ case VG_lARGB_8888_PRE:
+ case VG_sBGRA_8888:
+ case VG_sBGRA_8888_PRE:
+ case VG_sBGRA_5551:
+ case VG_sBGRA_4444:
+ case VG_lBGRA_8888:
+ case VG_lBGRA_8888_PRE:
+ case VG_sABGR_8888:
+ case VG_sABGR_8888_PRE:
+ case VG_sABGR_1555:
+ case VG_sABGR_4444:
+ case VG_lABGR_8888:
+ case VG_lABGR_8888_PRE:
+ return true;
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+bool QSGOpenVGLayer::hasMipmaps() const
+{
+ return false;
+}
+
+void QSGOpenVGLayer::bind()
+{
+}
+
+bool QSGOpenVGLayer::updateTexture()
+{
+ bool doGrab = (m_live || m_grab) && m_dirtyTexture;
+ if (doGrab)
+ grab();
+ if (m_grab)
+ emit scheduledUpdateCompleted();
+ m_grab = false;
+ return doGrab;
+}
+
+void QSGOpenVGLayer::setItem(QSGNode *item)
+{
+ if (item == m_item)
+ return;
+ m_item = item;
+
+ if (m_live && !m_item) {
+ vgDestroyImage(m_image);
+ m_image = 0;
+ }
+
+ markDirtyTexture();
+}
+
+void QSGOpenVGLayer::setRect(const QRectF &rect)
+{
+ if (rect == m_rect)
+ return;
+ m_rect = rect;
+ markDirtyTexture();
+}
+
+void QSGOpenVGLayer::setSize(const QSize &size)
+{
+ if (size == m_size)
+ return;
+ m_size = size;
+
+ if (m_live && m_size.isNull()) {
+ vgDestroyImage(m_image);
+ m_image = 0;
+ }
+
+ markDirtyTexture();
+}
+
+void QSGOpenVGLayer::scheduleUpdate()
+{
+ if (m_grab)
+ return;
+ m_grab = true;
+ if (m_dirtyTexture) {
+ emit updateRequested();
+ }
+}
+
+QImage QSGOpenVGLayer::toImage() const
+{
+ // XXX
+ return QImage();
+}
+
+void QSGOpenVGLayer::setLive(bool live)
+{
+ if (live == m_live)
+ return;
+ m_live = live;
+
+ if (m_live && (!m_item || m_size.isNull())) {
+ vgDestroyImage(m_image);
+ m_image = 0;
+ }
+
+ markDirtyTexture();
+}
+
+void QSGOpenVGLayer::setRecursive(bool recursive)
+{
+ m_recursive = recursive;
+}
+
+void QSGOpenVGLayer::setFormat(uint format)
+{
+ Q_UNUSED(format)
+}
+
+void QSGOpenVGLayer::setHasMipmaps(bool mipmap)
+{
+ Q_UNUSED(mipmap)
+}
+
+void QSGOpenVGLayer::setDevicePixelRatio(qreal ratio)
+{
+ m_device_pixel_ratio = ratio;
+}
+
+void QSGOpenVGLayer::setMirrorHorizontal(bool mirror)
+{
+ if (m_mirrorHorizontal == mirror)
+ return;
+ m_mirrorHorizontal = mirror;
+ markDirtyTexture();
+}
+
+void QSGOpenVGLayer::setMirrorVertical(bool mirror)
+{
+ if (m_mirrorVertical == mirror)
+ return;
+ m_mirrorVertical = mirror;
+ markDirtyTexture();
+}
+
+void QSGOpenVGLayer::markDirtyTexture()
+{
+ m_dirtyTexture = true;
+ if (m_live || m_grab) {
+ emit updateRequested();
+ }
+}
+
+void QSGOpenVGLayer::invalidated()
+{
+ delete m_renderer;
+ m_renderer = 0;
+}
+
+void QSGOpenVGLayer::grab()
+{
+ if (!m_item || m_size.isNull()) {
+ vgDestroyImage(m_image);
+ m_image = 0;
+ 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 = new QSGOpenVGRenderer(m_context);
+ connect(m_renderer, SIGNAL(sceneGraphChanged()), this, SLOT(markDirtyTexture()));
+ }
+ m_renderer->setDevicePixelRatio(m_device_pixel_ratio);
+ m_renderer->setRootNode(static_cast<QSGRootNode *>(root));
+
+ if (m_image == 0 || m_imageSize != m_size ) {
+ if (m_image != 0)
+ vgDestroyImage(m_image);
+
+ m_image = vgCreateImage(VG_lARGB_8888_PRE, m_size.width(), m_size.height(), VG_IMAGE_QUALITY_BETTER);
+ m_imageSize = m_size;
+
+ //Destroy old RenderTarget
+ if (m_renderTarget != 0)
+ eglDestroySurface(m_vgContext->eglDisplay(), m_renderTarget);
+
+ const EGLint configAttribs[] = {
+ EGL_CONFORMANT, EGL_OPENVG_BIT,
+ EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ EGL_ALPHA_MASK_SIZE, 8,
+ EGL_NONE
+ };
+
+ EGLConfig pbufferConfig;
+ EGLint numConfig;
+ eglChooseConfig(m_vgContext->eglDisplay(), configAttribs, &pbufferConfig, 1, &numConfig);
+
+ if (m_layerContext == 0) {
+ // Create new context
+ m_layerContext = eglCreateContext(m_vgContext->eglDisplay(), pbufferConfig, m_vgContext->eglContext(), 0);
+ }
+
+ m_renderTarget = eglCreatePbufferFromClientBuffer(m_vgContext->eglDisplay(),
+ EGL_OPENVG_IMAGE,
+ (EGLClientBuffer)m_image,
+ pbufferConfig,
+ 0);
+ }
+
+ if (m_renderTarget == EGL_NO_SURFACE) {
+ qDebug() << "invalid renderTarget!";
+ return;
+ }
+
+ // Render texture.
+ root->markDirty(QSGNode::DirtyForceUpdate); // Force matrix, clip and opacity update.
+ m_renderer->nodeChanged(root, QSGNode::DirtyForceUpdate); // Force render list update.
+
+ m_dirtyTexture = false;
+
+ m_renderer->setDeviceRect(m_size);
+ m_renderer->setViewportRect(m_size);
+ QRect mirrored(m_mirrorHorizontal ? m_rect.right() * m_device_pixel_ratio : m_rect.left() * m_device_pixel_ratio,
+ m_mirrorVertical ? m_rect.top() * m_device_pixel_ratio : m_rect.bottom() * m_device_pixel_ratio,
+ m_mirrorHorizontal ? -m_rect.width() * m_device_pixel_ratio : m_rect.width() * m_device_pixel_ratio,
+ m_mirrorVertical ? m_rect.height() * m_device_pixel_ratio : -m_rect.height() * m_device_pixel_ratio);
+ m_renderer->setProjectionMatrixToRect(mirrored);
+ m_renderer->setClearColor(Qt::transparent);
+
+ eglMakeCurrent(m_vgContext->eglDisplay(), m_renderTarget, m_renderTarget, m_layerContext);
+
+ // Before Rendering setup context for adjusting to Qt Coordinates to PixelBuffer
+ // Should already be inverted by default
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+ vgLoadIdentity();
+
+ m_renderer->renderScene();
+
+ eglSwapBuffers(m_vgContext->eglDisplay(), m_renderTarget);
+
+ // make the default surface current again
+ m_vgContext->makeCurrent();
+
+ root->markDirty(QSGNode::DirtyForceUpdate); // Force matrix, clip, opacity and render list update.
+
+ if (m_recursive)
+ markDirtyTexture(); // Continuously update if 'live' and 'recursive'.
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvglayer.h b/src/plugins/scenegraph/openvg/qsgopenvglayer.h
new file mode 100644
index 0000000000..ee9984b9d9
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvglayer.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGLAYER_H
+#define QSGOPENVGLAYER_H
+
+#include <private/qsgadaptationlayer_p.h>
+#include <private/qsgcontext_p.h>
+
+#include "qopenvgcontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QSGOpenVGRenderer;
+class QSGOpenVGRenderContext;
+
+class QSGOpenVGLayer : public QSGLayer
+{
+public:
+ QSGOpenVGLayer(QSGRenderContext *renderContext);
+ ~QSGOpenVGLayer();
+
+ // QSGTexture interface
+public:
+ int textureId() const override;
+ QSize textureSize() const override;
+ bool hasAlphaChannel() const override;
+ bool hasMipmaps() const override;
+ void bind() override;
+
+ // QSGDynamicTexture interface
+public:
+ bool updateTexture() override;
+
+ // QSGLayer interface
+public:
+ 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;
+
+public slots:
+ void markDirtyTexture() override;
+ void invalidated() override;
+
+private:
+ void grab();
+
+ QSGNode *m_item;
+ QSGOpenVGRenderContext *m_context;
+ QSGOpenVGRenderer *m_renderer;
+ QRectF m_rect;
+ QSize m_size;
+ qreal m_device_pixel_ratio;
+ bool m_mirrorHorizontal;
+ bool m_mirrorVertical;
+ bool m_live;
+ bool m_grab;
+ bool m_recursive;
+ bool m_dirtyTexture;
+
+ QOpenVGContext *m_vgContext;
+ VGImage m_image;
+ QSize m_imageSize;
+ EGLSurface m_renderTarget;
+ EGLContext m_layerContext;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGLAYER_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.cpp b/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.cpp
new file mode 100644
index 0000000000..fc9f5eb57c
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.cpp
@@ -0,0 +1,283 @@
+/****************************************************************************
+**
+** 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 "qsgopenvgnodevisitor.h"
+#include "qsgopenvginternalrectanglenode.h"
+#include "qsgopenvginternalimagenode.h"
+#include "qsgopenvgpublicnodes.h"
+#include "qsgopenvgglyphnode_p.h"
+#include "qsgopenvgpainternode.h"
+#include "qsgopenvgspritenode.h"
+#include "qsgopenvgrenderable.h"
+
+#include "qopenvgcontext_p.h"
+
+#include <QtQuick/qsgsimplerectnode.h>
+#include <QtQuick/qsgsimpletexturenode.h>
+#include <QtQuick/qsgrendernode.h>
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGNodeVisitor::QSGOpenVGNodeVisitor()
+{
+ //Store the current matrix state
+ QVector<VGfloat> matrix(9);
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+ vgGetMatrix(matrix.data());
+
+ m_transformStack.push(QOpenVGMatrix(matrix.constData()));
+
+ // Opacity
+ m_opacityState.push(1.0f);
+}
+
+bool QSGOpenVGNodeVisitor::visit(QSGTransformNode *node)
+{
+ const QVector<float> matrixData = { node->matrix().constData()[0], node->matrix().constData()[1], node->matrix().constData()[3],
+ node->matrix().constData()[4], node->matrix().constData()[5], node->matrix().constData()[7],
+ node->matrix().constData()[12], node->matrix().constData()[13], node->matrix().constData()[15] };
+ const QOpenVGMatrix matrix2d(matrixData.constData());
+
+ m_transformStack.push(m_transformStack.top() * matrix2d);
+ return true;
+}
+
+void QSGOpenVGNodeVisitor::endVisit(QSGTransformNode *)
+{
+ m_transformStack.pop();
+}
+
+bool QSGOpenVGNodeVisitor::visit(QSGClipNode *node)
+{
+ VGMaskOperation maskOperation = VG_INTERSECT_MASK;
+ if (m_clipStack.count() == 0) {
+ vgSeti(VG_MASKING, VG_TRUE);
+ vgMask(0,VG_FILL_MASK, 0, 0, VG_MAXINT, VG_MAXINT);
+ }
+
+ // Render clip node geometry to mask
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+ vgLoadMatrix(m_transformStack.top().constData());
+ VGPath clipPath = generateClipPath(node->clipRect());
+ vgRenderToMask(clipPath, VG_FILL_PATH, maskOperation);
+
+ auto clipState = new ClipState(clipPath, m_transformStack.top());
+ m_clipStack.push(clipState);
+
+ return true;
+}
+
+void QSGOpenVGNodeVisitor::endVisit(QSGClipNode *)
+{
+ // Remove clip node geometry from mask
+ auto clipState = m_clipStack.pop();
+ vgDestroyPath(clipState->path);
+
+ if (m_clipStack.count() == 0) {
+ vgSeti(VG_MASKING, VG_FALSE);
+ } else {
+ // Recreate the mask
+ vgMask(0,VG_FILL_MASK, 0, 0, VG_MAXINT, VG_MAXINT);
+ for (auto state : m_clipStack) {
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+ vgLoadMatrix(state->transform.constData());
+ vgRenderToMask(state->path, VG_FILL_PATH, VG_INTERSECT_MASK);
+ }
+ }
+
+ delete clipState;
+}
+
+bool QSGOpenVGNodeVisitor::visit(QSGGeometryNode *node)
+{
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+ vgLoadMatrix(m_transformStack.top().constData());
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+ vgLoadMatrix(m_transformStack.top().constData());
+ if (QSGSimpleRectNode *rectNode = dynamic_cast<QSGSimpleRectNode *>(node)) {
+ // TODO: Try and render the QSGSimpleRectNode
+ Q_UNUSED(rectNode)
+ return false;
+ } else if (QSGSimpleTextureNode *tn = dynamic_cast<QSGSimpleTextureNode *>(node)) {
+ // TODO: Try and render the QSGSimpleTextureNode
+ Q_UNUSED(tn)
+ return false;
+ } else if (QSGOpenVGNinePatchNode *nn = dynamic_cast<QSGOpenVGNinePatchNode *>(node)) {
+ renderRenderableNode(nn);
+ } else if (QSGOpenVGRectangleNode *rn = dynamic_cast<QSGOpenVGRectangleNode *>(node)) {
+ renderRenderableNode(rn);
+ } else if (QSGOpenVGImageNode *n = dynamic_cast<QSGOpenVGImageNode *>(node)) {
+ renderRenderableNode(n);
+ } else {
+ // We dont know, so skip
+ return false;
+ }
+
+ return true;
+}
+
+void QSGOpenVGNodeVisitor::endVisit(QSGGeometryNode *)
+{
+}
+
+bool QSGOpenVGNodeVisitor::visit(QSGOpacityNode *node)
+{
+ m_opacityState.push(m_opacityState.top() * node->opacity());
+ return true;
+}
+
+void QSGOpenVGNodeVisitor::endVisit(QSGOpacityNode *)
+{
+ m_opacityState.pop();
+}
+
+bool QSGOpenVGNodeVisitor::visit(QSGInternalImageNode *node)
+{
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+ vgLoadMatrix(m_transformStack.top().constData());
+ renderRenderableNode(static_cast<QSGOpenVGInternalImageNode*>(node));
+ return true;
+}
+
+void QSGOpenVGNodeVisitor::endVisit(QSGInternalImageNode *)
+{
+}
+
+bool QSGOpenVGNodeVisitor::visit(QSGPainterNode *node)
+{
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+ vgLoadMatrix(m_transformStack.top().constData());
+ renderRenderableNode(static_cast<QSGOpenVGPainterNode*>(node));
+ return true;
+}
+
+void QSGOpenVGNodeVisitor::endVisit(QSGPainterNode *)
+{
+}
+
+bool QSGOpenVGNodeVisitor::visit(QSGInternalRectangleNode *node)
+{
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+ vgLoadMatrix(m_transformStack.top().constData());
+ renderRenderableNode(static_cast<QSGOpenVGInternalRectangleNode*>(node));
+ return true;
+}
+
+void QSGOpenVGNodeVisitor::endVisit(QSGInternalRectangleNode *)
+{
+}
+
+bool QSGOpenVGNodeVisitor::visit(QSGGlyphNode *node)
+{
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_GLYPH_USER_TO_SURFACE);
+ vgLoadMatrix(m_transformStack.top().constData());
+ renderRenderableNode(static_cast<QSGOpenVGGlyphNode*>(node));
+ return true;
+}
+
+void QSGOpenVGNodeVisitor::endVisit(QSGGlyphNode *)
+{
+}
+
+bool QSGOpenVGNodeVisitor::visit(QSGRootNode *)
+{
+ return true;
+}
+
+void QSGOpenVGNodeVisitor::endVisit(QSGRootNode *)
+{
+}
+
+bool QSGOpenVGNodeVisitor::visit(QSGSpriteNode *node)
+{
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+ vgLoadMatrix(m_transformStack.top().constData());
+ renderRenderableNode(static_cast<QSGOpenVGSpriteNode*>(node));
+ return true;
+}
+
+void QSGOpenVGNodeVisitor::endVisit(QSGSpriteNode *)
+{
+}
+
+bool QSGOpenVGNodeVisitor::visit(QSGRenderNode *)
+{
+ return true;
+}
+
+void QSGOpenVGNodeVisitor::endVisit(QSGRenderNode *)
+{
+}
+
+VGPath QSGOpenVGNodeVisitor::generateClipPath(const QRectF &rect) const
+{
+ VGPath clipPath = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1, 0, 0, 0,
+ VG_PATH_CAPABILITY_APPEND_TO);
+
+ // Create command list
+ static const VGubyte rectCommands[] = {
+ VG_MOVE_TO_ABS,
+ VG_HLINE_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_HLINE_TO_REL,
+ VG_CLOSE_PATH
+ };
+
+ // Create command data
+ QVector<VGfloat> coordinates(5);
+ coordinates[0] = rect.x();
+ coordinates[1] = rect.y();
+ coordinates[2] = rect.width();
+ coordinates[3] = rect.height();
+ coordinates[4] = -rect.width();
+
+ vgAppendPathData(clipPath, 5, rectCommands, coordinates.constData());
+ return clipPath;
+}
+
+void QSGOpenVGNodeVisitor::renderRenderableNode(QSGOpenVGRenderable *node)
+{
+ if (!node)
+ return;
+
+ node->setOpacity(m_opacityState.top());
+ node->render();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.h b/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.h
new file mode 100644
index 0000000000..3105f2076d
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGNODEVISITOR_H
+#define QSGOPENVGNODEVISITOR_H
+
+#include <private/qsgadaptationlayer_p.h>
+#include <QtCore/QStack>
+
+#include "qopenvgmatrix.h"
+
+#include <VG/openvg.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSGOpenVGRenderable;
+class QSGOpenVGNodeVisitor : public QSGNodeVisitorEx
+{
+public:
+ QSGOpenVGNodeVisitor();
+
+ bool visit(QSGTransformNode *) override;
+ void endVisit(QSGTransformNode *) override;
+ bool visit(QSGClipNode *) override;
+ void endVisit(QSGClipNode *) override;
+ bool visit(QSGGeometryNode *) override;
+ void endVisit(QSGGeometryNode *) override;
+ bool visit(QSGOpacityNode *) override;
+ void endVisit(QSGOpacityNode *) override;
+ bool visit(QSGInternalImageNode *) override;
+ void endVisit(QSGInternalImageNode *) override;
+ bool visit(QSGPainterNode *) override;
+ void endVisit(QSGPainterNode *) override;
+ bool visit(QSGInternalRectangleNode *) override;
+ void endVisit(QSGInternalRectangleNode *) override;
+ bool visit(QSGGlyphNode *) override;
+ void endVisit(QSGGlyphNode *) override;
+ bool visit(QSGRootNode *) override;
+ void endVisit(QSGRootNode *) override;
+ bool visit(QSGSpriteNode *) override;
+ void endVisit(QSGSpriteNode *) override;
+ bool visit(QSGRenderNode *) override;
+ void endVisit(QSGRenderNode *) override;
+
+private:
+ struct ClipState {
+ ClipState(VGPath p, QOpenVGMatrix t)
+ {
+ path = p;
+ transform = t;
+ }
+
+ VGPath path;
+ QOpenVGMatrix transform;
+ };
+
+ VGPath generateClipPath(const QRectF &rect) const;
+ void renderRenderableNode(QSGOpenVGRenderable *node);
+
+
+ QStack<QOpenVGMatrix> m_transformStack;
+ QStack<float> m_opacityState;
+ QStack<ClipState*> m_clipStack;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGNODEVISITOR_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgpainternode.cpp b/src/plugins/scenegraph/openvg/qsgopenvgpainternode.cpp
new file mode 100644
index 0000000000..c09ca6a47e
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgpainternode.cpp
@@ -0,0 +1,249 @@
+/****************************************************************************
+**
+** 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 "qsgopenvgpainternode.h"
+#include "qsgopenvgtexture.h"
+#include <qmath.h>
+
+#include <QtGui/QPainter>
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGPainterNode::QSGOpenVGPainterNode(QQuickPaintedItem *item)
+ : m_preferredRenderTarget(QQuickPaintedItem::Image)
+ , m_item(item)
+ , m_texture(nullptr)
+ , m_dirtyContents(false)
+ , m_opaquePainting(false)
+ , m_linear_filtering(false)
+ , m_smoothPainting(false)
+ , m_fillColor(Qt::transparent)
+ , m_contentsScale(1.0)
+ , m_dirtyGeometry(false)
+{
+ // Set Dummy material and geometry to avoid asserts
+ setMaterial((QSGMaterial*)1);
+ setGeometry((QSGGeometry*)1);
+}
+
+QSGOpenVGPainterNode::~QSGOpenVGPainterNode()
+{
+ delete m_texture;
+}
+
+void QSGOpenVGPainterNode::setPreferredRenderTarget(QQuickPaintedItem::RenderTarget)
+{
+}
+
+void QSGOpenVGPainterNode::setSize(const QSize &size)
+{
+ if (size == m_size)
+ return;
+
+ m_size = size;
+
+ m_dirtyGeometry = true;
+}
+
+void QSGOpenVGPainterNode::setDirty(const QRect &dirtyRect)
+{
+ m_dirtyContents = true;
+ m_dirtyRect = dirtyRect;
+ markDirty(DirtyMaterial);
+}
+
+void QSGOpenVGPainterNode::setOpaquePainting(bool opaque)
+{
+ if (opaque == m_opaquePainting)
+ return;
+
+ m_opaquePainting = opaque;
+}
+
+void QSGOpenVGPainterNode::setLinearFiltering(bool linearFiltering)
+{
+ if (linearFiltering == m_linear_filtering)
+ return;
+
+ m_linear_filtering = linearFiltering;
+}
+
+void QSGOpenVGPainterNode::setMipmapping(bool)
+{
+
+}
+
+void QSGOpenVGPainterNode::setSmoothPainting(bool s)
+{
+ if (s == m_smoothPainting)
+ return;
+
+ m_smoothPainting = s;
+}
+
+void QSGOpenVGPainterNode::setFillColor(const QColor &c)
+{
+ if (c == m_fillColor)
+ return;
+
+ m_fillColor = c;
+ markDirty(DirtyMaterial);
+}
+
+void QSGOpenVGPainterNode::setContentsScale(qreal s)
+{
+ if (s == m_contentsScale)
+ return;
+
+ m_contentsScale = s;
+ markDirty(DirtyMaterial);
+}
+
+void QSGOpenVGPainterNode::setFastFBOResizing(bool)
+{
+}
+
+void QSGOpenVGPainterNode::setTextureSize(const QSize &size)
+{
+ if (size == m_textureSize)
+ return;
+
+ m_textureSize = size;
+ m_dirtyGeometry = true;
+}
+
+QImage QSGOpenVGPainterNode::toImage() const
+{
+ return m_image;
+}
+
+void QSGOpenVGPainterNode::update()
+{
+ if (m_dirtyGeometry) {
+ if (!m_opaquePainting)
+ m_image = QImage(m_size, QImage::Format_ARGB32_Premultiplied);
+ else
+ m_image = QImage(m_size, QImage::Format_RGB32);
+ }
+
+ if (m_dirtyContents)
+ paint();
+
+ m_dirtyGeometry = false;
+ m_dirtyContents = false;
+}
+
+QSGTexture *QSGOpenVGPainterNode::texture() const
+{
+ return m_texture;
+}
+
+void QSGOpenVGPainterNode::render()
+{
+ if (!m_texture)
+ return;
+
+ // Set Draw Mode
+ if (opacity() < 1.0) {
+ //Transparent
+ vgSetPaint(opacityPaint(), VG_FILL_PATH);
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_MULTIPLY);
+ } else {
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL);
+ }
+
+ if (m_linear_filtering)
+ vgSeti(VG_IMAGE_QUALITY, VG_IMAGE_QUALITY_BETTER);
+ else
+ vgSeti(VG_IMAGE_QUALITY, VG_IMAGE_QUALITY_NONANTIALIASED);
+
+ vgDrawImage(static_cast<VGImage>(m_texture->textureId()));
+}
+
+void QSGOpenVGPainterNode::paint()
+{
+ QRect dirtyRect = m_dirtyRect.isNull() ? QRect(0, 0, m_size.width(), m_size.height()) : m_dirtyRect;
+
+ QPainter painter;
+
+ painter.begin(&m_image);
+ if (m_smoothPainting) {
+ painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
+ }
+
+ QRect clipRect;
+
+ if (m_contentsScale == 1) {
+ qreal scaleX = m_textureSize.width() / (qreal) m_size.width();
+ qreal scaleY = m_textureSize.height() / (qreal) m_size.height();
+ painter.scale(scaleX, scaleY);
+ clipRect = dirtyRect;
+ } 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;
+ }
+
+ 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_dirtyRect = QRect();
+
+ if (m_texture)
+ delete m_texture;
+
+ uint textureFlags = m_opaquePainting ? 0 : QSGRenderContext::CreateTexture_Alpha;
+ m_texture = new QSGOpenVGTexture(m_image, textureFlags);
+}
+
+QT_END_NAMESPACE
+
+
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgpainternode.h b/src/plugins/scenegraph/openvg/qsgopenvgpainternode.h
new file mode 100644
index 0000000000..1fe992115f
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgpainternode.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGPAINTERNODE_H
+#define QSGOPENVGPAINTERNODE_H
+
+#include <private/qsgadaptationlayer_p.h>
+#include <QtQuick/QQuickPaintedItem>
+#include "qsgopenvgrenderable.h"
+
+QT_BEGIN_NAMESPACE
+
+class QSGOpenVGTexture;
+
+class QSGOpenVGPainterNode : public QSGPainterNode, public QSGOpenVGRenderable
+{
+public:
+ QSGOpenVGPainterNode(QQuickPaintedItem *item);
+ ~QSGOpenVGPainterNode();
+
+ void setPreferredRenderTarget(QQuickPaintedItem::RenderTarget target) override;
+ void setSize(const QSize &size) override;
+ void setDirty(const QRect &dirtyRect) 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;
+
+ void render() override;
+ void paint();
+
+private:
+ QQuickPaintedItem::RenderTarget m_preferredRenderTarget;
+
+ QQuickPaintedItem *m_item;
+ QSGOpenVGTexture *m_texture;
+ QImage m_image;
+
+ QSize m_size;
+ bool m_dirtyContents;
+ QRect m_dirtyRect;
+ bool m_opaquePainting;
+ bool m_linear_filtering;
+ bool m_smoothPainting;
+ QColor m_fillColor;
+ qreal m_contentsScale;
+ QSize m_textureSize;
+
+ bool m_dirtyGeometry;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGPAINTERNODE_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.cpp b/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.cpp
new file mode 100644
index 0000000000..f5890210a9
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.cpp
@@ -0,0 +1,266 @@
+/****************************************************************************
+**
+** 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 "qsgopenvgpublicnodes.h"
+#include "qsgopenvghelpers.h"
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGRectangleNode::QSGOpenVGRectangleNode()
+{
+ // Set Dummy material and geometry to avoid asserts
+ setMaterial((QSGMaterial*)1);
+ setGeometry((QSGGeometry*)1);
+
+ m_rectPath = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1, 0, 0, 0,
+ VG_PATH_CAPABILITY_APPEND_TO);
+ m_rectPaint = vgCreatePaint();
+}
+
+QSGOpenVGRectangleNode::~QSGOpenVGRectangleNode()
+{
+ vgDestroyPaint(m_rectPaint);
+ vgDestroyPath(m_rectPath);
+}
+
+void QSGOpenVGRectangleNode::setRect(const QRectF &rect)
+{
+ m_rect = rect;
+ m_pathDirty = true;
+ markDirty(DirtyMaterial);
+}
+
+void QSGOpenVGRectangleNode::setColor(const QColor &color)
+{
+ m_color = color;
+ m_paintDirty = true;
+ markDirty(DirtyMaterial);
+}
+
+void QSGOpenVGRectangleNode::render()
+{
+ if (m_pathDirty) {
+ vgClearPath(m_rectPath, VG_PATH_CAPABILITY_APPEND_TO);
+ // Create command list
+ static const VGubyte rectCommands[] = {
+ VG_MOVE_TO_ABS,
+ VG_HLINE_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_HLINE_TO_REL,
+ VG_CLOSE_PATH
+ };
+
+ // Create command data
+ QVector<VGfloat> coordinates(5);
+ coordinates[0] = m_rect.x();
+ coordinates[1] = m_rect.y();
+ coordinates[2] = m_rect.width();
+ coordinates[3] = m_rect.height();
+ coordinates[4] = -m_rect.width();
+
+ vgAppendPathData(m_rectPath, 5, rectCommands, coordinates.constData());
+ m_pathDirty = false;
+ }
+
+ if (m_paintDirty) {
+ vgSetPaint(m_rectPaint, VG_FILL_PATH);
+ vgSetParameteri(m_rectPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
+ vgSetParameterfv(m_rectPaint, VG_PAINT_COLOR, 4, QSGOpenVGHelpers::qColorToVGColor(m_color).constData());
+
+ m_paintDirty = false;
+ }
+
+ vgSetPaint(m_rectPaint, VG_FILL_PATH);
+ vgDrawPath(m_rectPath, VG_FILL_PATH);
+
+}
+
+QSGOpenVGImageNode::QSGOpenVGImageNode()
+{
+ // Set Dummy material and geometry to avoid asserts
+ setMaterial((QSGMaterial*)1);
+ setGeometry((QSGGeometry*)1);
+
+}
+
+QSGOpenVGImageNode::~QSGOpenVGImageNode()
+{
+ if (m_owns) {
+ m_texture->deleteLater();
+ }
+}
+
+void QSGOpenVGImageNode::setTexture(QSGTexture *texture)
+{
+ m_texture = texture;
+ markDirty(DirtyMaterial);
+}
+
+void QSGOpenVGImageNode::setTextureCoordinatesTransform(QSGImageNode::TextureCoordinatesTransformMode transformNode)
+{
+ if (m_transformMode == transformNode)
+ return;
+ m_transformMode = transformNode;
+ markDirty(DirtyGeometry);
+}
+
+void QSGOpenVGImageNode::render()
+{
+ if (!m_texture) {
+ return;
+ }
+
+ // Set Draw Mode
+ if (opacity() < 1.0) {
+ //Transparent
+ vgSetPaint(opacityPaint(), VG_FILL_PATH);
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_MULTIPLY);
+ } else {
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL);
+ }
+
+ VGImage image = static_cast<VGImage>(m_texture->textureId());
+
+ //Apply the TextureCoordinateTransform Flag
+ if (m_transformMode != QSGImageNode::NoTransform) {
+ float translateX = 0.0f;
+ float translateY = 0.0f;
+ float scaleX = 1.0f;
+ float scaleY = 1.0f;
+
+ if (m_transformMode & QSGImageNode::MirrorHorizontally) {
+ translateX = m_rect.width();
+ scaleX = -1.0;
+ }
+
+ if (m_transformMode & QSGImageNode::MirrorVertically) {
+ translateY = m_rect.height();
+ scaleY = -1.0;
+ }
+
+ vgTranslate(translateX, translateY);
+ vgScale(scaleX, scaleY);
+ }
+
+ // If the the source rect is the same as the target rect
+ if (m_sourceRect == m_rect) {
+ vgDrawImage(image);
+ } else {
+ // Scale
+ float scaleX = m_rect.width() / m_sourceRect.width();
+ float scaleY = m_rect.height() / m_sourceRect.height();
+ vgScale(scaleX, scaleY);
+ VGImage subImage = vgChildImage(image, m_sourceRect.x(), m_sourceRect.y(), m_sourceRect.width(), m_sourceRect.height());
+ vgDrawImage(subImage);
+ vgDestroyImage(subImage);
+ }
+
+}
+
+QSGOpenVGNinePatchNode::QSGOpenVGNinePatchNode()
+{
+ // Set Dummy material and geometry to avoid asserts
+ setMaterial((QSGMaterial*)1);
+ setGeometry((QSGGeometry*)1);
+
+}
+
+void QSGOpenVGNinePatchNode::setTexture(QSGTexture *texture)
+{
+ m_texture = texture;
+ markDirty(DirtyMaterial);
+}
+
+void QSGOpenVGNinePatchNode::setBounds(const QRectF &bounds)
+{
+ if (m_bounds == bounds)
+ return;
+ m_bounds = bounds;
+ markDirty(DirtyGeometry);
+}
+
+void QSGOpenVGNinePatchNode::setDevicePixelRatio(qreal ratio)
+{
+ if (m_pixelRatio == ratio)
+ return;
+ m_pixelRatio = ratio;
+ markDirty(DirtyGeometry);
+}
+
+void QSGOpenVGNinePatchNode::setPadding(qreal left, qreal top, qreal right, qreal bottom)
+{
+ QMarginsF margins(left, top, right, bottom);
+ if (m_margins == margins)
+ return;
+ m_margins = margins;
+ markDirty(DirtyGeometry);
+}
+
+void QSGOpenVGNinePatchNode::update()
+{
+
+}
+
+void QSGOpenVGNinePatchNode::render()
+{
+ if (!m_texture)
+ return;
+
+ // Set Draw Mode
+ if (opacity() < 1.0) {
+ //Transparent
+ vgSetPaint(opacityPaint(), VG_FILL_PATH);
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_MULTIPLY);
+ } else {
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL);
+ }
+
+ VGImage image = static_cast<VGImage>(m_texture->textureId());
+
+ //Draw borderImage
+ QSGOpenVGHelpers::qDrawBorderImage(image, m_texture->textureSize(), m_bounds, m_bounds.marginsRemoved(m_margins), QRectF(0, 0, 1, 1));
+}
+
+QRectF QSGOpenVGNinePatchNode::bounds() const
+{
+ return m_bounds;
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.h b/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.h
new file mode 100644
index 0000000000..70b087e9fc
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.h
@@ -0,0 +1,143 @@
+#ifndef QSGOPENVGPUBLICNODES_H
+#define QSGOPENVGPUBLICNODES_H
+
+/****************************************************************************
+**
+** 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 <QtQuick/qsgrectanglenode.h>
+#include <QtQuick/qsgimagenode.h>
+#include <QtQuick/qsgninepatchnode.h>
+
+#include <QtGui/QPixmap>
+
+#include <VG/openvg.h>
+
+#include "qsgopenvgrenderable.h"
+
+QT_BEGIN_NAMESPACE
+
+class QSGOpenVGRectangleNode : public QSGRectangleNode, public QSGOpenVGRenderable
+{
+public:
+ QSGOpenVGRectangleNode();
+ ~QSGOpenVGRectangleNode();
+
+ void setRect(const QRectF &rect) override;
+ QRectF rect() const override { return m_rect; }
+
+ void setColor(const QColor &color) override;
+ QColor color() const override { return m_color; }
+
+ void render() override;
+
+private:
+ QRectF m_rect;
+ QColor m_color;
+
+
+ bool m_pathDirty = true;
+ bool m_paintDirty = true;
+
+ VGPath m_rectPath;
+ VGPaint m_rectPaint;
+};
+
+class QSGOpenVGImageNode : public QSGImageNode, public QSGOpenVGRenderable
+{
+public:
+ QSGOpenVGImageNode();
+ ~QSGOpenVGImageNode();
+
+ void setRect(const QRectF &rect) override { m_rect = rect; markDirty(DirtyMaterial); }
+ QRectF rect() const override { return m_rect; }
+
+ void setSourceRect(const QRectF &r) override { m_sourceRect = r; }
+ QRectF sourceRect() const override { return m_sourceRect; }
+
+ void setTexture(QSGTexture *texture) override;
+ QSGTexture *texture() const override { return m_texture; }
+
+ void setFiltering(QSGTexture::Filtering filtering) override { m_filtering = filtering; markDirty(DirtyMaterial); }
+ QSGTexture::Filtering filtering() const override { return m_filtering; }
+
+ void setMipmapFiltering(QSGTexture::Filtering) override { }
+ QSGTexture::Filtering mipmapFiltering() const override { return QSGTexture::None; }
+
+ void setTextureCoordinatesTransform(TextureCoordinatesTransformMode transformNode) override;
+ TextureCoordinatesTransformMode textureCoordinatesTransform() const override { return m_transformMode; }
+
+ void setOwnsTexture(bool owns) override { m_owns = owns; }
+ bool ownsTexture() const override { return m_owns; }
+
+ void render() override;
+
+private:
+ QSGTexture *m_texture;
+ QRectF m_rect;
+ QRectF m_sourceRect;
+ bool m_owns;
+ QSGTexture::Filtering m_filtering;
+ TextureCoordinatesTransformMode m_transformMode;
+};
+
+class QSGOpenVGNinePatchNode : public QSGNinePatchNode, public QSGOpenVGRenderable
+{
+public:
+ QSGOpenVGNinePatchNode();
+
+ 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;
+
+ void render() override;
+
+ QRectF bounds() const;
+
+private:
+ QSGTexture *m_texture;
+ QRectF m_bounds;
+ qreal m_pixelRatio;
+ QMarginsF m_margins;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGPUBLICNODES_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgrenderable.cpp b/src/plugins/scenegraph/openvg/qsgopenvgrenderable.cpp
new file mode 100644
index 0000000000..0856acfc9a
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgrenderable.cpp
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** 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 "qsgopenvgrenderable.h"
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGRenderable::QSGOpenVGRenderable()
+ : m_opacity(1.0f)
+{
+ m_opacityPaint = vgCreatePaint();
+}
+
+QSGOpenVGRenderable::~QSGOpenVGRenderable()
+{
+ vgDestroyPaint(m_opacityPaint);
+}
+
+void QSGOpenVGRenderable::setOpacity(float opacity)
+{
+ if (m_opacity == opacity)
+ return;
+
+ m_opacity = opacity;
+ VGfloat values[] = {
+ 1.0f, 1.0f, 1.0f, m_opacity
+ };
+ vgSetParameterfv(m_opacityPaint, VG_PAINT_COLOR, 4, values);
+}
+
+float QSGOpenVGRenderable::opacity() const
+{
+ return m_opacity;
+}
+
+VGPaint QSGOpenVGRenderable::opacityPaint() const
+{
+ return m_opacityPaint;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgrenderable.h b/src/plugins/scenegraph/openvg/qsgopenvgrenderable.h
new file mode 100644
index 0000000000..7a09f2afbe
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgrenderable.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGRENDERABLE_H
+#define QSGOPENVGRENDERABLE_H
+
+#include <QtGlobal>
+
+#include <VG/openvg.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSGOpenVGRenderable
+{
+public:
+ QSGOpenVGRenderable();
+ virtual ~QSGOpenVGRenderable();
+
+ virtual void render() = 0;
+
+ virtual void setOpacity(float opacity);
+ float opacity() const;
+ VGPaint opacityPaint() const;
+
+private:
+ float m_opacity;
+ VGPaint m_opacityPaint;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGRENDERABLE_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgrenderer.cpp b/src/plugins/scenegraph/openvg/qsgopenvgrenderer.cpp
new file mode 100644
index 0000000000..acd4cf88dc
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgrenderer.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** 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 "qsgopenvgrenderer_p.h"
+#include "qsgopenvgcontext_p.h"
+#include "qsgopenvgnodevisitor.h"
+#include "qopenvgcontext_p.h"
+#include "qsgopenvghelpers.h"
+
+#include <QtGui/QWindow>
+
+#include <VG/openvg.h>
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGRenderer::QSGOpenVGRenderer(QSGRenderContext *context)
+ : QSGRenderer(context)
+{
+
+}
+
+QSGOpenVGRenderer::~QSGOpenVGRenderer()
+{
+
+}
+
+void QSGOpenVGRenderer::renderScene(uint fboId)
+{
+ Q_UNUSED(fboId)
+ class B : public QSGBindable
+ {
+ public:
+ void bind() const { }
+ } bindable;
+ QSGRenderer::renderScene(bindable);
+}
+
+void QSGOpenVGRenderer::render()
+{
+ //Clear the window geometry with the clear color
+ vgSetfv(VG_CLEAR_COLOR, 4, QSGOpenVGHelpers::qColorToVGColor(clearColor()).constData());
+ vgClear(0, 0, VG_MAXINT, VG_MAXINT);
+
+ // Visit each node to render scene
+ QSGOpenVGNodeVisitor rendererVisitor;
+ rendererVisitor.visitChildren(rootNode());
+}
+
+void QSGOpenVGRenderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state)
+{
+ QSGRenderer::nodeChanged(node, state);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgrenderer_p.h b/src/plugins/scenegraph/openvg/qsgopenvgrenderer_p.h
new file mode 100644
index 0000000000..24cabd1b89
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgrenderer_p.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGRENDERER_H
+#define QSGOPENVGRENDERER_H
+
+#include <private/qsgrenderer_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSGOpenVGRenderer : public QSGRenderer
+{
+public:
+ QSGOpenVGRenderer(QSGRenderContext *context);
+ virtual ~QSGOpenVGRenderer();
+
+ void nodeChanged(QSGNode *node, QSGNode::DirtyState state) override;
+
+ void renderScene(uint fboId = 0) final;
+ void render() final;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGRENDERER_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgrenderloop.cpp b/src/plugins/scenegraph/openvg/qsgopenvgrenderloop.cpp
new file mode 100644
index 0000000000..290ee8028c
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgrenderloop.cpp
@@ -0,0 +1,257 @@
+/****************************************************************************
+**
+** 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 "qsgopenvgrenderloop_p.h"
+#include "qsgopenvgcontext_p.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QElapsedTimer>
+
+#include <private/qquickwindow_p.h>
+#include <private/qquickprofiler_p.h>
+
+#include "qopenvgcontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGRenderLoop::QSGOpenVGRenderLoop()
+ : vg(nullptr)
+{
+ sg = QSGContext::createDefaultContext();
+ rc = sg->createRenderContext();
+}
+
+QSGOpenVGRenderLoop::~QSGOpenVGRenderLoop()
+{
+ delete rc;
+ delete sg;
+}
+
+void QSGOpenVGRenderLoop::show(QQuickWindow *window)
+{
+ WindowData data;
+ data.updatePending = false;
+ data.grabOnly = false;
+ m_windows[window] = data;
+
+ maybeUpdate(window);
+}
+
+void QSGOpenVGRenderLoop::hide(QQuickWindow *window)
+{
+ QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window);
+ cd->fireAboutToStop();
+}
+
+void QSGOpenVGRenderLoop::windowDestroyed(QQuickWindow *window)
+{
+ m_windows.remove(window);
+ hide(window);
+
+ QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
+ d->cleanupNodesOnShutdown();
+
+ if (m_windows.size() == 0) {
+ rc->invalidate();
+ delete vg;
+ vg = nullptr;
+ QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+ } else if (vg && window == vg->window()) {
+ vg->doneCurrent();
+ }
+}
+
+void QSGOpenVGRenderLoop::exposureChanged(QQuickWindow *window)
+{
+ if (window->isExposed()) {
+ m_windows[window].updatePending = true;
+ renderWindow(window);
+ }
+}
+
+QImage QSGOpenVGRenderLoop::grab(QQuickWindow *window)
+{
+ if (!m_windows.contains(window))
+ return QImage();
+
+ m_windows[window].grabOnly = true;
+
+ renderWindow(window);
+
+ QImage grabbed = grabContent;
+ grabContent = QImage();
+ return grabbed;
+}
+
+void QSGOpenVGRenderLoop::update(QQuickWindow *window)
+{
+ maybeUpdate(window);
+}
+
+void QSGOpenVGRenderLoop::handleUpdateRequest(QQuickWindow *window)
+{
+ renderWindow(window);
+}
+
+void QSGOpenVGRenderLoop::maybeUpdate(QQuickWindow *window)
+{
+ if (!m_windows.contains(window))
+ return;
+
+ m_windows[window].updatePending = true;
+ window->requestUpdate();
+}
+
+QAnimationDriver *QSGOpenVGRenderLoop::animationDriver() const
+{
+ return nullptr;
+}
+
+QSGContext *QSGOpenVGRenderLoop::sceneGraphContext() const
+{
+ return sg;
+}
+
+QSGRenderContext *QSGOpenVGRenderLoop::createRenderContext(QSGContext *) const
+{
+ return rc;
+}
+
+void QSGOpenVGRenderLoop::releaseResources(QQuickWindow *window)
+{
+ Q_UNUSED(window)
+}
+
+QSurface::SurfaceType QSGOpenVGRenderLoop::windowSurfaceType() const
+{
+ return QSurface::OpenVGSurface;
+}
+
+void QSGOpenVGRenderLoop::renderWindow(QQuickWindow *window)
+{
+ QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window);
+ if (!cd->isRenderable() || !m_windows.contains(window))
+ return;
+
+ WindowData &data = const_cast<WindowData &>(m_windows[window]);
+
+ if (vg == nullptr) {
+ vg = new QOpenVGContext(window);
+ vg->makeCurrent();
+ cd->context->initialize(vg);
+ } else {
+ vg->makeCurrent();
+ }
+
+ bool alsoSwap = data.updatePending;
+ data.updatePending = false;
+
+ if (!data.grabOnly) {
+ // Event delivery/processing triggered the window to be deleted or stop rendering.
+ if (!m_windows.contains(window))
+ return;
+ }
+ QElapsedTimer renderTimer;
+ qint64 renderTime = 0, syncTime = 0, polishTime = 0;
+ bool profileFrames = QSG_OPENVG_LOG_TIME_RENDERLOOP().isDebugEnabled();
+ if (profileFrames)
+ renderTimer.start();
+ Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishFrame);
+
+ cd->polishItems();
+
+ if (profileFrames)
+ polishTime = renderTimer.nsecsElapsed();
+ Q_QUICK_SG_PROFILE_SWITCH(QQuickProfiler::SceneGraphPolishFrame,
+ QQuickProfiler::SceneGraphRenderLoopFrame);
+
+ emit window->afterAnimating();
+
+ cd->syncSceneGraph();
+
+ if (profileFrames)
+ syncTime = renderTimer.nsecsElapsed();
+ Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame);
+
+ // setup coordinate system for window
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+ vgLoadIdentity();
+ vgTranslate(0.0f, window->size().height());
+ vgScale(1.0, -1.0);
+
+ cd->renderSceneGraph(window->size());
+
+ if (profileFrames)
+ renderTime = renderTimer.nsecsElapsed();
+ Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame);
+
+ if (data.grabOnly) {
+ grabContent = vg->readFramebuffer(window->size() * window->effectiveDevicePixelRatio());
+ data.grabOnly = false;
+ }
+
+ if (alsoSwap && window->isVisible()) {
+ vg->swapBuffers();
+ cd->fireFrameSwapped();
+ }
+
+ qint64 swapTime = 0;
+ if (profileFrames)
+ swapTime = renderTimer.nsecsElapsed();
+ Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame);
+
+ if (QSG_OPENVG_LOG_TIME_RENDERLOOP().isDebugEnabled()) {
+ static QTime lastFrameTime = QTime::currentTime();
+ qCDebug(QSG_OPENVG_LOG_TIME_RENDERLOOP,
+ "Frame rendered with 'basic' 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();
+ }
+
+ // Might have been set during syncSceneGraph()
+ if (data.updatePending)
+ maybeUpdate(window);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgrenderloop_p.h b/src/plugins/scenegraph/openvg/qsgopenvgrenderloop_p.h
new file mode 100644
index 0000000000..f35b689e00
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgrenderloop_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGRENDERLOOP_H
+#define QSGOPENVGRENDERLOOP_H
+
+#include <private/qsgrenderloop_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenVGContext;
+
+class QSGOpenVGRenderLoop : public QSGRenderLoop
+{
+public:
+ QSGOpenVGRenderLoop();
+ ~QSGOpenVGRenderLoop();
+
+
+ void show(QQuickWindow *window) override;
+ void hide(QQuickWindow *window) override;
+
+ void windowDestroyed(QQuickWindow *window) override;
+
+ void renderWindow(QQuickWindow *window);
+ void exposureChanged(QQuickWindow *window) override;
+ QImage grab(QQuickWindow *window) override;
+
+ void maybeUpdate(QQuickWindow *window) override;
+ void update(QQuickWindow *window) override;
+ void handleUpdateRequest(QQuickWindow *window) override;
+
+ void releaseResources(QQuickWindow *) override;
+
+ QSurface::SurfaceType windowSurfaceType() const override;
+
+ QAnimationDriver *animationDriver() const override;
+
+ QSGContext *sceneGraphContext() const override;
+ QSGRenderContext *createRenderContext(QSGContext *) const override;
+
+ struct WindowData {
+ bool updatePending : 1;
+ bool grabOnly : 1;
+ };
+
+ QHash<QQuickWindow *, WindowData> m_windows;
+
+ QSGContext *sg;
+ QSGRenderContext *rc;
+ QOpenVGContext *vg;
+
+ QImage grabContent;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGRENDERLOOP_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgspritenode.cpp b/src/plugins/scenegraph/openvg/qsgopenvgspritenode.cpp
new file mode 100644
index 0000000000..9bce12c83f
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgspritenode.cpp
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** 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 "qsgopenvgspritenode.h"
+#include "qsgopenvgtexture.h"
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGSpriteNode::QSGOpenVGSpriteNode()
+ : m_time(0.0f)
+{
+ // Set Dummy material and geometry to avoid asserts
+ setMaterial((QSGMaterial*)1);
+ setGeometry((QSGGeometry*)1);
+}
+
+QSGOpenVGSpriteNode::~QSGOpenVGSpriteNode()
+{
+
+}
+
+void QSGOpenVGSpriteNode::setTexture(QSGTexture *texture)
+{
+ m_texture = static_cast<QSGOpenVGTexture*>(texture);
+ markDirty(DirtyMaterial);
+}
+
+void QSGOpenVGSpriteNode::setTime(float time)
+{
+ if (m_time != time) {
+ m_time = time;
+ markDirty(DirtyMaterial);
+ }
+}
+
+void QSGOpenVGSpriteNode::setSourceA(const QPoint &source)
+{
+ if (m_sourceA != source) {
+ m_sourceA = source;
+ markDirty(DirtyMaterial);
+ }
+}
+
+void QSGOpenVGSpriteNode::setSourceB(const QPoint &source)
+{
+ if (m_sourceB != source) {
+ m_sourceB = source;
+ markDirty(DirtyMaterial);
+ }
+}
+
+void QSGOpenVGSpriteNode::setSpriteSize(const QSize &size)
+{
+ if (m_spriteSize != size) {
+ m_spriteSize = size;
+ markDirty(DirtyMaterial);
+ }
+}
+
+void QSGOpenVGSpriteNode::setSheetSize(const QSize &size)
+{
+ if (m_sheetSize != size) {
+ m_sheetSize = size;
+ markDirty(DirtyMaterial);
+ }
+}
+
+void QSGOpenVGSpriteNode::setSize(const QSizeF &size)
+{
+ if (m_size != size) {
+ m_size = size;
+ markDirty(DirtyGeometry);
+ }
+}
+
+void QSGOpenVGSpriteNode::setFiltering(QSGTexture::Filtering)
+{
+}
+
+void QSGOpenVGSpriteNode::update()
+{
+}
+
+void QSGOpenVGSpriteNode::render()
+{
+ if (!m_texture)
+ return;
+
+ VGImage image = static_cast<VGImage>(m_texture->textureId());
+
+ QRectF sourceRect(m_sourceA, m_spriteSize);
+ QRectF targetRect(0, 0, m_size.width(), m_size.height());
+
+ VGImage sourceImage = vgChildImage(image, sourceRect.x(), sourceRect.y(), sourceRect.width(), sourceRect.height());
+
+ // Set Draw Mode
+ if (opacity() < 1.0) {
+ //Transparent
+ vgSetPaint(opacityPaint(), VG_FILL_PATH);
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_MULTIPLY);
+ } else {
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL);
+ }
+
+ if (sourceRect != targetRect) {
+ // Scale
+ float scaleX = targetRect.width() / sourceRect.width();
+ float scaleY = targetRect.height() / sourceRect.height();
+ vgScale(scaleX, scaleY);
+ }
+
+ vgDrawImage(sourceImage);
+
+ vgDestroyImage(sourceImage);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgspritenode.h b/src/plugins/scenegraph/openvg/qsgopenvgspritenode.h
new file mode 100644
index 0000000000..3ade2ef8ad
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgspritenode.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGSPRITENODE_H
+#define QSGOPENVGSPRITENODE_H
+
+#include <private/qsgadaptationlayer_p.h>
+#include "qsgopenvgrenderable.h"
+
+QT_BEGIN_NAMESPACE
+class QSGOpenVGTexture;
+class QSGOpenVGSpriteNode : public QSGSpriteNode, public QSGOpenVGRenderable
+{
+public:
+ QSGOpenVGSpriteNode();
+ ~QSGOpenVGSpriteNode();
+
+ 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;
+
+ void render() override;
+
+private:
+ QSGOpenVGTexture *m_texture;
+ float m_time;
+ QPoint m_sourceA;
+ QPoint m_sourceB;
+ QSize m_spriteSize;
+ QSize m_sheetSize;
+ QSizeF m_size;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGSPRITENODE_H
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgtexture.cpp b/src/plugins/scenegraph/openvg/qsgopenvgtexture.cpp
new file mode 100644
index 0000000000..dd2fdc7020
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgtexture.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** 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 "qsgopenvgtexture.h"
+#include "qsgopenvghelpers.h"
+
+QT_BEGIN_NAMESPACE
+
+QSGOpenVGTexture::QSGOpenVGTexture(const QImage &image, uint flags)
+{
+ Q_UNUSED(flags)
+
+ VGImageFormat format = QSGOpenVGHelpers::qImageFormatToVGImageFormat(image.format());
+ m_image = vgCreateImage(format, image.width(), image.height(), VG_IMAGE_QUALITY_BETTER);
+
+ // Do Texture Upload
+ vgImageSubData(m_image, image.constBits(), image.bytesPerLine(), format, 0, 0, image.width(), image.height());
+}
+
+QSGOpenVGTexture::~QSGOpenVGTexture()
+{
+ vgDestroyImage(m_image);
+}
+
+int QSGOpenVGTexture::textureId() const
+{
+ return static_cast<int>(m_image);
+}
+
+QSize QSGOpenVGTexture::textureSize() const
+{
+ VGint imageWidth = vgGetParameteri(m_image, VG_IMAGE_WIDTH);
+ VGint imageHeight = vgGetParameteri(m_image, VG_IMAGE_HEIGHT);
+ return QSize(imageWidth, imageHeight);
+}
+
+bool QSGOpenVGTexture::hasAlphaChannel() const
+{
+ VGImageFormat format = static_cast<VGImageFormat>(vgGetParameteri(m_image, VG_IMAGE_FORMAT));
+
+ switch (format) {
+ case VG_sRGBA_8888:
+ case VG_sRGBA_8888_PRE:
+ case VG_sRGBA_5551:
+ case VG_sRGBA_4444:
+ case VG_lRGBA_8888:
+ case VG_lRGBA_8888_PRE:
+ case VG_A_8:
+ case VG_A_1:
+ case VG_A_4:
+ case VG_sARGB_8888:
+ case VG_sARGB_8888_PRE:
+ case VG_sARGB_1555:
+ case VG_sARGB_4444:
+ case VG_lARGB_8888:
+ case VG_lARGB_8888_PRE:
+ case VG_sBGRA_8888:
+ case VG_sBGRA_8888_PRE:
+ case VG_sBGRA_5551:
+ case VG_sBGRA_4444:
+ case VG_lBGRA_8888:
+ case VG_lBGRA_8888_PRE:
+ case VG_sABGR_8888:
+ case VG_sABGR_8888_PRE:
+ case VG_sABGR_1555:
+ case VG_sABGR_4444:
+ case VG_lABGR_8888:
+ case VG_lABGR_8888_PRE:
+ return true;
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+bool QSGOpenVGTexture::hasMipmaps() const
+{
+ return false;
+}
+
+void QSGOpenVGTexture::bind()
+{
+ // No need to bind
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgtexture.h b/src/plugins/scenegraph/openvg/qsgopenvgtexture.h
new file mode 100644
index 0000000000..523c9e690d
--- /dev/null
+++ b/src/plugins/scenegraph/openvg/qsgopenvgtexture.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** 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 QSGOPENVGTEXTURE_H
+#define QSGOPENVGTEXTURE_H
+
+#include <private/qsgtexture_p.h>
+
+#include <VG/openvg.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSGOpenVGTexture : public QSGTexture
+{
+public:
+ QSGOpenVGTexture(const QImage &image, uint flags);
+ ~QSGOpenVGTexture();
+
+ int textureId() const override;
+ QSize textureSize() const override;
+ bool hasAlphaChannel() const override;
+ bool hasMipmaps() const override;
+ void bind() override;
+
+private:
+ VGImage m_image;;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGOPENVGTEXTURE_H
diff --git a/src/plugins/scenegraph/scenegraph.pro b/src/plugins/scenegraph/scenegraph.pro
index a90e8d4814..39c0c0815c 100644
--- a/src/plugins/scenegraph/scenegraph.pro
+++ b/src/plugins/scenegraph/scenegraph.pro
@@ -1,3 +1,5 @@
TEMPLATE = subdirs
QT_FOR_CONFIG += quick
qtConfig(d3d12): SUBDIRS += d3d12
+qtConfig(openvg): SUBDIRS += openvg
+