source: mainline/uspace/srv/hid/display/test/clonegc.c@ 5271e4c

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 5271e4c was 5271e4c, checked in by Jiri Svoboda <jiri@…>, 5 years ago

Duplicate rendering to additional output devices using a cloning GC

This gives the display server a pretty good illusion of rendering to just
one output device, while supporting multiple. This makes RFB work properly.

  • Property mode set to 100644
File size: 18.8 KB
Line 
1/*
2 * Copyright (c) 2020 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <errno.h>
30#include <gfx/color.h>
31#include <gfx/render.h>
32#include <pcut/pcut.h>
33#include <stdio.h>
34
35#include "../clonegc.h"
36
37PCUT_INIT;
38
39PCUT_TEST_SUITE(clonegc);
40
41static errno_t testgc_set_color(void *, gfx_color_t *);
42static errno_t testgc_fill_rect(void *, gfx_rect_t *);
43static errno_t testgc_bitmap_create(void *, gfx_bitmap_params_t *,
44 gfx_bitmap_alloc_t *, void **);
45static errno_t testgc_bitmap_destroy(void *);
46static errno_t testgc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
47static errno_t testgc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
48
49static gfx_context_ops_t ops = {
50 .set_color = testgc_set_color,
51 .fill_rect = testgc_fill_rect,
52 .bitmap_create = testgc_bitmap_create,
53 .bitmap_destroy = testgc_bitmap_destroy,
54 .bitmap_render = testgc_bitmap_render,
55 .bitmap_get_alloc = testgc_bitmap_get_alloc
56};
57
58typedef struct {
59 /** Error code to return */
60 errno_t rc;
61
62 bool set_color_called;
63 gfx_color_t *set_color_color;
64
65 bool fill_rect_called;
66 gfx_rect_t *fill_rect_rect;
67
68 bool bm_created;
69 bool bm_destroyed;
70 gfx_bitmap_params_t bm_params;
71 void *bm_pixels;
72 gfx_rect_t bm_srect;
73 gfx_coord2_t bm_offs;
74 bool bm_rendered;
75 bool bm_got_alloc;
76} test_gc_t;
77
78typedef struct {
79 test_gc_t *tgc;
80 gfx_bitmap_alloc_t alloc;
81 bool myalloc;
82} testgc_bitmap_t;
83
84enum {
85 alloc_pitch = 42,
86 alloc_off0 = 33
87};
88
89/** Test creating and deleting clone GC */
90PCUT_TEST(create_delete)
91{
92 ds_clonegc_t *cgc;
93 errno_t rc;
94
95 rc = ds_clonegc_create(NULL, &cgc);
96 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
97
98 rc = ds_clonegc_delete(cgc);
99 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
100}
101
102/** Test set color operation with two output GCs */
103PCUT_TEST(set_color)
104{
105 ds_clonegc_t *cgc;
106 gfx_context_t *gc;
107 test_gc_t tgc1;
108 gfx_context_t *gc1;
109 test_gc_t tgc2;
110 gfx_context_t *gc2;
111 gfx_color_t *color;
112 errno_t rc;
113
114 /* Create clone GC */
115 rc = ds_clonegc_create(NULL, &cgc);
116 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
117
118 gc = ds_clonegc_get_ctx(cgc);
119 PCUT_ASSERT_NOT_NULL(gc);
120
121 /* Add two output GCs */
122
123 rc = gfx_context_new(&ops, &tgc1, &gc1);
124 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
125
126 rc = ds_clonegc_add_output(cgc, gc1);
127 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
128
129 rc = gfx_context_new(&ops, &tgc2, &gc2);
130 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
131
132 rc = ds_clonegc_add_output(cgc, gc2);
133 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
134
135 rc = gfx_color_new_rgb_i16(0xaaaa, 0xbbbb, 0xcccc, &color);
136 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
137
138 /* Set color returning error */
139
140 tgc1.set_color_called = false;
141 tgc2.set_color_called = false;
142 tgc1.rc = EINVAL;
143 tgc2.rc = EINVAL;
144
145 rc = gfx_set_color(gc, color);
146 PCUT_ASSERT_ERRNO_VAL(EINVAL, rc);
147
148 PCUT_ASSERT_TRUE(tgc1.set_color_called);
149 PCUT_ASSERT_EQUALS(color, tgc1.set_color_color);
150 PCUT_ASSERT_FALSE(tgc2.set_color_called);
151
152 /* Set color returning success for all outputs */
153 tgc1.set_color_called = false;
154 tgc2.set_color_called = false;
155 tgc1.rc = EOK;
156 tgc2.rc = EOK;
157
158 rc = gfx_set_color(gc, color);
159 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
160
161 PCUT_ASSERT_TRUE(tgc1.set_color_called);
162 PCUT_ASSERT_EQUALS(color, tgc1.set_color_color);
163 PCUT_ASSERT_TRUE(tgc2.set_color_called);
164 PCUT_ASSERT_EQUALS(color, tgc2.set_color_color);
165
166 rc = ds_clonegc_delete(cgc);
167 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
168
169 gfx_color_delete(color);
170}
171
172/** Fill rectangle operation with two output GCs */
173PCUT_TEST(fill_rect)
174{
175 ds_clonegc_t *cgc;
176 gfx_context_t *gc;
177 test_gc_t tgc1;
178 gfx_context_t *gc1;
179 test_gc_t tgc2;
180 gfx_context_t *gc2;
181 gfx_rect_t rect;
182 errno_t rc;
183
184 /* Create clone GC */
185 rc = ds_clonegc_create(NULL, &cgc);
186 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
187
188 gc = ds_clonegc_get_ctx(cgc);
189 PCUT_ASSERT_NOT_NULL(gc);
190
191 /* Add two output GCs */
192
193 rc = gfx_context_new(&ops, &tgc1, &gc1);
194 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
195
196 rc = ds_clonegc_add_output(cgc, gc1);
197 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
198
199 rc = gfx_context_new(&ops, &tgc2, &gc2);
200 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
201
202 rc = ds_clonegc_add_output(cgc, gc2);
203 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
204
205 rect.p0.x = 1;
206 rect.p0.y = 2;
207 rect.p1.x = 3;
208 rect.p1.y = 4;
209
210 /* Fill rectangle returning error */
211
212 tgc1.fill_rect_called = false;
213 tgc2.fill_rect_called = false;
214 tgc1.rc = EINVAL;
215 tgc2.rc = EINVAL;
216
217 rc = gfx_fill_rect(gc, &rect);
218 PCUT_ASSERT_ERRNO_VAL(EINVAL, rc);
219
220 PCUT_ASSERT_TRUE(tgc1.fill_rect_called);
221 PCUT_ASSERT_EQUALS(&rect, tgc1.fill_rect_rect);
222 PCUT_ASSERT_FALSE(tgc2.fill_rect_called);
223
224 /* Fill rectangle returning success for all outputs */
225 tgc1.fill_rect_called = false;
226 tgc2.fill_rect_called = false;
227 tgc1.rc = EOK;
228 tgc2.rc = EOK;
229
230 rc = gfx_fill_rect(gc, &rect);
231 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
232
233 PCUT_ASSERT_TRUE(tgc1.fill_rect_called);
234 PCUT_ASSERT_EQUALS(&rect, tgc1.fill_rect_rect);
235 PCUT_ASSERT_TRUE(tgc2.fill_rect_called);
236 PCUT_ASSERT_EQUALS(&rect, tgc2.fill_rect_rect);
237
238 rc = ds_clonegc_delete(cgc);
239 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
240}
241
242/** Operations on regular bitmap with two output GCs, callee allocation */
243PCUT_TEST(bitmap_twogc_callee_alloc)
244{
245 ds_clonegc_t *cgc;
246 gfx_context_t *gc;
247 test_gc_t tgc1;
248 gfx_context_t *gc1;
249 test_gc_t tgc2;
250 gfx_context_t *gc2;
251 gfx_bitmap_params_t params;
252 gfx_bitmap_t *bitmap;
253 gfx_bitmap_alloc_t alloc;
254 gfx_rect_t rect;
255 gfx_coord2_t off;
256 errno_t rc;
257
258 /* Create clone GC */
259 rc = ds_clonegc_create(NULL, &cgc);
260 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
261
262 gc = ds_clonegc_get_ctx(cgc);
263 PCUT_ASSERT_NOT_NULL(gc);
264
265 /* Add two output GCs */
266
267 rc = gfx_context_new(&ops, &tgc1, &gc1);
268 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
269
270 rc = ds_clonegc_add_output(cgc, gc1);
271 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
272
273 rc = gfx_context_new(&ops, &tgc2, &gc2);
274 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
275
276 rc = ds_clonegc_add_output(cgc, gc2);
277 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
278
279 /* Create bitmap with NULL allocation */
280 tgc1.bm_created = false;
281 tgc2.bm_created = false;
282 gfx_bitmap_params_init(&params);
283 params.rect.p0.x = 1;
284 params.rect.p0.y = 2;
285 params.rect.p1.x = 3;
286 params.rect.p1.y = 4;
287
288 rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
289 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
290
291 PCUT_ASSERT_TRUE(tgc1.bm_created);
292 PCUT_ASSERT_INT_EQUALS(params.rect.p0.x, tgc1.bm_params.rect.p0.x);
293 PCUT_ASSERT_INT_EQUALS(params.rect.p0.y, tgc1.bm_params.rect.p0.y);
294 PCUT_ASSERT_INT_EQUALS(params.rect.p1.x, tgc1.bm_params.rect.p1.x);
295 PCUT_ASSERT_INT_EQUALS(params.rect.p1.y, tgc1.bm_params.rect.p1.y);
296
297 PCUT_ASSERT_TRUE(tgc2.bm_created);
298 PCUT_ASSERT_INT_EQUALS(params.rect.p0.x, tgc2.bm_params.rect.p0.x);
299 PCUT_ASSERT_INT_EQUALS(params.rect.p0.y, tgc2.bm_params.rect.p0.y);
300 PCUT_ASSERT_INT_EQUALS(params.rect.p1.x, tgc2.bm_params.rect.p1.x);
301 PCUT_ASSERT_INT_EQUALS(params.rect.p1.y, tgc2.bm_params.rect.p1.y);
302
303 /* Get allocation */
304
305 rc = gfx_bitmap_get_alloc(bitmap, &alloc);
306 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
307 PCUT_ASSERT_INT_EQUALS(alloc_pitch, alloc.pitch);
308 PCUT_ASSERT_EQUALS(tgc1.bm_pixels, alloc.pixels);
309 PCUT_ASSERT_EQUALS(tgc2.bm_pixels, alloc.pixels);
310
311 /* Render bitmap */
312 tgc1.bm_rendered = false;
313 tgc1.bm_rendered = false;
314 rect.p0.x = 10;
315 rect.p0.y = 20;
316 rect.p1.x = 30;
317 rect.p1.y = 40;
318 off.x = 50;
319 off.y = 60;
320 rc = gfx_bitmap_render(bitmap, &rect, &off);
321 PCUT_ASSERT_TRUE(tgc1.bm_rendered);
322 PCUT_ASSERT_INT_EQUALS(rect.p0.x, tgc1.bm_srect.p0.x);
323 PCUT_ASSERT_INT_EQUALS(rect.p0.y, tgc1.bm_srect.p0.y);
324 PCUT_ASSERT_INT_EQUALS(rect.p1.x, tgc1.bm_srect.p1.x);
325 PCUT_ASSERT_INT_EQUALS(rect.p1.y, tgc1.bm_srect.p1.y);
326 PCUT_ASSERT_TRUE(tgc2.bm_rendered);
327 PCUT_ASSERT_INT_EQUALS(rect.p0.x, tgc2.bm_srect.p0.x);
328 PCUT_ASSERT_INT_EQUALS(rect.p0.y, tgc2.bm_srect.p0.y);
329 PCUT_ASSERT_INT_EQUALS(rect.p1.x, tgc2.bm_srect.p1.x);
330 PCUT_ASSERT_INT_EQUALS(rect.p1.y, tgc2.bm_srect.p1.y);
331
332 rc = ds_clonegc_delete(cgc);
333 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
334}
335
336/** Operations on regular bitmap with two output GCs, caller allocation */
337PCUT_TEST(bitmap_twogc_caller_alloc)
338{
339 ds_clonegc_t *cgc;
340 gfx_context_t *gc;
341 test_gc_t tgc1;
342 gfx_context_t *gc1;
343 test_gc_t tgc2;
344 gfx_context_t *gc2;
345 gfx_bitmap_params_t params;
346 gfx_bitmap_t *bitmap;
347 gfx_bitmap_alloc_t alloc;
348 gfx_bitmap_alloc_t galloc;
349 void *pixels;
350 gfx_rect_t rect;
351 gfx_coord2_t off;
352 errno_t rc;
353
354 /* Create clone GC */
355 rc = ds_clonegc_create(NULL, &cgc);
356 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
357
358 gc = ds_clonegc_get_ctx(cgc);
359 PCUT_ASSERT_NOT_NULL(gc);
360
361 /* Add two output GCs */
362 rc = gfx_context_new(&ops, &tgc1, &gc1);
363 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
364
365 rc = ds_clonegc_add_output(cgc, gc1);
366 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
367
368 rc = gfx_context_new(&ops, &tgc2, &gc2);
369 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
370
371 rc = ds_clonegc_add_output(cgc, gc2);
372 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
373
374 /* Create bitmap with caller allocation */
375 tgc1.bm_created = false;
376 tgc2.bm_created = false;
377 gfx_bitmap_params_init(&params);
378 params.rect.p0.x = 1;
379 params.rect.p0.y = 2;
380 params.rect.p1.x = 3;
381 params.rect.p1.y = 4;
382
383 pixels = calloc(2 * 2, sizeof(uint32_t));
384 PCUT_ASSERT_NOT_NULL(pixels);
385
386 alloc.pitch = 8;
387 alloc.off0 = 0;
388 alloc.pixels = pixels;
389
390 rc = gfx_bitmap_create(gc, &params, &alloc, &bitmap);
391 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
392
393 PCUT_ASSERT_TRUE(tgc1.bm_created);
394 PCUT_ASSERT_INT_EQUALS(params.rect.p0.x, tgc1.bm_params.rect.p0.x);
395 PCUT_ASSERT_INT_EQUALS(params.rect.p0.y, tgc1.bm_params.rect.p0.y);
396 PCUT_ASSERT_INT_EQUALS(params.rect.p1.x, tgc1.bm_params.rect.p1.x);
397 PCUT_ASSERT_INT_EQUALS(params.rect.p1.y, tgc1.bm_params.rect.p1.y);
398
399 PCUT_ASSERT_TRUE(tgc2.bm_created);
400 PCUT_ASSERT_INT_EQUALS(params.rect.p0.x, tgc2.bm_params.rect.p0.x);
401 PCUT_ASSERT_INT_EQUALS(params.rect.p0.y, tgc2.bm_params.rect.p0.y);
402 PCUT_ASSERT_INT_EQUALS(params.rect.p1.x, tgc2.bm_params.rect.p1.x);
403 PCUT_ASSERT_INT_EQUALS(params.rect.p1.y, tgc2.bm_params.rect.p1.y);
404
405 /* Get allocation */
406 rc = gfx_bitmap_get_alloc(bitmap, &galloc);
407 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
408 PCUT_ASSERT_INT_EQUALS(alloc.pitch, galloc.pitch);
409 PCUT_ASSERT_INT_EQUALS(alloc.off0, galloc.off0);
410 PCUT_ASSERT_EQUALS(alloc.pixels, galloc.pixels);
411 PCUT_ASSERT_EQUALS(tgc1.bm_pixels, galloc.pixels);
412 PCUT_ASSERT_EQUALS(tgc2.bm_pixels, galloc.pixels);
413
414 /* Render bitmap */
415 tgc1.bm_rendered = false;
416 tgc1.bm_rendered = false;
417 rect.p0.x = 10;
418 rect.p0.y = 20;
419 rect.p1.x = 30;
420 rect.p1.y = 40;
421 off.x = 50;
422 off.y = 60;
423 rc = gfx_bitmap_render(bitmap, &rect, &off);
424 PCUT_ASSERT_TRUE(tgc1.bm_rendered);
425 PCUT_ASSERT_INT_EQUALS(rect.p0.x, tgc1.bm_srect.p0.x);
426 PCUT_ASSERT_INT_EQUALS(rect.p0.y, tgc1.bm_srect.p0.y);
427 PCUT_ASSERT_INT_EQUALS(rect.p1.x, tgc1.bm_srect.p1.x);
428 PCUT_ASSERT_INT_EQUALS(rect.p1.y, tgc1.bm_srect.p1.y);
429 PCUT_ASSERT_TRUE(tgc2.bm_rendered);
430 PCUT_ASSERT_INT_EQUALS(rect.p0.x, tgc2.bm_srect.p0.x);
431 PCUT_ASSERT_INT_EQUALS(rect.p0.y, tgc2.bm_srect.p0.y);
432 PCUT_ASSERT_INT_EQUALS(rect.p1.x, tgc2.bm_srect.p1.x);
433 PCUT_ASSERT_INT_EQUALS(rect.p1.y, tgc2.bm_srect.p1.y);
434
435 free(pixels);
436
437 rc = ds_clonegc_delete(cgc);
438 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
439}
440
441/** Create bitmap, then add second GC, callee allocation */
442PCUT_TEST(bitmap_addgc_callee_alloc)
443{
444 ds_clonegc_t *cgc;
445 gfx_context_t *gc;
446 test_gc_t tgc1;
447 gfx_context_t *gc1;
448 test_gc_t tgc2;
449 gfx_context_t *gc2;
450 gfx_bitmap_params_t params;
451 gfx_bitmap_t *bitmap;
452 gfx_bitmap_alloc_t alloc;
453 gfx_rect_t rect;
454 gfx_coord2_t off;
455 errno_t rc;
456
457 /* Create clone GC */
458 rc = ds_clonegc_create(NULL, &cgc);
459 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
460
461 gc = ds_clonegc_get_ctx(cgc);
462 PCUT_ASSERT_NOT_NULL(gc);
463
464 /* Add one output GC */
465 rc = gfx_context_new(&ops, &tgc1, &gc1);
466 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
467
468 rc = ds_clonegc_add_output(cgc, gc1);
469 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
470
471 /* Create bitmap with NULL allocation */
472 tgc1.bm_created = false;
473 tgc2.bm_created = false;
474 gfx_bitmap_params_init(&params);
475 params.rect.p0.x = 1;
476 params.rect.p0.y = 2;
477 params.rect.p1.x = 3;
478 params.rect.p1.y = 4;
479
480 rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
481 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
482
483 PCUT_ASSERT_TRUE(tgc1.bm_created);
484 PCUT_ASSERT_INT_EQUALS(params.rect.p0.x, tgc1.bm_params.rect.p0.x);
485 PCUT_ASSERT_INT_EQUALS(params.rect.p0.y, tgc1.bm_params.rect.p0.y);
486 PCUT_ASSERT_INT_EQUALS(params.rect.p1.x, tgc1.bm_params.rect.p1.x);
487 PCUT_ASSERT_INT_EQUALS(params.rect.p1.y, tgc1.bm_params.rect.p1.y);
488
489 PCUT_ASSERT_FALSE(tgc2.bm_created);
490
491 /* Get allocation */
492 rc = gfx_bitmap_get_alloc(bitmap, &alloc);
493 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
494 PCUT_ASSERT_INT_EQUALS(alloc_pitch, alloc.pitch);
495 PCUT_ASSERT_EQUALS(tgc1.bm_pixels, alloc.pixels);
496
497 /* Add second output GC */
498 rc = gfx_context_new(&ops, &tgc2, &gc2);
499 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
500
501 rc = ds_clonegc_add_output(cgc, gc2);
502 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
503
504 /* Render bitmap */
505 tgc1.bm_rendered = false;
506 tgc1.bm_rendered = false;
507 rect.p0.x = 10;
508 rect.p0.y = 20;
509 rect.p1.x = 30;
510 rect.p1.y = 40;
511 off.x = 50;
512 off.y = 60;
513 rc = gfx_bitmap_render(bitmap, &rect, &off);
514 PCUT_ASSERT_TRUE(tgc1.bm_rendered);
515 PCUT_ASSERT_INT_EQUALS(rect.p0.x, tgc1.bm_srect.p0.x);
516 PCUT_ASSERT_INT_EQUALS(rect.p0.y, tgc1.bm_srect.p0.y);
517 PCUT_ASSERT_INT_EQUALS(rect.p1.x, tgc1.bm_srect.p1.x);
518 PCUT_ASSERT_INT_EQUALS(rect.p1.y, tgc1.bm_srect.p1.y);
519 PCUT_ASSERT_TRUE(tgc2.bm_rendered);
520 PCUT_ASSERT_INT_EQUALS(rect.p0.x, tgc2.bm_srect.p0.x);
521 PCUT_ASSERT_INT_EQUALS(rect.p0.y, tgc2.bm_srect.p0.y);
522 PCUT_ASSERT_INT_EQUALS(rect.p1.x, tgc2.bm_srect.p1.x);
523 PCUT_ASSERT_INT_EQUALS(rect.p1.y, tgc2.bm_srect.p1.y);
524
525 rc = ds_clonegc_delete(cgc);
526 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
527}
528
529/** Create bitmap, then add second GC, caller allocation */
530PCUT_TEST(bitmap_addgc_caller_alloc)
531{
532 ds_clonegc_t *cgc;
533 gfx_context_t *gc;
534 test_gc_t tgc1;
535 gfx_context_t *gc1;
536 test_gc_t tgc2;
537 gfx_context_t *gc2;
538 gfx_bitmap_params_t params;
539 gfx_bitmap_t *bitmap;
540 gfx_bitmap_alloc_t alloc;
541 gfx_bitmap_alloc_t galloc;
542 void *pixels;
543 gfx_rect_t rect;
544 gfx_coord2_t off;
545 errno_t rc;
546
547 /* Create clone GC */
548 rc = ds_clonegc_create(NULL, &cgc);
549 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
550
551 gc = ds_clonegc_get_ctx(cgc);
552 PCUT_ASSERT_NOT_NULL(gc);
553
554 /* Add one output GC */
555 rc = gfx_context_new(&ops, &tgc1, &gc1);
556 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
557
558 rc = ds_clonegc_add_output(cgc, gc1);
559 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
560
561 /* Create bitmap with caller allocation */
562 tgc1.bm_created = false;
563 tgc2.bm_created = false;
564 gfx_bitmap_params_init(&params);
565 params.rect.p0.x = 1;
566 params.rect.p0.y = 2;
567 params.rect.p1.x = 3;
568 params.rect.p1.y = 4;
569
570 pixels = calloc(2 * 2, sizeof(uint32_t));
571 PCUT_ASSERT_NOT_NULL(pixels);
572
573 alloc.pitch = 8;
574 alloc.off0 = 0;
575 alloc.pixels = pixels;
576
577 rc = gfx_bitmap_create(gc, &params, &alloc, &bitmap);
578 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
579
580 PCUT_ASSERT_TRUE(tgc1.bm_created);
581 PCUT_ASSERT_INT_EQUALS(params.rect.p0.x, tgc1.bm_params.rect.p0.x);
582 PCUT_ASSERT_INT_EQUALS(params.rect.p0.y, tgc1.bm_params.rect.p0.y);
583 PCUT_ASSERT_INT_EQUALS(params.rect.p1.x, tgc1.bm_params.rect.p1.x);
584 PCUT_ASSERT_INT_EQUALS(params.rect.p1.y, tgc1.bm_params.rect.p1.y);
585
586 PCUT_ASSERT_FALSE(tgc2.bm_created);
587
588 /* Get allocation */
589 rc = gfx_bitmap_get_alloc(bitmap, &galloc);
590 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
591 PCUT_ASSERT_INT_EQUALS(alloc.pitch, galloc.pitch);
592 PCUT_ASSERT_INT_EQUALS(alloc.off0, galloc.off0);
593 PCUT_ASSERT_EQUALS(alloc.pixels, galloc.pixels);
594 PCUT_ASSERT_EQUALS(tgc1.bm_pixels, galloc.pixels);
595
596 /* Add second output GC */
597 rc = gfx_context_new(&ops, &tgc2, &gc2);
598 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
599
600 rc = ds_clonegc_add_output(cgc, gc2);
601 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
602
603 /* Render bitmap */
604 tgc1.bm_rendered = false;
605 tgc1.bm_rendered = false;
606 rect.p0.x = 10;
607 rect.p0.y = 20;
608 rect.p1.x = 30;
609 rect.p1.y = 40;
610 off.x = 50;
611 off.y = 60;
612 rc = gfx_bitmap_render(bitmap, &rect, &off);
613 PCUT_ASSERT_TRUE(tgc1.bm_rendered);
614 PCUT_ASSERT_INT_EQUALS(rect.p0.x, tgc1.bm_srect.p0.x);
615 PCUT_ASSERT_INT_EQUALS(rect.p0.y, tgc1.bm_srect.p0.y);
616 PCUT_ASSERT_INT_EQUALS(rect.p1.x, tgc1.bm_srect.p1.x);
617 PCUT_ASSERT_INT_EQUALS(rect.p1.y, tgc1.bm_srect.p1.y);
618 PCUT_ASSERT_TRUE(tgc2.bm_rendered);
619 PCUT_ASSERT_INT_EQUALS(rect.p0.x, tgc2.bm_srect.p0.x);
620 PCUT_ASSERT_INT_EQUALS(rect.p0.y, tgc2.bm_srect.p0.y);
621 PCUT_ASSERT_INT_EQUALS(rect.p1.x, tgc2.bm_srect.p1.x);
622 PCUT_ASSERT_INT_EQUALS(rect.p1.y, tgc2.bm_srect.p1.y);
623
624 free(pixels);
625
626 rc = ds_clonegc_delete(cgc);
627 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
628}
629
630static errno_t testgc_set_color(void *arg, gfx_color_t *color)
631{
632 test_gc_t *tgc = (test_gc_t *) arg;
633
634 tgc->set_color_called = true;
635 tgc->set_color_color = color;
636
637 return tgc->rc;
638}
639
640static errno_t testgc_fill_rect(void *arg, gfx_rect_t *rect)
641{
642 test_gc_t *tgc = (test_gc_t *) arg;
643
644 tgc->fill_rect_called = true;
645 tgc->fill_rect_rect = rect;
646
647 return tgc->rc;
648}
649
650static errno_t testgc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
651 gfx_bitmap_alloc_t *alloc, void **rbm)
652{
653 test_gc_t *tgc = (test_gc_t *) arg;
654 testgc_bitmap_t *tbm;
655
656 tbm = calloc(1, sizeof(testgc_bitmap_t));
657 if (tbm == NULL)
658 return ENOMEM;
659
660 if (alloc == NULL) {
661 tbm->alloc.pitch = alloc_pitch;
662 tbm->alloc.off0 = alloc_off0;
663 tbm->alloc.pixels = calloc(1, 420);
664 tbm->myalloc = true;
665 if (tbm->alloc.pixels == NULL) {
666 free(tbm);
667 return ENOMEM;
668 }
669 } else {
670 tbm->alloc = *alloc;
671 }
672
673 tbm->tgc = tgc;
674 tgc->bm_created = true;
675 tgc->bm_params = *params;
676 tgc->bm_pixels = tbm->alloc.pixels;
677 *rbm = (void *)tbm;
678 return EOK;
679}
680
681static errno_t testgc_bitmap_destroy(void *bm)
682{
683 testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
684 if (tbm->myalloc)
685 free(tbm->alloc.pixels);
686 tbm->tgc->bm_destroyed = true;
687 free(tbm);
688 return EOK;
689}
690
691static errno_t testgc_bitmap_render(void *bm, gfx_rect_t *srect,
692 gfx_coord2_t *offs)
693{
694 testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
695 tbm->tgc->bm_rendered = true;
696 tbm->tgc->bm_srect = *srect;
697 tbm->tgc->bm_offs = *offs;
698 return EOK;
699}
700
701static errno_t testgc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
702{
703 testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
704 *alloc = tbm->alloc;
705 tbm->tgc->bm_got_alloc = true;
706 return EOK;
707}
708
709PCUT_EXPORT(clonegc);
Note: See TracBrowser for help on using the repository browser.