common taskscheduler: revise functionalities.
[platform/core/graphics/tizenvg.git] / test / testGradientTransform.cpp
1 #include "testCommon.h"
2
3 /************************************************************************/
4 /* Drawing Commands                                                     */
5 /************************************************************************/
6 tvg::Shape* pShape = nullptr;
7 tvg::Shape* pShape2 = nullptr;
8 tvg::Shape* pShape3 = nullptr;
9
10 void tvgDrawCmds(tvg::Canvas* canvas)
11 {
12     if (!canvas) return;
13
14     //Shape1
15     auto shape = tvg::Shape::gen();
16
17     /* Acquire shape pointer to access it again.
18        instead, you should consider not to interrupt this pointer life-cycle. */
19     pShape = shape.get();
20
21     shape->appendRect(-285, -300, 200, 200, 0, 0);
22     shape->appendRect(-185, -200, 300, 300, 100, 100);
23     shape->appendCircle(115, 100, 100, 100);
24     shape->appendCircle(115, 200, 170, 100);
25
26     //LinearGradient
27     auto fill = tvg::LinearGradient::gen();
28     fill->linear(-285, -300, 285, 300);
29
30     //Gradient Color Stops
31     tvg::Fill::ColorStop colorStops[3];
32     colorStops[0] = {0, 255, 0, 0, 255};
33     colorStops[1] = {0.5, 255, 255, 0, 255};
34     colorStops[2] = {1, 255, 255, 255, 255};
35
36     fill->colorStops(colorStops, 3);
37     shape->fill(move(fill));
38     shape->translate(385, 400);
39     if (canvas->push(move(shape)) != tvg::Result::Success) return;
40
41     //Shape2
42     auto shape2 = tvg::Shape::gen();
43     pShape2 = shape2.get();
44     shape2->appendRect(-50, -50, 100, 100, 0, 0);
45     shape2->translate(400, 400);
46
47     //LinearGradient
48     auto fill2 = tvg::LinearGradient::gen();
49     fill2->linear(-50, -50, 50, 50);
50
51     //Gradient Color Stops
52     tvg::Fill::ColorStop colorStops2[2];
53     colorStops2[0] = {0, 0, 0, 0, 255};
54     colorStops2[1] = {1, 255, 255, 255, 255};
55
56     fill2->colorStops(colorStops2, 2);
57     shape2->fill(move(fill2));
58     if (canvas->push(move(shape2)) != tvg::Result::Success) return;
59
60     //Shape3
61     auto shape3 = tvg::Shape::gen();
62     pShape3 = shape3.get();
63
64     /* Look, how shape3's origin is different with shape2
65        The center of the shape is the anchor point for transformation. */
66     shape3->appendRect(100, 100, 150, 100, 20, 20);
67
68     //RadialGradient
69     auto fill3 = tvg::RadialGradient::gen();
70     fill3->radial(175, 150, 75);
71
72     //Gradient Color Stops
73     tvg::Fill::ColorStop colorStops3[4];
74     colorStops3[0] = {0, 0, 127, 0, 127};
75     colorStops3[1] = {0.25, 0, 170, 170, 170};
76     colorStops3[2] = {0.5, 200, 0, 200, 200};
77     colorStops3[3] = {1, 255, 255, 255, 255};
78
79     fill3->colorStops(colorStops3, 4);
80
81     shape3->fill(move(fill3));
82     shape3->translate(400, 400);
83     if (canvas->push(move(shape3)) != tvg::Result::Success) return;
84 }
85
86 void tvgUpdateCmds(tvg::Canvas* canvas, float progress)
87 {
88     if (!canvas) return;
89
90     /* Update shape directly.
91        You can update only necessary properties of this shape,
92        while retaining other properties. */
93
94     //Update Shape1
95     pShape->scale(1 - 0.75 * progress);
96     pShape->rotate(360 * progress);
97
98     //Update shape for drawing (this may work asynchronously)
99     if (canvas->update(pShape) != tvg::Result::Success) return;
100
101     //Update Shape2
102     pShape2->rotate(360 * progress);
103     pShape2->translate(400 + progress * 300, 400);
104     if (canvas->update(pShape2) != tvg::Result::Success) return;
105
106     //Update Shape3
107     pShape3->rotate(-360 * progress);
108     pShape3->scale(0.5 + progress);
109     if (canvas->update(pShape3) != tvg::Result::Success) return;
110 }
111
112
113 /************************************************************************/
114 /* Sw Engine Test Code                                                  */
115 /************************************************************************/
116
117 static unique_ptr<tvg::SwCanvas> swCanvas;
118
119 void tvgSwTest(uint32_t* buffer)
120 {
121     //Create a Canvas
122     swCanvas = tvg::SwCanvas::gen();
123     swCanvas->target(buffer, WIDTH, WIDTH, HEIGHT, tvg::SwCanvas::ARGB8888);
124
125     /* Push the shape into the Canvas drawing list
126        When this shape is into the canvas list, the shape could update & prepare
127        internal data asynchronously for coming rendering.
128        Canvas keeps this shape node unless user call canvas->clear() */
129     tvgDrawCmds(swCanvas.get());
130 }
131
132 void transitSwCb(Elm_Transit_Effect *effect, Elm_Transit* transit, double progress)
133 {
134     tvgUpdateCmds(swCanvas.get(), progress);
135
136     //Update Efl Canvas
137     Eo* img = (Eo*) effect;
138     evas_object_image_data_update_add(img, 0, 0, WIDTH, HEIGHT);
139     evas_object_image_pixels_dirty_set(img, EINA_TRUE);
140 }
141
142 void drawSwView(void* data, Eo* obj)
143 {
144     if (swCanvas->draw() == tvg::Result::Success) {
145         swCanvas->sync();
146     }
147 }
148
149
150 /************************************************************************/
151 /* GL Engine Test Code                                                  */
152 /************************************************************************/
153
154 static unique_ptr<tvg::GlCanvas> glCanvas;
155
156 void initGLview(Evas_Object *obj)
157 {
158     static constexpr auto BPP = 4;
159
160     //Create a Canvas
161     glCanvas = tvg::GlCanvas::gen();
162     glCanvas->target(nullptr, WIDTH * BPP, WIDTH, HEIGHT);
163
164     /* Push the shape into the Canvas drawing list
165        When this shape is into the canvas list, the shape could update & prepare
166        internal data asynchronously for coming rendering.
167        Canvas keeps this shape node unless user call canvas->clear() */
168     tvgDrawCmds(glCanvas.get());
169 }
170
171 void drawGLview(Evas_Object *obj)
172 {
173     auto gl = elm_glview_gl_api_get(obj);
174     gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
175     gl->glClear(GL_COLOR_BUFFER_BIT);
176
177     if (glCanvas->draw() == tvg::Result::Success) {
178         glCanvas->sync();
179     }
180 }
181
182 void transitGlCb(Elm_Transit_Effect *effect, Elm_Transit* transit, double progress)
183 {
184     tvgUpdateCmds(glCanvas.get(), progress);
185 }
186
187
188 /************************************************************************/
189 /* Main Code                                                            */
190 /************************************************************************/
191
192 int main(int argc, char **argv)
193 {
194     tvg::CanvasEngine tvgEngine = tvg::CanvasEngine::Sw;
195
196     if (argc > 1) {
197         if (!strcmp(argv[1], "gl")) tvgEngine = tvg::CanvasEngine::Gl;
198     }
199
200     //Initialize ThorVG Engine
201     if (tvgEngine == tvg::CanvasEngine::Sw) {
202         cout << "tvg engine: software" << endl;
203     } else {
204         cout << "tvg engine: opengl" << endl;
205     }
206
207     //Threads Count
208     auto threads = std::thread::hardware_concurrency();
209
210     //Initialize ThorVG Engine
211     if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) {
212
213         elm_init(argc, argv);
214
215         Elm_Transit *transit = elm_transit_add();
216
217         if (tvgEngine == tvg::CanvasEngine::Sw) {
218             auto view = createSwView();
219             elm_transit_effect_add(transit, transitSwCb, view, nullptr);
220         } else {
221             auto view = createGlView();
222             elm_transit_effect_add(transit, transitGlCb, view, nullptr);
223         }
224
225         elm_transit_duration_set(transit, 2);
226         elm_transit_repeat_times_set(transit, -1);
227         elm_transit_auto_reverse_set(transit, EINA_TRUE);
228         elm_transit_go(transit);
229
230         elm_run();
231         elm_shutdown();
232
233         //Terminate ThorVG Engine
234         tvg::Initializer::term(tvgEngine);
235
236     } else {
237         cout << "engine is not supported" << endl;
238     }
239     return 0;
240 }