submodule: add rive-cpp to rive-tizen as submodule
[platform/core/uifw/rive-tizen.git] / submodule / skia / viewer / src / main.cpp
1 #define SK_GL
2 #include "GLFW/glfw3.h"
3
4 #include "GrBackendSurface.h"
5 #include "GrContext.h"
6 #include "SkCanvas.h"
7 #include "SkColorSpace.h"
8 #include "SkSurface.h"
9 #include "SkTypes.h"
10 #include "gl/GrGLInterface.h"
11
12 #include "animation/linear_animation_instance.hpp"
13 #include "artboard.hpp"
14 #include "file.hpp"
15 #include "layout.hpp"
16 #include "math/aabb.hpp"
17 #include "skia_renderer.hpp"
18
19 #include <cmath>
20 #include <stdio.h>
21
22 rive::File* currentFile = nullptr;
23 rive::Artboard* artboard = nullptr;
24 rive::LinearAnimationInstance* animationInstance = nullptr;
25
26 void glfwErrorCallback(int error, const char* description)
27 {
28         puts(description);
29 }
30
31 void glfwDropCallback(GLFWwindow* window, int count, const char** paths)
32 {
33         // Just get the last dropped file for now...
34         auto filename = paths[count - 1];
35         FILE* fp = fopen(filename, "r");
36         fseek(fp, 0, SEEK_END);
37         auto length = ftell(fp);
38         fseek(fp, 0, SEEK_SET);
39         uint8_t* bytes = new uint8_t[length];
40         if (fread(bytes, 1, length, fp) != length)
41         {
42                 delete[] bytes;
43                 fprintf(stderr, "failed to read all of %s\n", filename);
44                 return;
45         }
46         auto reader = rive::BinaryReader(bytes, length);
47         rive::File* file = nullptr;
48         auto result = rive::File::import(reader, &file);
49         if (result != rive::ImportResult::success)
50         {
51                 delete[] bytes;
52                 fprintf(stderr, "failed to import %s\n", filename);
53                 return;
54         }
55         artboard = file->artboard();
56         artboard->advance(0.0f);
57
58         delete animationInstance;
59         delete currentFile;
60
61         auto animation = artboard->firstAnimation<rive::LinearAnimation>();
62         if (animation != nullptr)
63         {
64                 animationInstance = new rive::LinearAnimationInstance(animation);
65         }
66         else
67         {
68                 animationInstance = nullptr;
69         }
70
71         currentFile = file;
72         delete[] bytes;
73 }
74
75 int main()
76 {
77         if (!glfwInit())
78         {
79                 fprintf(stderr, "Failed to initialize glfw.\n");
80                 return 1;
81         }
82         glfwSetErrorCallback(glfwErrorCallback);
83
84         glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
85         glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
86         GLFWwindow* window = glfwCreateWindow(1280, 720, "Rive Viewer", NULL, NULL);
87         if (window == nullptr)
88         {
89                 fprintf(stderr, "Failed to make window or GL.\n");
90                 glfwTerminate();
91                 return 1;
92         }
93
94         glfwSetDropCallback(window, glfwDropCallback);
95         glfwMakeContextCurrent(window);
96         // Enable VSYNC.
97         glfwSwapInterval(1);
98
99         // Setup Skia
100         GrContextOptions options;
101         sk_sp<GrContext> context = GrContext::MakeGL(nullptr, options);
102         GrGLFramebufferInfo framebufferInfo;
103         framebufferInfo.fFBOID = 0;
104         framebufferInfo.fFormat = GL_RGBA8;
105
106         SkSurface* surface = nullptr;
107         SkCanvas* canvas = nullptr;
108
109         // Render loop.
110         int width = 0, height = 0;
111         int lastScreenWidth = 0, lastScreenHeight = 0;
112         double lastTime = glfwGetTime();
113         while (!glfwWindowShouldClose(window))
114         {
115                 glfwGetFramebufferSize(window, &width, &height);
116
117                 // Update surface.
118                 if (surface == nullptr || width != lastScreenWidth ||
119                     height != lastScreenHeight)
120                 {
121                         lastScreenWidth = width;
122                         lastScreenHeight = height;
123
124                         SkColorType colorType =
125                             kRGBA_8888_SkColorType; // GrColorTypeToSkColorType(GrPixelConfigToColorType(kRGBA_8888_GrPixelConfig));
126                         //
127                         // if (kRGBA_8888_GrPixelConfig == kSkia8888_GrPixelConfig)
128                         // {
129                         //      colorType = kRGBA_8888_SkColorType;
130                         // }
131                         // else
132                         // {
133                         //      colorType = kBGRA_8888_SkColorType;
134                         // }
135
136                         GrBackendRenderTarget backendRenderTarget(width,
137                                                                   height,
138                                                                   0, // sample count
139                                                                   0, // stencil bits
140                                                                   framebufferInfo);
141
142                         delete surface;
143                         surface = SkSurface::MakeFromBackendRenderTarget(
144                                       context.get(),
145                                       backendRenderTarget,
146                                       kBottomLeft_GrSurfaceOrigin,
147                                       colorType,
148                                       nullptr,
149                                       nullptr)
150                                       .release();
151                         if (surface == nullptr)
152                         {
153                                 fprintf(stderr, "Failed to create Skia surface\n");
154                                 return 1;
155                         }
156                         canvas = surface->getCanvas();
157                 }
158
159                 double time = glfwGetTime();
160                 float elapsed = (float)(time - lastTime);
161                 lastTime = time;
162
163                 // Clear screen.
164                 SkPaint paint;
165                 paint.setColor(SK_ColorDKGRAY);
166                 canvas->drawPaint(paint);
167
168                 if (artboard != nullptr)
169                 {
170                         if (animationInstance != nullptr)
171                         {
172                                 animationInstance->advance(elapsed);
173                                 animationInstance->apply(artboard);
174                         }
175                         artboard->advance(elapsed);
176
177                         rive::SkiaRenderer renderer(canvas);
178                         renderer.save();
179                         renderer.align(rive::Fit::contain,
180                                        rive::Alignment::center,
181                                        rive::AABB(0, 0, width, height),
182                                        artboard->bounds());
183                         artboard->draw(&renderer);
184                         renderer.restore();
185                 }
186
187                 context->flush();
188
189                 glfwSwapBuffers(window);
190                 glfwPollEvents();
191         }
192
193         delete currentFile;
194
195         // Cleanup Skia.
196         delete surface;
197         context = nullptr;
198
199         // Cleanup GLFW.
200         glfwDestroyWindow(window);
201         glfwTerminate();
202
203         return 0;
204 }