5b8ad9d0fbc92c55a2cab700916450157d2a3bd9
[platform/core/uifw/rive-tizen.git] / src / rive_tizen.cpp
1 #include "rive_tizen.hpp"
2
3 #include <skia_factory.hpp>
4 #include <skia_renderer.hpp>
5
6 #include <SkCanvas.h>
7 #include <SkColorSpace.h>
8 #include <SkSurface.h>
9 #include <SkTypes.h>
10
11 #ifdef USE_GL
12 #define SK_GL
13 #include <GLFW/glfw3.h>
14
15 #include "GrBackendSurface.h"
16 #include "GrDirectContext.h"
17 #include "gl/GrGLInterface.h"
18 #endif
19
20 #include <rive/node.hpp>
21 #include <rive/shapes/paint/color.hpp>
22 #include <rive/shapes/paint/solid_color.hpp>
23 #include <rive/shapes/paint/stroke.hpp>
24 #include <rive/shapes/paint/fill.hpp>
25 #include <rive/artboard.hpp>
26
27 #ifdef LOG_TAG
28 #undef LOG_TAG
29 #endif
30 #define LOG_TAG "RIVE_TIZEN"
31
32 #ifdef TIZEN
33 #include <dlog.h>
34 #define LOGE(fmt, ...) dlog_print(DLOG_ERROR, LOG_TAG, "[%s]" fmt, __func__, ##__VA_ARGS__)
35 #else
36 #define C_RED "\e[31m"
37 #define C_END "\e[0m"
38 #define LOGE(fmt, ...) printf(C_RED "[" LOG_TAG "]" C_END "[%s]" fmt "\n", __func__, ##__VA_ARGS__)
39 #endif
40
41 static sk_sp<SkSurface> mSkiaSurface;
42 static SkCanvas *mSkiaCanvas = nullptr;
43 static rive::SkiaFactory mSkiaFactory;
44 static std::unique_ptr<rive::File> mFile;
45 static std::unique_ptr<rive::ArtboardInstance> mArtboardInstance;
46
47 #ifdef USE_GL
48 static sk_sp<GrDirectContext> mContext;
49 #endif
50
51 RiveTizen::RiveTizen()
52 {
53 }
54
55 RiveTizen::~RiveTizen()
56 {
57 }
58
59 rive::Artboard *RiveTizen::getArtboard()
60 {
61    return mArtboardInstance.get();
62 }
63
64 void RiveTizen::animationAdvanceApply(rive::LinearAnimationInstance *animation, double elapsed)
65 {
66    if (!animation)
67    {
68       LOGE("[Invalid parameter][animation == nullptr]");
69       return;
70    }
71    animation->advanceAndApply(elapsed);
72    animation->apply();
73 }
74
75 void RiveTizen::animationApply(rive::LinearAnimationInstance *animation, double elapsed)
76 {
77    if (!animation)
78    {
79       LOGE("[Invalid parameter][animation == nullptr]");
80       return;
81    }
82    animation->time(elapsed);
83    animation->apply();
84 }
85
86 rive::LinearAnimationInstance *RiveTizen::createLinearAnimationInstance(size_t index)
87 {
88    auto animation = mArtboardInstance->animation(index);
89
90    if (!animation)
91    {
92       LOGE("[Invalid parameter][animation == nullptr]");
93       return nullptr;
94    }
95
96    rive::LinearAnimationInstance *instance = new rive::LinearAnimationInstance(animation, mArtboardInstance.get());
97    return instance;
98 }
99
100 bool RiveTizen::loadRiveResource(uint8_t *bytes, size_t size)
101 {
102    mFile = nullptr;
103    mArtboardInstance = nullptr;
104
105    const rive::Span<const uint8_t> span(bytes, size);
106    auto file = rive::File::import(span, &mSkiaFactory);
107    if (!file)
108    {
109       return false;
110    }
111
112    mFile = std::move(file);
113
114    mArtboardInstance = mFile->artboardDefault();
115    mArtboardInstance->advance(0.0f);
116
117    return true;
118 }
119
120 bool RiveTizen::createCanvas(unsigned char *buffer, unsigned int width, unsigned int height, unsigned int stride)
121 {
122 #ifdef USE_GL
123    // Buffer is unused for gpu-based version
124    GrContextOptions options;
125    mContext = GrDirectContext::MakeGL(nullptr, options);
126
127    GrGLFramebufferInfo framebufferInfo;
128    framebufferInfo.fFBOID = 0;
129    framebufferInfo.fFormat = GL_RGBA8;
130    GrBackendRenderTarget backendRenderTarget(width, height, 0 /* sample count */, 0 /* stencil bits */, framebufferInfo);
131
132    mSkiaSurface = SkSurface::MakeFromBackendRenderTarget(mContext.get(), backendRenderTarget, kBottomLeft_GrSurfaceOrigin,
133                   kRGBA_8888_SkColorType, nullptr, nullptr);
134 #else
135    SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
136    mSkiaSurface = SkSurface::MakeRasterDirect(info, buffer, stride * 4);
137 #endif
138
139    if (!mSkiaSurface)
140    {
141       #ifdef USE_GL
142       #define USE_GL_VALUE "true"
143       #else
144       #define USE_GL_VALUE "false"
145       #endif
146       LOGE("[Failed to create Skia surface][USE_GL = " USE_GL_VALUE "]");
147       return false;
148    }
149
150    mSkiaCanvas = mSkiaSurface->getCanvas();
151    mSkiaCanvas->clear(SK_ColorTRANSPARENT);
152    return true;
153 }
154
155 bool RiveTizen::render(double elapsed, unsigned int width, unsigned int height)
156 {
157    rive::SkiaRenderer renderer(mSkiaCanvas);
158    renderer.save();
159    auto viewTransform = rive::computeAlignment(rive::Fit::contain, rive::Alignment::center,
160                                                rive::AABB(0, 0, width, height), mArtboardInstance->bounds());
161
162    renderer.transform(viewTransform);
163    mArtboardInstance->draw(&renderer);
164    renderer.restore();
165
166 #ifdef USE_GL
167    mContext->flush();
168 #endif
169
170    return true;
171 }
172
173 bool RiveTizen::setShapeFillColor(const std::string &name, int a, int r, int g, int b)
174 {
175    auto instance = mArtboardInstance->find<rive::Fill>(name.c_str());
176    if (!instance || !instance->paint()->is<rive::SolidColor>())
177       return false;
178
179    instance->paint()->as<rive::SolidColor>()->colorValue(rive::colorARGB(a, r, g, b));
180    return true;
181 }
182
183 bool RiveTizen::setShapeStrokeColor(const std::string &name, int a, int r, int g, int b)
184 {
185    auto instance = mArtboardInstance->find<rive::Stroke>(name.c_str());
186    if (!instance || !instance->paint()->is<rive::SolidColor>())
187       return false;
188
189    instance->paint()->as<rive::SolidColor>()->colorValue(rive::colorARGB(a, r, g, b));
190    return true;
191 }
192
193 bool RiveTizen::setNodeOpacity(const std::string &name, float opacity)
194 {
195    auto node = mArtboardInstance->find(name.c_str());
196    if (!node)
197       return false;
198
199    node->as<rive::Node>()->opacity(opacity);
200    return true;
201 }
202
203 bool RiveTizen::setNodeScale(const std::string &name, float scale_x, float scale_y)
204 {
205    auto node = mArtboardInstance->find(name.c_str());
206    if (!node)
207       return false;
208
209    auto nodeInstance = node->as<rive::Node>();
210    nodeInstance->scaleX(scale_x);
211    nodeInstance->scaleY(scale_y);
212    return true;
213 }
214
215 bool RiveTizen::setNodeRotation(const std::string &name, float degree)
216 {
217    auto node = mArtboardInstance->find(name.c_str());
218    if (!node)
219       return false;
220
221    node->as<rive::Node>()->rotation(degree);
222    return true;
223 }
224
225 bool RiveTizen::setNodePosition(const std::string &name, float position_x, float position_y)
226 {
227    auto node = mArtboardInstance->find(name.c_str());
228    if (!node)
229       return false;
230
231    auto nodeInstance = node->as<rive::Node>();
232    nodeInstance->x(position_x);
233    nodeInstance->y(position_y);
234    return true;
235 }