From: "Reimar Döffinger" <Reimar.Doeffinger@gmx.de>
To: andrzej zaborowski <balrogg@gmail.com>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH] use corect depth from DisplaySurface in vmware_vga.c
Date: Tue, 25 Aug 2009 16:54:11 +0200 [thread overview]
Message-ID: <20090825145411.GA13710@1und1.de> (raw)
In-Reply-To: <fb249edb0908241645m6d9690b8pe5b35d44ad07f251@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2187 bytes --]
On Tue, Aug 25, 2009 at 01:45:15AM +0200, andrzej zaborowski wrote:
> 2009/8/24 Reimar Döffinger <Reimar.Doeffinger@gmx.de>:
> > On Sun, Aug 23, 2009 at 07:25:32PM +0200, andrzej zaborowski wrote:
> >> It was discussed at some point earlier that at the time this code runs
> >> SDL is not initialised and the depth returned is an arbitrary value
> >> from default allocator.
> >
> > It is not arbitrary. It matches exactly the DisplaySurface's
> > linesize and data buffer size.
>
> Only at the moment the function is called. The value is still
> hardcoded, just elsewhere. Once display backend initialises this
> value may be invalid.
Ok, I looked at the code again and it seems that the issue is that
we have to expect that the depth of the DisplayState/surface may change
any time.
I'm not sure that really was intentional and it just can't really work
in general, but vmware_vga can handle it just as well as vga by just
not storing/caching the depth and anything that depends on it.
So attached is a patch that does that.
Obviously it has to assume that the depth is not changed "under its
feet" after the guest OS has initialized a graphics mode but otherwise
it will not care.
I also have not tested it on hardware/software where the current code
works, since I don't know in which cases that would be.
And lastly, I suspect it breaks DIRECT_VRAM even more - given that
(AFAICT) it does not compile even now I'd suggest just removing that
code...
> > As such, I want to add that the revert commit message of "was
> > incorrect." doesn't qualify as useful to me.
>
> I wasn't intending to push this commit, instead I responded to the
> thread but later noticed I had pushed it.
I can't resist pointing out that that doesn't make the commit message any
better.
> Beside that it's an obvious performance gain. The API change did not
> magically remove the pixel by pixel conversion of the colour space, it
> just hid it in SDL, under more indirection.
I see the point, but while I don't know SDL internals well enough to
know if it does this, it might be possible to do the conversion in
hardware in some cases.
Signed-off-by: Reimar Döffinger <Reimar.Doeffinger@gmx.de>
[-- Attachment #2: vmware_depth2.diff --]
[-- Type: text/plain, Size: 8217 bytes --]
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 5ceebf1..d6c8831 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -44,8 +44,6 @@ struct vmsvga_state_s {
int width;
int height;
int invalidated;
- int depth;
- int bypp;
int enable;
int config;
struct {
@@ -70,11 +68,7 @@ struct vmsvga_state_s {
int new_height;
uint32_t guest;
uint32_t svgaid;
- uint32_t wred;
- uint32_t wgreen;
- uint32_t wblue;
int syncing;
- int fb_size;
union {
uint32_t *fifo;
@@ -297,11 +291,18 @@ enum {
SVGA_CURSOR_ON_RESTORE_TO_FB = 3,
};
+static int fb_size(struct vmsvga_state_s *s)
+{
+ if (!s->enable) return 0;
+ return ds_get_linesize(s->vga.ds) * ds_get_height(s->vga.ds);
+}
+
static inline void vmsvga_update_rect(struct vmsvga_state_s *s,
int x, int y, int w, int h)
{
#ifndef DIRECT_VRAM
int line;
+ int bypp = ds_get_bytes_per_pixel(s->vga.ds);
int bypl;
int width;
int start;
@@ -323,9 +324,9 @@ static inline void vmsvga_update_rect(struct vmsvga_state_s *s,
}
line = h;
- bypl = s->bypp * s->width;
- width = s->bypp * w;
- start = s->bypp * x + bypl * y;
+ bypl = ds_get_linesize(s->vga.ds);
+ width = bypp * w;
+ start = bypp * x + bypl * y;
src = s->vga.vram_ptr + start;
dst = ds_get_data(s->vga.ds) + start;
@@ -339,7 +340,8 @@ static inline void vmsvga_update_rect(struct vmsvga_state_s *s,
static inline void vmsvga_update_screen(struct vmsvga_state_s *s)
{
#ifndef DIRECT_VRAM
- memcpy(ds_get_data(s->vga.ds), s->vga.vram_ptr, s->bypp * s->width * s->height);
+ int bypp = ds_get_bytes_per_pixel(s->vga.ds);
+ memcpy(ds_get_data(s->vga.ds), s->vga.vram_ptr, bypp * s->width * s->height);
#endif
dpy_update(s->vga.ds, 0, 0, s->width, s->height);
@@ -385,8 +387,9 @@ static inline void vmsvga_copy_rect(struct vmsvga_state_s *s,
# else
uint8_t *vram = s->vga.vram_ptr;
# endif
- int bypl = s->bypp * s->width;
- int width = s->bypp * w;
+ int bypp = ds_get_bytes_per_pixel(s->vga.ds);
+ int bypl = ds_get_linesize(s->vga.ds);
+ int width = bypp * w;
int line = h;
uint8_t *ptr[2];
@@ -397,13 +400,13 @@ static inline void vmsvga_copy_rect(struct vmsvga_state_s *s,
# endif
{
if (y1 > y0) {
- ptr[0] = vram + s->bypp * x0 + bypl * (y0 + h - 1);
- ptr[1] = vram + s->bypp * x1 + bypl * (y1 + h - 1);
+ ptr[0] = vram + bypp * x0 + bypl * (y0 + h - 1);
+ ptr[1] = vram + bypp * x1 + bypl * (y1 + h - 1);
for (; line > 0; line --, ptr[0] -= bypl, ptr[1] -= bypl)
memmove(ptr[1], ptr[0], width);
} else {
- ptr[0] = vram + s->bypp * x0 + bypl * y0;
- ptr[1] = vram + s->bypp * x1 + bypl * y1;
+ ptr[0] = vram + bypp * x0 + bypl * y0;
+ ptr[1] = vram + bypp * x1 + bypl * y1;
for (; line > 0; line --, ptr[0] += bypl, ptr[1] += bypl)
memmove(ptr[1], ptr[0], width);
}
@@ -422,8 +425,8 @@ static inline void vmsvga_fill_rect(struct vmsvga_state_s *s,
# else
uint8_t *vram = s->vga.vram_ptr;
# endif
- int bypp = s->bypp;
- int bypl = bypp * s->width;
+ int bypp = ds_get_bytes_per_pixel(s->vga.ds);
+ int bypl = ds_get_linesize(s->vga.ds);
int width = bypp * w;
int line = h;
int column;
@@ -664,23 +667,24 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address)
return SVGA_MAX_HEIGHT;
case SVGA_REG_DEPTH:
- return s->depth;
+ return ds_get_bits_per_pixel(s->vga.ds);
+ case SVGA_REG_HOST_BITS_PER_PIXEL:
case SVGA_REG_BITS_PER_PIXEL:
- return (s->depth + 7) & ~7;
+ return ds_get_bytes_per_pixel(s->vga.ds) << 3;
case SVGA_REG_PSEUDOCOLOR:
return 0x0;
case SVGA_REG_RED_MASK:
- return s->wred;
+ return s->vga.ds->surface->pf.rmask;
case SVGA_REG_GREEN_MASK:
- return s->wgreen;
+ return s->vga.ds->surface->pf.gmask;
case SVGA_REG_BLUE_MASK:
- return s->wblue;
+ return s->vga.ds->surface->pf.bmask;
case SVGA_REG_BYTES_PER_LINE:
- return ((s->depth + 7) >> 3) * s->new_width;
+ return ds_get_linesize(s->vga.ds);
case SVGA_REG_FB_START:
return s->vram_base;
@@ -692,7 +696,7 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address)
return s->vga.vram_size - SVGA_FIFO_SIZE;
case SVGA_REG_FB_SIZE:
- return s->fb_size;
+ return fb_size(s);
case SVGA_REG_CAPABILITIES:
caps = SVGA_CAP_NONE;
@@ -737,9 +741,6 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address)
case SVGA_REG_CURSOR_ON:
return s->cursor.on;
- case SVGA_REG_HOST_BITS_PER_PIXEL:
- return (s->depth + 7) & ~7;
-
case SVGA_REG_SCRATCH_SIZE:
return s->scratch_size;
@@ -777,8 +778,6 @@ static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value)
#ifdef EMBED_STDVGA
s->vga.invalidate(&s->vga);
#endif
- if (s->enable)
- s->fb_size = ((s->depth + 7) >> 3) * s->new_width * s->new_height;
break;
case SVGA_REG_WIDTH:
@@ -793,7 +792,7 @@ static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value)
case SVGA_REG_DEPTH:
case SVGA_REG_BITS_PER_PIXEL:
- if (value != s->depth) {
+ if (value != ds_get_bits_per_pixel(s->vga.ds)) {
printf("%s: Bad colour depth: %i bits\n", __FUNCTION__, value);
s->config = 0;
}
@@ -923,38 +922,9 @@ static void vmsvga_reset(struct vmsvga_state_s *s)
s->width = -1;
s->height = -1;
s->svgaid = SVGA_ID;
- s->depth = 24;
- s->bypp = (s->depth + 7) >> 3;
s->cursor.on = 0;
s->redraw_fifo_first = 0;
s->redraw_fifo_last = 0;
- switch (s->depth) {
- case 8:
- s->wred = 0x00000007;
- s->wgreen = 0x00000038;
- s->wblue = 0x000000c0;
- break;
- case 15:
- s->wred = 0x0000001f;
- s->wgreen = 0x000003e0;
- s->wblue = 0x00007c00;
- break;
- case 16:
- s->wred = 0x0000001f;
- s->wgreen = 0x000007e0;
- s->wblue = 0x0000f800;
- break;
- case 24:
- s->wred = 0x00ff0000;
- s->wgreen = 0x0000ff00;
- s->wblue = 0x000000ff;
- break;
- case 32:
- s->wred = 0x00ff0000;
- s->wgreen = 0x0000ff00;
- s->wblue = 0x000000ff;
- break;
- }
s->syncing = 0;
}
@@ -983,7 +953,7 @@ static void vmsvga_screen_dump(void *opaque, const char *filename)
return;
}
- if (s->depth == 32) {
+ if (ds_get_bits_per_pixel(s->vga.ds) == 32) {
DisplaySurface *ds = qemu_create_displaysurface_from(s->width,
s->height, 32, ds_get_linesize(s->vga.ds), s->vga.vram_ptr);
ppm_save(filename, ds);
@@ -1072,7 +1042,7 @@ static CPUWriteMemoryFunc *vmsvga_vram_write[] = {
static void vmsvga_save(struct vmsvga_state_s *s, QEMUFile *f)
{
- qemu_put_be32(f, s->depth);
+ qemu_put_be32(f, ds_get_bits_per_pixel(s->vga.ds));
qemu_put_be32(f, s->enable);
qemu_put_be32(f, s->config);
qemu_put_be32(f, s->cursor.id);
@@ -1086,7 +1056,7 @@ static void vmsvga_save(struct vmsvga_state_s *s, QEMUFile *f)
qemu_put_be32s(f, &s->guest);
qemu_put_be32s(f, &s->svgaid);
qemu_put_be32(f, s->syncing);
- qemu_put_be32(f, s->fb_size);
+ qemu_put_be32(f, fb_size(s));
}
static int vmsvga_load(struct vmsvga_state_s *s, QEMUFile *f)
@@ -1106,9 +1076,9 @@ static int vmsvga_load(struct vmsvga_state_s *s, QEMUFile *f)
qemu_get_be32s(f, &s->guest);
qemu_get_be32s(f, &s->svgaid);
s->syncing=qemu_get_be32(f);
- s->fb_size=qemu_get_be32(f);
+ qemu_get_be32(f); // fb_size is not used anymore
- if (s->enable && depth != s->depth) {
+ if (s->enable && depth != ds_get_bits_per_pixel(s->vga.ds)) {
printf("%s: need colour depth of %i bits to resume operation.\n",
__FUNCTION__, depth);
return -EINVAL;
prev parent reply other threads:[~2009-08-25 15:01 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-08-17 10:08 [Qemu-devel] [PATCH] use corect depth from DisplaySurface in vmware_vga.c Reimar Döffinger
2009-08-23 17:25 ` andrzej zaborowski
2009-08-24 13:22 ` Reimar Döffinger
2009-08-24 23:45 ` andrzej zaborowski
2009-08-25 14:54 ` Reimar Döffinger [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090825145411.GA13710@1und1.de \
--to=reimar.doeffinger@gmx.de \
--cc=balrogg@gmail.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).