[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 09/13] sm501: Fix and optimize overlap check
From: |
Gerd Hoffmann |
Subject: |
[PULL 09/13] sm501: Fix and optimize overlap check |
Date: |
Wed, 1 Jul 2020 17:04:21 +0200 |
From: BALATON Zoltan <balaton@eik.bme.hu>
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>
Message-Id: <20200624164737.A941374633D@zero.eik.bme.hu>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
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 2db347dcbc1c..9cccc68c35e5 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.18.4
- [PULL 00/13] Vga 20200701 patches, Gerd Hoffmann, 2020/07/01
- [PULL 01/13] sm501: Fix bounds checks, Gerd Hoffmann, 2020/07/01
- [PULL 13/13] configure: vgabios cleanups, Gerd Hoffmann, 2020/07/01
- [PULL 03/13] sm501: Ignore no-op blits, Gerd Hoffmann, 2020/07/01
- [PULL 06/13] sm501: Use stn_he_p/ldn_he_p instead of switch/case, Gerd Hoffmann, 2020/07/01
- [PULL 09/13] sm501: Fix and optimize overlap check,
Gerd Hoffmann <=
- [PULL 10/13] ati-vga: Support unaligned access to hardware cursor registers, Gerd Hoffmann, 2020/07/01
- [PULL 04/13] sm501: Introduce variable for commonly used value for better readability, Gerd Hoffmann, 2020/07/01
- [PULL 08/13] sm501: Convert debug printfs to traces, Gerd Hoffmann, 2020/07/01
- [PULL 02/13] sm501: Drop unneded variable, Gerd Hoffmann, 2020/07/01
- [PULL 12/13] ati-vga: Add dummy MEM_SDRAM_MODE_REG, Gerd Hoffmann, 2020/07/01
- [PULL 11/13] ati-vga: Do not assert on error, Gerd Hoffmann, 2020/07/01
- [PULL 07/13] sm501: Do not allow guest to set invalid format, Gerd Hoffmann, 2020/07/01
- [PULL 05/13] sm501: Optimise 1 pixel 2d ops, Gerd Hoffmann, 2020/07/01
- Re: [PULL 00/13] Vga 20200701 patches, Peter Maydell, 2020/07/02