- Fixed HW cursor issues:

- in order to set cursor position SVGA_CURSOR_ON_SHOW has to be written to register SVGA_REG_CURSOR_ON. 
  - do not use alpha cursor because it does not support inverting of source pixels.
- Fixed wrong usage of if-statement inside switch-statement
- Sync at end of SCREEN_TO_SCREEN_BLIT so that app_server does not write to frame buffer while accelerated operation is still running.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23193 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Pfeiffer
2007-12-30 10:06:46 +00:00
parent bf41a1c034
commit 5d632c2aba
5 changed files with 109 additions and 43 deletions
@@ -6,6 +6,7 @@
* Authors: * Authors:
* Be Incorporated * Be Incorporated
* Eric Petit <[email protected]> * Eric Petit <[email protected]>
* Michael Pfeiffer <[email protected]>
*/ */
#ifndef DRIVERINTERFACE_H #ifndef DRIVERINTERFACE_H
@@ -14,6 +15,7 @@
#include <GraphicsDefs.h> #include <GraphicsDefs.h>
#include <Accelerant.h> #include <Accelerant.h>
#include <Drivers.h> #include <Drivers.h>
#include <KernelExport.h>
#include <PCI.h> #include <PCI.h>
#include <OS.h> #include <OS.h>
@@ -99,6 +101,7 @@ typedef struct {
/* For registers access */ /* For registers access */
uint16 indexPort; uint16 indexPort;
uint16 valuePort; uint16 valuePort;
spinlock portLock;
/* Mapped areas */ /* Mapped areas */
area_id fbArea; area_id fbArea;
@@ -116,6 +119,11 @@ typedef struct {
Benaphore engineLock; Benaphore engineLock;
Benaphore fifoLock; Benaphore fifoLock;
uint32 fifoNext; uint32 fifoNext;
/* Cursor state */
bool cursorShow;
uint16 cursorX;
uint16 cursorY;
} SharedInfo; } SharedInfo;
#endif #endif
@@ -6,6 +6,7 @@
* Authors: * Authors:
* Be Incorporated * Be Incorporated
* Eric Petit <[email protected]> * Eric Petit <[email protected]>
* Michael Pfeiffer <[email protected]>
*/ */
@@ -18,13 +19,13 @@ SCREEN_TO_SCREEN_BLIT(engine_token *et, blit_params *list, uint32 count)
uint32 i; uint32 i;
blit_params *b; blit_params *b;
FifoBeginWrite();
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
b = &list[i]; b = &list[i];
#if 0 #if 0
TRACE("BLIT %dx%d, %dx%d->%dx%d\n", b->width + 1, b->height + 1, 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); b->src_left, b->src_top, b->dest_left, b->dest_top);
#endif #endif
FifoBeginWrite();
FifoWrite(SVGA_CMD_RECT_COPY); FifoWrite(SVGA_CMD_RECT_COPY);
FifoWrite(b->src_left); FifoWrite(b->src_left);
FifoWrite(b->src_top); 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->dest_top);
FifoWrite(b->width + 1); FifoWrite(b->width + 1);
FifoWrite(b->height + 1); FifoWrite(b->height + 1);
FifoEndWrite();
} }
FifoEndWrite();
FifoSync();
} }
+74 -26
View File
@@ -6,16 +6,75 @@
* Authors: * Authors:
* Be Incorporated * Be Incorporated
* Eric Petit <[email protected]> * Eric Petit <[email protected]>
* Michael Pfeiffer <[email protected]>
*/ */
#include "GlobalData.h" #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 status_t
SET_CURSOR_SHAPE(uint16 width, uint16 height, uint16 hot_x, SET_CURSOR_SHAPE(uint16 width, uint16 height, uint16 hot_x,
uint16 hot_y, uint8 * andMask, uint8 * xorMask) 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); 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) if (hot_x >= width || hot_y >= height)
return B_ERROR; return B_ERROR;
/* Build ARGB image */ scanlineSize = 4 * ((width + 31) / 32);
alphaCursor = calloc(1, height * width * sizeof(uint32)); scanline = calloc(1, scanlineSize);
shift = 7; if (calloc == NULL)
for (i = 0; i < height * width; i++) { return B_ERROR;
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 */
FifoBeginWrite(); FifoBeginWrite();
FifoWrite(SVGA_CMD_DEFINE_ALPHA_CURSOR); FifoWrite(SVGA_CMD_DEFINE_CURSOR);
FifoWrite(CURSOR_ID); FifoWrite(CURSOR_ID);
FifoWrite(hot_x); FifoWrite(hot_x);
FifoWrite(hot_y); FifoWrite(hot_y);
FifoWrite(width); FifoWrite(width);
FifoWrite(height); FifoWrite(height);
for (i = 0; i < height * width; i++) FifoWrite(1);
FifoWrite(alphaCursor[i]); FifoWrite(1);
WriteAndMask(andMask, width, height, scanline, scanlineSize);
WriteXorMask(andMask, xorMask, width, height, scanline, scanlineSize);
FifoEndWrite(); FifoEndWrite();
FifoSync();
free(alphaCursor);
free(scanline);
return B_OK; return B_OK;
} }
@@ -6,6 +6,7 @@
* Authors: * Authors:
* Be Incorporated * Be Incorporated
* Eric Petit <[email protected]> * Eric Petit <[email protected]>
* Michael Pfeiffer <[email protected]>
*/ */
#include "GlobalData.h" #include "GlobalData.h"
@@ -17,6 +18,7 @@ get_accelerant_hook(uint32 feature, void *data)
switch (feature) { switch (feature) {
#define HOOK(x) case B_##x: return (void *)x #define HOOK(x) case B_##x: return (void *)x
#define ZERO(x) case B_##x: return (void *)0 #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 */ /* initialization */
HOOK(INIT_ACCELERANT); HOOK(INIT_ACCELERANT);
@@ -46,13 +48,9 @@ get_accelerant_hook(uint32 feature, void *data)
HOOK(SET_DPMS_MODE); HOOK(SET_DPMS_MODE);
/* Cursor managment (Cursor.c) */ /* Cursor managment (Cursor.c) */
#if 0 HOOK_IF(SET_CURSOR_SHAPE, SVGA_CAP_ALPHA_CURSOR);
if (gSi->capabilities & SVGA_CAP_ALPHA_CURSOR) { HOOK_IF(MOVE_CURSOR, SVGA_CAP_ALPHA_CURSOR);
HOOK(SET_CURSOR_SHAPE); HOOK_IF(SHOW_CURSOR, SVGA_CAP_ALPHA_CURSOR);
HOOK(MOVE_CURSOR);
HOOK(SHOW_CURSOR);
}
#endif
/* synchronization */ /* synchronization */
HOOK(ACCELERANT_ENGINE_COUNT); HOOK(ACCELERANT_ENGINE_COUNT);
@@ -63,8 +61,7 @@ get_accelerant_hook(uint32 feature, void *data)
HOOK(SYNC_TO_TOKEN); HOOK(SYNC_TO_TOKEN);
/* 2D acceleration (Acceleration.c) */ /* 2D acceleration (Acceleration.c) */
if (gSi->capabilities & SVGA_CAP_RECT_COPY) HOOK_IF(SCREEN_TO_SCREEN_BLIT, SVGA_CAP_RECT_COPY);
HOOK(SCREEN_TO_SCREEN_BLIT);
ZERO(FILL_RECTANGLE); ZERO(FILL_RECTANGLE);
ZERO(INVERT_RECTANGLE); ZERO(INVERT_RECTANGLE);
ZERO(FILL_SPAN); ZERO(FILL_SPAN);
@@ -4,6 +4,7 @@
* *
* Authors: * Authors:
* Eric Petit <[email protected]> * Eric Petit <[email protected]>
* Michael Pfeiffer <[email protected]>
*/ */
@@ -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 */ /* 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: case VMWARE_MOVE_CURSOR:
{ {
uint16 *pos = buf; uint16 *pos = buf;
WriteReg(SVGA_REG_CURSOR_ID, CURSOR_ID); si->cursorX = pos[0];
WriteReg(SVGA_REG_CURSOR_X, pos[0]); si->cursorY = pos[1];
WriteReg(SVGA_REG_CURSOR_Y, pos[1]); UpdateCursor(si);
return B_OK; return B_OK;
} }
case VMWARE_SHOW_CURSOR: case VMWARE_SHOW_CURSOR:
{ {
bool show = *((bool *)buf); si->cursorShow = *((bool *)buf);
WriteReg(SVGA_REG_CURSOR_ON, show ? SVGA_CURSOR_ON_HIDE : UpdateCursor(si);
SVGA_CURSOR_ON_SHOW);
return B_OK; return B_OK;
} }