bc650a8d5e51eee8ecfa0a82f25a0ff9337fb375
[platform/core/uifw/rive-tizen.git] / viewer / viewer_cpu.cpp
1 #include <iostream>
2 #include <thread>
3 #include <Elementary.h>
4 #include <time.h>
5
6 #include "SkCanvas.h"
7 #include "SkColorSpace.h"
8 #include "SkSurface.h"
9 #include "SkTypes.h"
10
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"
23
24 #define WIDTH 1280
25 #define HEIGHT 720
26
27 Evas_Object *view = nullptr;
28
29 void* pixels;
30 sk_sp<SkSurface> surface;
31 SkCanvas* canvas = nullptr;
32
33 std::vector<uint8_t> fileBytes;
34 int animationIndex = 0;
35 int stateMachineIndex = -1;
36
37 rive::SkiaFactory skiaFactory;
38
39 std::unique_ptr<rive::File> currentFile;
40 std::unique_ptr<rive::ArtboardInstance> artboardInstance;
41 std::unique_ptr<rive::Scene> currentScene;
42
43 std::vector<std::string> animationNames;
44 std::vector<std::string> stateMachineNames;
45
46 static Ecore_Animator *anim;
47
48 static Eina_Bool _do_animation(void *data, double pos)
49 {
50     return ECORE_CALLBACK_RENEW;
51 }
52
53 static void createCanvas(unsigned int width, unsigned int height) {
54     static constexpr auto BPP = 4;
55
56     if (pixels) free(pixels);
57     pixels = (void*) malloc (width * height * BPP);
58
59     static constexpr SkAlphaType at = kPremul_SkAlphaType;
60     const SkImageInfo info = SkImageInfo::MakeN32(width, height, at);
61
62     surface = SkSurface::MakeRasterDirect(info, pixels, width * BPP);
63     if (!surface) {
64         fprintf(stderr, "Failed to create Skia surface\n");
65     }
66
67     canvas = surface->getCanvas();
68 }
69
70 static void loadNames(const rive::Artboard* ab) {
71     animationNames.clear();
72     stateMachineNames.clear();
73     if (ab) {
74         for (size_t i = 0; i < ab->animationCount(); ++i) {
75             animationNames.push_back(ab->animationNameAt(i));
76         }
77         for (size_t i = 0; i < ab->stateMachineCount(); ++i) {
78             stateMachineNames.push_back(ab->stateMachineNameAt(i));
79         }
80     }
81 }
82
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);
88     if (!file) {
89         fileBytes.clear();
90         fprintf(stderr, "failed to import file\n");
91         return;
92     }
93     currentScene = nullptr;
94     artboardInstance = nullptr;
95
96     currentFile = std::move(file);
97     artboardInstance = currentFile->artboardDefault();
98     artboardInstance->advance(0.0f);
99     loadNames(artboardInstance.get());
100
101     if (index >= 0 && index < artboardInstance->animationCount()) {
102         currentScene = artboardInstance->animationAt(index);
103         currentScene->inputCount();
104     }
105
106     evas_object_image_pixels_dirty_set(view, EINA_TRUE);
107     evas_render(view);
108 }
109
110 static void loadRivFile(const char* filename) {
111     FILE* fp = fopen(filename, "rb");
112     if (!fp) {
113         fprintf(stderr, "file %s opening failure.\n", filename);
114         return;
115     }
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) {
121         fileBytes.clear();
122         fprintf(stderr, "failed to read all of %s\n", filename);
123         return;
124     }
125     printf("Loaded %s file succesfully.\n", filename);
126     initAnimation(0);
127 }
128
129 static float getElapsedTime() {
130     static clock_t staticClock = clock();
131     clock_t t = clock();
132
133     float elapsed = (float)(t - staticClock)/CLOCKS_PER_SEC;
134     staticClock = t;
135     return elapsed;
136
137
138 void initSwView() {
139     printf("[mszczeci][%s:%d][%s]\n",__FILE__, __LINE__, __func__);
140     SkPaint paint;
141     paint.setColor(SK_ColorGRAY);
142     canvas->drawPaint(paint);
143
144     loadRivFile("file.riv");
145 }
146
147 void drawSwView(void* data, Eo* obj) {
148     if (currentScene) {
149         const float elapsed = getElapsedTime();
150         bool ret = currentScene->advanceAndApply(elapsed);
151
152         clock_t t = clock();
153
154         rive::SkiaRenderer renderer(canvas);
155         renderer.save();
156
157         const unsigned int width = WIDTH, height = HEIGHT;
158
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);
164
165         currentScene->draw(&renderer);
166         renderer.restore();
167
168         t = clock() - t;
169         double time_taken = ((double)t)/CLOCKS_PER_SEC;
170         printf("Frame rendering time %f sec\n", time_taken);
171     }
172 }
173
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);
178 }
179
180 void win_del(void *data, Evas_Object *o, void *ev) {
181    elm_exit();
182 }
183
184 int main(int argc, char **argv) {
185     elm_init(argc, argv);
186
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);
189
190     createCanvas(WIDTH, HEIGHT);
191
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);
200
201     elm_win_resize_object_add(win, view);
202     evas_object_geometry_set(win, 0, 0, WIDTH, HEIGHT);
203     evas_object_show(win);
204
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);
211
212     initSwView();
213
214     elm_run();
215     elm_shutdown();
216
217     return 0;
218 }