* Implemented hardware cursor support.
* Turns out cursor handling is simpler as originally thought, so I could remove its physical mapping - it's still put into the shared area, though, although that isn't needed for this chip (but could eventually simplify the handling of other generations of this chip). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17450 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
8cb10e136c
commit
7d5957df85
@ -64,7 +64,6 @@ struct intel_shared_info {
|
||||
|
||||
area_id registers_area; // area of memory mapped registers
|
||||
uint8 *physical_status_page;
|
||||
area_id cursor_area;
|
||||
uint8 *physical_cursor_memory;
|
||||
area_id graphics_memory_area;
|
||||
uint8 *graphics_memory;
|
||||
@ -83,6 +82,12 @@ struct intel_shared_info {
|
||||
|
||||
sem_id vblank_sem;
|
||||
|
||||
uint32 cursor_buffer_offset;
|
||||
uint32 cursor_format;
|
||||
bool cursor_visible;
|
||||
uint16 cursor_hot_x;
|
||||
uint16 cursor_hot_y;
|
||||
|
||||
uint32 device_type;
|
||||
char device_identifier[32];
|
||||
struct pll_info pll_info;
|
||||
@ -97,7 +102,6 @@ struct intel_info {
|
||||
area_id registers_area;
|
||||
struct intel_shared_info *shared_info;
|
||||
area_id shared_area;
|
||||
area_id cursor_area;
|
||||
|
||||
struct overlay_registers *overlay_registers;
|
||||
// update buffer, shares an area with shared_info
|
||||
@ -267,6 +271,8 @@ struct intel_free_graphics_memory {
|
||||
#define CURSOR_FORMAT_4_COLORS (2UL << 24)
|
||||
#define CURSOR_FORMAT_ARGB (4UL << 24)
|
||||
#define CURSOR_FORMAT_XRGB (5UL << 24)
|
||||
#define CURSOR_POSITION_NEGATIVE 0x8000
|
||||
#define CURSOR_POSITION_MASK 0x3fff
|
||||
|
||||
// ring buffer commands
|
||||
|
||||
|
@ -8,6 +8,7 @@ UsePrivateHeaders [ FDirName graphics common ] ;
|
||||
|
||||
Addon intel_extreme.accelerant : accelerants :
|
||||
accelerant.cpp
|
||||
cursor.cpp
|
||||
dpms.cpp
|
||||
engine.cpp
|
||||
hooks.cpp
|
||||
|
@ -128,19 +128,8 @@ init_common(int device, bool isClone)
|
||||
return status;
|
||||
}
|
||||
|
||||
AreaCloner cursorCloner;
|
||||
gInfo->cursor_area = cursorCloner.Clone("intel extreme cursor",
|
||||
(void **)&gInfo->cursor_memory, B_ANY_ADDRESS,
|
||||
B_READ_AREA | B_WRITE_AREA,
|
||||
gInfo->shared_info->cursor_area);
|
||||
if (cursorCloner.InitCheck() < B_OK) {
|
||||
// we can't do a hardware cursor then...
|
||||
gInfo->cursor_memory = NULL;
|
||||
}
|
||||
|
||||
sharedCloner.Keep();
|
||||
regsCloner.Keep();
|
||||
cursorCloner.Keep();
|
||||
|
||||
// The overlay registers, hardware status, and cursor memory share
|
||||
// a single area with the shared_info
|
||||
@ -159,7 +148,6 @@ init_common(int device, bool isClone)
|
||||
static void
|
||||
uninit_common(void)
|
||||
{
|
||||
delete_area(gInfo->cursor_area);
|
||||
delete_area(gInfo->regs_area);
|
||||
delete_area(gInfo->shared_info_area);
|
||||
|
||||
|
@ -49,7 +49,6 @@ struct accelerant_info {
|
||||
|
||||
hardware_status *status;
|
||||
uint8 *cursor_memory;
|
||||
area_id cursor_area;
|
||||
|
||||
int device;
|
||||
bool is_clone;
|
||||
|
124
src/add-ons/accelerants/intel_extreme/cursor.cpp
Normal file
124
src/add-ons/accelerants/intel_extreme/cursor.cpp
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Axel Dörfler, axeld@pinc-software.de
|
||||
*/
|
||||
|
||||
|
||||
#include "accelerant_protos.h"
|
||||
#include "accelerant.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
status_t
|
||||
intel_set_cursor_shape(uint16 width, uint16 height, uint16 hotX, uint16 hotY,
|
||||
uint8 *andMask, uint8 *xorMask)
|
||||
{
|
||||
if (width > 64 || height > 64)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
write32(INTEL_CURSOR_CONTROL, 0);
|
||||
// disable cursor
|
||||
|
||||
// In two-color mode, the data is ordered as follows (always 64 bit per line):
|
||||
// plane 1: line 0 (AND mask)
|
||||
// plane 0: line 0 (XOR mask)
|
||||
// plane 1: line 1 (AND mask)
|
||||
// ...
|
||||
//
|
||||
// If the planes add to the value 0x2, the corresponding pixel is
|
||||
// transparent, for 0x3 it inverts the background, so only the first
|
||||
// two palette entries will be used (since we're using the 2 color mode).
|
||||
|
||||
uint8 *data = gInfo->cursor_memory;
|
||||
uint8 byteWidth = (width + 7) / 8;
|
||||
|
||||
for (int32 y = 0; y < height; y++) {
|
||||
for (int32 x = 0; x < byteWidth; x++) {
|
||||
data[16 * y + x] = andMask[byteWidth * y + x];
|
||||
data[16 * y + x + 8] = xorMask[byteWidth * y + x];
|
||||
}
|
||||
}
|
||||
|
||||
// We can only change the width of the pixel, but apparently
|
||||
// not the height (or at least I couldn't figure out how),
|
||||
// so we need to make the rest transparent
|
||||
for (uint32 y = height; y < 64; y++) {
|
||||
for (int32 x = 0; x < byteWidth; x++) {
|
||||
data[16 * y + x] = 0xff;
|
||||
data[16 * y + x + 8] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// set palette entries to white/black
|
||||
write32(INTEL_CURSOR_PALETTE + 0, 0x00ffffff);
|
||||
write32(INTEL_CURSOR_PALETTE + 4, 0);
|
||||
|
||||
gInfo->shared_info->cursor_format = CURSOR_FORMAT_2_COLORS;
|
||||
|
||||
write32(INTEL_CURSOR_CONTROL, CURSOR_ENABLED | gInfo->shared_info->cursor_format);
|
||||
write32(INTEL_CURSOR_SIZE, width);
|
||||
// TODO: I've no idea how to specify the height of the cursor - it seems to
|
||||
// be always 64 pixels
|
||||
|
||||
write32(INTEL_CURSOR_BASE, (uint32)gInfo->shared_info->physical_graphics_memory
|
||||
+ gInfo->shared_info->cursor_buffer_offset);
|
||||
|
||||
// changing the hot point changes the cursor position, too
|
||||
|
||||
if (hotX != gInfo->shared_info->cursor_hot_x
|
||||
|| hotY != gInfo->shared_info->cursor_hot_y) {
|
||||
int32 x = read32(INTEL_CURSOR_POSITION);
|
||||
int32 y = x >> 16;
|
||||
x &= 0xffff;
|
||||
|
||||
if (x & CURSOR_POSITION_NEGATIVE)
|
||||
x = -(x & CURSOR_POSITION_MASK);
|
||||
if (y & CURSOR_POSITION_NEGATIVE)
|
||||
y = -(y & CURSOR_POSITION_MASK);
|
||||
|
||||
x += gInfo->shared_info->cursor_hot_x;
|
||||
y += gInfo->shared_info->cursor_hot_y;
|
||||
|
||||
gInfo->shared_info->cursor_hot_x = hotX;
|
||||
gInfo->shared_info->cursor_hot_y = hotY;
|
||||
|
||||
intel_move_cursor(x, y);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
intel_move_cursor(uint16 _x, uint16 _y)
|
||||
{
|
||||
int32 x = (int32)_x - gInfo->shared_info->cursor_hot_x;
|
||||
int32 y = (int32)_y - gInfo->shared_info->cursor_hot_x;
|
||||
|
||||
if (x < 0)
|
||||
x = -x | CURSOR_POSITION_NEGATIVE;
|
||||
if (y < 0)
|
||||
y = -y | CURSOR_POSITION_NEGATIVE;
|
||||
|
||||
write32(INTEL_CURSOR_POSITION, (y << 16) | x);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
intel_show_cursor(bool isVisible)
|
||||
{
|
||||
if (gInfo->shared_info->cursor_visible == isVisible)
|
||||
return;
|
||||
|
||||
write32(INTEL_CURSOR_CONTROL, (isVisible ? CURSOR_ENABLED : 0)
|
||||
| gInfo->shared_info->cursor_format);
|
||||
write32(INTEL_CURSOR_BASE, (uint32)gInfo->shared_info->physical_graphics_memory
|
||||
+ gInfo->shared_info->cursor_buffer_offset);
|
||||
|
||||
gInfo->shared_info->cursor_visible = isVisible;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
|
||||
#include "accelerant_protos.h"
|
||||
#include "accelerant.h"
|
||||
|
||||
|
||||
extern "C" void *
|
||||
@ -61,13 +62,18 @@ get_accelerant_hook(uint32 feature, void *data)
|
||||
return intel_set_dpms_mode;
|
||||
|
||||
/* cursor managment */
|
||||
/* case B_SET_CURSOR_SHAPE:
|
||||
return intel_set_cursor_shape;
|
||||
case B_SET_CURSOR_SHAPE:
|
||||
if (gInfo->cursor_memory != NULL)
|
||||
return intel_set_cursor_shape;
|
||||
case B_MOVE_CURSOR:
|
||||
return intel_move_cursor;
|
||||
if (gInfo->cursor_memory != NULL)
|
||||
return intel_move_cursor;
|
||||
case B_SHOW_CURSOR:
|
||||
return intel_show_cursor;
|
||||
*/
|
||||
if (gInfo->cursor_memory != NULL)
|
||||
return intel_show_cursor;
|
||||
|
||||
return NULL;
|
||||
|
||||
/* engine/synchronization */
|
||||
case B_ACCELERANT_ENGINE_COUNT:
|
||||
return intel_accelerant_engine_count;
|
||||
|
@ -438,25 +438,15 @@ intel_extreme_init(intel_info &info)
|
||||
|
||||
// We also need to map the cursor memory into the GTT
|
||||
|
||||
// This could also be part of the usual graphics memory, but for some
|
||||
// reason we need its physical address, too - and we only know that of
|
||||
// the additional memory we allocated.
|
||||
// Unfortunately, the GTT is not readable - we would need to compute
|
||||
// the physical location of stolen memory with some heuristics (as it
|
||||
// should be taken from the top of system memory), and hope that the
|
||||
// BIOS adhered to this specification.
|
||||
// This could also be part of the usual graphics memory, but since we
|
||||
// need to make sure it's not in the graphics local memory (and I don't
|
||||
// even know yet how to determine that a chip has local memory...), we
|
||||
// keep the current strategy and put it into the shared area.
|
||||
// Unfortunately, the GTT is not readable until it has been written into
|
||||
// the double buffered register set; we cannot get its original contents.
|
||||
|
||||
set_gtt_entry(info, totalSize, info.shared_info->physical_cursor_memory);
|
||||
|
||||
AreaKeeper cursorMapper;
|
||||
void *cursorMemory;
|
||||
info.cursor_area = cursorMapper.Map("intel extreme cursor",
|
||||
(void *)(info.shared_info->physical_graphics_memory + totalSize),
|
||||
B_PAGE_SIZE, B_ANY_KERNEL_ADDRESS, 0, &cursorMemory);
|
||||
if (cursorMapper.InitCheck() < B_OK) {
|
||||
// we can't do a hardware cursor, then...
|
||||
}
|
||||
info.shared_info->cursor_area = info.cursor_area;
|
||||
info.shared_info->cursor_buffer_offset = totalSize;
|
||||
|
||||
init_interrupt_handler(info);
|
||||
|
||||
@ -488,7 +478,6 @@ intel_extreme_uninit(intel_info &info)
|
||||
delete_area(info.graphics_memory_area);
|
||||
delete_area(info.registers_area);
|
||||
delete_area(info.shared_area);
|
||||
delete_area(info.cursor_area);
|
||||
|
||||
// we may or may not have allocated additional graphics memory
|
||||
if (info.additional_memory_area >= B_OK)
|
||||
|
Loading…
Reference in New Issue
Block a user