Compare commits

...

14 Commits

Author SHA1 Message Date
Gerd Hoffmann
cb47dc9ab9 sdl2/opengl: add opengl context and scanout support
This allows virtio-gpu to render in 3d mode.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
2016-01-08 12:20:15 +01:00
OGAWA Hirofumi
4083733db5 ui/curses: Fix color attribute of monitor for curses
Current text_console_update() writes totally broken color attributes
to console_write_ch(). The format now is writing,

[WRONG]
	bold << 21 | fg << 12 | bg << 8 | char
	fg == 3bits curses color number
	bg == 3bits curses color number

I can't see this format is where come from. Anyway, this doesn't work
at all.

What curses expects is actually (and vga.c is using),

[RIGHT]
	bold << 21 | bg << 11 | fg << 8 | char
	fg == 3bits vga color number
	bg == 3bits vga color number

And curses set COLOR_PAIR() up to match this format, and curses's
chtype. I.e,

	bold | color_pair | char
	color_pair == (bg << 3 | fg)

To fix, this simply uses VGA color number everywhere except curses.c
internal. Then, convert it to above [RIGHT] format to write by
console_write_ch(). And as bonus, this reduces to expose curses define
to other parts (removes COLOR_* from console.c).

[Tested the first line is displayed as white on blue back for monitor
in curses console]

Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Message-id: 87r3j95407.fsf@mail.parknet.co.jp
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2016-01-08 12:20:07 +01:00
Edgar E. Iglesias
a7e00e2536 petalogix-ml605: Set the MicroBlaze CPU version to 8.10.a
Set the MicroBlaze CPU version to 8.10.a avoiding a runtime
warning due to an unset CPU version.

Reviewed-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2016-01-07 14:57:26 +01:00
Edgar E. Iglesias
ad24f947be s3adsp1800: Set the MicroBlaze CPU version to 7.10.d
Set the MicroBlaze CPU version to 7.10.d avoiding a runtime
warning due to an unset CPU version.

Reviewed-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2016-01-07 14:57:26 +01:00
Peter Maydell
263699432c Merge remote-tracking branch 'remotes/mcayland/tags/qemu-sparc-signed' into staging
qemu-sparc update

# gpg: Signature made Thu 07 Jan 2016 13:20:13 GMT using RSA key ID AE0F321F
# gpg: Good signature from "Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>"

* remotes/mcayland/tags/qemu-sparc-signed:
  target-sparc: implement NPT timer bit
  sun4u: split NPT and INT_DIS accesses between timer and compare registers
  sun4u: split out NPT and INT_DIS into separate CPUTimer fields

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2016-01-07 13:33:19 +00:00
Mark Cave-Ayland
c9a464420d target-sparc: implement NPT timer bit
If the NPT bit is set in the timer register, all non-supervisor read accesses
to the register should fail with a privilege exception.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-By: Artyom Tarasenko <atar4qemu@gmail.com>
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
2016-01-07 12:21:06 +00:00
Mark Cave-Ayland
bf43330aa4 sun4u: split NPT and INT_DIS accesses between timer and compare registers
Accesses to the timer register high bit should only set NPT, whilst accesses
to the timer compare register high bit should only set INT_DIS. This fixes
issues with the timer being unexpectedly disabled whilst trying to boot
FreeBSD SPARC64.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-By: Artyom Tarasenko <atar4qemu@gmail.com>
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
2016-01-07 12:21:02 +00:00
Mark Cave-Ayland
e913cac71b sun4u: split out NPT and INT_DIS into separate CPUTimer fields
Currently there is confusion between use of these bits for the timer and timer
compare registers (while they both have the same value, the behaviour is
different). Split into two separate CPUTimer fields so we can always reference
the correct value.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-By: Artyom Tarasenko <atar4qemu@gmail.com>
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
2016-01-07 12:20:53 +00:00
Peter Maydell
ac93a06786 Merge remote-tracking branch 'remotes/kraxel/tags/pull-seabios-20160105-1' into staging
seabios: update to release 1.9.0

# gpg: Signature made Tue 05 Jan 2016 12:07:22 GMT using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/kraxel/tags/pull-seabios-20160105-1:
  seabios: update binaries to release 1.9.0
  seabios: stop updating aml files
  seabios: update 128k bios config
  seabios: use new EXTRAVERSION to tag qemu builds
  seabios: update submodule to release 1.9.0

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2016-01-07 11:22:18 +00:00
Peter Maydell
4101dfe0cd Merge remote-tracking branch 'remotes/stefanha/tags/tracing-pull-request' into staging
# gpg: Signature made Thu 07 Jan 2016 09:13:22 GMT using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"

* remotes/stefanha/tags/tracing-pull-request:
  trace: add make dependencies on tracetool source
  trace: fix make foo-timestamp rules
  trace: fix PRIx64 constants in trace-events
  trace: reflect the file name change

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2016-01-07 10:19:28 +00:00
Stefan Hajnoczi
cef517ca4b trace: add make dependencies on tracetool source
Patches that change tracetool can break the build if old build output
files are lying around.

This happens because the Makefile does not specify dependencies on
tracetool.  The build will use old object files that do not match the
current source code.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2016-01-07 16:59:56 +08:00
Stefan Hajnoczi
9967e4fec0 trace: fix make foo-timestamp rules
The Makefile uses intermediate timestamp files to avoid rebuilding if
tracetool output is unchanged.

Timestamps are implemented incorrectly.  This was fixed for rules.mak in
commit 4b25966ab9 ("rules.mak: cleanup
config generation rules") but never fixed in trace/Makefile.objs.

The problem with the old timestamp implementation was that make doesn't
notice the updated file modification time until the next time it is run.
It was necessary to run make twice in a row to achieve a full rebuild.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2016-01-07 16:59:38 +08:00
Mark Cave-Ayland
c6daed8654 trace: fix PRIx64 constants in trace-events
Commit c8ee0a4 introduced new events containing PRIx64 constants without
including the % prefix in the preceding string. This results in a compile
error during build if --enable-trace-backends is passed to configure.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Message-id: 1450566522-6003-1-git-send-email-mark.cave-ayland@ilande.co.uk
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2016-01-07 09:39:11 +08:00
Qinghua Jin
67a9faccef trace: reflect the file name change
Some functions was moved from block.c to block/io.c, so the trace-events file should reflect that change.

Signed-off-by: Qinghua Jin <qhjin_dev@163.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2016-01-07 09:39:11 +08:00
17 changed files with 326 additions and 108 deletions

View File

@@ -233,8 +233,10 @@ static void jazz_led_text_update(void *opaque, console_ch_t *chardata)
/* TODO: draw the segments */
snprintf(buf, 2, "%02hhx\n", s->segments);
console_write_ch(chardata++, 0x00200100 | buf[0]);
console_write_ch(chardata++, 0x00200100 | buf[1]);
console_write_ch(chardata++, ATTR2CHTYPE(buf[0], QEMU_COLOR_BLUE,
QEMU_COLOR_BLACK, 1));
console_write_ch(chardata++, ATTR2CHTYPE(buf[1], QEMU_COLOR_BLUE,
QEMU_COLOR_BLACK, 1));
dpy_text_update(s->con, 0, 0, 2, 1);
}

View File

@@ -1979,7 +1979,8 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
width = (s->last_width - size) / 2;
dst = chardata + s->last_width + width;
for (i = 0; i < size; i ++)
console_write_ch(dst ++, 0x00200100 | msg_buffer[i]);
console_write_ch(dst ++, ATTR2CHTYPE(msg_buffer[i], QEMU_COLOR_BLUE,
QEMU_COLOR_BLACK, 1));
dpy_text_update(s->con, 0, 0, s->last_width, height);
}

View File

@@ -81,6 +81,7 @@ petalogix_ml605_init(MachineState *machine)
/* init CPUs */
cpu = MICROBLAZE_CPU(object_new(TYPE_MICROBLAZE_CPU));
object_property_set_str(OBJECT(cpu), "8.10.a", "version", &error_abort);
/* Use FPU but don't use floating point conversion and square
* root instructions
*/

View File

@@ -66,6 +66,7 @@ petalogix_s3adsp1800_init(MachineState *machine)
MemoryRegion *sysmem = get_system_memory();
cpu = MICROBLAZE_CPU(object_new(TYPE_MICROBLAZE_CPU));
object_property_set_str(OBJECT(cpu), "7.10.d", "version", &error_abort);
object_property_set_bool(OBJECT(cpu), true, "realized", &error_abort);
/* Attach emulated BRAM through the LMB. */

View File

@@ -363,6 +363,8 @@ void cpu_put_timer(QEMUFile *f, CPUTimer *s)
qemu_put_be32s(f, &s->frequency);
qemu_put_be32s(f, &s->disabled);
qemu_put_be64s(f, &s->disabled_mask);
qemu_put_be32s(f, &s->npt);
qemu_put_be64s(f, &s->npt_mask);
qemu_put_sbe64s(f, &s->clock_offset);
timer_put(f, s->qtimer);
@@ -373,6 +375,8 @@ void cpu_get_timer(QEMUFile *f, CPUTimer *s)
qemu_get_be32s(f, &s->frequency);
qemu_get_be32s(f, &s->disabled);
qemu_get_be64s(f, &s->disabled_mask);
qemu_get_be32s(f, &s->npt);
qemu_get_be64s(f, &s->npt_mask);
qemu_get_sbe64s(f, &s->clock_offset);
timer_get(f, s->qtimer);
@@ -380,15 +384,17 @@ void cpu_get_timer(QEMUFile *f, CPUTimer *s)
static CPUTimer *cpu_timer_create(const char *name, SPARCCPU *cpu,
QEMUBHFunc *cb, uint32_t frequency,
uint64_t disabled_mask)
uint64_t disabled_mask, uint64_t npt_mask)
{
CPUTimer *timer = g_malloc0(sizeof (CPUTimer));
timer->name = name;
timer->frequency = frequency;
timer->disabled_mask = disabled_mask;
timer->npt_mask = npt_mask;
timer->disabled = 1;
timer->npt = 1;
timer->clock_offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
timer->qtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cb, cpu);
@@ -494,17 +500,17 @@ static uint64_t timer_to_cpu_ticks(int64_t timer_ticks, uint32_t frequency)
void cpu_tick_set_count(CPUTimer *timer, uint64_t count)
{
uint64_t real_count = count & ~timer->disabled_mask;
uint64_t disabled_bit = count & timer->disabled_mask;
uint64_t real_count = count & ~timer->npt_mask;
uint64_t npt_bit = count & timer->npt_mask;
int64_t vm_clock_offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
cpu_to_timer_ticks(real_count, timer->frequency);
TIMER_DPRINTF("%s set_count count=0x%016lx (%s) p=%p\n",
TIMER_DPRINTF("%s set_count count=0x%016lx (npt %s) p=%p\n",
timer->name, real_count,
timer->disabled?"disabled":"enabled", timer);
timer->npt ? "disabled" : "enabled", timer);
timer->disabled = disabled_bit ? 1 : 0;
timer->npt = npt_bit ? 1 : 0;
timer->clock_offset = vm_clock_offset;
}
@@ -514,12 +520,13 @@ uint64_t cpu_tick_get_count(CPUTimer *timer)
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - timer->clock_offset,
timer->frequency);
TIMER_DPRINTF("%s get_count count=0x%016lx (%s) p=%p\n",
TIMER_DPRINTF("%s get_count count=0x%016lx (npt %s) p=%p\n",
timer->name, real_count,
timer->disabled?"disabled":"enabled", timer);
timer->npt ? "disabled" : "enabled", timer);
if (timer->disabled)
real_count |= timer->disabled_mask;
if (timer->npt) {
real_count |= timer->npt_mask;
}
return real_count;
}
@@ -799,13 +806,16 @@ static SPARCCPU *cpu_devinit(const char *cpu_model, const struct hwdef *hwdef)
env = &cpu->env;
env->tick = cpu_timer_create("tick", cpu, tick_irq,
tick_frequency, TICK_NPT_MASK);
tick_frequency, TICK_INT_DIS,
TICK_NPT_MASK);
env->stick = cpu_timer_create("stick", cpu, stick_irq,
stick_frequency, TICK_INT_DIS);
stick_frequency, TICK_INT_DIS,
TICK_NPT_MASK);
env->hstick = cpu_timer_create("hstick", cpu, hstick_irq,
hstick_frequency, TICK_INT_DIS);
hstick_frequency, TICK_INT_DIS,
TICK_NPT_MASK);
reset_info = g_malloc0(sizeof(ResetData));
reset_info->cpu = cpu;

View File

@@ -30,6 +30,21 @@
#define GUI_REFRESH_INTERVAL_DEFAULT 30
#define GUI_REFRESH_INTERVAL_IDLE 3000
/* Color number is match to standard vga palette */
enum qemu_color_names {
QEMU_COLOR_BLACK = 0,
QEMU_COLOR_BLUE = 1,
QEMU_COLOR_GREEN = 2,
QEMU_COLOR_CYAN = 3,
QEMU_COLOR_RED = 4,
QEMU_COLOR_MAGENTA = 5,
QEMU_COLOR_YELLOW = 6,
QEMU_COLOR_WHITE = 7
};
/* Convert to curses char attributes */
#define ATTR2CHTYPE(c, fg, bg, bold) \
((bold) << 21 | (bg) << 11 | (fg) << 8 | (c))
typedef void QEMUPutKBDEvent(void *opaque, int keycode);
typedef void QEMUPutLEDEvent(void *opaque, int ledstate);
typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state);

View File

@@ -15,12 +15,18 @@ struct sdl2_console {
SDL_Renderer *real_renderer;
int idx;
int last_vm_running; /* per console for caption reasons */
int x, y;
int x, y, w, h;
int hidden;
int opengl;
int updates;
SDL_GLContext winctx;
#ifdef CONFIG_OPENGL
ConsoleGLState *gls;
GLuint tex_id;
GLuint fbo_id;
bool y0_top;
bool scanout_mode;
#endif
};
void sdl2_window_create(struct sdl2_console *scon);
@@ -48,4 +54,18 @@ void sdl2_gl_switch(DisplayChangeListener *dcl,
void sdl2_gl_refresh(DisplayChangeListener *dcl);
void sdl2_gl_redraw(struct sdl2_console *scon);
QEMUGLContext sdl2_gl_create_context(DisplayChangeListener *dcl,
QEMUGLParams *params);
void sdl2_gl_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx);
int sdl2_gl_make_context_current(DisplayChangeListener *dcl,
QEMUGLContext ctx);
QEMUGLContext sdl2_gl_get_current_context(DisplayChangeListener *dcl);
void sdl2_gl_scanout(DisplayChangeListener *dcl,
uint32_t backing_id, bool backing_y_0_top,
uint32_t x, uint32_t y,
uint32_t w, uint32_t h);
void sdl2_gl_scanout_flush(DisplayChangeListener *dcl,
uint32_t x, uint32_t y, uint32_t w, uint32_t h);
#endif /* SDL2_H */

View File

@@ -366,6 +366,8 @@ struct CPUTimer
uint32_t frequency;
uint32_t disabled;
uint64_t disabled_mask;
uint32_t npt;
uint64_t npt_mask;
int64_t clock_offset;
QEMUTimer *qtimer;
};

View File

@@ -51,10 +51,16 @@ void helper_tick_set_count(void *opaque, uint64_t count)
#endif
}
uint64_t helper_tick_get_count(void *opaque)
uint64_t helper_tick_get_count(CPUSPARCState *env, void *opaque, int mem_idx)
{
#if !defined(CONFIG_USER_ONLY)
return cpu_tick_get_count(opaque);
CPUTimer *timer = opaque;
if (timer->npt && mem_idx < MMU_KERNEL_IDX) {
helper_raise_exception(env, TT_PRIV_INSN);
}
return cpu_tick_get_count(timer);
#else
return 0;
#endif

View File

@@ -25,7 +25,7 @@ DEF_HELPER_2(set_softint, void, env, i64)
DEF_HELPER_2(clear_softint, void, env, i64)
DEF_HELPER_2(write_softint, void, env, i64)
DEF_HELPER_2(tick_set_count, void, ptr, i64)
DEF_HELPER_1(tick_get_count, i64, ptr)
DEF_HELPER_3(tick_get_count, i64, env, ptr, int)
DEF_HELPER_2(tick_set_limit, void, ptr, i64)
#endif
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)

View File

@@ -2708,12 +2708,16 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
case 0x4: /* V9 rdtick */
{
TCGv_ptr r_tickptr;
TCGv_i32 r_const;
r_tickptr = tcg_temp_new_ptr();
r_const = tcg_const_i32(dc->mem_idx);
tcg_gen_ld_ptr(r_tickptr, cpu_env,
offsetof(CPUSPARCState, tick));
gen_helper_tick_get_count(cpu_dst, r_tickptr);
gen_helper_tick_get_count(cpu_dst, cpu_env, r_tickptr,
r_const);
tcg_temp_free_ptr(r_tickptr);
tcg_temp_free_i32(r_const);
gen_store_gpr(dc, rd, cpu_dst);
}
break;
@@ -2750,12 +2754,16 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
case 0x18: /* System tick */
{
TCGv_ptr r_tickptr;
TCGv_i32 r_const;
r_tickptr = tcg_temp_new_ptr();
r_const = tcg_const_i32(dc->mem_idx);
tcg_gen_ld_ptr(r_tickptr, cpu_env,
offsetof(CPUSPARCState, stick));
gen_helper_tick_get_count(cpu_dst, r_tickptr);
gen_helper_tick_get_count(cpu_dst, cpu_env, r_tickptr,
r_const);
tcg_temp_free_ptr(r_tickptr);
tcg_temp_free_i32(r_const);
gen_store_gpr(dc, rd, cpu_dst);
}
break;
@@ -2863,12 +2871,16 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
case 4: // tick
{
TCGv_ptr r_tickptr;
TCGv_i32 r_const;
r_tickptr = tcg_temp_new_ptr();
r_const = tcg_const_i32(dc->mem_idx);
tcg_gen_ld_ptr(r_tickptr, cpu_env,
offsetof(CPUSPARCState, tick));
gen_helper_tick_get_count(cpu_tmp0, r_tickptr);
gen_helper_tick_get_count(cpu_tmp0, cpu_env,
r_tickptr, r_const);
tcg_temp_free_ptr(r_tickptr);
tcg_temp_free_i32(r_const);
}
break;
case 5: // tba

View File

@@ -59,6 +59,9 @@ virtio_console_chr_event(unsigned int port, int event) "port %u, event %d"
# block.c
bdrv_open_common(void *bs, const char *filename, int flags, const char *format_name) "bs %p filename \"%s\" flags %#x format_name \"%s\""
bdrv_lock_medium(void *bs, bool locked) "bs %p locked %d"
# block/io.c
multiwrite_cb(void *mcb, int ret) "mcb %p ret %d"
bdrv_aio_multiwrite(void *mcb, int num_callbacks, int num_reqs) "mcb %p num_callbacks %d num_reqs %d"
bdrv_aio_discard(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
@@ -66,7 +69,6 @@ bdrv_aio_flush(void *bs, void *opaque) "bs %p opaque %p"
bdrv_aio_readv(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
bdrv_aio_writev(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
bdrv_aio_write_zeroes(void *bs, int64_t sector_num, int nb_sectors, int flags, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d flags %#x opaque %p"
bdrv_lock_medium(void *bs, bool locked) "bs %p locked %d"
bdrv_co_readv(void *bs, int64_t sector_num, int nb_sector) "bs %p sector_num %"PRId64" nb_sectors %d"
bdrv_co_copy_on_readv(void *bs, int64_t sector_num, int nb_sector) "bs %p sector_num %"PRId64" nb_sectors %d"
bdrv_co_readv_no_serialising(void *bs, int64_t sector_num, int nb_sector) "bs %p sector_num %"PRId64" nb_sectors %d"
@@ -1799,15 +1801,15 @@ qcrypto_tls_session_new(void *session, void *creds, const char *hostname, const
vhost_user_event(const char *chr, int event) "chr: %s got event: %d"
# linux-user/signal.c
user_setup_frame(void *env, uint64_t frame_addr) "env=%p frame_addr="PRIx64""
user_setup_rt_frame(void *env, uint64_t frame_addr) "env=%p frame_addr="PRIx64""
user_do_rt_sigreturn(void *env, uint64_t frame_addr) "env=%p frame_addr="PRIx64""
user_do_sigreturn(void *env, uint64_t frame_addr) "env=%p frame_addr="PRIx64""
user_setup_frame(void *env, uint64_t frame_addr) "env=%p frame_addr=%"PRIx64""
user_setup_rt_frame(void *env, uint64_t frame_addr) "env=%p frame_addr=%"PRIx64""
user_do_rt_sigreturn(void *env, uint64_t frame_addr) "env=%p frame_addr=%"PRIx64""
user_do_sigreturn(void *env, uint64_t frame_addr) "env=%p frame_addr=%"PRIx64""
user_force_sig(void *env, int target_sig, int host_sig) "env=%p signal %d (host %d)"
user_handle_signal(void *env, int target_sig) "env=%p signal %d"
user_host_signal(void *env, int host_sig, int target_sig) "env=%p signal %d (target %d("
user_queue_signal(void *env, int target_sig) "env=%p signal %d"
user_s390x_restore_sigregs(void *env, uint64_t sc_psw_addr, uint64_t env_psw_addr) "env=%p frame psw.addr "PRIx64 " current psw.addr "PRIx64""
user_s390x_restore_sigregs(void *env, uint64_t sc_psw_addr, uint64_t env_psw_addr) "env=%p frame psw.addr %"PRIx64 " current psw.addr %"PRIx64""
# io/task.c
qio_task_new(void *task, void *source, void *func, void *opaque) "Task new task=%p source=%p func=%p opaque=%p"

View File

@@ -1,24 +1,32 @@
# -*- mode: makefile -*-
######################################################################
# tracetool source files
# Every rule that invokes tracetool must depend on this so code is regenerated
# if tracetool itself changes.
tracetool-y = $(SRC_PATH)/scripts/tracetool.py
tracetool-y += $(shell find $(SRC_PATH)/scripts/tracetool -name "*.py")
######################################################################
# Auto-generated event descriptions for LTTng ust code
ifeq ($(findstring ust,$(TRACE_BACKENDS)),ust)
$(obj)/generated-ust-provider.h: $(obj)/generated-ust-provider.h-timestamp
$(obj)/generated-ust-provider.h-timestamp: $(SRC_PATH)/trace-events
@cmp $< $@ >/dev/null 2>&1 || cp $< $@
$(obj)/generated-ust-provider.h-timestamp: $(SRC_PATH)/trace-events $(tracetool-y)
$(call quiet-command,$(TRACETOOL) \
--format=ust-events-h \
--backends=$(TRACE_BACKENDS) \
< $< > $@," GEN $(patsubst %-timestamp,%,$@)")
@cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
$(obj)/generated-ust.c: $(obj)/generated-ust.c-timestamp $(BUILD_DIR)/config-host.mak
$(obj)/generated-ust.c-timestamp: $(SRC_PATH)/trace-events
@cmp $< $@ >/dev/null 2>&1 || cp $< $@
$(obj)/generated-ust.c-timestamp: $(SRC_PATH)/trace-events $(tracetool-y)
$(call quiet-command,$(TRACETOOL) \
--format=ust-events-c \
--backends=$(TRACE_BACKENDS) \
< $< > $@," GEN $(patsubst %-timestamp,%,$@)")
@cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
$(obj)/generated-events.h: $(obj)/generated-ust-provider.h
$(obj)/generated-events.c: $(obj)/generated-ust.c
@@ -28,20 +36,20 @@ endif
# Auto-generated event descriptions
$(obj)/generated-events.h: $(obj)/generated-events.h-timestamp
$(obj)/generated-events.h-timestamp: $(SRC_PATH)/trace-events
@cmp $< $@ >/dev/null 2>&1 || cp $< $@
$(obj)/generated-events.h-timestamp: $(SRC_PATH)/trace-events $(tracetool-y)
$(call quiet-command,$(TRACETOOL) \
--format=events-h \
--backends=$(TRACE_BACKENDS) \
< $< > $@," GEN $(patsubst %-timestamp,%,$@)")
@cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
$(obj)/generated-events.c: $(obj)/generated-events.c-timestamp $(BUILD_DIR)/config-host.mak
$(obj)/generated-events.c-timestamp: $(SRC_PATH)/trace-events
@cmp $< $@ >/dev/null 2>&1 || cp $< $@
$(obj)/generated-events.c-timestamp: $(SRC_PATH)/trace-events $(tracetool-y)
$(call quiet-command,$(TRACETOOL) \
--format=events-c \
--backends=$(TRACE_BACKENDS) \
< $< > $@," GEN $(patsubst %-timestamp,%,$@)")
@cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
util-obj-y += generated-events.o
@@ -54,7 +62,7 @@ util-obj-y += generated-events.o
$(obj)/generated-tracers.h: $(obj)/generated-tracers.h-timestamp
@cmp -s $< $@ || cp $< $@
$(obj)/generated-tracers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
$(obj)/generated-tracers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y)
$(call quiet-command,$(TRACETOOL) \
--format=h \
--backends=$(TRACE_BACKENDS) \
@@ -65,7 +73,7 @@ $(obj)/generated-tracers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/conf
$(obj)/generated-tracers.c: $(obj)/generated-tracers.c-timestamp
@cmp -s $< $@ || cp $< $@
$(obj)/generated-tracers.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
$(obj)/generated-tracers.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y)
$(call quiet-command,$(TRACETOOL) \
--format=c \
--backends=$(TRACE_BACKENDS) \
@@ -81,12 +89,12 @@ $(obj)/generated-tracers.o: $(obj)/generated-tracers.c $(obj)/generated-tracers.
# rule file. So we use '.dtrace' instead
ifeq ($(findstring dtrace,$(TRACE_BACKENDS)),dtrace)
$(obj)/generated-tracers-dtrace.dtrace: $(obj)/generated-tracers-dtrace.dtrace-timestamp
$(obj)/generated-tracers-dtrace.dtrace-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
@cmp $< $@ >/dev/null 2>&1 || cp $< $@
$(obj)/generated-tracers-dtrace.dtrace-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y)
$(call quiet-command,$(TRACETOOL) \
--format=d \
--backends=$(TRACE_BACKENDS) \
< $< > $@," GEN $(patsubst %-timestamp,%,$@)")
@cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
$(obj)/generated-tracers-dtrace.h: $(obj)/generated-tracers-dtrace.dtrace
$(call quiet-command,dtrace -o $@ -h -s $<, " GEN $@")
@@ -100,28 +108,28 @@ endif
# Translation level
$(obj)/generated-helpers-wrappers.h: $(obj)/generated-helpers-wrappers.h-timestamp
$(obj)/generated-helpers-wrappers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
@cmp $< $@ >/dev/null 2>&1 || cp $< $@
$(obj)/generated-helpers-wrappers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y)
$(call quiet-command,$(TRACETOOL) \
--format=tcg-helper-wrapper-h \
--backend=$(TRACE_BACKENDS) \
< $< > $@," GEN $(patsubst %-timestamp,%,$@)")
@cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
$(obj)/generated-helpers.h: $(obj)/generated-helpers.h-timestamp
$(obj)/generated-helpers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
@cmp $< $@ >/dev/null 2>&1 || cp $< $@
$(obj)/generated-helpers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y)
$(call quiet-command,$(TRACETOOL) \
--format=tcg-helper-h \
--backend=$(TRACE_BACKENDS) \
< $< > $@," GEN $(patsubst %-timestamp,%,$@)")
@cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
$(obj)/generated-helpers.c: $(obj)/generated-helpers.c-timestamp
$(obj)/generated-helpers.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
@cmp $< $@ >/dev/null 2>&1 || cp $< $@
$(obj)/generated-helpers.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y)
$(call quiet-command,$(TRACETOOL) \
--format=tcg-helper-c \
--backend=$(TRACE_BACKENDS) \
< $< > $@," GEN $(patsubst %-timestamp,%,$@)")
@cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
$(obj)/generated-helpers.o: $(obj)/generated-helpers.c
@@ -129,12 +137,12 @@ target-obj-y += generated-helpers.o
$(obj)/generated-tcg-tracers.h: $(obj)/generated-tcg-tracers.h-timestamp
$(obj)/generated-tcg-tracers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
@cmp $< $@ >/dev/null 2>&1 || cp $< $@
$(obj)/generated-tcg-tracers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y)
$(call quiet-command,$(TRACETOOL) \
--format=tcg-h \
--backend=$(TRACE_BACKENDS) \
< $< > $@," GEN $(patsubst %-timestamp,%,$@)")
@cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
######################################################################

View File

@@ -376,42 +376,29 @@ static void vga_bitblt(QemuConsole *con,
#include "vgafont.h"
#ifndef CONFIG_CURSES
enum color_names {
COLOR_BLACK = 0,
COLOR_RED = 1,
COLOR_GREEN = 2,
COLOR_YELLOW = 3,
COLOR_BLUE = 4,
COLOR_MAGENTA = 5,
COLOR_CYAN = 6,
COLOR_WHITE = 7
};
#endif
#define QEMU_RGB(r, g, b) \
{ .red = r << 8, .green = g << 8, .blue = b << 8, .alpha = 0xffff }
static const pixman_color_t color_table_rgb[2][8] = {
{ /* dark */
QEMU_RGB(0x00, 0x00, 0x00), /* black */
QEMU_RGB(0xaa, 0x00, 0x00), /* red */
QEMU_RGB(0x00, 0xaa, 0x00), /* green */
QEMU_RGB(0xaa, 0xaa, 0x00), /* yellow */
QEMU_RGB(0x00, 0x00, 0xaa), /* blue */
QEMU_RGB(0xaa, 0x00, 0xaa), /* magenta */
QEMU_RGB(0x00, 0xaa, 0xaa), /* cyan */
QEMU_RGB(0xaa, 0xaa, 0xaa), /* white */
[QEMU_COLOR_BLACK] = QEMU_RGB(0x00, 0x00, 0x00), /* black */
[QEMU_COLOR_BLUE] = QEMU_RGB(0x00, 0x00, 0xaa), /* blue */
[QEMU_COLOR_GREEN] = QEMU_RGB(0x00, 0xaa, 0x00), /* green */
[QEMU_COLOR_CYAN] = QEMU_RGB(0x00, 0xaa, 0xaa), /* cyan */
[QEMU_COLOR_RED] = QEMU_RGB(0xaa, 0x00, 0x00), /* red */
[QEMU_COLOR_MAGENTA] = QEMU_RGB(0xaa, 0x00, 0xaa), /* magenta */
[QEMU_COLOR_YELLOW] = QEMU_RGB(0xaa, 0xaa, 0x00), /* yellow */
[QEMU_COLOR_WHITE] = QEMU_RGB(0xaa, 0xaa, 0xaa), /* white */
},
{ /* bright */
QEMU_RGB(0x00, 0x00, 0x00), /* black */
QEMU_RGB(0xff, 0x00, 0x00), /* red */
QEMU_RGB(0x00, 0xff, 0x00), /* green */
QEMU_RGB(0xff, 0xff, 0x00), /* yellow */
QEMU_RGB(0x00, 0x00, 0xff), /* blue */
QEMU_RGB(0xff, 0x00, 0xff), /* magenta */
QEMU_RGB(0x00, 0xff, 0xff), /* cyan */
QEMU_RGB(0xff, 0xff, 0xff), /* white */
[QEMU_COLOR_BLACK] = QEMU_RGB(0x00, 0x00, 0x00), /* black */
[QEMU_COLOR_BLUE] = QEMU_RGB(0x00, 0x00, 0xff), /* blue */
[QEMU_COLOR_GREEN] = QEMU_RGB(0x00, 0xff, 0x00), /* green */
[QEMU_COLOR_CYAN] = QEMU_RGB(0x00, 0xff, 0xff), /* cyan */
[QEMU_COLOR_RED] = QEMU_RGB(0xff, 0x00, 0x00), /* red */
[QEMU_COLOR_MAGENTA] = QEMU_RGB(0xff, 0x00, 0xff), /* magenta */
[QEMU_COLOR_YELLOW] = QEMU_RGB(0xff, 0xff, 0x00), /* yellow */
[QEMU_COLOR_WHITE] = QEMU_RGB(0xff, 0xff, 0xff), /* white */
}
};
@@ -560,7 +547,7 @@ static void console_refresh(QemuConsole *s)
}
vga_fill_rect(s, 0, 0, surface_width(surface), surface_height(surface),
color_table_rgb[0][COLOR_BLACK]);
color_table_rgb[0][QEMU_COLOR_BLACK]);
y1 = s->y_displayed;
for (y = 0; y < s->height; y++) {
c = s->cells + y1 * s->width;
@@ -698,53 +685,53 @@ static void console_handle_escape(QemuConsole *s)
break;
/* set foreground color */
case 30:
s->t_attrib.fgcol=COLOR_BLACK;
s->t_attrib.fgcol = QEMU_COLOR_BLACK;
break;
case 31:
s->t_attrib.fgcol=COLOR_RED;
s->t_attrib.fgcol = QEMU_COLOR_RED;
break;
case 32:
s->t_attrib.fgcol=COLOR_GREEN;
s->t_attrib.fgcol = QEMU_COLOR_GREEN;
break;
case 33:
s->t_attrib.fgcol=COLOR_YELLOW;
s->t_attrib.fgcol = QEMU_COLOR_YELLOW;
break;
case 34:
s->t_attrib.fgcol=COLOR_BLUE;
s->t_attrib.fgcol = QEMU_COLOR_BLUE;
break;
case 35:
s->t_attrib.fgcol=COLOR_MAGENTA;
s->t_attrib.fgcol = QEMU_COLOR_MAGENTA;
break;
case 36:
s->t_attrib.fgcol=COLOR_CYAN;
s->t_attrib.fgcol = QEMU_COLOR_CYAN;
break;
case 37:
s->t_attrib.fgcol=COLOR_WHITE;
s->t_attrib.fgcol = QEMU_COLOR_WHITE;
break;
/* set background color */
case 40:
s->t_attrib.bgcol=COLOR_BLACK;
s->t_attrib.bgcol = QEMU_COLOR_BLACK;
break;
case 41:
s->t_attrib.bgcol=COLOR_RED;
s->t_attrib.bgcol = QEMU_COLOR_RED;
break;
case 42:
s->t_attrib.bgcol=COLOR_GREEN;
s->t_attrib.bgcol = QEMU_COLOR_GREEN;
break;
case 43:
s->t_attrib.bgcol=COLOR_YELLOW;
s->t_attrib.bgcol = QEMU_COLOR_YELLOW;
break;
case 44:
s->t_attrib.bgcol=COLOR_BLUE;
s->t_attrib.bgcol = QEMU_COLOR_BLUE;
break;
case 45:
s->t_attrib.bgcol=COLOR_MAGENTA;
s->t_attrib.bgcol = QEMU_COLOR_MAGENTA;
break;
case 46:
s->t_attrib.bgcol=COLOR_CYAN;
s->t_attrib.bgcol = QEMU_COLOR_CYAN;
break;
case 47:
s->t_attrib.bgcol=COLOR_WHITE;
s->t_attrib.bgcol = QEMU_COLOR_WHITE;
break;
}
}
@@ -1165,11 +1152,13 @@ static void text_console_update(void *opaque, console_ch_t *chardata)
src = (s->y_base + s->text_y[0]) * s->width;
chardata += s->text_y[0] * s->width;
for (i = s->text_y[0]; i <= s->text_y[1]; i ++)
for (j = 0; j < s->width; j ++, src ++)
console_write_ch(chardata ++, s->cells[src].ch |
(s->cells[src].t_attrib.fgcol << 12) |
(s->cells[src].t_attrib.bgcol << 8) |
(s->cells[src].t_attrib.bold << 21));
for (j = 0; j < s->width; j++, src++) {
console_write_ch(chardata ++,
ATTR2CHTYPE(s->cells[src].ch,
s->cells[src].t_attrib.fgcol,
s->cells[src].t_attrib.bgcol,
s->cells[src].t_attrib.bold));
}
dpy_text_update(s, s->text_x[0], s->text_y[0],
s->text_x[1] - s->text_x[0], i - s->text_y[0]);
s->text_x[0] = s->width;
@@ -1306,8 +1295,8 @@ static DisplaySurface *qemu_create_message_surface(int w, int h,
const char *msg)
{
DisplaySurface *surface = qemu_create_displaysurface(w, h);
pixman_color_t bg = color_table_rgb[0][COLOR_BLACK];
pixman_color_t fg = color_table_rgb[0][COLOR_WHITE];
pixman_color_t bg = color_table_rgb[0][QEMU_COLOR_BLACK];
pixman_color_t fg = color_table_rgb[0][QEMU_COLOR_WHITE];
pixman_image_t *glyph;
int len, x, y, i;
@@ -1941,8 +1930,8 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
s->t_attrib_default.blink = 0;
s->t_attrib_default.invers = 0;
s->t_attrib_default.unvisible = 0;
s->t_attrib_default.fgcol = COLOR_WHITE;
s->t_attrib_default.bgcol = COLOR_BLACK;
s->t_attrib_default.fgcol = QEMU_COLOR_WHITE;
s->t_attrib_default.bgcol = QEMU_COLOR_BLACK;
/* set current text attributes to default */
s->t_attrib = s->t_attrib_default;
text_console_resize(s);
@@ -1951,7 +1940,7 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
char msg[128];
int len;
s->t_attrib.bgcol = COLOR_BLUE;
s->t_attrib.bgcol = QEMU_COLOR_BLUE;
len = snprintf(msg, sizeof(msg), "%s console\r\n", chr->label);
console_puts(chr, (uint8_t*)msg, len);
s->t_attrib = s->t_attrib_default;

View File

@@ -333,8 +333,14 @@ static void curses_atexit(void)
static void curses_setup(void)
{
int i, colour_default[8] = {
COLOR_BLACK, COLOR_BLUE, COLOR_GREEN, COLOR_CYAN,
COLOR_RED, COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE,
[QEMU_COLOR_BLACK] = COLOR_BLACK,
[QEMU_COLOR_BLUE] = COLOR_BLUE,
[QEMU_COLOR_GREEN] = COLOR_GREEN,
[QEMU_COLOR_CYAN] = COLOR_CYAN,
[QEMU_COLOR_RED] = COLOR_RED,
[QEMU_COLOR_MAGENTA] = COLOR_MAGENTA,
[QEMU_COLOR_YELLOW] = COLOR_YELLOW,
[QEMU_COLOR_WHITE] = COLOR_WHITE,
};
/* input as raw as possible, let everything be interpreted
@@ -343,10 +349,11 @@ static void curses_setup(void)
nodelay(stdscr, TRUE); nonl(); keypad(stdscr, TRUE);
start_color(); raw(); scrollok(stdscr, FALSE);
/* Make color pair to match color format (3bits bg:3bits fg) */
for (i = 0; i < 64; i++) {
init_pair(i, colour_default[i & 7], colour_default[i >> 3]);
}
/* Set default color for more than 64. (monitor uses 0x74xx for example) */
/* Set default color for more than 64 for safety. */
for (i = 64; i < COLOR_PAIRS; i++) {
init_pair(i, COLOR_WHITE, COLOR_BLACK);
}

View File

@@ -31,11 +31,37 @@
#include "ui/sdl2.h"
#include "sysemu/sysemu.h"
#include <epoxy/gl.h>
static void sdl2_set_scanout_mode(struct sdl2_console *scon, bool scanout)
{
if (scon->scanout_mode == scanout) {
return;
}
scon->scanout_mode = scanout;
if (!scon->scanout_mode) {
if (scon->fbo_id) {
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, 0, 0);
glDeleteFramebuffers(1, &scon->fbo_id);
glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
scon->fbo_id = 0;
}
if (scon->surface) {
surface_gl_destroy_texture(scon->gls, scon->surface);
surface_gl_create_texture(scon->gls, scon->surface);
}
}
}
static void sdl2_gl_render_surface(struct sdl2_console *scon)
{
int ww, wh;
SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
sdl2_set_scanout_mode(scon, false);
SDL_GetWindowSize(scon->real_window, &ww, &wh);
surface_gl_setup_viewport(scon->gls, scon->surface, ww, wh);
@@ -110,3 +136,112 @@ void sdl2_gl_redraw(struct sdl2_console *scon)
sdl2_gl_render_surface(scon);
}
}
QEMUGLContext sdl2_gl_create_context(DisplayChangeListener *dcl,
QEMUGLParams *params)
{
struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
SDL_GLContext ctx;
assert(scon->opengl);
SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, params->major_ver);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, params->minor_ver);
ctx = SDL_GL_CreateContext(scon->real_window);
return (QEMUGLContext)ctx;
}
void sdl2_gl_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx)
{
SDL_GLContext sdlctx = (SDL_GLContext)ctx;
SDL_GL_DeleteContext(sdlctx);
}
int sdl2_gl_make_context_current(DisplayChangeListener *dcl,
QEMUGLContext ctx)
{
struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
SDL_GLContext sdlctx = (SDL_GLContext)ctx;
assert(scon->opengl);
return SDL_GL_MakeCurrent(scon->real_window, sdlctx);
}
QEMUGLContext sdl2_gl_get_current_context(DisplayChangeListener *dcl)
{
SDL_GLContext sdlctx;
sdlctx = SDL_GL_GetCurrentContext();
return (QEMUGLContext)sdlctx;
}
void sdl2_gl_scanout(DisplayChangeListener *dcl,
uint32_t backing_id, bool backing_y_0_top,
uint32_t x, uint32_t y,
uint32_t w, uint32_t h)
{
struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
assert(scon->opengl);
scon->x = x;
scon->y = y;
scon->w = w;
scon->h = h;
scon->tex_id = backing_id;
scon->y0_top = backing_y_0_top;
SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
if (scon->tex_id == 0 || scon->w == 0 || scon->h == 0) {
sdl2_set_scanout_mode(scon, false);
return;
}
sdl2_set_scanout_mode(scon, true);
if (!scon->fbo_id) {
glGenFramebuffers(1, &scon->fbo_id);
}
glBindFramebuffer(GL_FRAMEBUFFER_EXT, scon->fbo_id);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, scon->tex_id, 0);
}
void sdl2_gl_scanout_flush(DisplayChangeListener *dcl,
uint32_t x, uint32_t y, uint32_t w, uint32_t h)
{
struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
int ww, wh, y1, y2;
assert(scon->opengl);
if (!scon->scanout_mode) {
return;
}
if (!scon->fbo_id) {
return;
}
SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
glBindFramebuffer(GL_READ_FRAMEBUFFER, scon->fbo_id);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
SDL_GetWindowSize(scon->real_window, &ww, &wh);
glViewport(0, 0, ww, wh);
y1 = scon->y0_top ? 0 : scon->h;
y2 = scon->y0_top ? scon->h : 0;
glBlitFramebuffer(0, y1, scon->w, y2,
0, 0, ww, wh,
GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_FRAMEBUFFER_EXT, scon->fbo_id);
SDL_GL_SwapWindow(scon->real_window);
}

View File

@@ -700,6 +700,13 @@ static const DisplayChangeListenerOps dcl_gl_ops = {
.dpy_refresh = sdl2_gl_refresh,
.dpy_mouse_set = sdl_mouse_warp,
.dpy_cursor_define = sdl_mouse_define,
.dpy_gl_ctx_create = sdl2_gl_create_context,
.dpy_gl_ctx_destroy = sdl2_gl_destroy_context,
.dpy_gl_ctx_make_current = sdl2_gl_make_context_current,
.dpy_gl_ctx_get_current = sdl2_gl_get_current_context,
.dpy_gl_scanout = sdl2_gl_scanout,
.dpy_gl_update = sdl2_gl_scanout_flush,
};
#endif