return 0;
}
+// draw blanking line quickly (only if blanking can have overlay data, like lightpen crosshair)
+static bool draw_blank_fast(struct linestate *l, int ldv)
+{
+ if (l->hbstrt_offset < 0 || l->hbstop_offset < 0) {
+ return false;
+ }
+ start_draw_denise();
+ int dvp = calculate_linetype(ldv);
+ draw_denise_border_line_fast_queue(dvp, true, nextline_how, l);
+ return true;
+}
+
// draw border line quickly (no copper, no sprites, no weird things, normal mode)
static bool draw_border_fast(struct linestate *l, int ldv)
{
l->color0 = aga_mode ? agnus_colors.color_regs_aga[0] : agnus_colors.color_regs_ecs[0];
l->brdblank = brdblank;
int dvp = calculate_linetype(ldv);
- draw_denise_border_line_fast_queue(dvp, nextline_how, l);
+ draw_denise_border_line_fast_queue(dvp, false, nextline_how, l);
return true;
}
return true;
}
-static bool draw_always(void)
+static int draw_always(void)
{
if (nextline_how == nln_lower_black_always || nextline_how == nln_upper_black_always) {
- return true;
+ return -1;
}
if (lineoptimizations_draw_always) {
- return true;
+ return 1;
}
- return false;
+ return 0;
}
static void resetlinestate(void)
return false;
}
bool ret = false;
- bool always = draw_always();
+ int always = draw_always();
struct linestate *l = &lines[lvpos][lof_display];
int type = getlinetype();
if (type && type == l->type && displayresetcnt == l->cnt) {
if (type == LINETYPE_BLANK) {
- if (1) {
- ret = true;
+ if (always > 0) {
+ draw_blank_fast(l, linear_display_vpos + 1);
}
+ ret = true;
} else if (type == LINETYPE_BORDER) {
if (1) {
bool brdblank = (bplcon0 & 1) && (bplcon3 & 0x20);
static void vsync_nosync(void)
{
- if (!nosignal_trigger) {
- denise_clearbuffers();
- }
+ denise_clearbuffers();
nosignal_trigger = true;
linear_vpos = 0;
vsync_handler_post();
static struct denise_rga_queue temp_line;
static struct denise_rga_queue *this_line;
static volatile bool thread_debug_lock;
+static bool full_line_draw;
static void denise_handle_quick_strobe(uae_u16 strobe, int offset, int vpos);
static void draw_denise_vsync(int);
} else if (q->type == 1) {
draw_denise_bitplane_line_fast(q->gfx_ypos, q->how, q->ls);
} else if (q->type == 2) {
- draw_denise_border_line_fast(q->gfx_ypos, q->how, q->ls);
+ draw_denise_border_line_fast(q->gfx_ypos, q->blanked, q->how, q->ls);
} else if (q->type == 3) {
quick_denise_rga(q->linecnt, q->startpos, q->endpos);
} else if (q->type == 4) {
struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo;
if (!drawing_can_lineoptimizations()) {
+ // full line is drawn because overlay graphics can be drawn on top of border and blanking
+ full_line_draw = true;
vidinfo->inbuffer = &vidinfo->tempbuffer;
struct vidbuffer *vb = &vidinfo->tempbuffer;
if (!vb->outwidth || !vb->outheight) {
vb->monitor_id = vb2->monitor_id;
}
} else {
+ full_line_draw = false;
vidinfo->inbuffer = &vidinfo->drawbuffer;
}
}
}
}
+static void draw_blank_start(int len)
+{
+ if (len > 0 && buf1 < (uae_u32*)xlinebuffer_start) {
+ int d = (uae_u32*)xlinebuffer_start - buf1;
+ buf1 += d;
+ len -= d;
+ }
+ if (buf1 + len > (uae_u32*)xlinebuffer_end) {
+ len = (uae_u32*)xlinebuffer_end - buf1;
+ }
+ if (len > 0) {
+ memset(buf1, 0, len * sizeof(uae_u32));
+ if (buf2) {
+ memset(buf2, 0, len * sizeof(uae_u32));
+ }
+ }
+}
+static void draw_blank_end(void)
+{
+ if (buf1 < (uae_u32*)xlinebuffer_start) {
+ buf1 = (uae_u32*)xlinebuffer_start;
+ }
+ if (buf1 < (uae_u32*)xlinebuffer_end) {
+ int len = (uae_u32*)xlinebuffer_end - buf1;
+ if (len > 0) {
+ memset(buf1, 0, len * sizeof(uae_u32));
+ if (buf2) {
+ memset(buf2, 0, len * sizeof(uae_u32));
+ }
+ }
+ }
+}
+
static void fill_border(int total, uae_u32 bgcol)
{
if (buf2) {
}
// draw border from hb to hb
-void draw_denise_border_line_fast(int gfx_ypos, enum nln_how how, struct linestate *ls)
+void draw_denise_border_line_fast(int gfx_ypos, bool blank, enum nln_how how, struct linestate *ls)
{
if (ls->strlong_seen) {
set_strlong();
get_line(0, gfx_ypos, how, ls->lol_shift_prev);
- if (!buf1 && !ls->blankedline && denise_planes > 0) {
+ if (!buf1 && !ls->blankedline && denise_planes > 0 && !blank) {
resolution_count[denise_res]++;
}
lines_count++;
buf1 = buf1p;
buf2 = buf2p;
- int start = draw_startoffset;
- if (start < hbstop_offset) {
- int diff = hbstop_offset - start;
- buf1 += diff;
+ if (blank) {
+ memset(buf1, 0, xlinebuffer_end - (uae_u8*)buf1);
if (buf2) {
- buf2 += diff;
+ memset(buf2, 0, xlinebuffer_end - (uae_u8 *)buf1);
}
- if (gbufp) {
- gbufp += diff;
+ } else {
+ if (full_line_draw) {
+ draw_blank_start(hbstop_offset);
}
- start = hbstop_offset;
- }
- int end = draw_end > hbstrt_offset ? hbstrt_offset : draw_end;
- int total = end - start;
+ int start = draw_startoffset;
+ if (start < hbstop_offset) {
+ int diff = hbstop_offset - start;
+ buf1 += diff;
+ if (buf2) {
+ buf2 += diff;
+ }
+ if (gbufp) {
+ gbufp += diff;
+ }
+ start = hbstop_offset;
+ }
+ int end = draw_end > hbstrt_offset ? hbstrt_offset : draw_end;
+ int total = end - start;
- fill_border(total, bgcol);
+ fill_border(total, bgcol);
+ if (full_line_draw) {
+ draw_blank_end();
+ }
- total = end - start;
- if (need_genlock_data && gbuf && total) {
- int max = addrdiff(xlinebuffer_genlock_end, gbufp);
- total += GENLOCK_EXTRA_CLEAR;
- if (total > max) {
- total = max;
+ total = end - start;
+ if (need_genlock_data && gbuf && total) {
+ int max = addrdiff(xlinebuffer_genlock_end, gbufp);
+ total += GENLOCK_EXTRA_CLEAR;
+ if (total > max) {
+ total = max;
+ }
+ memset(gbufp, 0, total);
}
- memset(gbufp, 0, total);
}
-
}
static int ltsf_init(int draw_start, int draw_startoffset, int *draw_end, int hbstrt_offset, int hbstop_offset, int bpl1dat_trigger_offset, uae_u8 *buf_end, uae_u32 *buf1)
buf1 = buf1p;
buf2 = buf2p;
}
+ if (full_line_draw) {
+ draw_blank_start(hbstop_offset);
+ }
int cnt = ltsf_init(draw_start, draw_startoffset, &draw_end, hbstrt_offset, hbstop_offset, bpl1dat_trigger_offset, xlinebuffer_end, buf1);
ltsf(cnt, draw_end, hbstrt_offset, hbstop_offset, hstrt_offset, hstop_offset, bpl1dat_trigger_offset,
planecnt, bgcol, &cp, &cp2, 1 << cpadd, cpadds, 1 << bufadd, ls);
}
}
+ if (full_line_draw) {
+ draw_blank_end();
+ }
+
// clear some more bytes to clear possible lightpen cursor graphics
if (need_genlock_data && gbuf) {
int max = addrdiff(xlinebuffer_genlock_end, gbuf);
uae_sem_post(&write_sem);
}
-void draw_denise_border_line_fast_queue(int gfx_ypos, enum nln_how how, struct linestate *ls)
+void draw_denise_border_line_fast_queue(int gfx_ypos, bool blank, enum nln_how how, struct linestate *ls)
{
if (MULTITHREADED_DENISE) {
struct denise_rga_queue *q = &rga_queue[rga_queue_write & DENISE_RGA_SLOT_CHUNKS_MASK];
q->gfx_ypos = gfx_ypos;
+ q->blanked = blank;
q->how = how;
q->ls = ls;
q->type = 2;
} else {
updatelinedata();
- draw_denise_border_line_fast(gfx_ypos, how, ls);
+ draw_denise_border_line_fast(gfx_ypos, blank, how, ls);
}
}
void draw_denise_line_queue(int gfx_ypos, nln_how how, uae_u32 linecnt, int startpos, int endpos, int startcycle, int endcycle, int skip, int skip2, int dtotal, int calib_start, int calib_len, bool lof, bool lol, int hdelay, bool blanked, bool finalseg, struct linestate *ls);
void draw_denise_bitplane_line_fast(int gfx_ypos, enum nln_how how, struct linestate *ls);
void draw_denise_bitplane_line_fast_queue(int gfx_ypos, enum nln_how how, struct linestate *ls);
-void draw_denise_border_line_fast(int gfx_ypos, enum nln_how how, struct linestate *ls);
-void draw_denise_border_line_fast_queue(int gfx_ypos, enum nln_how how, struct linestate *ls);
+void draw_denise_border_line_fast(int gfx_ypos, bool blank, enum nln_how how, struct linestate *ls);
+void draw_denise_border_line_fast_queue(int gfx_ypos, bool blank, enum nln_how how, struct linestate *ls);
bool start_draw_denise(void);
void end_draw_denise(void);
void denise_reset(bool);