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>
This commit is contained in:
parent
bff7302fc2
commit
3f57f2b7cc
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"Keys": ["openvg"]
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -1,3 +1,5 @@
|
|||
TEMPLATE = subdirs
|
||||
QT_FOR_CONFIG += quick
|
||||
qtConfig(d3d12): SUBDIRS += d3d12
|
||||
qtConfig(openvg): SUBDIRS += openvg
|
||||
|
||||
|
|
|
@ -58,6 +58,8 @@ The supported backends are the following
|
|||
|
||||
\li Direct3D 12 - Requested by the string \c{"d3d12"} or the enum value QSGRendererInterface::Direct3D12.
|
||||
|
||||
\li OpenVG - Requested by the string \c{"openvg"} or the enum value QSGRendererInterface::OpenVG.
|
||||
|
||||
\endlist
|
||||
|
||||
When in doubt which backend is in use, enable basic scenegraph information
|
||||
|
@ -92,6 +94,14 @@ running on Windows 10, both for Win32 and UWP applications. The details for
|
|||
this adaptation are available here:
|
||||
\l{qtquick-visualcanvas-adaptations-d3d12.html}{Direct3D 12 Adaptation}
|
||||
|
||||
\section1 OpenVG
|
||||
|
||||
The OpenVG adaptation is an alternative renderer for \l {Qt Quick} 2 that will
|
||||
renderer the contents of the scene graph using OpenVG commands to provide
|
||||
hardware-acclerated 2D vector and raster graphics. The details for this
|
||||
adaptation are available here:
|
||||
\l{qtquick-visualcanvas-scenegraph-openvg.html}{OpenVG Adaptation}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
@ -387,3 +397,73 @@ between the frames). By default blocking present is disabled.
|
|||
\endlist
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\title Qt Quick OpenVG Adaptation
|
||||
\page qtquick-visualcanvas-adaptations-openvg.html
|
||||
|
||||
The OpenVG adaptation is an alternative renderer for \l {Qt Quick} 2 that will
|
||||
renderer the contents of the scene graph using OpenVG commands to provide
|
||||
hardware-acclerated 2D vector and raster graphics. Much like the Software
|
||||
adaptation, some features and optimizations are no longer available. Most
|
||||
Qt Quick 2 applications will run without modification though any attempts to
|
||||
use unsupported features will be ignored.
|
||||
|
||||
\section2 EGL Requirement
|
||||
Unlike the defualt OpenGL Renderer, there is no built in support for acquiring
|
||||
an OpenVG context. This means that the renderer has the responsbility of
|
||||
requesting and managing the the current context. To do this EGL has to be used
|
||||
directly in the OpenVG renderer. This means that the OpenVG renderer is only
|
||||
usable with platform plugins that support creating QWindows with support for
|
||||
QSurfaceFormat::OpenVG. From this window, the renderer can get an EGLSurface
|
||||
which can be used with an EGLContext to render OpenVG content.
|
||||
|
||||
\section2 Renderer
|
||||
The OpenVG Renderer works by using the OpenVG API to send commands and data to
|
||||
a Vector GPU which will render the scenegraph in an accelerated manner, offloading
|
||||
graphics rendering from the CPU. Many operations like the rendering of rectangles
|
||||
and fonts glyphs ideal for OpenVG because these can be represented as paths which
|
||||
are stroked and filled. Rendering scenegraph items that would typically involve
|
||||
textures are handled in the OpenVG renderer by using VGImage. In addition when
|
||||
rendering to offscreen surfaces (like when using Layers), the scene subtree is
|
||||
rendered to a VGImage which can be reused in the scene.
|
||||
|
||||
\section2 Render Loop
|
||||
The OpenVG Renderer mirrors the behavior of the Basic render loop and will execute
|
||||
all OpenVG commands in a single thread.
|
||||
|
||||
See the \l{qtquick-visualcanvas-scenegraph.html}{Scene Graph page} for more
|
||||
information on render loops
|
||||
|
||||
\section2 Shader Effects
|
||||
ShaderEffect components in QtQuick 2 can not be rendered by the OpenVG adaptation.
|
||||
While it is possible to user ShaderEffectSource and QML Item Layers (which are both
|
||||
offscreen surfaces), it is not actually possible to apply shader effects to them
|
||||
via the ShaderEffect item. This is because OpenVG lacks an API for applying per
|
||||
vertex and per fragment shader operations. It may be possible however to take
|
||||
advantage of Image Filter operations in the OpenVG API to get similar effects to
|
||||
what is provided by ShaderEffects in custom items. To integrate custom OpenVG
|
||||
rendering, use QSGRenderNode in combination with QSGRendererInterface.
|
||||
|
||||
\section2 Qt Graphical Effects Module
|
||||
\l {Qt Graphical Effects} uses ShaderEffect items to render effects. If you use
|
||||
graphical effects from this module, then you should not hide the source
|
||||
item so that the original item can still be rendered.
|
||||
|
||||
\section2 Particle Effects
|
||||
It is not possible to render particle effects with the OpenVG adaptation. Whenever
|
||||
possible, remove particles completely from the scene. Otherwise they will still
|
||||
require some processing, even though they are not visible.
|
||||
|
||||
\section2 Rendering Text
|
||||
The text rendering with the OpenVG adaptation is based on rendering the glpyh
|
||||
paths, and does not use the distance fields technique used by the OpenGL backend.
|
||||
|
||||
\section2 Perspective Transforms
|
||||
The OpenVG API does not allow paths to be transformed with non-affine transforms,
|
||||
while it is possible with Qt Quick. This means that rendering components using
|
||||
paths like Rectangles and Text, when applying perspective transforms the OpenVG
|
||||
backend will first render to a VGImage before applying transformations. This uses
|
||||
more memory at runtime and is a slower path so avoid doing this if necessary.
|
||||
|
||||
*/
|
||||
|
|
|
@ -77,6 +77,7 @@ QT_BEGIN_NAMESPACE
|
|||
\value Software The Qt Quick 2D Renderer is in use
|
||||
\value OpenGL OpenGL ES 2.0 or higher
|
||||
\value Direct3D12 Direct3D 12
|
||||
\value OpenVG OpenVG via EGL
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
|
|
@ -53,7 +53,8 @@ public:
|
|||
Unknown,
|
||||
Software,
|
||||
OpenGL,
|
||||
Direct3D12
|
||||
Direct3D12,
|
||||
OpenVG
|
||||
};
|
||||
|
||||
enum Resource {
|
||||
|
|
Loading…
Reference in New Issue