From 973d499ee1ed8d233b5c8c03685dbcfb25c03816 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sun, 14 May 2006 14:27:50 +0000 Subject: [PATCH] * 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 --- .../graphics/intel_extreme/intel_extreme.h | 3 ++ .../accelerants/intel_extreme/accelerant.cpp | 20 ++++++++--- .../accelerants/intel_extreme/accelerant.h | 1 + .../accelerants/intel_extreme/engine.cpp | 15 ++++++++ .../accelerants/intel_extreme/mode.cpp | 35 +++++++++++-------- 5 files changed, 55 insertions(+), 19 deletions(-) diff --git a/headers/private/graphics/intel_extreme/intel_extreme.h b/headers/private/graphics/intel_extreme/intel_extreme.h index 0d19a4e664..df619f8fef 100644 --- a/headers/private/graphics/intel_extreme/intel_extreme.h +++ b/headers/private/graphics/intel_extreme/intel_extreme.h @@ -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; diff --git a/src/add-ons/accelerants/intel_extreme/accelerant.cpp b/src/add-ons/accelerants/intel_extreme/accelerant.cpp index 3719a32af9..9103be8e49 100644 --- a/src/add-ons/accelerants/intel_extreme/accelerant.cpp +++ b/src/add-ons/accelerants/intel_extreme/accelerant.cpp @@ -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(); } diff --git a/src/add-ons/accelerants/intel_extreme/accelerant.h b/src/add-ons/accelerants/intel_extreme/accelerant.h index 86ce0a68a7..2f4841ac43 100644 --- a/src/add-ons/accelerants/intel_extreme/accelerant.h +++ b/src/add-ons/accelerants/intel_extreme/accelerant.h @@ -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 diff --git a/src/add-ons/accelerants/intel_extreme/engine.cpp b/src/add-ons/accelerants/intel_extreme/engine.cpp index 56bd204a68..7e57703773 100644 --- a/src/add-ons/accelerants/intel_extreme/engine.cpp +++ b/src/add-ons/accelerants/intel_extreme/engine.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; } diff --git a/src/add-ons/accelerants/intel_extreme/mode.cpp b/src/add-ons/accelerants/intel_extreme/mode.cpp index 90f86947fd..2e82ac4bf5 100644 --- a/src/add-ons/accelerants/intel_extreme/mode.cpp +++ b/src/add-ons/accelerants/intel_extreme/mode.cpp @@ -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;