aboutsummaryrefslogtreecommitdiffstats
path: root/exynos
diff options
context:
space:
mode:
authorTobias Jakobi2015-09-08 10:22:28 -0500
committerEmil Velikov2015-09-21 11:43:14 -0500
commit2362c88251d4bba0bb76d2a25f233004c6f99134 (patch)
treeed097aa38a1a9f993a68757adeec9a008f512993 /exynos
parent9017619714eb432fa9bb1e94139cc2ad40fc7001 (diff)
downloadexternal-libgbm-2362c88251d4bba0bb76d2a25f233004c6f99134.tar.gz
external-libgbm-2362c88251d4bba0bb76d2a25f233004c6f99134.tar.xz
external-libgbm-2362c88251d4bba0bb76d2a25f233004c6f99134.zip
exynos/fimg2d: add g2d_check_space()
This is going to be used to check if the command buffers have enough space left prior to actual submission of the commands. Use this in g2d_{solid_fill,copy,copy_with_scale}(). For this the parameter validation before buffer space checking so that we can exit early if it fails. Also don't reset the G2D context in this situation since the buffers are not partially submitted anymore. The repeat mode in g2d_copy_with_scale() is checked first to make computation of space easier. Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de> Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
Diffstat (limited to 'exynos')
-rw-r--r--exynos/exynos_fimg2d.c99
1 files changed, 64 insertions, 35 deletions
diff --git a/exynos/exynos_fimg2d.c b/exynos/exynos_fimg2d.c
index 85b2317b..2e04f4a8 100644
--- a/exynos/exynos_fimg2d.c
+++ b/exynos/exynos_fimg2d.c
@@ -102,6 +102,23 @@ static unsigned int g2d_get_blend_op(enum e_g2d_op op)
102} 102}
103 103
104/* 104/*
105 * g2d_check_space - check if command buffers have enough space left.
106 *
107 * @ctx: a pointer to g2d_context structure.
108 * @num_cmds: number of (regular) commands.
109 * @num_gem_cmds: number of GEM commands.
110 */
111static unsigned int g2d_check_space(const struct g2d_context *ctx,
112 unsigned int num_cmds, unsigned int num_gem_cmds)
113{
114 if (ctx->cmd_nr + num_cmds >= G2D_MAX_CMD_NR ||
115 ctx->cmd_buf_nr + num_gem_cmds >= G2D_MAX_GEM_CMD_NR)
116 return 1;
117 else
118 return 0;
119}
120
121/*
105 * g2d_add_cmd - set given command and value to user side command buffer. 122 * g2d_add_cmd - set given command and value to user side command buffer.
106 * 123 *
107 * @ctx: a pointer to g2d_context structure. 124 * @ctx: a pointer to g2d_context structure.
@@ -302,6 +319,9 @@ g2d_solid_fill(struct g2d_context *ctx, struct g2d_image *img,
302 union g2d_bitblt_cmd_val bitblt; 319 union g2d_bitblt_cmd_val bitblt;
303 union g2d_point_val pt; 320 union g2d_point_val pt;
304 321
322 if (g2d_check_space(ctx, 7, 1))
323 return -ENOSPC;
324
305 g2d_add_cmd(ctx, DST_SELECT_REG, G2D_SELECT_MODE_NORMAL); 325 g2d_add_cmd(ctx, DST_SELECT_REG, G2D_SELECT_MODE_NORMAL);
306 g2d_add_cmd(ctx, DST_COLOR_MODE_REG, img->color_mode); 326 g2d_add_cmd(ctx, DST_COLOR_MODE_REG, img->color_mode);
307 g2d_add_base_addr(ctx, img, g2d_dst); 327 g2d_add_base_addr(ctx, img, g2d_dst);
@@ -355,17 +375,7 @@ g2d_copy(struct g2d_context *ctx, struct g2d_image *src,
355{ 375{
356 union g2d_rop4_val rop4; 376 union g2d_rop4_val rop4;
357 union g2d_point_val pt; 377 union g2d_point_val pt;
358 unsigned int src_w = 0, src_h = 0, dst_w = 0, dst_h = 0; 378 unsigned int src_w, src_h, dst_w, dst_h;
359
360 g2d_add_cmd(ctx, DST_SELECT_REG, G2D_SELECT_MODE_BGCOLOR);
361 g2d_add_cmd(ctx, DST_COLOR_MODE_REG, dst->color_mode);
362 g2d_add_base_addr(ctx, dst, g2d_dst);
363 g2d_add_cmd(ctx, DST_STRIDE_REG, dst->stride);
364
365 g2d_add_cmd(ctx, SRC_SELECT_REG, G2D_SELECT_MODE_NORMAL);
366 g2d_add_cmd(ctx, SRC_COLOR_MODE_REG, src->color_mode);
367 g2d_add_base_addr(ctx, src, g2d_src);
368 g2d_add_cmd(ctx, SRC_STRIDE_REG, src->stride);
369 379
370 src_w = w; 380 src_w = w;
371 src_h = h; 381 src_h = h;
@@ -386,10 +396,22 @@ g2d_copy(struct g2d_context *ctx, struct g2d_image *src,
386 396
387 if (w <= 0 || h <= 0) { 397 if (w <= 0 || h <= 0) {
388 fprintf(stderr, "invalid width or height.\n"); 398 fprintf(stderr, "invalid width or height.\n");
389 g2d_reset(ctx);
390 return -EINVAL; 399 return -EINVAL;
391 } 400 }
392 401
402 if (g2d_check_space(ctx, 11, 2))
403 return -ENOSPC;
404
405 g2d_add_cmd(ctx, DST_SELECT_REG, G2D_SELECT_MODE_BGCOLOR);
406 g2d_add_cmd(ctx, DST_COLOR_MODE_REG, dst->color_mode);
407 g2d_add_base_addr(ctx, dst, g2d_dst);
408 g2d_add_cmd(ctx, DST_STRIDE_REG, dst->stride);
409
410 g2d_add_cmd(ctx, SRC_SELECT_REG, G2D_SELECT_MODE_NORMAL);
411 g2d_add_cmd(ctx, SRC_COLOR_MODE_REG, src->color_mode);
412 g2d_add_base_addr(ctx, src, g2d_src);
413 g2d_add_cmd(ctx, SRC_STRIDE_REG, src->stride);
414
393 pt.val = 0; 415 pt.val = 0;
394 pt.data.x = src_x; 416 pt.data.x = src_x;
395 pt.data.y = src_y; 417 pt.data.y = src_y;
@@ -445,23 +467,12 @@ g2d_copy_with_scale(struct g2d_context *ctx, struct g2d_image *src,
445{ 467{
446 union g2d_rop4_val rop4; 468 union g2d_rop4_val rop4;
447 union g2d_point_val pt; 469 union g2d_point_val pt;
448 unsigned int scale; 470 unsigned int scale, repeat_pad;
449 unsigned int scale_x, scale_y; 471 unsigned int scale_x, scale_y;
450 472
451 g2d_add_cmd(ctx, DST_SELECT_REG, G2D_SELECT_MODE_BGCOLOR); 473 /* Sanitize this parameter to facilitate space computation below. */
452 g2d_add_cmd(ctx, DST_COLOR_MODE_REG, dst->color_mode); 474 if (negative)
453 g2d_add_base_addr(ctx, dst, g2d_dst); 475 negative = 1;
454 g2d_add_cmd(ctx, DST_STRIDE_REG, dst->stride);
455
456 g2d_add_cmd(ctx, SRC_SELECT_REG, G2D_SELECT_MODE_NORMAL);
457 g2d_add_cmd(ctx, SRC_COLOR_MODE_REG, src->color_mode);
458
459 g2d_add_cmd(ctx, SRC_REPEAT_MODE_REG, src->repeat_mode);
460 if (src->repeat_mode == G2D_REPEAT_MODE_PAD)
461 g2d_add_cmd(ctx, SRC_PAD_VALUE_REG, dst->color);
462
463 g2d_add_base_addr(ctx, src, g2d_src);
464 g2d_add_cmd(ctx, SRC_STRIDE_REG, src->stride);
465 476
466 if (src_w == dst_w && src_h == dst_h) 477 if (src_w == dst_w && src_h == dst_h)
467 scale = 0; 478 scale = 0;
@@ -471,6 +482,8 @@ g2d_copy_with_scale(struct g2d_context *ctx, struct g2d_image *src,
471 scale_y = g2d_get_scaling(src_h, dst_h); 482 scale_y = g2d_get_scaling(src_h, dst_h);
472 } 483 }
473 484
485 repeat_pad = src->repeat_mode == G2D_REPEAT_MODE_PAD ? 1 : 0;
486
474 if (src_x + src_w > src->width) 487 if (src_x + src_w > src->width)
475 src_w = src->width - src_x; 488 src_w = src->width - src_x;
476 if (src_y + src_h > src->height) 489 if (src_y + src_h > src->height)
@@ -483,21 +496,37 @@ g2d_copy_with_scale(struct g2d_context *ctx, struct g2d_image *src,
483 496
484 if (src_w <= 0 || src_h <= 0 || dst_w <= 0 || dst_h <= 0) { 497 if (src_w <= 0 || src_h <= 0 || dst_w <= 0 || dst_h <= 0) {
485 fprintf(stderr, "invalid width or height.\n"); 498 fprintf(stderr, "invalid width or height.\n");
486 g2d_reset(ctx);
487 return -EINVAL; 499 return -EINVAL;
488 } 500 }
489 501
502 if (g2d_check_space(ctx, 12 + scale * 3 + negative + repeat_pad, 2))
503 return -ENOSPC;
504
505 g2d_add_cmd(ctx, DST_SELECT_REG, G2D_SELECT_MODE_BGCOLOR);
506 g2d_add_cmd(ctx, DST_COLOR_MODE_REG, dst->color_mode);
507 g2d_add_base_addr(ctx, dst, g2d_dst);
508 g2d_add_cmd(ctx, DST_STRIDE_REG, dst->stride);
509
510 g2d_add_cmd(ctx, SRC_SELECT_REG, G2D_SELECT_MODE_NORMAL);
511 g2d_add_cmd(ctx, SRC_COLOR_MODE_REG, src->color_mode);
512
513 g2d_add_cmd(ctx, SRC_REPEAT_MODE_REG, src->repeat_mode);
514 if (repeat_pad)
515 g2d_add_cmd(ctx, SRC_PAD_VALUE_REG, dst->color);
516
517 g2d_add_base_addr(ctx, src, g2d_src);
518 g2d_add_cmd(ctx, SRC_STRIDE_REG, src->stride);
519
520 rop4.val = 0;
521 rop4.data.unmasked_rop3 = G2D_ROP3_SRC;
522
490 if (negative) { 523 if (negative) {
491 g2d_add_cmd(ctx, BG_COLOR_REG, 0x00FFFFFF); 524 g2d_add_cmd(ctx, BG_COLOR_REG, 0x00FFFFFF);
492 rop4.val = 0; 525 rop4.data.unmasked_rop3 ^= G2D_ROP3_DST;
493 rop4.data.unmasked_rop3 = G2D_ROP3_SRC^G2D_ROP3_DST;
494 g2d_add_cmd(ctx, ROP4_REG, rop4.val);
495 } else {
496 rop4.val = 0;
497 rop4.data.unmasked_rop3 = G2D_ROP3_SRC;
498 g2d_add_cmd(ctx, ROP4_REG, rop4.val);
499 } 526 }
500 527
528 g2d_add_cmd(ctx, ROP4_REG, rop4.val);
529
501 if (scale) { 530 if (scale) {
502 g2d_add_cmd(ctx, SRC_SCALE_CTRL_REG, G2D_SCALE_MODE_BILINEAR); 531 g2d_add_cmd(ctx, SRC_SCALE_CTRL_REG, G2D_SCALE_MODE_BILINEAR);
503 g2d_add_cmd(ctx, SRC_XSCALE_REG, scale_x); 532 g2d_add_cmd(ctx, SRC_XSCALE_REG, scale_x);