[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v4] sm501: Fix and optimize overlap check
From: |
BALATON Zoltan |
Subject: |
[PATCH v4] sm501: Fix and optimize overlap check |
Date: |
Wed, 24 Jun 2020 18:42:18 +0200 |
When doing reverse blit we need to check if source and dest overlap
but it is not trivial due to possible different base and pitch of
source and dest. Do rectangle overlap if base and pitch match,
otherwise just check if memory area containing the rects overlaps so
rects could possibly overlap.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
This version fixes overlap check according to Peter's suggestion, only
resending this patch as v4, others still valid from v3. Let me know if
you want the whole series resent instead.
hw/display/sm501.c | 26 ++++++++++++++++----------
1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index 2db347dcbc..9cccc68c35 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -690,6 +690,7 @@ static void sm501_2d_operation(SM501State *s)
unsigned int dst_pitch = (s->twoD_pitch >> 16) & 0x1FFF;
int crt = (s->dc_crt_control & SM501_DC_CRT_CONTROL_SEL) ? 1 : 0;
int fb_len = get_width(s, crt) * get_height(s, crt) * get_bpp(s, crt);
+ bool overlap = false;
if ((s->twoD_stretch >> 16) & 0xF) {
qemu_log_mask(LOG_UNIMP, "sm501: only XY addressing is supported.\n");
@@ -784,16 +785,21 @@ static void sm501_2d_operation(SM501State *s)
ldn_he_p(&s->local_mem[src_base + si], bypp));
break;
}
- /* Check for overlaps, this could be made more exact */
- uint32_t sb, se, db, de;
- sb = src_base + src_x + src_y * (width + src_pitch);
- se = sb + width + height * (width + src_pitch);
- db = dst_base + dst_x + dst_y * (width + dst_pitch);
- de = db + width + height * (width + dst_pitch);
- if (rtl && ((db >= sb && db <= se) || (de >= sb && de <= se))) {
- /* regions may overlap: copy via temporary */
- int llb = width * bypp;
- int tmp_stride = DIV_ROUND_UP(llb, sizeof(uint32_t));
+ /* If reverse blit do simple check for overlaps */
+ if (rtl && src_base == dst_base && src_pitch == dst_pitch) {
+ overlap = (src_x < dst_x + width && src_x + width > dst_x &&
+ src_y < dst_y + height && src_y + height > dst_y);
+ } else if (rtl) {
+ unsigned int sb, se, db, de;
+ sb = src_base + (src_x + src_y * src_pitch) * bypp;
+ se = sb + (width + (height - 1) * src_pitch) * bypp;
+ db = dst_base + (dst_x + dst_y * dst_pitch) * bypp;
+ de = db + (width + (height - 1) * dst_pitch) * bypp;
+ overlap = (db < se && sb < de);
+ }
+ if (overlap) {
+ /* pixman can't do reverse blit: copy via temporary */
+ int tmp_stride = DIV_ROUND_UP(width * bypp, sizeof(uint32_t));
uint32_t *tmp = tmp_buf;
if (tmp_stride * sizeof(uint32_t) * height > sizeof(tmp_buf)) {
--
2.21.3
- [PATCH v3 0/9] More sm501 fixes and optimisations, BALATON Zoltan, 2020/06/20
- [PATCH v3 5/9] sm501: Optimise 1 pixel 2d ops, BALATON Zoltan, 2020/06/20
- [PATCH v3 4/9] sm501: Introduce variable for commonly used value for better readability, BALATON Zoltan, 2020/06/20
- [PATCH v3 6/9] sm501: Use stn_he_p/ldn_he_p instead of switch/case, BALATON Zoltan, 2020/06/20
- [PATCH v3 1/9] sm501: Fix bounds checks, BALATON Zoltan, 2020/06/20
- [PATCH v3 7/9] sm501: Do not allow guest to set invalid format, BALATON Zoltan, 2020/06/20
- [PATCH v3 3/9] sm501: Ignore no-op blits, BALATON Zoltan, 2020/06/20
- [PATCH v3 9/9] sm501: Fix and optimize overlap check, BALATON Zoltan, 2020/06/20
- [PATCH v3 2/9] sm501: Drop unneded variable, BALATON Zoltan, 2020/06/20
- [PATCH v3 8/9] sm501: Convert debug printfs to traces, BALATON Zoltan, 2020/06/20