diff --git a/headers/private/graphics/vmware/DriverInterface.h b/headers/private/graphics/vmware/DriverInterface.h index a41611885e..7f0de896e0 100644 --- a/headers/private/graphics/vmware/DriverInterface.h +++ b/headers/private/graphics/vmware/DriverInterface.h @@ -6,6 +6,7 @@ * Authors: * Be Incorporated * Eric Petit + * Michael Pfeiffer */ #ifndef DRIVERINTERFACE_H @@ -14,6 +15,7 @@ #include #include #include +#include #include #include @@ -99,6 +101,7 @@ typedef struct { /* For registers access */ uint16 indexPort; uint16 valuePort; + spinlock portLock; /* Mapped areas */ area_id fbArea; @@ -116,6 +119,11 @@ typedef struct { Benaphore engineLock; Benaphore fifoLock; uint32 fifoNext; + + /* Cursor state */ + bool cursorShow; + uint16 cursorX; + uint16 cursorY; } SharedInfo; #endif diff --git a/src/add-ons/accelerants/vmware/Acceleration.c b/src/add-ons/accelerants/vmware/Acceleration.c index 03ca0985a0..d0757e4f5f 100644 --- a/src/add-ons/accelerants/vmware/Acceleration.c +++ b/src/add-ons/accelerants/vmware/Acceleration.c @@ -6,6 +6,7 @@ * Authors: * Be Incorporated * Eric Petit + * Michael Pfeiffer */ @@ -18,13 +19,13 @@ SCREEN_TO_SCREEN_BLIT(engine_token *et, blit_params *list, uint32 count) uint32 i; blit_params *b; + FifoBeginWrite(); for (i = 0; i < count; i++) { b = &list[i]; #if 0 TRACE("BLIT %dx%d, %dx%d->%dx%d\n", b->width + 1, b->height + 1, b->src_left, b->src_top, b->dest_left, b->dest_top); #endif - FifoBeginWrite(); FifoWrite(SVGA_CMD_RECT_COPY); FifoWrite(b->src_left); FifoWrite(b->src_top); @@ -32,8 +33,9 @@ SCREEN_TO_SCREEN_BLIT(engine_token *et, blit_params *list, uint32 count) FifoWrite(b->dest_top); FifoWrite(b->width + 1); FifoWrite(b->height + 1); - FifoEndWrite(); } + FifoEndWrite(); + FifoSync(); } diff --git a/src/add-ons/accelerants/vmware/Cursor.c b/src/add-ons/accelerants/vmware/Cursor.c index db380e78f8..f107127bda 100644 --- a/src/add-ons/accelerants/vmware/Cursor.c +++ b/src/add-ons/accelerants/vmware/Cursor.c @@ -6,16 +6,75 @@ * Authors: * Be Incorporated * Eric Petit + * Michael Pfeiffer */ #include "GlobalData.h" + +static void +WriteScanline(void * scanline, uint16 sizeInBytes) +{ + uint32* words = (uint32*)scanline; + /* sizeInBytes must be a multiple of 4 */ + uint16 sizeInWords = sizeInBytes / 4; + uint16 i; + for (i = 0; i < sizeInWords; i ++) + FifoWrite(words[i]); +} + + +static void +WriteAndMask(uint8 * andMask, uint16 width, uint16 height, uint8 * scanline, + uint16 scanlineSize) +{ + uint16 y; + uint16 bpr = (width + 7) / 8; + for (y = 0; y < height; y ++) { + // copy andMask into scanline to avoid + // out of bounds access at last row + memcpy(scanline, &andMask[y * bpr], bpr); + WriteScanline(scanline, scanlineSize); + } +} + + +static void +WriteXorMask(uint8 * andMask, uint8 * xorMask, uint16 width, uint16 height, + uint8 * scanline, uint16 scanlineSize) +{ + uint16 x; + uint16 y; + uint16 bpr = (width + 7) / 8; + for (y = 0; y < height; y ++) { + uint8 * andMaskRow = &andMask[y * bpr]; + // copy xorMask into scanline to avoid + // out of bounds access at last row + memcpy(scanline, &xorMask[y * bpr], bpr); + // in case of a 1 bit in andMask + // the meaning of the corresponding bit + // in xorMask is the opposite in the + // emulated graphics HW (1 = white, 0 = + // black). Be API: 1 = black, 0 = white. + for (x = 0; x < width; x ++) { + uint8 bit = 7 - x % 8; + uint8 bitMask = 1 << bit; + uint16 byte = x / 8; + if ((andMaskRow[byte] & bitMask) == 0) + scanline[byte] = scanline[byte] ^ bitMask; + } + WriteScanline(scanline, scanlineSize); + } +} + + status_t SET_CURSOR_SHAPE(uint16 width, uint16 height, uint16 hot_x, uint16 hot_y, uint8 * andMask, uint8 * xorMask) { - int i, shift; - uint32 * alphaCursor; + + uint16 scanlineSize; + uint8 * scanline; TRACE("SET_CURSOR_SHAPE (%d, %d, %d, %d)\n", width, height, hot_x, hot_y); @@ -23,37 +82,26 @@ SET_CURSOR_SHAPE(uint16 width, uint16 height, uint16 hot_x, if (hot_x >= width || hot_y >= height) return B_ERROR; - /* Build ARGB image */ - alphaCursor = calloc(1, height * width * sizeof(uint32)); - shift = 7; - for (i = 0; i < height * width; i++) { - if (!((*andMask >> shift) & 1)) { - /* Opaque */ - alphaCursor[i] |= 0xFF000000; - if (!((*xorMask >> shift) & 1)) - /* White */ - alphaCursor[i] |= 0x00FFFFFF; - } - if (--shift < 0) { - shift = 7; - andMask++; - xorMask++; - } - } - - /* Give it to VMware */ + scanlineSize = 4 * ((width + 31) / 32); + scanline = calloc(1, scanlineSize); + if (calloc == NULL) + return B_ERROR; + FifoBeginWrite(); - FifoWrite(SVGA_CMD_DEFINE_ALPHA_CURSOR); + FifoWrite(SVGA_CMD_DEFINE_CURSOR); FifoWrite(CURSOR_ID); FifoWrite(hot_x); FifoWrite(hot_y); FifoWrite(width); FifoWrite(height); - for (i = 0; i < height * width; i++) - FifoWrite(alphaCursor[i]); + FifoWrite(1); + FifoWrite(1); + WriteAndMask(andMask, width, height, scanline, scanlineSize); + WriteXorMask(andMask, xorMask, width, height, scanline, scanlineSize); FifoEndWrite(); - - free(alphaCursor); + FifoSync(); + + free(scanline); return B_OK; } diff --git a/src/add-ons/accelerants/vmware/GetAccelerantHook.c b/src/add-ons/accelerants/vmware/GetAccelerantHook.c index 3cebed241e..94e1806adc 100644 --- a/src/add-ons/accelerants/vmware/GetAccelerantHook.c +++ b/src/add-ons/accelerants/vmware/GetAccelerantHook.c @@ -6,6 +6,7 @@ * Authors: * Be Incorporated * Eric Petit + * Michael Pfeiffer */ #include "GlobalData.h" @@ -17,6 +18,7 @@ get_accelerant_hook(uint32 feature, void *data) switch (feature) { #define HOOK(x) case B_##x: return (void *)x #define ZERO(x) case B_##x: return (void *)0 +#define HOOK_IF(x, cap) case B_##x: if (gSi->capabilities & cap) return (void *)x; else return (void *)0 /* initialization */ HOOK(INIT_ACCELERANT); @@ -46,13 +48,9 @@ get_accelerant_hook(uint32 feature, void *data) HOOK(SET_DPMS_MODE); /* Cursor managment (Cursor.c) */ -#if 0 - if (gSi->capabilities & SVGA_CAP_ALPHA_CURSOR) { - HOOK(SET_CURSOR_SHAPE); - HOOK(MOVE_CURSOR); - HOOK(SHOW_CURSOR); - } -#endif + HOOK_IF(SET_CURSOR_SHAPE, SVGA_CAP_ALPHA_CURSOR); + HOOK_IF(MOVE_CURSOR, SVGA_CAP_ALPHA_CURSOR); + HOOK_IF(SHOW_CURSOR, SVGA_CAP_ALPHA_CURSOR); /* synchronization */ HOOK(ACCELERANT_ENGINE_COUNT); @@ -63,8 +61,7 @@ get_accelerant_hook(uint32 feature, void *data) HOOK(SYNC_TO_TOKEN); /* 2D acceleration (Acceleration.c) */ - if (gSi->capabilities & SVGA_CAP_RECT_COPY) - HOOK(SCREEN_TO_SCREEN_BLIT); + HOOK_IF(SCREEN_TO_SCREEN_BLIT, SVGA_CAP_RECT_COPY); ZERO(FILL_RECTANGLE); ZERO(INVERT_RECTANGLE); ZERO(FILL_SPAN); diff --git a/src/add-ons/kernel/drivers/graphics/vmware/device.c b/src/add-ons/kernel/drivers/graphics/vmware/device.c index 5e3eac6277..6daf315fbc 100644 --- a/src/add-ons/kernel/drivers/graphics/vmware/device.c +++ b/src/add-ons/kernel/drivers/graphics/vmware/device.c @@ -4,6 +4,7 @@ * * Authors: * Eric Petit + * Michael Pfeiffer */ @@ -259,6 +260,17 @@ FreeHook(void *dev) } +static void +UpdateCursor(SharedInfo *si) +{ + WriteReg(SVGA_REG_CURSOR_ID, CURSOR_ID); + WriteReg(SVGA_REG_CURSOR_X, si->cursorX); + WriteReg(SVGA_REG_CURSOR_Y, si->cursorY); + WriteReg(SVGA_REG_CURSOR_ON, si->cursorShow ? SVGA_CURSOR_ON_SHOW : + SVGA_CURSOR_ON_HIDE); +} + + /*--------------------------------------------------------------------*/ /* ControlHook: responds the the ioctl from the accelerant */ @@ -325,17 +337,16 @@ ControlHook(void *dev, uint32 msg, void *buf, size_t len) case VMWARE_MOVE_CURSOR: { uint16 *pos = buf; - WriteReg(SVGA_REG_CURSOR_ID, CURSOR_ID); - WriteReg(SVGA_REG_CURSOR_X, pos[0]); - WriteReg(SVGA_REG_CURSOR_Y, pos[1]); + si->cursorX = pos[0]; + si->cursorY = pos[1]; + UpdateCursor(si); return B_OK; } case VMWARE_SHOW_CURSOR: { - bool show = *((bool *)buf); - WriteReg(SVGA_REG_CURSOR_ON, show ? SVGA_CURSOR_ON_HIDE : - SVGA_CURSOR_ON_SHOW); + si->cursorShow = *((bool *)buf); + UpdateCursor(si); return B_OK; }