cirrus: blitter fixes.
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJYylVSAAoJEEy22O7T6HE4zzkQALxdIoO2Na1+iLqumzZHBl5y czfhtiu9jIZPYs2n7d04LJklnJxNA+3whvculwyVQprXmjwA/WCFPM7gPerI8AMC sNTqH5VhyIU+CljNUFV5nJXmrNpwd2os0rGwkIAohgyXgt7le5fyIpw4QcGr0b7m quFP3sVQXGp0LjPKwSwzHDrtXjHS4vvsxUFEdXbqoFIsCXjCmIRM4DK2g6XyQZMA ttFEWQTN0jRinR4s2aptbzLZp04GxUutw01EEWfavcwZg3MtWJtUuYOT5eObhd2T yustoBBakxBaAvIcWY+MIXQFHD7tHjnKgjJLOJTxa12psGTZYmpwavAq/SmXT1RL PggJpnsnEqodkeiX3VeNelMo0HDWOzrezpDbQLya5kNE/puS3r8tglVO4d6CVJYN 0gzgkT5b4to5FbJkYfoSjZ0SFfAqFkXC5v5/xc9bHbc+EKTp+K7bkB0Z9X2c82Qh HTdwOdTL6mB+GqOwPAUHBGfiwcZ/uMPW1sedUBYzrWEGeOa76oXj5mDa3cx5po1g rzi0dlgTrzXIsmcOr6z2Q8Mk8FEGl6awvXmtAvF6SY1cRHBRYPUw9KMRvwCgkqr0 ldn8kY03n/ZQMVLETQbsWq68/E3hea8id4QSFLu0OxC7zi6ruloGnDrUUeRYnjXX atBgO7G+482f/m5Jvt/G =iKnI -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/kraxel/tags/pull-cirrus-20170316-1' into staging cirrus: blitter fixes. # gpg: Signature made Thu 16 Mar 2017 09:05:22 GMT # gpg: using RSA key 0x4CB6D8EED3E87138 # 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>" # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * remotes/kraxel/tags/pull-cirrus-20170316-1: cirrus: stop passing around src pointers in the blitter cirrus: stop passing around dst pointers in the blitter cirrus: fix cirrus_invalidate_region cirrus: add option to disable blitter cirrus: switch to 4 MB video memory by default cirrus/vnc: zap bitblit support from console code. fix :cirrus_vga fix OOB read case qemu Segmentation fault # Conflicts: # include/hw/compat.h Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
272d7dee59
@ -178,11 +178,12 @@
|
|||||||
|
|
||||||
struct CirrusVGAState;
|
struct CirrusVGAState;
|
||||||
typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s,
|
typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s,
|
||||||
uint8_t * dst, const uint8_t * src,
|
uint32_t dstaddr, uint32_t srcaddr,
|
||||||
int dstpitch, int srcpitch,
|
int dstpitch, int srcpitch,
|
||||||
int bltwidth, int bltheight);
|
int bltwidth, int bltheight);
|
||||||
typedef void (*cirrus_fill_t)(struct CirrusVGAState *s,
|
typedef void (*cirrus_fill_t)(struct CirrusVGAState *s,
|
||||||
uint8_t *dst, int dst_pitch, int width, int height);
|
uint32_t dstaddr, int dst_pitch,
|
||||||
|
int width, int height);
|
||||||
|
|
||||||
typedef struct CirrusVGAState {
|
typedef struct CirrusVGAState {
|
||||||
VGACommonState vga;
|
VGACommonState vga;
|
||||||
@ -205,6 +206,7 @@ typedef struct CirrusVGAState {
|
|||||||
uint32_t cirrus_bank_base[2];
|
uint32_t cirrus_bank_base[2];
|
||||||
uint32_t cirrus_bank_limit[2];
|
uint32_t cirrus_bank_limit[2];
|
||||||
uint8_t cirrus_hidden_palette[48];
|
uint8_t cirrus_hidden_palette[48];
|
||||||
|
bool enable_blitter;
|
||||||
int cirrus_blt_pixelwidth;
|
int cirrus_blt_pixelwidth;
|
||||||
int cirrus_blt_width;
|
int cirrus_blt_width;
|
||||||
int cirrus_blt_height;
|
int cirrus_blt_height;
|
||||||
@ -320,18 +322,57 @@ static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void cirrus_bitblt_rop_nop(CirrusVGAState *s,
|
static void cirrus_bitblt_rop_nop(CirrusVGAState *s,
|
||||||
uint8_t *dst,const uint8_t *src,
|
uint32_t dstaddr, uint32_t srcaddr,
|
||||||
int dstpitch,int srcpitch,
|
int dstpitch,int srcpitch,
|
||||||
int bltwidth,int bltheight)
|
int bltwidth,int bltheight)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cirrus_bitblt_fill_nop(CirrusVGAState *s,
|
static void cirrus_bitblt_fill_nop(CirrusVGAState *s,
|
||||||
uint8_t *dst,
|
uint32_t dstaddr,
|
||||||
int dstpitch, int bltwidth,int bltheight)
|
int dstpitch, int bltwidth,int bltheight)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint8_t cirrus_src(CirrusVGAState *s, uint32_t srcaddr)
|
||||||
|
{
|
||||||
|
if (s->cirrus_srccounter) {
|
||||||
|
/* cputovideo */
|
||||||
|
return s->cirrus_bltbuf[srcaddr & (CIRRUS_BLTBUFSIZE - 1)];
|
||||||
|
} else {
|
||||||
|
/* videotovideo */
|
||||||
|
return s->vga.vram_ptr[srcaddr & s->cirrus_addr_mask];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint16_t cirrus_src16(CirrusVGAState *s, uint32_t srcaddr)
|
||||||
|
{
|
||||||
|
uint16_t *src;
|
||||||
|
|
||||||
|
if (s->cirrus_srccounter) {
|
||||||
|
/* cputovideo */
|
||||||
|
src = (void *)&s->cirrus_bltbuf[srcaddr & (CIRRUS_BLTBUFSIZE - 1) & ~1];
|
||||||
|
} else {
|
||||||
|
/* videotovideo */
|
||||||
|
src = (void *)&s->vga.vram_ptr[srcaddr & s->cirrus_addr_mask & ~1];
|
||||||
|
}
|
||||||
|
return *src;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t cirrus_src32(CirrusVGAState *s, uint32_t srcaddr)
|
||||||
|
{
|
||||||
|
uint32_t *src;
|
||||||
|
|
||||||
|
if (s->cirrus_srccounter) {
|
||||||
|
/* cputovideo */
|
||||||
|
src = (void *)&s->cirrus_bltbuf[srcaddr & (CIRRUS_BLTBUFSIZE - 1) & ~3];
|
||||||
|
} else {
|
||||||
|
/* videotovideo */
|
||||||
|
src = (void *)&s->vga.vram_ptr[srcaddr & s->cirrus_addr_mask & ~3];
|
||||||
|
}
|
||||||
|
return *src;
|
||||||
|
}
|
||||||
|
|
||||||
#define ROP_NAME 0
|
#define ROP_NAME 0
|
||||||
#define ROP_FN(d, s) 0
|
#define ROP_FN(d, s) 0
|
||||||
#include "cirrus_vga_rop.h"
|
#include "cirrus_vga_rop.h"
|
||||||
@ -666,21 +707,18 @@ static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (y = 0; y < lines; y++) {
|
for (y = 0; y < lines; y++) {
|
||||||
off_cur = off_begin;
|
off_cur = off_begin;
|
||||||
off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask;
|
off_cur_end = ((off_cur + bytesperline - 1) & s->cirrus_addr_mask) + 1;
|
||||||
assert(off_cur_end >= off_cur);
|
assert(off_cur_end >= off_cur);
|
||||||
memory_region_set_dirty(&s->vga.vram, off_cur, off_cur_end - off_cur);
|
memory_region_set_dirty(&s->vga.vram, off_cur, off_cur_end - off_cur);
|
||||||
off_begin += off_pitch;
|
off_begin += off_pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cirrus_bitblt_common_patterncopy(CirrusVGAState *s, bool videosrc)
|
static int cirrus_bitblt_common_patterncopy(CirrusVGAState *s)
|
||||||
{
|
{
|
||||||
uint32_t patternsize;
|
uint32_t patternsize;
|
||||||
uint8_t *dst;
|
bool videosrc = !s->cirrus_srccounter;
|
||||||
uint8_t *src;
|
|
||||||
|
|
||||||
dst = s->vga.vram_ptr + s->cirrus_blt_dstaddr;
|
|
||||||
|
|
||||||
if (videosrc) {
|
if (videosrc) {
|
||||||
switch (s->vga.get_bpp(&s->vga)) {
|
switch (s->vga.get_bpp(&s->vga)) {
|
||||||
@ -701,16 +739,14 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState *s, bool videosrc)
|
|||||||
if (s->cirrus_blt_srcaddr + patternsize > s->vga.vram_size) {
|
if (s->cirrus_blt_srcaddr + patternsize > s->vga.vram_size) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
src = s->vga.vram_ptr + s->cirrus_blt_srcaddr;
|
|
||||||
} else {
|
|
||||||
src = s->cirrus_bltbuf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blit_is_unsafe(s, true)) {
|
if (blit_is_unsafe(s, true)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*s->cirrus_rop) (s, dst, src,
|
(*s->cirrus_rop) (s, s->cirrus_blt_dstaddr,
|
||||||
|
videosrc ? s->cirrus_blt_srcaddr : 0,
|
||||||
s->cirrus_blt_dstpitch, 0,
|
s->cirrus_blt_dstpitch, 0,
|
||||||
s->cirrus_blt_width, s->cirrus_blt_height);
|
s->cirrus_blt_width, s->cirrus_blt_height);
|
||||||
cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
|
cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
|
||||||
@ -729,7 +765,7 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
|
rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
|
||||||
rop_func(s, s->vga.vram_ptr + s->cirrus_blt_dstaddr,
|
rop_func(s, s->cirrus_blt_dstaddr,
|
||||||
s->cirrus_blt_dstpitch,
|
s->cirrus_blt_dstpitch,
|
||||||
s->cirrus_blt_width, s->cirrus_blt_height);
|
s->cirrus_blt_width, s->cirrus_blt_height);
|
||||||
cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
|
cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
|
||||||
@ -747,7 +783,7 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop)
|
|||||||
|
|
||||||
static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s)
|
static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s)
|
||||||
{
|
{
|
||||||
return cirrus_bitblt_common_patterncopy(s, true);
|
return cirrus_bitblt_common_patterncopy(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
|
static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
|
||||||
@ -796,21 +832,15 @@ static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we have to flush all pending changes so that the copy
|
(*s->cirrus_rop) (s, s->cirrus_blt_dstaddr,
|
||||||
is generated at the appropriate moment in time */
|
s->cirrus_blt_srcaddr,
|
||||||
if (notify)
|
|
||||||
graphic_hw_update(s->vga.con);
|
|
||||||
|
|
||||||
(*s->cirrus_rop) (s, s->vga.vram_ptr + s->cirrus_blt_dstaddr,
|
|
||||||
s->vga.vram_ptr + s->cirrus_blt_srcaddr,
|
|
||||||
s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
|
s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
|
||||||
s->cirrus_blt_width, s->cirrus_blt_height);
|
s->cirrus_blt_width, s->cirrus_blt_height);
|
||||||
|
|
||||||
if (notify) {
|
if (notify) {
|
||||||
qemu_console_copy(s->vga.con,
|
dpy_gfx_update(s->vga.con, dx, dy,
|
||||||
sx, sy, dx, dy,
|
s->cirrus_blt_width / depth,
|
||||||
s->cirrus_blt_width / depth,
|
s->cirrus_blt_height);
|
||||||
s->cirrus_blt_height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we don't have to notify the display that this portion has
|
/* we don't have to notify the display that this portion has
|
||||||
@ -846,15 +876,15 @@ static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s)
|
|||||||
|
|
||||||
if (s->cirrus_srccounter > 0) {
|
if (s->cirrus_srccounter > 0) {
|
||||||
if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
|
if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
|
||||||
cirrus_bitblt_common_patterncopy(s, false);
|
cirrus_bitblt_common_patterncopy(s);
|
||||||
the_end:
|
the_end:
|
||||||
s->cirrus_srccounter = 0;
|
s->cirrus_srccounter = 0;
|
||||||
cirrus_bitblt_reset(s);
|
cirrus_bitblt_reset(s);
|
||||||
} else {
|
} else {
|
||||||
/* at least one scan line */
|
/* at least one scan line */
|
||||||
do {
|
do {
|
||||||
(*s->cirrus_rop)(s, s->vga.vram_ptr + s->cirrus_blt_dstaddr,
|
(*s->cirrus_rop)(s, s->cirrus_blt_dstaddr,
|
||||||
s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1);
|
0, 0, 0, s->cirrus_blt_width, 1);
|
||||||
cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0,
|
cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0,
|
||||||
s->cirrus_blt_width, 1);
|
s->cirrus_blt_width, 1);
|
||||||
s->cirrus_blt_dstaddr += s->cirrus_blt_dstpitch;
|
s->cirrus_blt_dstaddr += s->cirrus_blt_dstpitch;
|
||||||
@ -966,6 +996,10 @@ static void cirrus_bitblt_start(CirrusVGAState * s)
|
|||||||
{
|
{
|
||||||
uint8_t blt_rop;
|
uint8_t blt_rop;
|
||||||
|
|
||||||
|
if (!s->enable_blitter) {
|
||||||
|
goto bitblt_ignore;
|
||||||
|
}
|
||||||
|
|
||||||
s->vga.gr[0x31] |= CIRRUS_BLT_BUSY;
|
s->vga.gr[0x31] |= CIRRUS_BLT_BUSY;
|
||||||
|
|
||||||
s->cirrus_blt_width = (s->vga.gr[0x20] | (s->vga.gr[0x21] << 8)) + 1;
|
s->cirrus_blt_width = (s->vga.gr[0x20] | (s->vga.gr[0x21] << 8)) + 1;
|
||||||
@ -3029,7 +3063,9 @@ static void isa_cirrus_vga_realizefn(DeviceState *dev, Error **errp)
|
|||||||
|
|
||||||
static Property isa_cirrus_vga_properties[] = {
|
static Property isa_cirrus_vga_properties[] = {
|
||||||
DEFINE_PROP_UINT32("vgamem_mb", struct ISACirrusVGAState,
|
DEFINE_PROP_UINT32("vgamem_mb", struct ISACirrusVGAState,
|
||||||
cirrus_vga.vga.vram_size_mb, 8),
|
cirrus_vga.vga.vram_size_mb, 4),
|
||||||
|
DEFINE_PROP_BOOL("blitter", struct ISACirrusVGAState,
|
||||||
|
cirrus_vga.enable_blitter, true),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3098,7 +3134,9 @@ static void pci_cirrus_vga_realize(PCIDevice *dev, Error **errp)
|
|||||||
|
|
||||||
static Property pci_vga_cirrus_properties[] = {
|
static Property pci_vga_cirrus_properties[] = {
|
||||||
DEFINE_PROP_UINT32("vgamem_mb", struct PCICirrusVGAState,
|
DEFINE_PROP_UINT32("vgamem_mb", struct PCICirrusVGAState,
|
||||||
cirrus_vga.vga.vram_size_mb, 8),
|
cirrus_vga.vga.vram_size_mb, 4),
|
||||||
|
DEFINE_PROP_BOOL("blitter", struct PCICirrusVGAState,
|
||||||
|
cirrus_vga.enable_blitter, true),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -22,31 +22,65 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static inline void glue(rop_8_,ROP_NAME)(uint8_t *dst, uint8_t src)
|
static inline void glue(rop_8_, ROP_NAME)(CirrusVGAState *s,
|
||||||
|
uint32_t dstaddr, uint8_t src)
|
||||||
{
|
{
|
||||||
|
uint8_t *dst = &s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask];
|
||||||
*dst = ROP_FN(*dst, src);
|
*dst = ROP_FN(*dst, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void glue(rop_16_,ROP_NAME)(uint16_t *dst, uint16_t src)
|
static inline void glue(rop_tr_8_, ROP_NAME)(CirrusVGAState *s,
|
||||||
|
uint32_t dstaddr, uint8_t src,
|
||||||
|
uint8_t transp)
|
||||||
{
|
{
|
||||||
|
uint8_t *dst = &s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask];
|
||||||
|
uint8_t pixel = ROP_FN(*dst, src);
|
||||||
|
if (pixel != transp) {
|
||||||
|
*dst = pixel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void glue(rop_16_, ROP_NAME)(CirrusVGAState *s,
|
||||||
|
uint32_t dstaddr, uint16_t src)
|
||||||
|
{
|
||||||
|
uint16_t *dst = (uint16_t *)
|
||||||
|
(&s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask & ~1]);
|
||||||
*dst = ROP_FN(*dst, src);
|
*dst = ROP_FN(*dst, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void glue(rop_32_,ROP_NAME)(uint32_t *dst, uint32_t src)
|
static inline void glue(rop_tr_16_, ROP_NAME)(CirrusVGAState *s,
|
||||||
|
uint32_t dstaddr, uint16_t src,
|
||||||
|
uint16_t transp)
|
||||||
{
|
{
|
||||||
|
uint16_t *dst = (uint16_t *)
|
||||||
|
(&s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask & ~1]);
|
||||||
|
uint16_t pixel = ROP_FN(*dst, src);
|
||||||
|
if (pixel != transp) {
|
||||||
|
*dst = pixel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void glue(rop_32_, ROP_NAME)(CirrusVGAState *s,
|
||||||
|
uint32_t dstaddr, uint32_t src)
|
||||||
|
{
|
||||||
|
uint32_t *dst = (uint32_t *)
|
||||||
|
(&s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask & ~3]);
|
||||||
*dst = ROP_FN(*dst, src);
|
*dst = ROP_FN(*dst, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ROP_OP(d, s) glue(rop_8_,ROP_NAME)(d, s)
|
#define ROP_OP(st, d, s) glue(rop_8_, ROP_NAME)(st, d, s)
|
||||||
#define ROP_OP_16(d, s) glue(rop_16_,ROP_NAME)(d, s)
|
#define ROP_OP_TR(st, d, s, t) glue(rop_tr_8_, ROP_NAME)(st, d, s, t)
|
||||||
#define ROP_OP_32(d, s) glue(rop_32_,ROP_NAME)(d, s)
|
#define ROP_OP_16(st, d, s) glue(rop_16_, ROP_NAME)(st, d, s)
|
||||||
|
#define ROP_OP_TR_16(st, d, s, t) glue(rop_tr_16_, ROP_NAME)(st, d, s, t)
|
||||||
|
#define ROP_OP_32(st, d, s) glue(rop_32_, ROP_NAME)(st, d, s)
|
||||||
#undef ROP_FN
|
#undef ROP_FN
|
||||||
|
|
||||||
static void
|
static void
|
||||||
glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,
|
glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,
|
||||||
uint8_t *dst,const uint8_t *src,
|
uint32_t dstaddr,
|
||||||
int dstpitch,int srcpitch,
|
uint32_t srcaddr,
|
||||||
int bltwidth,int bltheight)
|
int dstpitch, int srcpitch,
|
||||||
|
int bltwidth, int bltheight)
|
||||||
{
|
{
|
||||||
int x,y;
|
int x,y;
|
||||||
dstpitch -= bltwidth;
|
dstpitch -= bltwidth;
|
||||||
@ -58,134 +92,139 @@ glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,
|
|||||||
|
|
||||||
for (y = 0; y < bltheight; y++) {
|
for (y = 0; y < bltheight; y++) {
|
||||||
for (x = 0; x < bltwidth; x++) {
|
for (x = 0; x < bltwidth; x++) {
|
||||||
ROP_OP(dst, *src);
|
ROP_OP(s, dstaddr, cirrus_src(s, srcaddr));
|
||||||
dst++;
|
dstaddr++;
|
||||||
src++;
|
srcaddr++;
|
||||||
}
|
}
|
||||||
dst += dstpitch;
|
dstaddr += dstpitch;
|
||||||
src += srcpitch;
|
srcaddr += srcpitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s,
|
glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s,
|
||||||
uint8_t *dst,const uint8_t *src,
|
uint32_t dstaddr,
|
||||||
int dstpitch,int srcpitch,
|
uint32_t srcaddr,
|
||||||
int bltwidth,int bltheight)
|
int dstpitch, int srcpitch,
|
||||||
|
int bltwidth, int bltheight)
|
||||||
{
|
{
|
||||||
int x,y;
|
int x,y;
|
||||||
dstpitch += bltwidth;
|
dstpitch += bltwidth;
|
||||||
srcpitch += bltwidth;
|
srcpitch += bltwidth;
|
||||||
for (y = 0; y < bltheight; y++) {
|
for (y = 0; y < bltheight; y++) {
|
||||||
for (x = 0; x < bltwidth; x++) {
|
for (x = 0; x < bltwidth; x++) {
|
||||||
ROP_OP(dst, *src);
|
ROP_OP(s, dstaddr, cirrus_src(s, srcaddr));
|
||||||
dst--;
|
dstaddr--;
|
||||||
src--;
|
srcaddr--;
|
||||||
}
|
}
|
||||||
dst += dstpitch;
|
dstaddr += dstpitch;
|
||||||
src += srcpitch;
|
srcaddr += srcpitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
|
glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
|
||||||
uint8_t *dst,const uint8_t *src,
|
uint32_t dstaddr,
|
||||||
int dstpitch,int srcpitch,
|
uint32_t srcaddr,
|
||||||
int bltwidth,int bltheight)
|
int dstpitch,
|
||||||
|
int srcpitch,
|
||||||
|
int bltwidth,
|
||||||
|
int bltheight)
|
||||||
{
|
{
|
||||||
int x,y;
|
int x,y;
|
||||||
uint8_t p;
|
uint8_t transp = s->vga.gr[0x34];
|
||||||
dstpitch -= bltwidth;
|
dstpitch -= bltwidth;
|
||||||
srcpitch -= bltwidth;
|
srcpitch -= bltwidth;
|
||||||
|
|
||||||
|
if (bltheight > 1 && (dstpitch < 0 || srcpitch < 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (y = 0; y < bltheight; y++) {
|
for (y = 0; y < bltheight; y++) {
|
||||||
for (x = 0; x < bltwidth; x++) {
|
for (x = 0; x < bltwidth; x++) {
|
||||||
p = *dst;
|
ROP_OP_TR(s, dstaddr, cirrus_src(s, srcaddr), transp);
|
||||||
ROP_OP(&p, *src);
|
dstaddr++;
|
||||||
if (p != s->vga.gr[0x34]) *dst = p;
|
srcaddr++;
|
||||||
dst++;
|
|
||||||
src++;
|
|
||||||
}
|
}
|
||||||
dst += dstpitch;
|
dstaddr += dstpitch;
|
||||||
src += srcpitch;
|
srcaddr += srcpitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
|
glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
|
||||||
uint8_t *dst,const uint8_t *src,
|
uint32_t dstaddr,
|
||||||
int dstpitch,int srcpitch,
|
uint32_t srcaddr,
|
||||||
int bltwidth,int bltheight)
|
int dstpitch,
|
||||||
|
int srcpitch,
|
||||||
|
int bltwidth,
|
||||||
|
int bltheight)
|
||||||
{
|
{
|
||||||
int x,y;
|
int x,y;
|
||||||
uint8_t p;
|
uint8_t transp = s->vga.gr[0x34];
|
||||||
dstpitch += bltwidth;
|
dstpitch += bltwidth;
|
||||||
srcpitch += bltwidth;
|
srcpitch += bltwidth;
|
||||||
for (y = 0; y < bltheight; y++) {
|
for (y = 0; y < bltheight; y++) {
|
||||||
for (x = 0; x < bltwidth; x++) {
|
for (x = 0; x < bltwidth; x++) {
|
||||||
p = *dst;
|
ROP_OP_TR(s, dstaddr, cirrus_src(s, srcaddr), transp);
|
||||||
ROP_OP(&p, *src);
|
dstaddr--;
|
||||||
if (p != s->vga.gr[0x34]) *dst = p;
|
srcaddr--;
|
||||||
dst--;
|
|
||||||
src--;
|
|
||||||
}
|
}
|
||||||
dst += dstpitch;
|
dstaddr += dstpitch;
|
||||||
src += srcpitch;
|
srcaddr += srcpitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
|
glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
|
||||||
uint8_t *dst,const uint8_t *src,
|
uint32_t dstaddr,
|
||||||
int dstpitch,int srcpitch,
|
uint32_t srcaddr,
|
||||||
int bltwidth,int bltheight)
|
int dstpitch,
|
||||||
|
int srcpitch,
|
||||||
|
int bltwidth,
|
||||||
|
int bltheight)
|
||||||
{
|
{
|
||||||
int x,y;
|
int x,y;
|
||||||
uint8_t p1, p2;
|
uint16_t transp = s->vga.gr[0x34] | (uint16_t)s->vga.gr[0x35] << 8;
|
||||||
dstpitch -= bltwidth;
|
dstpitch -= bltwidth;
|
||||||
srcpitch -= bltwidth;
|
srcpitch -= bltwidth;
|
||||||
|
|
||||||
|
if (bltheight > 1 && (dstpitch < 0 || srcpitch < 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (y = 0; y < bltheight; y++) {
|
for (y = 0; y < bltheight; y++) {
|
||||||
for (x = 0; x < bltwidth; x+=2) {
|
for (x = 0; x < bltwidth; x+=2) {
|
||||||
p1 = *dst;
|
ROP_OP_TR_16(s, dstaddr, cirrus_src16(s, srcaddr), transp);
|
||||||
p2 = *(dst+1);
|
dstaddr += 2;
|
||||||
ROP_OP(&p1, *src);
|
srcaddr += 2;
|
||||||
ROP_OP(&p2, *(src + 1));
|
|
||||||
if ((p1 != s->vga.gr[0x34]) || (p2 != s->vga.gr[0x35])) {
|
|
||||||
*dst = p1;
|
|
||||||
*(dst+1) = p2;
|
|
||||||
}
|
|
||||||
dst+=2;
|
|
||||||
src+=2;
|
|
||||||
}
|
}
|
||||||
dst += dstpitch;
|
dstaddr += dstpitch;
|
||||||
src += srcpitch;
|
srcaddr += srcpitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
|
glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
|
||||||
uint8_t *dst,const uint8_t *src,
|
uint32_t dstaddr,
|
||||||
int dstpitch,int srcpitch,
|
uint32_t srcaddr,
|
||||||
int bltwidth,int bltheight)
|
int dstpitch,
|
||||||
|
int srcpitch,
|
||||||
|
int bltwidth,
|
||||||
|
int bltheight)
|
||||||
{
|
{
|
||||||
int x,y;
|
int x,y;
|
||||||
uint8_t p1, p2;
|
uint16_t transp = s->vga.gr[0x34] | (uint16_t)s->vga.gr[0x35] << 8;
|
||||||
dstpitch += bltwidth;
|
dstpitch += bltwidth;
|
||||||
srcpitch += bltwidth;
|
srcpitch += bltwidth;
|
||||||
for (y = 0; y < bltheight; y++) {
|
for (y = 0; y < bltheight; y++) {
|
||||||
for (x = 0; x < bltwidth; x+=2) {
|
for (x = 0; x < bltwidth; x+=2) {
|
||||||
p1 = *(dst-1);
|
ROP_OP_TR_16(s, dstaddr, cirrus_src16(s, srcaddr), transp);
|
||||||
p2 = *dst;
|
dstaddr -= 2;
|
||||||
ROP_OP(&p1, *(src - 1));
|
srcaddr -= 2;
|
||||||
ROP_OP(&p2, *src);
|
|
||||||
if ((p1 != s->vga.gr[0x34]) || (p2 != s->vga.gr[0x35])) {
|
|
||||||
*(dst-1) = p1;
|
|
||||||
*dst = p2;
|
|
||||||
}
|
|
||||||
dst-=2;
|
|
||||||
src-=2;
|
|
||||||
}
|
}
|
||||||
dst += dstpitch;
|
dstaddr += dstpitch;
|
||||||
src += srcpitch;
|
srcaddr += srcpitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,30 +23,32 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#if DEPTH == 8
|
#if DEPTH == 8
|
||||||
#define PUTPIXEL() ROP_OP(&d[0], col)
|
#define PUTPIXEL(s, a, c) ROP_OP(s, a, c)
|
||||||
#elif DEPTH == 16
|
#elif DEPTH == 16
|
||||||
#define PUTPIXEL() ROP_OP_16((uint16_t *)&d[0], col)
|
#define PUTPIXEL(s, a, c) ROP_OP_16(s, a, c)
|
||||||
#elif DEPTH == 24
|
#elif DEPTH == 24
|
||||||
#define PUTPIXEL() ROP_OP(&d[0], col); \
|
#define PUTPIXEL(s, a, c) do { \
|
||||||
ROP_OP(&d[1], (col >> 8)); \
|
ROP_OP(s, a, c); \
|
||||||
ROP_OP(&d[2], (col >> 16))
|
ROP_OP(s, a + 1, (col >> 8)); \
|
||||||
|
ROP_OP(s, a + 2, (col >> 16)); \
|
||||||
|
} while (0)
|
||||||
#elif DEPTH == 32
|
#elif DEPTH == 32
|
||||||
#define PUTPIXEL() ROP_OP_32(((uint32_t *)&d[0]), col)
|
#define PUTPIXEL(s, a, c) ROP_OP_32(s, a, c)
|
||||||
#else
|
#else
|
||||||
#error unsupported DEPTH
|
#error unsupported DEPTH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH)
|
glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH)
|
||||||
(CirrusVGAState * s, uint8_t * dst,
|
(CirrusVGAState *s, uint32_t dstaddr,
|
||||||
const uint8_t * src,
|
uint32_t srcaddr,
|
||||||
int dstpitch, int srcpitch,
|
int dstpitch, int srcpitch,
|
||||||
int bltwidth, int bltheight)
|
int bltwidth, int bltheight)
|
||||||
{
|
{
|
||||||
uint8_t *d;
|
uint32_t addr;
|
||||||
int x, y, pattern_y, pattern_pitch, pattern_x;
|
int x, y, pattern_y, pattern_pitch, pattern_x;
|
||||||
unsigned int col;
|
unsigned int col;
|
||||||
const uint8_t *src1;
|
uint32_t src1addr;
|
||||||
#if DEPTH == 24
|
#if DEPTH == 24
|
||||||
int skipleft = s->vga.gr[0x2f] & 0x1f;
|
int skipleft = s->vga.gr[0x2f] & 0x1f;
|
||||||
#else
|
#else
|
||||||
@ -63,42 +65,44 @@ glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH)
|
|||||||
pattern_y = s->cirrus_blt_srcaddr & 7;
|
pattern_y = s->cirrus_blt_srcaddr & 7;
|
||||||
for(y = 0; y < bltheight; y++) {
|
for(y = 0; y < bltheight; y++) {
|
||||||
pattern_x = skipleft;
|
pattern_x = skipleft;
|
||||||
d = dst + skipleft;
|
addr = dstaddr + skipleft;
|
||||||
src1 = src + pattern_y * pattern_pitch;
|
src1addr = srcaddr + pattern_y * pattern_pitch;
|
||||||
for (x = skipleft; x < bltwidth; x += (DEPTH / 8)) {
|
for (x = skipleft; x < bltwidth; x += (DEPTH / 8)) {
|
||||||
#if DEPTH == 8
|
#if DEPTH == 8
|
||||||
col = src1[pattern_x];
|
col = cirrus_src(s, src1addr + pattern_x);
|
||||||
pattern_x = (pattern_x + 1) & 7;
|
pattern_x = (pattern_x + 1) & 7;
|
||||||
#elif DEPTH == 16
|
#elif DEPTH == 16
|
||||||
col = ((uint16_t *)(src1 + pattern_x))[0];
|
col = cirrus_src16(s, src1addr + pattern_x);
|
||||||
pattern_x = (pattern_x + 2) & 15;
|
pattern_x = (pattern_x + 2) & 15;
|
||||||
#elif DEPTH == 24
|
#elif DEPTH == 24
|
||||||
{
|
{
|
||||||
const uint8_t *src2 = src1 + pattern_x * 3;
|
uint32_t src2addr = src1addr + pattern_x * 3;
|
||||||
col = src2[0] | (src2[1] << 8) | (src2[2] << 16);
|
col = cirrus_src(s, src2addr) |
|
||||||
|
(cirrus_src(s, src2addr + 1) << 8) |
|
||||||
|
(cirrus_src(s, src2addr + 2) << 16);
|
||||||
pattern_x = (pattern_x + 1) & 7;
|
pattern_x = (pattern_x + 1) & 7;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
col = ((uint32_t *)(src1 + pattern_x))[0];
|
col = cirrus_src32(s, src1addr + pattern_x);
|
||||||
pattern_x = (pattern_x + 4) & 31;
|
pattern_x = (pattern_x + 4) & 31;
|
||||||
#endif
|
#endif
|
||||||
PUTPIXEL();
|
PUTPIXEL(s, addr, col);
|
||||||
d += (DEPTH / 8);
|
addr += (DEPTH / 8);
|
||||||
}
|
}
|
||||||
pattern_y = (pattern_y + 1) & 7;
|
pattern_y = (pattern_y + 1) & 7;
|
||||||
dst += dstpitch;
|
dstaddr += dstpitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NOTE: srcpitch is ignored */
|
/* NOTE: srcpitch is ignored */
|
||||||
static void
|
static void
|
||||||
glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
|
glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
|
||||||
(CirrusVGAState * s, uint8_t * dst,
|
(CirrusVGAState *s, uint32_t dstaddr,
|
||||||
const uint8_t * src,
|
uint32_t srcaddr,
|
||||||
int dstpitch, int srcpitch,
|
int dstpitch, int srcpitch,
|
||||||
int bltwidth, int bltheight)
|
int bltwidth, int bltheight)
|
||||||
{
|
{
|
||||||
uint8_t *d;
|
uint32_t addr;
|
||||||
int x, y;
|
int x, y;
|
||||||
unsigned bits, bits_xor;
|
unsigned bits, bits_xor;
|
||||||
unsigned int col;
|
unsigned int col;
|
||||||
@ -122,33 +126,33 @@ glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
|
|||||||
|
|
||||||
for(y = 0; y < bltheight; y++) {
|
for(y = 0; y < bltheight; y++) {
|
||||||
bitmask = 0x80 >> srcskipleft;
|
bitmask = 0x80 >> srcskipleft;
|
||||||
bits = *src++ ^ bits_xor;
|
bits = cirrus_src(s, srcaddr++) ^ bits_xor;
|
||||||
d = dst + dstskipleft;
|
addr = dstaddr + dstskipleft;
|
||||||
for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
|
for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
|
||||||
if ((bitmask & 0xff) == 0) {
|
if ((bitmask & 0xff) == 0) {
|
||||||
bitmask = 0x80;
|
bitmask = 0x80;
|
||||||
bits = *src++ ^ bits_xor;
|
bits = cirrus_src(s, srcaddr++) ^ bits_xor;
|
||||||
}
|
}
|
||||||
index = (bits & bitmask);
|
index = (bits & bitmask);
|
||||||
if (index) {
|
if (index) {
|
||||||
PUTPIXEL();
|
PUTPIXEL(s, addr, col);
|
||||||
}
|
}
|
||||||
d += (DEPTH / 8);
|
addr += (DEPTH / 8);
|
||||||
bitmask >>= 1;
|
bitmask >>= 1;
|
||||||
}
|
}
|
||||||
dst += dstpitch;
|
dstaddr += dstpitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
|
glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
|
||||||
(CirrusVGAState * s, uint8_t * dst,
|
(CirrusVGAState *s, uint32_t dstaddr,
|
||||||
const uint8_t * src,
|
uint32_t srcaddr,
|
||||||
int dstpitch, int srcpitch,
|
int dstpitch, int srcpitch,
|
||||||
int bltwidth, int bltheight)
|
int bltwidth, int bltheight)
|
||||||
{
|
{
|
||||||
uint32_t colors[2];
|
uint32_t colors[2];
|
||||||
uint8_t *d;
|
uint32_t addr;
|
||||||
int x, y;
|
int x, y;
|
||||||
unsigned bits;
|
unsigned bits;
|
||||||
unsigned int col;
|
unsigned int col;
|
||||||
@ -160,30 +164,30 @@ glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
|
|||||||
colors[1] = s->cirrus_blt_fgcol;
|
colors[1] = s->cirrus_blt_fgcol;
|
||||||
for(y = 0; y < bltheight; y++) {
|
for(y = 0; y < bltheight; y++) {
|
||||||
bitmask = 0x80 >> srcskipleft;
|
bitmask = 0x80 >> srcskipleft;
|
||||||
bits = *src++;
|
bits = cirrus_src(s, srcaddr++);
|
||||||
d = dst + dstskipleft;
|
addr = dstaddr + dstskipleft;
|
||||||
for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
|
for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
|
||||||
if ((bitmask & 0xff) == 0) {
|
if ((bitmask & 0xff) == 0) {
|
||||||
bitmask = 0x80;
|
bitmask = 0x80;
|
||||||
bits = *src++;
|
bits = cirrus_src(s, srcaddr++);
|
||||||
}
|
}
|
||||||
col = colors[!!(bits & bitmask)];
|
col = colors[!!(bits & bitmask)];
|
||||||
PUTPIXEL();
|
PUTPIXEL(s, addr, col);
|
||||||
d += (DEPTH / 8);
|
addr += (DEPTH / 8);
|
||||||
bitmask >>= 1;
|
bitmask >>= 1;
|
||||||
}
|
}
|
||||||
dst += dstpitch;
|
dstaddr += dstpitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH)
|
glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH)
|
||||||
(CirrusVGAState * s, uint8_t * dst,
|
(CirrusVGAState *s, uint32_t dstaddr,
|
||||||
const uint8_t * src,
|
uint32_t srcaddr,
|
||||||
int dstpitch, int srcpitch,
|
int dstpitch, int srcpitch,
|
||||||
int bltwidth, int bltheight)
|
int bltwidth, int bltheight)
|
||||||
{
|
{
|
||||||
uint8_t *d;
|
uint32_t addr;
|
||||||
int x, y, bitpos, pattern_y;
|
int x, y, bitpos, pattern_y;
|
||||||
unsigned int bits, bits_xor;
|
unsigned int bits, bits_xor;
|
||||||
unsigned int col;
|
unsigned int col;
|
||||||
@ -205,30 +209,30 @@ glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH)
|
|||||||
pattern_y = s->cirrus_blt_srcaddr & 7;
|
pattern_y = s->cirrus_blt_srcaddr & 7;
|
||||||
|
|
||||||
for(y = 0; y < bltheight; y++) {
|
for(y = 0; y < bltheight; y++) {
|
||||||
bits = src[pattern_y] ^ bits_xor;
|
bits = cirrus_src(s, srcaddr + pattern_y) ^ bits_xor;
|
||||||
bitpos = 7 - srcskipleft;
|
bitpos = 7 - srcskipleft;
|
||||||
d = dst + dstskipleft;
|
addr = dstaddr + dstskipleft;
|
||||||
for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
|
for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
|
||||||
if ((bits >> bitpos) & 1) {
|
if ((bits >> bitpos) & 1) {
|
||||||
PUTPIXEL();
|
PUTPIXEL(s, addr, col);
|
||||||
}
|
}
|
||||||
d += (DEPTH / 8);
|
addr += (DEPTH / 8);
|
||||||
bitpos = (bitpos - 1) & 7;
|
bitpos = (bitpos - 1) & 7;
|
||||||
}
|
}
|
||||||
pattern_y = (pattern_y + 1) & 7;
|
pattern_y = (pattern_y + 1) & 7;
|
||||||
dst += dstpitch;
|
dstaddr += dstpitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH)
|
glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH)
|
||||||
(CirrusVGAState * s, uint8_t * dst,
|
(CirrusVGAState *s, uint32_t dstaddr,
|
||||||
const uint8_t * src,
|
uint32_t srcaddr,
|
||||||
int dstpitch, int srcpitch,
|
int dstpitch, int srcpitch,
|
||||||
int bltwidth, int bltheight)
|
int bltwidth, int bltheight)
|
||||||
{
|
{
|
||||||
uint32_t colors[2];
|
uint32_t colors[2];
|
||||||
uint8_t *d;
|
uint32_t addr;
|
||||||
int x, y, bitpos, pattern_y;
|
int x, y, bitpos, pattern_y;
|
||||||
unsigned int bits;
|
unsigned int bits;
|
||||||
unsigned int col;
|
unsigned int col;
|
||||||
@ -240,40 +244,39 @@ glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH)
|
|||||||
pattern_y = s->cirrus_blt_srcaddr & 7;
|
pattern_y = s->cirrus_blt_srcaddr & 7;
|
||||||
|
|
||||||
for(y = 0; y < bltheight; y++) {
|
for(y = 0; y < bltheight; y++) {
|
||||||
bits = src[pattern_y];
|
bits = cirrus_src(s, srcaddr + pattern_y);
|
||||||
bitpos = 7 - srcskipleft;
|
bitpos = 7 - srcskipleft;
|
||||||
d = dst + dstskipleft;
|
addr = dstaddr + dstskipleft;
|
||||||
for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
|
for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
|
||||||
col = colors[(bits >> bitpos) & 1];
|
col = colors[(bits >> bitpos) & 1];
|
||||||
PUTPIXEL();
|
PUTPIXEL(s, addr, col);
|
||||||
d += (DEPTH / 8);
|
addr += (DEPTH / 8);
|
||||||
bitpos = (bitpos - 1) & 7;
|
bitpos = (bitpos - 1) & 7;
|
||||||
}
|
}
|
||||||
pattern_y = (pattern_y + 1) & 7;
|
pattern_y = (pattern_y + 1) & 7;
|
||||||
dst += dstpitch;
|
dstaddr += dstpitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
glue(glue(glue(cirrus_fill_, ROP_NAME), _),DEPTH)
|
glue(glue(glue(cirrus_fill_, ROP_NAME), _),DEPTH)
|
||||||
(CirrusVGAState *s,
|
(CirrusVGAState *s,
|
||||||
uint8_t *dst, int dst_pitch,
|
uint32_t dstaddr, int dst_pitch,
|
||||||
int width, int height)
|
int width, int height)
|
||||||
{
|
{
|
||||||
uint8_t *d, *d1;
|
uint32_t addr;
|
||||||
uint32_t col;
|
uint32_t col;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
col = s->cirrus_blt_fgcol;
|
col = s->cirrus_blt_fgcol;
|
||||||
|
|
||||||
d1 = dst;
|
|
||||||
for(y = 0; y < height; y++) {
|
for(y = 0; y < height; y++) {
|
||||||
d = d1;
|
addr = dstaddr;
|
||||||
for(x = 0; x < width; x += (DEPTH / 8)) {
|
for(x = 0; x < width; x += (DEPTH / 8)) {
|
||||||
PUTPIXEL();
|
PUTPIXEL(s, addr, col);
|
||||||
d += (DEPTH / 8);
|
addr += (DEPTH / 8);
|
||||||
}
|
}
|
||||||
d1 += dst_pitch;
|
dstaddr += dst_pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,14 @@
|
|||||||
.driver = "virtio-pci",\
|
.driver = "virtio-pci",\
|
||||||
.property = "x-pcie-pm-init",\
|
.property = "x-pcie-pm-init",\
|
||||||
.value = "off",\
|
.value = "off",\
|
||||||
|
},{\
|
||||||
|
.driver = "cirrus-vga",\
|
||||||
|
.property = "vgamem_mb",\
|
||||||
|
.value = "8",\
|
||||||
|
},{\
|
||||||
|
.driver = "isa-cirrus-vga",\
|
||||||
|
.property = "vgamem_mb",\
|
||||||
|
.value = "8",\
|
||||||
},
|
},
|
||||||
|
|
||||||
#define HW_COMPAT_2_7 \
|
#define HW_COMPAT_2_7 \
|
||||||
|
@ -189,9 +189,6 @@ typedef struct DisplayChangeListenerOps {
|
|||||||
int x, int y, int w, int h);
|
int x, int y, int w, int h);
|
||||||
void (*dpy_gfx_switch)(DisplayChangeListener *dcl,
|
void (*dpy_gfx_switch)(DisplayChangeListener *dcl,
|
||||||
struct DisplaySurface *new_surface);
|
struct DisplaySurface *new_surface);
|
||||||
void (*dpy_gfx_copy)(DisplayChangeListener *dcl,
|
|
||||||
int src_x, int src_y,
|
|
||||||
int dst_x, int dst_y, int w, int h);
|
|
||||||
bool (*dpy_gfx_check_format)(DisplayChangeListener *dcl,
|
bool (*dpy_gfx_check_format)(DisplayChangeListener *dcl,
|
||||||
pixman_format_code_t format);
|
pixman_format_code_t format);
|
||||||
|
|
||||||
@ -277,8 +274,6 @@ int dpy_set_ui_info(QemuConsole *con, QemuUIInfo *info);
|
|||||||
void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h);
|
void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h);
|
||||||
void dpy_gfx_replace_surface(QemuConsole *con,
|
void dpy_gfx_replace_surface(QemuConsole *con,
|
||||||
DisplaySurface *surface);
|
DisplaySurface *surface);
|
||||||
void dpy_gfx_copy(QemuConsole *con, int src_x, int src_y,
|
|
||||||
int dst_x, int dst_y, int w, int h);
|
|
||||||
void dpy_text_cursor(QemuConsole *con, int x, int y);
|
void dpy_text_cursor(QemuConsole *con, int x, int y);
|
||||||
void dpy_text_update(QemuConsole *con, int x, int y, int w, int h);
|
void dpy_text_update(QemuConsole *con, int x, int y, int w, int h);
|
||||||
void dpy_text_resize(QemuConsole *con, int w, int h);
|
void dpy_text_resize(QemuConsole *con, int w, int h);
|
||||||
@ -411,8 +406,6 @@ void qemu_console_set_window_id(QemuConsole *con, int window_id);
|
|||||||
|
|
||||||
void console_select(unsigned int index);
|
void console_select(unsigned int index);
|
||||||
void qemu_console_resize(QemuConsole *con, int width, int height);
|
void qemu_console_resize(QemuConsole *con, int width, int height);
|
||||||
void qemu_console_copy(QemuConsole *con, int src_x, int src_y,
|
|
||||||
int dst_x, int dst_y, int w, int h);
|
|
||||||
DisplaySurface *qemu_console_surface(QemuConsole *con);
|
DisplaySurface *qemu_console_surface(QemuConsole *con);
|
||||||
|
|
||||||
/* console-gl.c */
|
/* console-gl.c */
|
||||||
|
28
ui/console.c
28
ui/console.c
@ -1586,27 +1586,6 @@ static void dpy_refresh(DisplayState *s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dpy_gfx_copy(QemuConsole *con, int src_x, int src_y,
|
|
||||||
int dst_x, int dst_y, int w, int h)
|
|
||||||
{
|
|
||||||
DisplayState *s = con->ds;
|
|
||||||
DisplayChangeListener *dcl;
|
|
||||||
|
|
||||||
if (!qemu_console_is_visible(con)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QLIST_FOREACH(dcl, &s->listeners, next) {
|
|
||||||
if (con != (dcl->con ? dcl->con : active_console)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (dcl->ops->dpy_gfx_copy) {
|
|
||||||
dcl->ops->dpy_gfx_copy(dcl, src_x, src_y, dst_x, dst_y, w, h);
|
|
||||||
} else { /* TODO */
|
|
||||||
dcl->ops->dpy_gfx_update(dcl, dst_x, dst_y, w, h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dpy_text_cursor(QemuConsole *con, int x, int y)
|
void dpy_text_cursor(QemuConsole *con, int x, int y)
|
||||||
{
|
{
|
||||||
DisplayState *s = con->ds;
|
DisplayState *s = con->ds;
|
||||||
@ -2138,13 +2117,6 @@ void qemu_console_resize(QemuConsole *s, int width, int height)
|
|||||||
dpy_gfx_replace_surface(s, surface);
|
dpy_gfx_replace_surface(s, surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
void qemu_console_copy(QemuConsole *con, int src_x, int src_y,
|
|
||||||
int dst_x, int dst_y, int w, int h)
|
|
||||||
{
|
|
||||||
assert(con->console_type == GRAPHIC_CONSOLE);
|
|
||||||
dpy_gfx_copy(con, src_x, src_y, dst_x, dst_y, w, h);
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplaySurface *qemu_console_surface(QemuConsole *console)
|
DisplaySurface *qemu_console_surface(QemuConsole *console)
|
||||||
{
|
{
|
||||||
return console->surface;
|
return console->surface;
|
||||||
|
100
ui/vnc.c
100
ui/vnc.c
@ -894,105 +894,6 @@ int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
|
|
||||||
{
|
|
||||||
/* send bitblit op to the vnc client */
|
|
||||||
vnc_lock_output(vs);
|
|
||||||
vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
|
|
||||||
vnc_write_u8(vs, 0);
|
|
||||||
vnc_write_u16(vs, 1); /* number of rects */
|
|
||||||
vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT);
|
|
||||||
vnc_write_u16(vs, src_x);
|
|
||||||
vnc_write_u16(vs, src_y);
|
|
||||||
vnc_unlock_output(vs);
|
|
||||||
vnc_flush(vs);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vnc_dpy_copy(DisplayChangeListener *dcl,
|
|
||||||
int src_x, int src_y,
|
|
||||||
int dst_x, int dst_y, int w, int h)
|
|
||||||
{
|
|
||||||
VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
|
|
||||||
VncState *vs, *vn;
|
|
||||||
uint8_t *src_row;
|
|
||||||
uint8_t *dst_row;
|
|
||||||
int i, x, y, pitch, inc, w_lim, s;
|
|
||||||
int cmp_bytes;
|
|
||||||
|
|
||||||
if (!vd->server) {
|
|
||||||
/* no client connected */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vnc_refresh_server_surface(vd);
|
|
||||||
QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
|
|
||||||
if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
|
|
||||||
vs->force_update = 1;
|
|
||||||
vnc_update_client(vs, 1, true);
|
|
||||||
/* vs might be free()ed here */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!vd->server) {
|
|
||||||
/* no client connected */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* do bitblit op on the local surface too */
|
|
||||||
pitch = vnc_server_fb_stride(vd);
|
|
||||||
src_row = vnc_server_fb_ptr(vd, src_x, src_y);
|
|
||||||
dst_row = vnc_server_fb_ptr(vd, dst_x, dst_y);
|
|
||||||
y = dst_y;
|
|
||||||
inc = 1;
|
|
||||||
if (dst_y > src_y) {
|
|
||||||
/* copy backwards */
|
|
||||||
src_row += pitch * (h-1);
|
|
||||||
dst_row += pitch * (h-1);
|
|
||||||
pitch = -pitch;
|
|
||||||
y = dst_y + h - 1;
|
|
||||||
inc = -1;
|
|
||||||
}
|
|
||||||
w_lim = w - (VNC_DIRTY_PIXELS_PER_BIT - (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
|
|
||||||
if (w_lim < 0) {
|
|
||||||
w_lim = w;
|
|
||||||
} else {
|
|
||||||
w_lim = w - (w_lim % VNC_DIRTY_PIXELS_PER_BIT);
|
|
||||||
}
|
|
||||||
for (i = 0; i < h; i++) {
|
|
||||||
for (x = 0; x <= w_lim;
|
|
||||||
x += s, src_row += cmp_bytes, dst_row += cmp_bytes) {
|
|
||||||
if (x == w_lim) {
|
|
||||||
if ((s = w - w_lim) == 0)
|
|
||||||
break;
|
|
||||||
} else if (!x) {
|
|
||||||
s = (VNC_DIRTY_PIXELS_PER_BIT -
|
|
||||||
(dst_x % VNC_DIRTY_PIXELS_PER_BIT));
|
|
||||||
s = MIN(s, w_lim);
|
|
||||||
} else {
|
|
||||||
s = VNC_DIRTY_PIXELS_PER_BIT;
|
|
||||||
}
|
|
||||||
cmp_bytes = s * VNC_SERVER_FB_BYTES;
|
|
||||||
if (memcmp(src_row, dst_row, cmp_bytes) == 0)
|
|
||||||
continue;
|
|
||||||
memmove(dst_row, src_row, cmp_bytes);
|
|
||||||
QTAILQ_FOREACH(vs, &vd->clients, next) {
|
|
||||||
if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
|
|
||||||
set_bit(((x + dst_x) / VNC_DIRTY_PIXELS_PER_BIT),
|
|
||||||
vs->dirty[y]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
src_row += pitch - w * VNC_SERVER_FB_BYTES;
|
|
||||||
dst_row += pitch - w * VNC_SERVER_FB_BYTES;
|
|
||||||
y += inc;
|
|
||||||
}
|
|
||||||
|
|
||||||
QTAILQ_FOREACH(vs, &vd->clients, next) {
|
|
||||||
if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
|
|
||||||
vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vnc_mouse_set(DisplayChangeListener *dcl,
|
static void vnc_mouse_set(DisplayChangeListener *dcl,
|
||||||
int x, int y, int visible)
|
int x, int y, int visible)
|
||||||
{
|
{
|
||||||
@ -3120,7 +3021,6 @@ static gboolean vnc_listen_io(QIOChannel *ioc,
|
|||||||
static const DisplayChangeListenerOps dcl_ops = {
|
static const DisplayChangeListenerOps dcl_ops = {
|
||||||
.dpy_name = "vnc",
|
.dpy_name = "vnc",
|
||||||
.dpy_refresh = vnc_refresh,
|
.dpy_refresh = vnc_refresh,
|
||||||
.dpy_gfx_copy = vnc_dpy_copy,
|
|
||||||
.dpy_gfx_update = vnc_dpy_update,
|
.dpy_gfx_update = vnc_dpy_update,
|
||||||
.dpy_gfx_switch = vnc_dpy_switch,
|
.dpy_gfx_switch = vnc_dpy_switch,
|
||||||
.dpy_gfx_check_format = qemu_pixman_check_format,
|
.dpy_gfx_check_format = qemu_pixman_check_format,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user