From: Michal Szczecinski Date: Sat, 13 Aug 2022 08:15:19 +0000 (+0200) Subject: [Adaptation Layer] Added rive-tizen adaptation layer class. X-Git-Tag: accepted/tizen/unified/20220824.135622^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=963fad417e7f751d5441ef0bba5906060d7b4e97;p=platform%2Fcore%2Fuifw%2Frive-tizen.git [Adaptation Layer] Added rive-tizen adaptation layer class. RiveTizen class is an adapter between two versions of rive-cpp. This allows us to seamlessly update the rive-cpp version, which in some cases provides a new API without breaking the entire dependency system. Update process will be performed in 3 or 4 steps: 1. Merge this commit 2. Use introduced class in the dali extension code. 3. Update rive-cpp 4. Remove or left adapter for future changes. Change-Id: I9cb26a7c4b875bdbb20830d5a286150bdbb46ced --- diff --git a/inc/rive_tizen.hpp b/inc/rive_tizen.hpp index be92d0e..7bbf0aa 100644 --- a/inc/rive_tizen.hpp +++ b/inc/rive_tizen.hpp @@ -1,5 +1,41 @@ +#ifndef _RIVE_TIZEN_HPP_ +#define _RIVE_TIZEN_HPP_ + #include +#include +#include +#include + #define RIVE_EXPORT __attribute__ ((visibility ("default"))) RIVE_EXPORT void rive_tizen_print(); + +#include + +class RiveTizen { + private: + rive::Artboard *mArtboard; ///< Loaded artboard + + public: + RiveTizen(); + ~RiveTizen(); + + rive::Artboard* getArtboard(); + rive::LinearAnimationInstance* createLinearAnimationInstance(size_t index); + void animationAdvanceApply(rive::LinearAnimationInstance* animation, double elapsed); + void animationApply(rive::LinearAnimationInstance* animation, double elapsed); + + bool loadRiveResource(uint8_t* bytes, size_t size); + bool createCanvas(unsigned char* buffer, unsigned width, unsigned height, unsigned stride); + bool render(double elapsed, unsigned width, unsigned height); + + bool setShapeFillColor(const std::string &name, int a, int r, int g, int b); + bool setShapeStrokeColor(const std::string &name, int a, int r, int g, int b); + bool setNodeOpacity(const std::string &name, float opacity); + bool setNodeScale(const std::string &name, float scale_x, float scale_y); + bool setNodeRotation(const std::string &name, float degree); + bool setNodePosition(const std::string &name, float position_x, float position_y); +}; + +#endif \ No newline at end of file diff --git a/meson.build b/meson.build index f4c53dd..596d831 100644 --- a/meson.build +++ b/meson.build @@ -8,6 +8,7 @@ run_command('script/install.sh') add_project_arguments('-DRIVE_FILE_DIR="@0@/example/resources/"'.format(meson.current_source_dir()), language : 'cpp') thorvg_dep = dependency('thorvg', required : true) +dlog_dep = dependency('dlog', required: true) install_headers([ 'submodule/include/artboard.hpp', @@ -375,12 +376,14 @@ rive_cpp_src = [ 'submodule/src/generated/shapes/paint/trim_path_base.cpp', ] +rive_cpp_inc = include_directories('submodule/include') + rive_cpp_dep = declare_dependency( - include_directories : include_directories('submodule/include'), + include_directories : rive_cpp_inc, sources : rive_cpp_src, ) -headers = [include_directories('inc'), include_directories('submodule/include'), include_directories('src/renderer')] +headers = [include_directories('inc'), include_directories('submodule/include'), include_directories('src/renderer'), include_directories('src')] subdir('inc') subdir('src') @@ -389,8 +392,3 @@ if get_option('example') == true message('Enable Examples') subdir('example') endif - -if get_option('test') == true - subdir('test') -endif - diff --git a/packaging/rive-tizen.spec b/packaging/rive-tizen.spec index 382da7f..0ac9a18 100644 --- a/packaging/rive-tizen.spec +++ b/packaging/rive-tizen.spec @@ -9,6 +9,7 @@ Source0: %{name}-%{version}.tar.gz BuildRequires: pkgconfig BuildRequires: pkgconfig(thorvg) +BuildRequires: pkgconfig(dlog) BuildRequires: meson BuildRequires: ninja diff --git a/src/renderer/meson.build b/src/renderer/meson.build index 401fc38..11c54b8 100644 --- a/src/renderer/meson.build +++ b/src/renderer/meson.build @@ -7,5 +7,5 @@ source_files = [ rive_tizen_renderer_dep = declare_dependency( include_directories : include_directories('.'), sources : source_files, - dependencies : thorvg_dep + dependencies : [thorvg_dep, dlog_dep] ) diff --git a/src/rive_tizen.cpp b/src/rive_tizen.cpp index 1c4f3ed..80975f9 100644 --- a/src/rive_tizen.cpp +++ b/src/rive_tizen.cpp @@ -1,10 +1,201 @@ #include "rive_tizen.hpp" -#include "math/aabb.hpp" -void rive_tizen_print() +#include +#include + +#include +#include +#include +#include +#include + +#include "tvg_renderer.hpp" + +//Remove compilation warning +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "RIVE_TIZEN" + +//TODO: maybe we have to introduce another class -> Adapter implementation +//and encapsulate header there. We don't want to put implementation related +//code in the class header file. +std::unique_ptr mSwCanvas; ///< ThorVG SW canvas handle + +RiveTizen::RiveTizen() +{ + tvg::Initializer::init(tvg::CanvasEngine::Sw, 0); + mArtboard = nullptr; +} + +RiveTizen::~RiveTizen() { - // This line to check calling Rive APIs - rive::AABB aabb(0, 0, 100, 100); - // This line to check rive_tizen API calls - std::cout << "hello rive-tizen" << std::endl; + tvg::Initializer::term(tvg::CanvasEngine::Sw); +} + +void RiveTizen::animationAdvanceApply(rive::LinearAnimationInstance *animation, double elapsed) +{ + if (!animation) + { + return; + } + animation->advance(elapsed); + animation->apply(mArtboard); +} + +void RiveTizen::animationApply(rive::LinearAnimationInstance *animation, double elapsed) +{ + if (!animation) + { + return; + } + animation->time(elapsed); + animation->apply(mArtboard); +} + +rive::LinearAnimationInstance *RiveTizen::createLinearAnimationInstance(size_t index) +{ + auto animation = mArtboard->animation(index); + if (!animation) + { + return nullptr; + } + + rive::LinearAnimationInstance *instance = new rive::LinearAnimationInstance(animation); + return instance; +} + +rive::Artboard *RiveTizen::getArtboard() +{ + return mArtboard; +} + +bool RiveTizen::loadRiveResource(uint8_t *bytes, size_t size) +{ + + if (!bytes) + { + dlog_print(DLOG_ERROR, LOG_TAG, "Invalid function parameters: bytes == nullptr"); + return false; + } + + auto reader = rive::BinaryReader(bytes, size); + + if (mArtboard) + { + delete mArtboard; + mArtboard = nullptr; + } + + rive::File *file = nullptr; + + auto result = rive::File::import(reader, &file); + if (result != rive::ImportResult::success) + { + dlog_print(DLOG_ERROR, LOG_TAG, "rive::File::import() failed."); + return false; + } + + mArtboard = file->artboard(); + + return true; +} + +bool RiveTizen::createCanvas(unsigned char *buffer, unsigned int width, unsigned int height, unsigned int stride) +{ + if (!mSwCanvas) + { + mSwCanvas = tvg::SwCanvas::gen(); + mSwCanvas->mempool(tvg::SwCanvas::MempoolPolicy::Individual); + } + mSwCanvas->clear(); + mSwCanvas->target((uint32_t *)buffer, stride, width, height, tvg::SwCanvas::ARGB8888); + return true; +} + +bool RiveTizen::render(double elapsed, unsigned int width, unsigned int height) +{ + mArtboard->advance(elapsed); + rive::TvgRenderer renderer(mSwCanvas.get()); + + renderer.save(); + renderer.align(rive::Fit::contain, + rive::Alignment::center, + rive::AABB(0, 0, width, height), + mArtboard->bounds()); + mArtboard->draw(&renderer); + renderer.restore(); + + auto result = mSwCanvas->draw(); + if (result == tvg::Result::Success) + { + mSwCanvas->sync(); + } + else + { + return false; + } + + return true; +} + +bool RiveTizen::setShapeFillColor(const std::string &name, int a, int r, int g, int b) +{ + auto instance = mArtboard->find(name.c_str()); + if (!instance || !instance->paint()->is()) + return false; + instance->paint()->as()->colorValue(rive::colorARGB(a, r, g, b)); + return true; +} + +bool RiveTizen::setShapeStrokeColor(const std::string &name, int a, int r, int g, int b) +{ + auto instance = mArtboard->find(name.c_str()); + if (!instance || !instance->paint()->is()) + return false; + instance->paint()->as()->colorValue(rive::colorARGB(a, r, g, b)); + return true; +} + +bool RiveTizen::setNodeOpacity(const std::string &name, float opacity) +{ + auto node = mArtboard->find(name.c_str()); + if (!node) + return false; + node->as()->opacity(opacity); + return true; +} + +bool RiveTizen::setNodeScale(const std::string &name, float scale_x, float scale_y) +{ + auto node = mArtboard->find(name.c_str()); + if (!node) + return false; + + auto nodeInstance = node->as(); + nodeInstance->scaleX(scale_x); + nodeInstance->scaleY(scale_y); + return true; +} + +bool RiveTizen::setNodeRotation(const std::string &name, float degree) +{ + auto node = mArtboard->find(name.c_str()); + if (!node) + return false; + + node->as()->rotation(degree); + return true; +} + +bool RiveTizen::setNodePosition(const std::string &name, float position_x, float position_y) +{ + auto node = mArtboard->find(name.c_str()); + if (!node) + return false; + + auto nodeInstance = node->as(); + nodeInstance->x(position_x); + nodeInstance->y(position_y); + return true; }