3 #include <Elementary.h>
7 #include "SkColorSpace.h"
11 #include "rive/animation/linear_animation_instance.hpp"
12 #include "rive/animation/state_machine_instance.hpp"
13 #include "rive/animation/state_machine_input_instance.hpp"
14 #include "rive/animation/state_machine_number.hpp"
15 #include "rive/animation/state_machine_bool.hpp"
16 #include "rive/animation/state_machine_trigger.hpp"
17 #include "rive/artboard.hpp"
18 #include "rive/file.hpp"
19 #include "rive/layout.hpp"
20 #include "rive/math/aabb.hpp"
21 #include "skia_factory.hpp"
22 #include "skia_renderer.hpp"
27 Evas_Object *view = nullptr;
30 sk_sp<SkSurface> surface;
31 SkCanvas* canvas = nullptr;
33 std::vector<uint8_t> fileBytes;
34 int animationIndex = 0;
35 int stateMachineIndex = -1;
37 rive::SkiaFactory skiaFactory;
39 std::unique_ptr<rive::File> currentFile;
40 std::unique_ptr<rive::ArtboardInstance> artboardInstance;
41 std::unique_ptr<rive::Scene> currentScene;
43 std::vector<std::string> animationNames;
44 std::vector<std::string> stateMachineNames;
46 static Ecore_Animator *anim;
48 static Eina_Bool _do_animation(void *data, double pos)
50 return ECORE_CALLBACK_RENEW;
53 static void createCanvas(unsigned int width, unsigned int height) {
54 static constexpr auto BPP = 4;
56 if (pixels) free(pixels);
57 pixels = (void*) malloc (width * height * BPP);
59 static constexpr SkAlphaType at = kPremul_SkAlphaType;
60 const SkImageInfo info = SkImageInfo::MakeN32(width, height, at);
62 surface = SkSurface::MakeRasterDirect(info, pixels, width * BPP);
64 fprintf(stderr, "Failed to create Skia surface\n");
67 canvas = surface->getCanvas();
70 static void loadNames(const rive::Artboard* ab) {
71 animationNames.clear();
72 stateMachineNames.clear();
74 for (size_t i = 0; i < ab->animationCount(); ++i) {
75 animationNames.push_back(ab->animationNameAt(i));
77 for (size_t i = 0; i < ab->stateMachineCount(); ++i) {
78 stateMachineNames.push_back(ab->stateMachineNameAt(i));
83 static void initAnimation(int index) {
84 animationIndex = index;
85 stateMachineIndex = -1;
86 assert(fileBytes.size() != 0);
87 auto file = rive::File::import(rive::toSpan(fileBytes), &skiaFactory);
90 fprintf(stderr, "failed to import file\n");
93 currentScene = nullptr;
94 artboardInstance = nullptr;
96 currentFile = std::move(file);
97 artboardInstance = currentFile->artboardDefault();
98 artboardInstance->advance(0.0f);
99 loadNames(artboardInstance.get());
101 if (index >= 0 && index < artboardInstance->animationCount()) {
102 currentScene = artboardInstance->animationAt(index);
103 currentScene->inputCount();
106 evas_object_image_pixels_dirty_set(view, EINA_TRUE);
110 static void loadRivFile(const char* filename) {
111 FILE* fp = fopen(filename, "rb");
113 fprintf(stderr, "file %s opening failure.\n", filename);
116 fseek(fp, 0, SEEK_END);
117 size_t size = ftell(fp);
118 fseek(fp, 0, SEEK_SET);
119 fileBytes.resize(size);
120 if (fread(fileBytes.data(), 1, size, fp) != size) {
122 fprintf(stderr, "failed to read all of %s\n", filename);
125 printf("Loaded %s file succesfully.\n", filename);
129 static float getElapsedTime() {
130 static clock_t staticClock = clock();
133 float elapsed = (float)(t - staticClock)/CLOCKS_PER_SEC;
139 printf("[mszczeci][%s:%d][%s]\n",__FILE__, __LINE__, __func__);
141 paint.setColor(SK_ColorGRAY);
142 canvas->drawPaint(paint);
144 loadRivFile("file.riv");
147 void drawSwView(void* data, Eo* obj) {
149 const float elapsed = getElapsedTime();
150 bool ret = currentScene->advanceAndApply(elapsed);
154 rive::SkiaRenderer renderer(canvas);
157 const unsigned int width = WIDTH, height = HEIGHT;
159 auto viewTransform = rive::computeAlignment(rive::Fit::contain,
160 rive::Alignment::center,
161 rive::AABB(0, 0, width, height),
162 currentScene->bounds());
163 renderer.transform(viewTransform);
165 currentScene->draw(&renderer);
169 double time_taken = ((double)t)/CLOCKS_PER_SEC;
170 printf("Frame rendering time %f sec\n", time_taken);
174 void transitSwCallback(Elm_Transit_Effect *effect, Elm_Transit* transit, double progress) {
175 Eo* img = (Eo*) effect;
176 evas_object_image_data_update_add(img, 0, 0, WIDTH, HEIGHT);
177 evas_object_image_pixels_dirty_set(img, EINA_TRUE);
180 void win_del(void *data, Evas_Object *o, void *ev) {
184 int main(int argc, char **argv) {
185 elm_init(argc, argv);
187 Eo* win = elm_win_util_standard_add(NULL, "Rive-skia CPU Viewer");
188 evas_object_smart_callback_add(win, "delete,request", win_del, 0);
190 createCanvas(WIDTH, HEIGHT);
192 view = evas_object_image_filled_add(evas_object_evas_get(win));
193 evas_object_image_size_set(view, WIDTH, HEIGHT);
194 evas_object_image_data_set(view, pixels);
195 evas_object_image_pixels_get_callback_set(view, drawSwView, nullptr);
196 evas_object_image_pixels_dirty_set(view, EINA_TRUE);
197 evas_object_image_data_update_add(view, 0, 0, WIDTH, HEIGHT);
198 evas_object_size_hint_weight_set(view, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
199 evas_object_show(view);
201 elm_win_resize_object_add(win, view);
202 evas_object_geometry_set(win, 0, 0, WIDTH, HEIGHT);
203 evas_object_show(win);
205 Elm_Transit *transit = elm_transit_add();
206 elm_transit_effect_add(transit, transitSwCallback, view, nullptr);
207 elm_transit_duration_set(transit, 1);
208 elm_transit_repeat_times_set(transit, -1);
209 elm_transit_auto_reverse_set(transit, EINA_TRUE);
210 elm_transit_go(transit);