Fission the CG and Skia renderers Diffs= c63346b93 Fission the CG and Skia renderers (#6071) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com>
diff --git a/.rive_head b/.rive_head index eb5f98f..ddd650c 100644 --- a/.rive_head +++ b/.rive_head
@@ -1 +1 @@ -45359b3e81085b85fa517ec8e26ac273eb40ad04 +c63346b93db6df8ecf299c44735cce95ccfbf2a8
diff --git a/cg_renderer/build/premake5.lua b/cg_renderer/build/premake5.lua new file mode 100644 index 0000000..e304207 --- /dev/null +++ b/cg_renderer/build/premake5.lua
@@ -0,0 +1,127 @@ +workspace 'rive' +configurations {'debug', 'release'} + +require 'setup_compiler' + +dependencies = os.getenv('DEPENDENCIES') + +project 'rive_cg_renderer' +do + kind 'StaticLib' + language 'C++' + cppdialect 'C++17' + targetdir '%{cfg.system}/bin/%{cfg.buildcfg}' + objdir '%{cfg.system}/obj/%{cfg.buildcfg}' + includedirs { + '../include', + '../../include', + } + + libdirs {'../../../build/%{cfg.system}/bin/%{cfg.buildcfg}'} + + files { + '../src/**.cpp', + } + + flags { + 'FatalCompileWarnings', + } + exceptionhandling 'off' + rtti 'off' + + filter "system:windows" + do + architecture 'x64' + defines {'_USE_MATH_DEFINES'} + end + + filter {'system:macosx', 'options:variant=runtime'} + do + buildoptions { + '-fembed-bitcode -arch arm64 -arch x86_64', + } + end + + if os.host() == 'macosx' then + iphoneos_sysroot = os.outputof('xcrun --sdk iphoneos --show-sdk-path') + iphonesimulator_sysroot = os.outputof('xcrun --sdk iphonesimulator --show-sdk-path') + + filter {'system:ios', 'options:variant=system'} + do + buildoptions { + '-mios-version-min=13.0 -fembed-bitcode -arch arm64 -isysroot ' .. iphoneos_sysroot + } + end + + filter {'system:ios', 'options:variant=emulator'} + do + buildoptions { + '--target=arm64-apple-ios13.0.0-simulator -mios-version-min=13.0 -arch x86_64 -arch arm64 -isysroot ' .. + iphonesimulator_sysroot + } + targetdir '%{cfg.system}_sim/bin/%{cfg.buildcfg}' + objdir '%{cfg.system}_sim/obj/%{cfg.buildcfg}' + end + end + + filter {'configurations:release', 'system:macosx'} + do + buildoptions {'-flto=full'} + end + + filter {'configurations:release', 'system:android'} + do + buildoptions {'-flto=full'} + end + + filter {'configurations:release', 'system:ios'} + do + buildoptions {'-flto=full'} + end + + filter 'configurations:debug' + do + defines {'DEBUG'} + symbols 'On' + end + + filter 'configurations:release' + do + defines {'RELEASE', 'NDEBUG'} + optimize 'On' + end + + filter {'options:with_rive_text'} + do + defines {'WITH_RIVE_TEXT'} + end +end + +newoption { + trigger = 'with_rive_text', + description = 'Enables text experiments' +} + +newoption { + trigger = 'variant', + value = 'type', + description = 'Choose a particular variant to build', + allowed = { + {'system', 'Builds the static library for the provided system'}, + {'emulator', 'Builds for an emulator/simulator for the provided system'}, + {'runtime', 'Build the static library specifically targeting our runtimes'} + }, + default = 'system' +} + +newoption { + trigger = 'arch', + value = 'ABI', + description = 'The ABI with the right toolchain for this build, generally with Android', + allowed = { + {'x86'}, + {'x64'}, + {'arm'}, + {'arm64'} + } +}
diff --git a/skia/renderer/include/cg_factory.hpp b/cg_renderer/include/cg_factory.hpp similarity index 100% rename from skia/renderer/include/cg_factory.hpp rename to cg_renderer/include/cg_factory.hpp
diff --git a/skia/renderer/include/cg_renderer.hpp b/cg_renderer/include/cg_renderer.hpp similarity index 87% rename from skia/renderer/include/cg_renderer.hpp rename to cg_renderer/include/cg_renderer.hpp index 945c2df..5b071fc 100644 --- a/skia/renderer/include/cg_renderer.hpp +++ b/cg_renderer/include/cg_renderer.hpp
@@ -6,6 +6,7 @@ #define _RIVE_CG_RENDERER_HPP_ #include "rive/renderer.hpp" +#include "utils/auto_cf.hpp" #if defined(RIVE_BUILD_FOR_OSX) #include <ApplicationServices/ApplicationServices.h> @@ -39,6 +40,9 @@ uint32_t indexCount, BlendMode, float opacity) override; + + static AutoCF<CGImageRef> DecodeToCGImage(Span<const uint8_t>); + static AutoCF<CGImageRef> FlipCGImageInY(AutoCF<CGImageRef>); }; } // namespace rive #endif
diff --git a/skia/renderer/src/cg_factory.cpp b/cg_renderer/src/cg_factory.cpp similarity index 92% rename from skia/renderer/src/cg_factory.cpp rename to cg_renderer/src/cg_factory.cpp index 89d3007..81e4e2f 100644 --- a/skia/renderer/src/cg_factory.cpp +++ b/cg_renderer/src/cg_factory.cpp
@@ -8,14 +8,6 @@ #include "cg_factory.hpp" #include "cg_renderer.hpp" -#include "mac_utils.hpp" - -#if defined(RIVE_BUILD_FOR_OSX) -#include <ApplicationServices/ApplicationServices.h> -#elif defined(RIVE_BUILD_FOR_IOS) -#include <CoreGraphics/CoreGraphics.h> -#include <ImageIO/ImageIO.h> -#endif #include "utils/factory_utils.hpp" #include "rive/math/vec2d.hpp" @@ -312,7 +304,7 @@ public: AutoCF<CGImageRef> m_image; - CGRenderImage(const Span<const uint8_t> span) : m_image(DecodeToCGImage(span)) + CGRenderImage(const Span<const uint8_t> span) : m_image(CGRenderer::DecodeToCGImage(span)) { if (m_image) { @@ -531,4 +523,44 @@ return std::make_unique<CGRenderImage>(encoded); } +AutoCF<CGImageRef> CGRenderer::FlipCGImageInY(AutoCF<CGImageRef> image) +{ + if (!image) + { + return nullptr; + } + + auto w = CGImageGetWidth(image); + auto h = CGImageGetHeight(image); + AutoCF space = CGColorSpaceCreateDeviceRGB(); + auto info = kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast; + AutoCF ctx = CGBitmapContextCreate(nullptr, w, h, 8, 0, space, info); + CGContextConcatCTM(ctx, CGAffineTransformMake(1, 0, 0, -1, 0, h)); + CGContextDrawImage(ctx, CGRectMake(0, 0, w, h), image); + return CGBitmapContextCreateImage(ctx); +} + +AutoCF<CGImageRef> CGRenderer::DecodeToCGImage(rive::Span<const uint8_t> span) +{ + AutoCF data = CFDataCreate(nullptr, span.data(), span.size()); + if (!data) + { + printf("CFDataCreate failed\n"); + return nullptr; + } + + AutoCF source = CGImageSourceCreateWithData(data, nullptr); + if (!source) + { + printf("CGImageSourceCreateWithData failed\n"); + return nullptr; + } + + AutoCF image = CGImageSourceCreateImageAtIndex(source, 0, nullptr); + if (!image) + { + printf("CGImageSourceCreateImageAtIndex failed\n"); + } + return image; +} #endif // APPLE
diff --git a/include/utils/auto_cf.hpp b/include/utils/auto_cf.hpp new file mode 100644 index 0000000..5512a0b --- /dev/null +++ b/include/utils/auto_cf.hpp
@@ -0,0 +1,74 @@ +#pragma once + +#include "rive/rive_types.hpp" + +#ifdef RIVE_BUILD_FOR_APPLE + +#if defined(RIVE_BUILD_FOR_OSX) +#include <ApplicationServices/ApplicationServices.h> +#elif defined(RIVE_BUILD_FOR_IOS) +#include <CoreFoundation/CoreFoundation.h> +#endif + +template <typename T> class AutoCF +{ + T m_obj; + +public: + AutoCF(T obj = nullptr) : m_obj(obj) {} + AutoCF(const AutoCF& other) + { + if (other.m_obj) + { + CFRetain(other.m_obj); + } + m_obj = other.m_obj; + } + AutoCF(AutoCF&& other) + { + m_obj = other.m_obj; + other.m_obj = nullptr; + } + ~AutoCF() + { + if (m_obj) + { + CFRelease(m_obj); + } + } + + AutoCF& operator=(const AutoCF& other) + { + if (m_obj != other.m_obj) + { + if (other.m_obj) + { + CFRetain(other.m_obj); + } + if (m_obj) + { + CFRelease(m_obj); + } + m_obj = other.m_obj; + } + return *this; + } + + void reset(T obj) + { + if (obj != m_obj) + { + if (m_obj) + { + CFRelease(m_obj); + } + m_obj = obj; + } + } + + operator T() const { return m_obj; } + operator bool() const { return m_obj != nullptr; } + T get() const { return m_obj; } +}; + +#endif // RIVE_BUILD_FOR_APPLE
diff --git a/skia/renderer/build/premake5.lua b/skia/renderer/build/premake5.lua index f89fc9d..e9bdc30 100644 --- a/skia/renderer/build/premake5.lua +++ b/skia/renderer/build/premake5.lua
@@ -24,6 +24,7 @@ objdir '%{cfg.system}/obj/%{cfg.buildcfg}' includedirs { '../include', + '../../../cg_renderer/include', '../../../include' }
diff --git a/skia/renderer/include/mac_utils.hpp b/skia/renderer/include/mac_utils.hpp index 13a9b3f..e283ab9 100644 --- a/skia/renderer/include/mac_utils.hpp +++ b/skia/renderer/include/mac_utils.hpp
@@ -3,17 +3,11 @@ #include "rive/rive_types.hpp" #include "rive/span.hpp" +#include "utils/auto_cf.hpp" #include <string> #ifdef RIVE_BUILD_FOR_APPLE -#if defined(RIVE_BUILD_FOR_OSX) -#include <ApplicationServices/ApplicationServices.h> -#elif defined(RIVE_BUILD_FOR_IOS) -#include <CoreFoundation/CoreFoundation.h> -#include <CoreGraphics/CGImage.h> -#endif - template <size_t N, typename T> class AutoSTArray { T m_storage[N]; @@ -61,67 +55,6 @@ return str; } -template <typename T> class AutoCF -{ - T m_obj; - -public: - AutoCF(T obj = nullptr) : m_obj(obj) {} - AutoCF(const AutoCF& other) - { - if (other.m_obj) - { - CFRetain(other.m_obj); - } - m_obj = other.m_obj; - } - AutoCF(AutoCF&& other) - { - m_obj = other.m_obj; - other.m_obj = nullptr; - } - ~AutoCF() - { - if (m_obj) - { - CFRelease(m_obj); - } - } - - AutoCF& operator=(const AutoCF& other) - { - if (m_obj != other.m_obj) - { - if (other.m_obj) - { - CFRetain(other.m_obj); - } - if (m_obj) - { - CFRelease(m_obj); - } - m_obj = other.m_obj; - } - return *this; - } - - void reset(T obj) - { - if (obj != m_obj) - { - if (m_obj) - { - CFRelease(m_obj); - } - m_obj = obj; - } - } - - operator T() const { return m_obj; } - operator bool() const { return m_obj != nullptr; } - T get() const { return m_obj; } -}; - static inline float find_float(CFDictionaryRef dict, const void* key) { auto num = (CFNumberRef)CFDictionaryGetValue(dict, key); @@ -155,11 +88,5 @@ return value; } -namespace rive -{ -AutoCF<CGImageRef> DecodeToCGImage(Span<const uint8_t>); -AutoCF<CGImageRef> FlipCGImageInY(AutoCF<CGImageRef>); -} // namespace rive - #endif #endif
diff --git a/skia/renderer/src/cg_skia_factory.cpp b/skia/renderer/src/cg_skia_factory.cpp index 5a4395a..a96acb7 100644 --- a/skia/renderer/src/cg_skia_factory.cpp +++ b/skia/renderer/src/cg_skia_factory.cpp
@@ -8,7 +8,7 @@ #ifdef RIVE_BUILD_FOR_APPLE #include "cg_skia_factory.hpp" -#include "mac_utils.hpp" +#include "cg_renderer.hpp" #if defined(RIVE_BUILD_FOR_OSX) #include <ApplicationServices/ApplicationServices.h> @@ -24,7 +24,7 @@ { std::vector<uint8_t> pixels; - AutoCF image = DecodeToCGImage(span); + AutoCF image = CGRenderer::DecodeToCGImage(span); if (!image) { return pixels;
diff --git a/skia/renderer/src/mac_utils.cpp b/skia/renderer/src/mac_utils.cpp deleted file mode 100644 index 89944d0..0000000 --- a/skia/renderer/src/mac_utils.cpp +++ /dev/null
@@ -1,55 +0,0 @@ -/* - * Copyright 2022 Rive - */ - -#include "mac_utils.hpp" - -#ifdef RIVE_BUILD_FOR_APPLE - -#if defined(RIVE_BUILD_FOR_IOS) -#include <CoreGraphics/CGImage.h> -#include <ImageIO/CGImageSource.h> -#endif - -AutoCF<CGImageRef> rive::FlipCGImageInY(AutoCF<CGImageRef> image) -{ - if (!image) - { - return nullptr; - } - - auto w = CGImageGetWidth(image); - auto h = CGImageGetHeight(image); - AutoCF space = CGColorSpaceCreateDeviceRGB(); - auto info = kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast; - AutoCF ctx = CGBitmapContextCreate(nullptr, w, h, 8, 0, space, info); - CGContextConcatCTM(ctx, CGAffineTransformMake(1, 0, 0, -1, 0, h)); - CGContextDrawImage(ctx, CGRectMake(0, 0, w, h), image); - return CGBitmapContextCreateImage(ctx); -} - -AutoCF<CGImageRef> rive::DecodeToCGImage(rive::Span<const uint8_t> span) -{ - AutoCF data = CFDataCreate(nullptr, span.data(), span.size()); - if (!data) - { - printf("CFDataCreate failed\n"); - return nullptr; - } - - AutoCF source = CGImageSourceCreateWithData(data, nullptr); - if (!source) - { - printf("CGImageSourceCreateWithData failed\n"); - return nullptr; - } - - AutoCF image = CGImageSourceCreateImageAtIndex(source, 0, nullptr); - if (!image) - { - printf("CGImageSourceCreateImageAtIndex failed\n"); - } - return image; -} - -#endif