Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102712931
D42057.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D42057.diff
View Options
diff --git a/sys/dev/vt/vt.h b/sys/dev/vt/vt.h
--- a/sys/dev/vt/vt.h
+++ b/sys/dev/vt/vt.h
@@ -165,6 +165,9 @@
term_char_t *vd_drawn; /* (?) Most recent char drawn. */
term_color_t *vd_drawnfg; /* (?) Most recent fg color drawn. */
term_color_t *vd_drawnbg; /* (?) Most recent bg color drawn. */
+
+ struct mtx vd_flush_lock; /* (?) vt_flush() lock. */
+ bool *vd_pos_to_flush;/* (?) Positions to flush. */
};
#define VD_PASTEBUF(vd) ((vd)->vd_pastebuf.vpb_buf)
@@ -175,6 +178,14 @@
#define VT_UNLOCK(vd) mtx_unlock(&(vd)->vd_lock)
#define VT_LOCK_ASSERT(vd, what) mtx_assert(&(vd)->vd_lock, what)
+#define VT_FLUSH_LOCK(vd) \
+ if ((vd)->vd_driver->vd_bitblt_after_vtbuf_unlock) \
+ mtx_lock(&(vd)->vd_flush_lock)
+
+#define VT_FLUSH_UNLOCK(vd) \
+ if ((vd)->vd_driver->vd_bitblt_after_vtbuf_unlock) \
+ mtx_unlock(&(vd)->vd_flush_lock)
+
void vt_resume(struct vt_device *vd);
void vt_resume_flush_timer(struct vt_window *vw, int ms);
void vt_suspend(struct vt_device *vd);
@@ -376,6 +387,14 @@
#define VD_PRIORITY_DUMB 10
#define VD_PRIORITY_GENERIC 100
#define VD_PRIORITY_SPECIFIC 1000
+
+ /*
+ * Should vd_bitblt_text() be called after unlocking vtbuf? If true,
+ * characters are copied before vd_bitblt_bmp() is called.
+ *
+ * This is only valid when the default bitblt_text callback is used.
+ */
+ bool vd_bitblt_after_vtbuf_unlock;
};
/*
diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c
--- a/sys/dev/vt/vt_core.c
+++ b/sys/dev/vt/vt_core.c
@@ -202,11 +202,10 @@
static struct terminal vt_consterm;
static struct vt_window vt_conswindow;
-#ifndef SC_NO_CONSDRAWN
static term_char_t vt_consdrawn[PIXEL_HEIGHT(VT_FB_MAX_HEIGHT) * PIXEL_WIDTH(VT_FB_MAX_WIDTH)];
static term_color_t vt_consdrawnfg[PIXEL_HEIGHT(VT_FB_MAX_HEIGHT) * PIXEL_WIDTH(VT_FB_MAX_WIDTH)];
static term_color_t vt_consdrawnbg[PIXEL_HEIGHT(VT_FB_MAX_HEIGHT) * PIXEL_WIDTH(VT_FB_MAX_WIDTH)];
-#endif
+static bool vt_cons_pos_to_flush[PIXEL_HEIGHT(VT_FB_MAX_HEIGHT) * PIXEL_WIDTH(VT_FB_MAX_WIDTH)];
struct vt_device vt_consdev = {
.vd_driver = NULL,
.vd_softc = NULL,
@@ -228,11 +227,11 @@
.vd_mcursor_bg = TC_BLACK,
#endif
-#ifndef SC_NO_CONSDRAWN
.vd_drawn = vt_consdrawn,
.vd_drawnfg = vt_consdrawnfg,
.vd_drawnbg = vt_consdrawnbg,
-#endif
+
+ .vd_pos_to_flush = vt_cons_pos_to_flush,
};
static term_char_t vt_constextbuf[(_VTDEFW) * (VBF_DEFAULT_HISTORY_SIZE)];
static term_char_t *vt_constextbufrows[VBF_DEFAULT_HISTORY_SIZE];
@@ -292,6 +291,7 @@
printf("VT: init without driver.\n");
mtx_init(&main_vd->vd_lock, "vtdev", NULL, MTX_DEF);
+ mtx_init(&main_vd->vd_flush_lock, "vtdev flush", NULL, MTX_DEF);
cv_init(&main_vd->vd_winswitch, "vtwswt");
}
@@ -1348,6 +1348,122 @@
vd->vd_height - 1, 1, c);
}
+static void
+vt_flush_to_buffer(struct vt_device *vd,
+ const struct vt_window *vw, const term_rect_t *area)
+{
+ unsigned int col, row;
+ term_char_t c;
+ term_color_t fg, bg;
+ size_t z;
+
+ for (row = area->tr_begin.tp_row; row < area->tr_end.tp_row; ++row) {
+ for (col = area->tr_begin.tp_col; col < area->tr_end.tp_col;
+ ++col) {
+ z = row * PIXEL_WIDTH(VT_FB_MAX_WIDTH) + col;
+ if (z >= PIXEL_HEIGHT(VT_FB_MAX_HEIGHT) *
+ PIXEL_WIDTH(VT_FB_MAX_WIDTH))
+ continue;
+
+ c = VTBUF_GET_FIELD(&vw->vw_buf, row, col);
+ vt_determine_colors(c,
+ VTBUF_ISCURSOR(&vw->vw_buf, row, col), &fg, &bg);
+
+ if (vd->vd_drawn && (vd->vd_drawn[z] == c) &&
+ vd->vd_drawnfg && (vd->vd_drawnfg[z] == fg) &&
+ vd->vd_drawnbg && (vd->vd_drawnbg[z] == bg)) {
+ vd->vd_pos_to_flush[z] = false;
+ continue;
+ }
+
+ vd->vd_pos_to_flush[z] = true;
+
+ if (vd->vd_drawn)
+ vd->vd_drawn[z] = c;
+ if (vd->vd_drawnfg)
+ vd->vd_drawnfg[z] = fg;
+ if (vd->vd_drawnbg)
+ vd->vd_drawnbg[z] = bg;
+ }
+ }
+}
+
+static void
+vt_bitblt_buffer(struct vt_device *vd, const struct vt_window *vw,
+ const term_rect_t *area)
+{
+ unsigned int col, row, x, y;
+ struct vt_font *vf;
+ term_char_t c;
+ term_color_t fg, bg;
+ const uint8_t *pattern;
+ size_t z;
+
+ vf = vw->vw_font;
+
+ for (row = area->tr_begin.tp_row; row < area->tr_end.tp_row; ++row) {
+ for (col = area->tr_begin.tp_col; col < area->tr_end.tp_col;
+ ++col) {
+ x = col * vf->vf_width +
+ vw->vw_draw_area.tr_begin.tp_col;
+ y = row * vf->vf_height +
+ vw->vw_draw_area.tr_begin.tp_row;
+
+ z = row * PIXEL_WIDTH(VT_FB_MAX_WIDTH) + col;
+ if (z >= PIXEL_HEIGHT(VT_FB_MAX_HEIGHT) *
+ PIXEL_WIDTH(VT_FB_MAX_WIDTH))
+ continue;
+ if (!vd->vd_pos_to_flush[z])
+ continue;
+
+ c = vd->vd_drawn[z];
+ fg = vd->vd_drawnfg[z];
+ bg = vd->vd_drawnbg[z];
+
+ pattern = vtfont_lookup(vf, c);
+ vd->vd_driver->vd_bitblt_bmp(vd, vw,
+ pattern, NULL, vf->vf_width, vf->vf_height,
+ x, y, fg, bg);
+ }
+ }
+
+#ifndef SC_NO_CUTPASTE
+ if (!vd->vd_mshown)
+ return;
+
+ term_rect_t drawn_area;
+
+ drawn_area.tr_begin.tp_col = area->tr_begin.tp_col * vf->vf_width;
+ drawn_area.tr_begin.tp_row = area->tr_begin.tp_row * vf->vf_height;
+ drawn_area.tr_end.tp_col = area->tr_end.tp_col * vf->vf_width;
+ drawn_area.tr_end.tp_row = area->tr_end.tp_row * vf->vf_height;
+
+ if (vt_is_cursor_in_area(vd, &drawn_area)) {
+ vd->vd_driver->vd_bitblt_bmp(vd, vw,
+ vd->vd_mcursor->map, vd->vd_mcursor->mask,
+ vd->vd_mcursor->width, vd->vd_mcursor->height,
+ vd->vd_mx_drawn + vw->vw_draw_area.tr_begin.tp_col,
+ vd->vd_my_drawn + vw->vw_draw_area.tr_begin.tp_row,
+ vd->vd_mcursor_fg, vd->vd_mcursor_bg);
+ }
+#endif
+}
+
+static void
+vt_draw_decorations(struct vt_device *vd)
+{
+ struct vt_window *vw;
+ const teken_attr_t *a;
+
+ vw = vd->vd_curwindow;
+
+ a = teken_get_curattr(&vw->vw_terminal->tm_emulator);
+ vt_set_border(vd, &vw->vw_draw_area, a->ta_bgcolor);
+
+ if (vt_draw_logo_cpus)
+ vtterm_draw_cpu_logos(vd);
+}
+
static int
vt_flush(struct vt_device *vd)
{
@@ -1357,6 +1473,7 @@
#ifndef SC_NO_CUTPASTE
int cursor_was_shown, cursor_moved;
#endif
+ bool needs_refresh;
if (inside_vt_flush && KERNEL_PANICKED())
return (0);
@@ -1372,8 +1489,9 @@
if (((vd->vd_flags & VDF_TEXTMODE) == 0) && (vf == NULL))
return (0);
- vtbuf_lock(&vw->vw_buf);
+ VT_FLUSH_LOCK(vd);
+ vtbuf_lock(&vw->vw_buf);
inside_vt_flush = true;
#ifndef SC_NO_CUTPASTE
@@ -1417,29 +1535,63 @@
vtbuf_undirty(&vw->vw_buf, &tarea);
/* Force a full redraw when the screen contents might be invalid. */
+ needs_refresh = false;
if (vd->vd_flags & (VDF_INVALID | VDF_SUSPENDED)) {
- const teken_attr_t *a;
-
+ needs_refresh = true;
vd->vd_flags &= ~VDF_INVALID;
- a = teken_get_curattr(&vw->vw_terminal->tm_emulator);
- vt_set_border(vd, &vw->vw_draw_area, a->ta_bgcolor);
vt_termrect(vd, vf, &tarea);
if (vd->vd_driver->vd_invalidate_text)
vd->vd_driver->vd_invalidate_text(vd, &tarea);
- if (vt_draw_logo_cpus)
- vtterm_draw_cpu_logos(vd);
}
if (tarea.tr_begin.tp_col < tarea.tr_end.tp_col) {
- vd->vd_driver->vd_bitblt_text(vd, vw, &tarea);
- inside_vt_flush = false;
- vtbuf_unlock(&vw->vw_buf);
+ if (vd->vd_driver->vd_bitblt_after_vtbuf_unlock) {
+ /*
+ * When `vd_bitblt_after_vtbuf_unlock` is set to true,
+ * we first remember the characters to redraw. They are
+ * already copied to the `vd_drawn` arrays.
+ *
+ * We then unlock vt_buf and proceed with the actual
+ * drawing using the backend driver.
+ */
+ vt_flush_to_buffer(vd, vw, &tarea);
+ vtbuf_unlock(&vw->vw_buf);
+ vt_bitblt_buffer(vd, vw, &tarea);
+
+ if (needs_refresh)
+ vt_draw_decorations(vd);
+
+ /*
+ * We can reset `inside_vt_flush` after unlocking vtbuf
+ * here because we also hold vt_flush_lock in this code
+ * path.
+ */
+ inside_vt_flush = false;
+ } else {
+ /*
+ * When `vd_bitblt_after_vtbuf_unlock` is false, we use
+ * the backend's `vd_bitblt_text` callback directly.
+ */
+ vd->vd_driver->vd_bitblt_text(vd, vw, &tarea);
+
+ if (needs_refresh)
+ vt_draw_decorations(vd);
+
+ inside_vt_flush = false;
+ vtbuf_unlock(&vw->vw_buf);
+ }
+
+ VT_FLUSH_UNLOCK(vd);
+
return (1);
}
inside_vt_flush = false;
vtbuf_unlock(&vw->vw_buf);
+
+ VT_FLUSH_UNLOCK(vd);
+
return (0);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Nov 17, 5:46 AM (21 h, 43 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14671227
Default Alt Text
D42057.diff (8 KB)
Attached To
Mode
D42057: vt(4): New bitblt_text variant making a copy before unlocking vt_buf
Attached
Detach File
Event Timeline
Log In to Comment