- 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:
* Be Incorporated
* Eric Petit <[email protected]>
* Michael Pfeiffer <[email protected]>
*/
#ifndef DRIVERINTERFACE_H
@@ -14,6 +15,7 @@
#include <GraphicsDefs.h>
#include <Accelerant.h>
#include <Drivers.h>
#include <KernelExport.h>
#include <PCI.h>
#include <OS.h>
@@ -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
@@ -6,6 +6,7 @@
* Authors:
* Be Incorporated
* 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;
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();
}
+74 -26
View File
@@ -6,16 +6,75 @@
* Authors:
* Be Incorporated
* Eric Petit <[email protected]>
* Michael Pfeiffer <[email protected]>
*/
#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;
}
@@ -6,6 +6,7 @@
* Authors:
* Be Incorporated
* Eric Petit <[email protected]>
* Michael Pfeiffer <[email protected]>
*/
#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);
@@ -4,6 +4,7 @@
*
* Authors:
* 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 */
@@ -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;
}