diff options
Diffstat (limited to 'exynos/exynos_fimg2d.c')
-rw-r--r-- | exynos/exynos_fimg2d.c | 181 |
1 files changed, 126 insertions, 55 deletions
diff --git a/exynos/exynos_fimg2d.c b/exynos/exynos_fimg2d.c index 2e04f4a8..9d9359ae 100644 --- a/exynos/exynos_fimg2d.c +++ b/exynos/exynos_fimg2d.c | |||
@@ -119,6 +119,54 @@ static unsigned int g2d_check_space(const struct g2d_context *ctx, | |||
119 | } | 119 | } |
120 | 120 | ||
121 | /* | 121 | /* |
122 | * g2d_validate_select_mode - validate select mode. | ||
123 | * | ||
124 | * @mode: the mode to validate | ||
125 | * | ||
126 | * Returns zero for an invalid mode and one otherwise. | ||
127 | */ | ||
128 | static int g2d_validate_select_mode( | ||
129 | enum e_g2d_select_mode mode) | ||
130 | { | ||
131 | switch (mode) { | ||
132 | case G2D_SELECT_MODE_NORMAL: | ||
133 | case G2D_SELECT_MODE_FGCOLOR: | ||
134 | case G2D_SELECT_MODE_BGCOLOR: | ||
135 | return 1; | ||
136 | } | ||
137 | |||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | /* | ||
142 | * g2d_validate_blending_op - validate blending operation. | ||
143 | * | ||
144 | * @operation: the operation to validate | ||
145 | * | ||
146 | * Returns zero for an invalid mode and one otherwise. | ||
147 | */ | ||
148 | static int g2d_validate_blending_op( | ||
149 | enum e_g2d_op operation) | ||
150 | { | ||
151 | switch (operation) { | ||
152 | case G2D_OP_CLEAR: | ||
153 | case G2D_OP_SRC: | ||
154 | case G2D_OP_DST: | ||
155 | case G2D_OP_OVER: | ||
156 | case G2D_OP_INTERPOLATE: | ||
157 | case G2D_OP_DISJOINT_CLEAR: | ||
158 | case G2D_OP_DISJOINT_SRC: | ||
159 | case G2D_OP_DISJOINT_DST: | ||
160 | case G2D_OP_CONJOINT_CLEAR: | ||
161 | case G2D_OP_CONJOINT_SRC: | ||
162 | case G2D_OP_CONJOINT_DST: | ||
163 | return 1; | ||
164 | } | ||
165 | |||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | /* | ||
122 | * g2d_add_cmd - set given command and value to user side command buffer. | 170 | * g2d_add_cmd - set given command and value to user side command buffer. |
123 | * | 171 | * |
124 | * @ctx: a pointer to g2d_context structure. | 172 | * @ctx: a pointer to g2d_context structure. |
@@ -579,7 +627,45 @@ g2d_blend(struct g2d_context *ctx, struct g2d_image *src, | |||
579 | union g2d_point_val pt; | 627 | union g2d_point_val pt; |
580 | union g2d_bitblt_cmd_val bitblt; | 628 | union g2d_bitblt_cmd_val bitblt; |
581 | union g2d_blend_func_val blend; | 629 | union g2d_blend_func_val blend; |
582 | unsigned int src_w = 0, src_h = 0, dst_w = 0, dst_h = 0; | 630 | unsigned int gem_space; |
631 | unsigned int src_w, src_h, dst_w, dst_h; | ||
632 | |||
633 | src_w = w; | ||
634 | src_h = h; | ||
635 | if (src_x + w > src->width) | ||
636 | src_w = src->width - src_x; | ||
637 | if (src_y + h > src->height) | ||
638 | src_h = src->height - src_y; | ||
639 | |||
640 | dst_w = w; | ||
641 | dst_h = h; | ||
642 | if (dst_x + w > dst->width) | ||
643 | dst_w = dst->width - dst_x; | ||
644 | if (dst_y + h > dst->height) | ||
645 | dst_h = dst->height - dst_y; | ||
646 | |||
647 | w = MIN(src_w, dst_w); | ||
648 | h = MIN(src_h, dst_h); | ||
649 | |||
650 | if (w <= 0 || h <= 0) { | ||
651 | fprintf(stderr, "invalid width or height.\n"); | ||
652 | return -EINVAL; | ||
653 | } | ||
654 | |||
655 | if (!g2d_validate_select_mode(src->select_mode)) { | ||
656 | fprintf(stderr , "invalid select mode for source.\n"); | ||
657 | return -EINVAL; | ||
658 | } | ||
659 | |||
660 | if (!g2d_validate_blending_op(op)) { | ||
661 | fprintf(stderr , "unsupported blending operation.\n"); | ||
662 | return -EINVAL; | ||
663 | } | ||
664 | |||
665 | gem_space = src->select_mode == G2D_SELECT_MODE_NORMAL ? 2 : 1; | ||
666 | |||
667 | if (g2d_check_space(ctx, 12, gem_space)) | ||
668 | return -ENOSPC; | ||
583 | 669 | ||
584 | bitblt.val = 0; | 670 | bitblt.val = 0; |
585 | blend.val = 0; | 671 | blend.val = 0; |
@@ -607,32 +693,6 @@ g2d_blend(struct g2d_context *ctx, struct g2d_image *src, | |||
607 | case G2D_SELECT_MODE_BGCOLOR: | 693 | case G2D_SELECT_MODE_BGCOLOR: |
608 | g2d_add_cmd(ctx, BG_COLOR_REG, src->color); | 694 | g2d_add_cmd(ctx, BG_COLOR_REG, src->color); |
609 | break; | 695 | break; |
610 | default: | ||
611 | fprintf(stderr , "failed to set src.\n"); | ||
612 | return -EINVAL; | ||
613 | } | ||
614 | |||
615 | src_w = w; | ||
616 | src_h = h; | ||
617 | if (src_x + w > src->width) | ||
618 | src_w = src->width - src_x; | ||
619 | if (src_y + h > src->height) | ||
620 | src_h = src->height - src_y; | ||
621 | |||
622 | dst_w = w; | ||
623 | dst_h = h; | ||
624 | if (dst_x + w > dst->width) | ||
625 | dst_w = dst->width - dst_x; | ||
626 | if (dst_y + h > dst->height) | ||
627 | dst_h = dst->height - dst_y; | ||
628 | |||
629 | w = MIN(src_w, dst_w); | ||
630 | h = MIN(src_h, dst_h); | ||
631 | |||
632 | if (w <= 0 || h <= 0) { | ||
633 | fprintf(stderr, "invalid width or height.\n"); | ||
634 | g2d_reset(ctx); | ||
635 | return -EINVAL; | ||
636 | } | 696 | } |
637 | 697 | ||
638 | bitblt.data.alpha_blend_mode = G2D_ALPHA_BLEND_MODE_ENABLE; | 698 | bitblt.data.alpha_blend_mode = G2D_ALPHA_BLEND_MODE_ENABLE; |
@@ -689,9 +749,47 @@ g2d_scale_and_blend(struct g2d_context *ctx, struct g2d_image *src, | |||
689 | union g2d_point_val pt; | 749 | union g2d_point_val pt; |
690 | union g2d_bitblt_cmd_val bitblt; | 750 | union g2d_bitblt_cmd_val bitblt; |
691 | union g2d_blend_func_val blend; | 751 | union g2d_blend_func_val blend; |
692 | unsigned int scale; | 752 | unsigned int scale, gem_space; |
693 | unsigned int scale_x, scale_y; | 753 | unsigned int scale_x, scale_y; |
694 | 754 | ||
755 | if (src_w == dst_w && src_h == dst_h) | ||
756 | scale = 0; | ||
757 | else { | ||
758 | scale = 1; | ||
759 | scale_x = g2d_get_scaling(src_w, dst_w); | ||
760 | scale_y = g2d_get_scaling(src_h, dst_h); | ||
761 | } | ||
762 | |||
763 | if (src_x + src_w > src->width) | ||
764 | src_w = src->width - src_x; | ||
765 | if (src_y + src_h > src->height) | ||
766 | src_h = src->height - src_y; | ||
767 | |||
768 | if (dst_x + dst_w > dst->width) | ||
769 | dst_w = dst->width - dst_x; | ||
770 | if (dst_y + dst_h > dst->height) | ||
771 | dst_h = dst->height - dst_y; | ||
772 | |||
773 | if (src_w <= 0 || src_h <= 0 || dst_w <= 0 || dst_h <= 0) { | ||
774 | fprintf(stderr, "invalid width or height.\n"); | ||
775 | return -EINVAL; | ||
776 | } | ||
777 | |||
778 | if (!g2d_validate_select_mode(src->select_mode)) { | ||
779 | fprintf(stderr , "invalid select mode for source.\n"); | ||
780 | return -EINVAL; | ||
781 | } | ||
782 | |||
783 | if (!g2d_validate_blending_op(op)) { | ||
784 | fprintf(stderr , "unsupported blending operation.\n"); | ||
785 | return -EINVAL; | ||
786 | } | ||
787 | |||
788 | gem_space = src->select_mode == G2D_SELECT_MODE_NORMAL ? 2 : 1; | ||
789 | |||
790 | if (g2d_check_space(ctx, 12 + scale * 3, gem_space)) | ||
791 | return -ENOSPC; | ||
792 | |||
695 | bitblt.val = 0; | 793 | bitblt.val = 0; |
696 | blend.val = 0; | 794 | blend.val = 0; |
697 | 795 | ||
@@ -718,33 +816,6 @@ g2d_scale_and_blend(struct g2d_context *ctx, struct g2d_image *src, | |||
718 | case G2D_SELECT_MODE_BGCOLOR: | 816 | case G2D_SELECT_MODE_BGCOLOR: |
719 | g2d_add_cmd(ctx, BG_COLOR_REG, src->color); | 817 | g2d_add_cmd(ctx, BG_COLOR_REG, src->color); |
720 | break; | 818 | break; |
721 | default: | ||
722 | fprintf(stderr , "failed to set src.\n"); | ||
723 | return -EINVAL; | ||
724 | } | ||
725 | |||
726 | if (src_w == dst_w && src_h == dst_h) | ||
727 | scale = 0; | ||
728 | else { | ||
729 | scale = 1; | ||
730 | scale_x = g2d_get_scaling(src_w, dst_w); | ||
731 | scale_y = g2d_get_scaling(src_h, dst_h); | ||
732 | } | ||
733 | |||
734 | if (src_x + src_w > src->width) | ||
735 | src_w = src->width - src_x; | ||
736 | if (src_y + src_h > src->height) | ||
737 | src_h = src->height - src_y; | ||
738 | |||
739 | if (dst_x + dst_w > dst->width) | ||
740 | dst_w = dst->width - dst_x; | ||
741 | if (dst_y + dst_h > dst->height) | ||
742 | dst_h = dst->height - dst_y; | ||
743 | |||
744 | if (src_w <= 0 || src_h <= 0 || dst_w <= 0 || dst_h <= 0) { | ||
745 | fprintf(stderr, "invalid width or height.\n"); | ||
746 | g2d_reset(ctx); | ||
747 | return -EINVAL; | ||
748 | } | 819 | } |
749 | 820 | ||
750 | if (scale) { | 821 | if (scale) { |