* Made the accelerant safer to use when cloned (though I didn't test cloning yet);
introduced a lock that is used in B_SET_DISPLAY_MODE etc. * Correctly implemented B_ACQUIRE_ENGINE and B_RELEASE_ENGINE now (ie. they lock the engine now). * The lock of the ring buffers is now deleted when the (primary) accelerant is closed. * Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17453 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -72,6 +72,9 @@ struct intel_shared_info {
|
||||
|
||||
uint32 frame_buffer_offset;
|
||||
|
||||
struct lock accelerant_lock;
|
||||
struct lock engine_lock;
|
||||
|
||||
ring_buffer primary_ring_buffer;
|
||||
ring_buffer secondary_ring_buffer;
|
||||
|
||||
|
||||
@@ -153,9 +153,6 @@ uninit_common(void)
|
||||
|
||||
gInfo->regs_area = gInfo->shared_info_area = -1;
|
||||
|
||||
gInfo->regs = NULL;
|
||||
gInfo->shared_info = NULL;
|
||||
|
||||
// close the file handle ONLY if we're the clone
|
||||
if (gInfo->is_clone)
|
||||
close(gInfo->device);
|
||||
@@ -178,8 +175,13 @@ intel_init_accelerant(int device)
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
setup_ring_buffer(gInfo->shared_info->primary_ring_buffer, "intel primary ring buffer");
|
||||
setup_ring_buffer(gInfo->shared_info->secondary_ring_buffer, "intel secondary ring buffer");
|
||||
intel_shared_info &info = *gInfo->shared_info;
|
||||
|
||||
init_lock(&info.accelerant_lock, "intel extreme accelerant");
|
||||
init_lock(&info.engine_lock, "intel extreme engine");
|
||||
|
||||
setup_ring_buffer(info.primary_ring_buffer, "intel primary ring buffer");
|
||||
setup_ring_buffer(info.secondary_ring_buffer, "intel secondary ring buffer");
|
||||
|
||||
status = create_mode_list();
|
||||
if (status != B_OK) {
|
||||
@@ -260,6 +262,14 @@ intel_uninit_accelerant(void)
|
||||
delete_area(gInfo->mode_list_area);
|
||||
gInfo->mode_list = NULL;
|
||||
|
||||
intel_shared_info &info = *gInfo->shared_info;
|
||||
|
||||
uninit_lock(&info.accelerant_lock);
|
||||
uninit_lock(&info.engine_lock);
|
||||
|
||||
uninit_ring_buffer(info.primary_ring_buffer);
|
||||
uninit_ring_buffer(info.secondary_ring_buffer);
|
||||
|
||||
uninit_common();
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ extern void enable_display_plane(bool enable);
|
||||
extern void set_display_power_mode(uint32 mode);
|
||||
|
||||
// engine.cpp
|
||||
extern void uninit_ring_buffer(ring_buffer &ringBuffer);
|
||||
extern void setup_ring_buffer(ring_buffer &ringBuffer, const char *name);
|
||||
|
||||
// modes.cpp
|
||||
|
||||
@@ -117,6 +117,14 @@ QueueCommands::_Write(uint32 data)
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
void
|
||||
uninit_ring_buffer(ring_buffer &ringBuffer)
|
||||
{
|
||||
uninit_lock(&ringBuffer.lock);
|
||||
write32(ringBuffer.register_base + RING_BUFFER_CONTROL, 0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
setup_ring_buffer(ring_buffer &ringBuffer, const char *name)
|
||||
{
|
||||
@@ -158,6 +166,12 @@ intel_acquire_engine(uint32 capabilities, uint32 maxWait, sync_token *syncToken,
|
||||
TRACE(("intel_acquire_engine()\n"));
|
||||
*_engineToken = &sEngineToken;
|
||||
|
||||
if (acquire_lock(&gInfo->shared_info->engine_lock) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
if (syncToken)
|
||||
intel_sync_to_token(syncToken);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -169,6 +183,7 @@ intel_release_engine(engine_token *engineToken, sync_token *syncToken)
|
||||
if (syncToken != NULL)
|
||||
syncToken->engine_id = engineToken->engine_id;
|
||||
|
||||
release_lock(&gInfo->shared_info->engine_lock);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -235,11 +235,12 @@ intel_set_display_mode(display_mode *mode)
|
||||
{
|
||||
TRACE(("intel_set_display_mode()\n"));
|
||||
|
||||
// TODO: locking!
|
||||
intel_shared_info &sharedInfo = *gInfo->shared_info;
|
||||
|
||||
if (mode == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
Autolock locker(sharedInfo.accelerant_lock);
|
||||
display_mode current = *mode;
|
||||
|
||||
set_display_power_mode(B_DPMS_OFF);
|
||||
@@ -255,17 +256,17 @@ intel_set_display_mode(display_mode *mode)
|
||||
if (intel_allocate_memory(bytesPerRow * current.virtual_height,
|
||||
gInfo->frame_buffer_handle, offset) < B_OK) {
|
||||
// oh, how did that happen? Unfortunately, there is no really good way back
|
||||
if (intel_allocate_memory(gInfo->shared_info->current_mode.virtual_height
|
||||
* gInfo->shared_info->bytes_per_row, gInfo->frame_buffer_handle,
|
||||
if (intel_allocate_memory(sharedInfo.current_mode.virtual_height
|
||||
* sharedInfo.bytes_per_row, gInfo->frame_buffer_handle,
|
||||
offset) == B_OK) {
|
||||
gInfo->shared_info->frame_buffer_offset = offset;
|
||||
sharedInfo.frame_buffer_offset = offset;
|
||||
write32(INTEL_DISPLAY_BASE, offset);
|
||||
}
|
||||
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
gInfo->shared_info->frame_buffer_offset = offset;
|
||||
sharedInfo.frame_buffer_offset = offset;
|
||||
|
||||
// update timing parameters
|
||||
|
||||
@@ -313,17 +314,17 @@ intel_set_display_mode(display_mode *mode)
|
||||
write32(INTEL_DISPLAY_CONTROL, (read32(INTEL_DISPLAY_CONTROL)
|
||||
& ~DISPLAY_CONTROL_COLOR_MASK) | colorMode);
|
||||
|
||||
set_display_power_mode(gInfo->shared_info->dpms_mode);
|
||||
set_display_power_mode(sharedInfo.dpms_mode);
|
||||
|
||||
// changing bytes per row seems to be ignored if the plane/pipe is turned off
|
||||
write32(INTEL_DISPLAY_BYTES_PER_ROW, bytesPerRow);
|
||||
write32(INTEL_DISPLAY_BASE, gInfo->shared_info->frame_buffer_offset);
|
||||
write32(INTEL_DISPLAY_BASE, sharedInfo.frame_buffer_offset);
|
||||
// triggers writing back double-buffered registers
|
||||
|
||||
// update shared info
|
||||
gInfo->shared_info->bytes_per_row = bytesPerRow;
|
||||
gInfo->shared_info->current_mode = current;
|
||||
gInfo->shared_info->bits_per_pixel = bitsPerPixel;
|
||||
sharedInfo.bytes_per_row = bytesPerRow;
|
||||
sharedInfo.current_mode = current;
|
||||
sharedInfo.bits_per_pixel = bitsPerPixel;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
@@ -381,7 +382,11 @@ status_t
|
||||
intel_move_display(uint16 horizontalStart, uint16 verticalStart)
|
||||
{
|
||||
TRACE(("intel_move_display()\n"));
|
||||
display_mode &mode = gInfo->shared_info->current_mode;
|
||||
|
||||
intel_shared_info &sharedInfo = *gInfo->shared_info;
|
||||
Autolock locker(sharedInfo.accelerant_lock);
|
||||
|
||||
display_mode &mode = sharedInfo.current_mode;
|
||||
|
||||
if (horizontalStart + mode.timing.h_display > mode.virtual_width
|
||||
|| verticalStart + mode.timing.v_display > mode.virtual_height)
|
||||
@@ -390,9 +395,9 @@ intel_move_display(uint16 horizontalStart, uint16 verticalStart)
|
||||
mode.h_display_start = horizontalStart;
|
||||
mode.v_display_start = verticalStart;
|
||||
|
||||
write32(INTEL_DISPLAY_BASE, gInfo->shared_info->frame_buffer_offset
|
||||
+ verticalStart * gInfo->shared_info->bytes_per_row
|
||||
+ horizontalStart * (gInfo->shared_info->bits_per_pixel + 7) / 8);
|
||||
write32(INTEL_DISPLAY_BASE, sharedInfo.frame_buffer_offset
|
||||
+ verticalStart * sharedInfo.bytes_per_row
|
||||
+ horizontalStart * (sharedInfo.bits_per_pixel + 7) / 8);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
@@ -414,6 +419,8 @@ intel_set_indexed_colors(uint count, uint8 first, uint8 *colors, uint32 flags)
|
||||
if (colors == NULL)
|
||||
return;
|
||||
|
||||
Autolock locker(gInfo->shared_info->accelerant_lock);
|
||||
|
||||
for (; count-- > 0; first++) {
|
||||
uint32 color = colors[0] << 16 | colors[1] << 8 | colors[2];
|
||||
colors += 3;
|
||||
|
||||
Reference in New Issue
Block a user