Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions 3rdParty/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,6 @@ endif()
# Define _UNICODE and UNICODE
add_definitions(-D_UNICODE -DUNICODE)

# Define _USE_MATH_DEFINES
add_definitions(-D_USE_MATH_DEFINES)

#
#
#
Expand Down
2 changes: 1 addition & 1 deletion 3rdParty/rive-runtime
Submodule rive-runtime updated 759 files
4 changes: 0 additions & 4 deletions examples/SimpleViewer/RiveInspectorView.qml
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,6 @@ Item {
text: riveItem.frameRate
font.pixelSize: 30
}

onStateMachineStringInterfaceChanged: {
dynamicProperties.model = riveItem.stateMachineInterface.riveInputs
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/RiveQtQuickItem/RiveQtQuickPlugin.qmltypes
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ Module {
exportMetaObjectRevisions: [256]
Enum {
name: "RivePropertyType"
isScoped: true
type: "short"
values: ["RiveNumber", "RiveBoolean", "RiveTrigger"]
}
Expand Down
8 changes: 3 additions & 5 deletions src/RiveQtQuickItem/datatypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

#pragma once

#include <QtQml>
#include <QQuickItem>
#include <QSGRendererInterface>

struct AnimationInfo
Expand Down Expand Up @@ -62,9 +60,9 @@ struct RiveRenderSettings
public:
enum RenderQuality
{
Low,
Medium,
High
Low = 1,
Medium = 5,
High = 10
};
Q_ENUM(RenderQuality)

Expand Down
156 changes: 8 additions & 148 deletions src/RiveQtQuickItem/renderer/riveqtfactory.cpp
Original file line number Diff line number Diff line change
@@ -1,79 +1,23 @@

// SPDX-FileCopyrightText: 2023 Jeremias Bosch <jeremias.bosch@basyskom.com>
// SPDX-FileCopyrightText: 2023 basysKom GmbH
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#include <QQuickWindow>

#include "renderer/riveqtfactory.h"
#include "renderer/riveqtfont.h"
#include "renderer/riveqtpainterrenderer.h"
#include "riveqsgrhirendernode.h"
#include "riveqsgsoftwarerendernode.h"
#include "riveqtpath.h"
#include "rqqplogging.h"
#include "riveqtutils.h"

#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
# include "renderer/riveqtrhirenderer.h"
#endif
#include <utils/factory_utils.hpp>

RiveQSGRenderNode *RiveQtFactory::renderNode(QQuickWindow *window, std::weak_ptr<rive::ArtboardInstance> artboardInstance,
const QRectF &geometry)
RiveQtFactory::RiveQtFactory(RiveRenderSettings &renderSettings)
: rive::Factory()
, m_renderSettings(renderSettings)
{
switch (window->rendererInterface()->graphicsApi()) {
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
case QSGRendererInterface::GraphicsApi::OpenGLRhi:
case QSGRendererInterface::GraphicsApi::MetalRhi:
case QSGRendererInterface::GraphicsApi::VulkanRhi:
case QSGRendererInterface::GraphicsApi::Direct3D11Rhi: {
auto sampleCount = 1;
QSGRendererInterface *renderInterface = window->rendererInterface();
QRhi *rhi = static_cast<QRhi *>(renderInterface->getResource(window, QSGRendererInterface::RhiResource));
const QRhiSwapChain *swapChain =
static_cast<QRhiSwapChain *>(renderInterface->getResource(window, QSGRendererInterface::RhiSwapchainResource));

auto sampleCounts = rhi->supportedSampleCounts();

if (swapChain) {
sampleCount = swapChain->sampleCount();
} else {
// maybe an offscreen render target is active;
// this is the case if the Rive scene is rendered
// inside an QQuickWidget
// try a different way to fetch the sample count
const auto redirectRenderTarget =
static_cast<QRhiTextureRenderTarget *>(renderInterface->getResource(window, QSGRendererInterface::RhiRedirectRenderTarget));
if (redirectRenderTarget) {
sampleCount = redirectRenderTarget->sampleCount();
} else {
qCritical(rqqpFactory)
<< "Swap chain or offscreen render target not found for given window: rendering may be faulty.";
}
}

if (sampleCount == 1 || (sampleCount > 1
&& rhi->isFeatureSupported(QRhi::MultisampleRenderBuffer)
&& sampleCounts.contains(sampleCount))) {
auto node = new RiveQSGRHIRenderNode(window, artboardInstance, geometry);
node->setFillMode(m_renderSettings.fillMode);
node->setPostprocessingMode(m_renderSettings.postprocessingMode);
return node;
} else {
qCritical(rqqpFactory)
<< "MSAA requested, but requested sample size is not supported - requested sample size:" << sampleCount;
return nullptr;
}
}
#endif
case QSGRendererInterface::GraphicsApi::Software:
default:
return new RiveQSGSoftwareRenderNode(window, artboardInstance, geometry);
}
}

rive::rcp<rive::RenderBuffer> RiveQtFactory::makeRenderBuffer(rive::RenderBufferType renderBufferType, rive::RenderBufferFlags renderBufferFlags, size_t size)
{
return rive::make_rcp<rive::DataRenderBuffer>(renderBufferType, renderBufferFlags, size);;
return rive::make_rcp<rive::DataRenderBuffer>(renderBufferType, renderBufferFlags, size);
}

rive::rcp<rive::RenderShader> RiveQtFactory::makeLinearGradient(float x1, float y1, float x2, float y2, const rive::ColorInt *colors,
Expand All @@ -92,39 +36,12 @@ rive::rcp<rive::RenderShader> RiveQtFactory::makeRadialGradient(float centerX, f

rive::rcp<rive::RenderPath> RiveQtFactory::makeRenderPath(rive::RawPath &rawPath, rive::FillRule fillRule)
{
switch (renderType()) {
case RiveQtRenderType::QPainterRenderer:
return rive::make_rcp<RiveQtPainterPath>(rawPath, fillRule);
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
case RiveQtRenderType::RHIRenderer: {
rive::rcp<RiveQtPath> riveQtPath = rive::make_rcp<RiveQtPath>(rawPath, fillRule);
riveQtPath->setLevelOfDetail(levelOfDetail());
return riveQtPath;
}
#endif

case RiveQtRenderType::None:
default:
return rive::make_rcp<RiveQtPainterPath>(rawPath, fillRule); // TODO Add Empty Path
}
return rive::make_rcp<RiveQtPath>(rawPath, fillRule, m_renderSettings.renderQuality);
}

rive::rcp<rive::RenderPath> RiveQtFactory::makeEmptyRenderPath()
{
switch (renderType()) {
case RiveQtRenderType::QPainterRenderer:
return rive::make_rcp<RiveQtPainterPath>();
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
case RiveQtRenderType::RHIRenderer: {
rive::rcp<RiveQtPath> riveQtPath = rive::make_rcp<RiveQtPath>();
riveQtPath->setLevelOfDetail(levelOfDetail());
return riveQtPath;
}
#endif
case RiveQtRenderType::None:
default:
return rive::make_rcp<RiveQtPainterPath>(); // TODO Add Empty Path
}
return rive::make_rcp<RiveQtPath>();
}

rive::rcp<rive::RenderPaint> RiveQtFactory::makeRenderPaint()
Expand All @@ -142,60 +59,3 @@ rive::rcp<rive::RenderImage> RiveQtFactory::decodeImage(rive::Span<const uint8_t
}
return rive::rcp<RiveQtImage>(new RiveQtImage(image));
}

rive::rcp<rive::Font> RiveQtFactory::decodeFont(rive::Span<const uint8_t> span)
{
#ifdef WITH_RIVE_TEXT
return HBFont::Decode(span);
#else
return nullptr;
#endif
// Todo: would be nice to use qt build in support for fonts
// however qt is missing an api to access AXIS data from a font; lets for now use the HBFont maintained by rivecpp and consider
// switching later using qt directy would maybe allow us to drop the direct dependency on harfbuzz ...

/*QByteArray fontData(reinterpret_cast<const char *>(span.data()), static_cast<int>(span.size()));
int fontId = QFontDatabase::addApplicationFontFromData(fontData);

if (fontId == -1) {
return nullptr;
}

const QStringList fontFamilies = QFontDatabase::applicationFontFamilies(fontId);
if (fontFamilies.isEmpty()) {
return nullptr;
}

QFont font(fontFamilies.first());
return rive::rcp<RiveQtFont>(new RiveQtFont(font));*/

}

unsigned int RiveQtFactory::levelOfDetail()
{
switch (m_renderSettings.renderQuality) {
case RiveRenderSettings::Low:
return 1;
default:
case RiveRenderSettings::Medium:
return 5;
case RiveRenderSettings::High:
return 10;
}
}

RiveQtFactory::RiveQtRenderType RiveQtFactory::renderType()
{
switch (m_renderSettings.graphicsApi) {
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
case QSGRendererInterface::GraphicsApi::Direct3D11Rhi:
case QSGRendererInterface::GraphicsApi::OpenGLRhi:
case QSGRendererInterface::GraphicsApi::MetalRhi:
case QSGRendererInterface::GraphicsApi::VulkanRhi:
return RiveQtFactory::RiveQtRenderType::RHIRenderer;
#endif
case QSGRendererInterface::GraphicsApi::Software:
default:
return RiveQtFactory::RiveQtRenderType::QPainterRenderer;
}
}
40 changes: 4 additions & 36 deletions src/RiveQtQuickItem/renderer/riveqtfactory.h
Original file line number Diff line number Diff line change
@@ -1,62 +1,30 @@

// SPDX-FileCopyrightText: 2023 Jeremias Bosch <jeremias.bosch@basyskom.com>
// SPDX-FileCopyrightText: 2023 basysKom GmbH
//
// SPDX-License-Identifier: LGPL-3.0-or-later

#pragma once
#include <vector>

#include <QFont>
#include <QFontDatabase>

#include <rive/file.hpp>
#include <rive/factory.hpp>
#include <rive/artboard.hpp>
#include <rive/renderer.hpp>
#include <rive/span.hpp>
#include <utils/factory_utils.hpp>

#ifdef WITH_RIVE_TEXT
#include <rive/text/font_hb.hpp>
#endif

#include "datatypes.h"
#include "riveqsgrendernode.h"

class RiveQtQuickItem;

class RiveQtFactory : public rive::Factory
{
public:
enum class RiveQtRenderType : quint8
{
None,
QPainterRenderer,
RHIRenderer
};

explicit RiveQtFactory(const RiveRenderSettings &renderSettings = RiveRenderSettings())
: rive::Factory()
, m_renderSettings(renderSettings)
{
}
explicit RiveQtFactory(RiveRenderSettings &renderSettings);

void setRenderSettings(const RiveRenderSettings &renderSettings) { m_renderSettings = renderSettings; }

RiveQSGRenderNode *renderNode(QQuickWindow *window, std::weak_ptr<rive::ArtboardInstance> artboardInstance, const QRectF &geometry);
rive::rcp<rive::RenderBuffer> makeRenderBuffer(rive::RenderBufferType, rive::RenderBufferFlags, size_t) override;

rive::rcp<rive::RenderShader> makeLinearGradient(float, float, float, float, const rive::ColorInt[], const float[], size_t) override;
rive::rcp<rive::RenderShader> makeRadialGradient(float, float, float, const rive::ColorInt[], const float[], size_t) override;
rive::rcp<rive::RenderPath> makeRenderPath(rive::RawPath &rawPath, rive::FillRule fillRule) override;
rive::rcp<rive::RenderPath> makeEmptyRenderPath() override;
rive::rcp<rive::RenderPaint> makeRenderPaint() override;
rive::rcp<rive::RenderImage> decodeImage(rive::Span<const uint8_t> span) override;
rive::rcp<rive::Font> decodeFont(rive::Span<const uint8_t> span) override;

private:
unsigned levelOfDetail();

RiveQtRenderType renderType();

RiveRenderSettings m_renderSettings;
RiveRenderSettings& m_renderSettings;
};
4 changes: 2 additions & 2 deletions src/RiveQtQuickItem/renderer/riveqtfont.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
//
// SPDX-License-Identifier: LGPL-3.0-or-later

#include <QPainterPath>

#include "renderer/riveqtfont.h"

#include <QPainterPath>

RiveQtFont::RiveQtFont(const QFont &font, const QFontMetricsF &fontMetrics)
: rive::Font({ static_cast<float>(fontMetrics.ascent()), static_cast<float>(fontMetrics.descent()) })
, m_font(font)
Expand Down
7 changes: 3 additions & 4 deletions src/RiveQtQuickItem/renderer/riveqtfont.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@

// SPDX-FileCopyrightText: 2023 Jeremias Bosch <jeremias.bosch@basyskom.com>
// SPDX-FileCopyrightText: 2023 basysKom GmbH
//
// SPDX-License-Identifier: LGPL-3.0-or-later

#pragma once

#include <rive/text_engine.hpp>
#include <rive/core.hpp>

#include <QFont>
#include <QFontDatabase>
#include <QFontInfo>
Expand All @@ -15,9 +17,6 @@
#include <QTextLayout>
#include <QTextOption>

#include <rive/text_engine.hpp>
#include <rive/core.hpp>

class RiveQtFont : public rive::Font, public std::enable_shared_from_this<RiveQtFont>
{

Expand Down
Loading
Loading