vfs: check userland buffers before reading them.
[haiku.git] / src / tests / servers / app / newerClipping / drawing / AccelerantHWInterface.cpp
blob630dd83cf0445f77c13c3331f0456ccd41b83ff1
1 /*
2 * Copyright 2001-2005, Haiku.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Michael Lotz <mmlr@mlotz.ch>
7 * DarkWyrm <bpmagic@columbus.rr.com>
8 * Stephan Aßmus <superstippi@gmx.de>
9 */
11 /** Accelerant based HWInterface implementation */
13 #include <new>
14 #include <malloc.h>
15 #include <stdio.h>
16 #include <string.h>
18 #include <Cursor.h>
20 #include <graphic_driver.h>
21 #include <FindDirectory.h>
22 #include <image.h>
23 #include <dirent.h>
24 #include <sys/ioctl.h>
25 #include <unistd.h>
27 #include "AccelerantHWInterface.h"
28 //#include "AccelerantBuffer.h"
29 //#include "MallocBuffer.h"
31 using std::nothrow;
33 #define DEBUG_DRIVER_MODULE
35 #ifdef DEBUG_DRIVER_MODULE
36 # include <stdio.h>
37 # define ATRACE(x) printf x
38 #else
39 # define ATRACE(x) ;
40 #endif
42 // constructor
43 AccelerantHWInterface::AccelerantHWInterface()
44 : //HWInterface(),
45 fCardFD(-1),
46 fAccelerantImage(-1),
47 fAccelerantHook(NULL),
48 fEngineToken(NULL),
49 fSyncToken(),
51 // required hooks
52 fAccAcquireEngine(NULL),
53 fAccReleaseEngine(NULL),
54 fAccSyncToToken(NULL),
55 fAccGetModeCount(NULL),
56 fAccGetModeList(NULL),
57 fAccGetFrameBufferConfig(NULL),
58 fAccSetDisplayMode(NULL),
59 fAccGetDisplayMode(NULL),
60 fAccGetPixelClockLimits(NULL),
62 // optional accelerant hooks
63 fAccGetTimingConstraints(NULL),
64 fAccProposeDisplayMode(NULL),
65 fAccFillRect(NULL),
66 fAccInvertRect(NULL),
67 fAccScreenBlit(NULL),
68 fAccSetCursorShape(NULL),
69 fAccMoveCursor(NULL),
70 fAccShowCursor(NULL)//,
72 // dpms hooks
73 /* fAccDPMSCapabilities(NULL),
74 fAccDPMSMode(NULL),
75 fAccSetDPMSMode(NULL),
77 fModeCount(0),
78 fModeList(NULL),*/
80 // fBackBuffer(NULL),
81 // fFrontBuffer(new(nothrow) AccelerantBuffer())
83 /* fDisplayMode.virtual_width = 640;
84 fDisplayMode.virtual_height = 480;
85 fDisplayMode.space = B_RGB32;*/
87 // NOTE: I have no clue what I'm doing here.
88 // fSyncToken.counter = 0;
89 // fSyncToken.engine_id = 0;
90 memset(&fSyncToken, 0, sizeof(sync_token));
93 // destructor
94 AccelerantHWInterface::~AccelerantHWInterface()
96 // delete fBackBuffer;
97 // delete fFrontBuffer;
98 // delete[] fModeList;
103 \brief Opens the first available graphics device and initializes it
104 \return B_OK on success or an appropriate error message on failure.
106 status_t
107 AccelerantHWInterface::Initialize()
109 status_t ret = B_OK;//HWInterface::Initialize();
110 if (ret >= B_OK) {
111 for (int32 i = 1; fCardFD != B_ENTRY_NOT_FOUND; i++) {
112 fCardFD = _OpenGraphicsDevice(i);
113 if (fCardFD < 0) {
114 ATRACE(("Failed to open graphics device\n"));
115 continue;
118 if (_OpenAccelerant(fCardFD) == B_OK)
119 break;
121 close(fCardFD);
122 // _OpenAccelerant() failed, try to open next graphics card
125 return fCardFD >= 0 ? B_OK : fCardFD;
127 return ret;
132 \brief Opens a graphics device for read-write access
133 \param deviceNumber Number identifying which graphics card to open (1 for first card)
134 \return The file descriptor for the opened graphics device
136 The deviceNumber is relative to the number of graphics devices that can be successfully
137 opened. One represents the first card that can be successfully opened (not necessarily
138 the first one listed in the directory).
139 Graphics drivers must be able to be opened more than once, so we really get
140 the first working entry.
143 AccelerantHWInterface::_OpenGraphicsDevice(int deviceNumber)
145 DIR *directory = opendir("/dev/graphics");
146 if (!directory)
147 return -1;
149 // ToDo: the former R5 "stub" driver is called "vesa" under Haiku; however,
150 // we do not need to avoid this driver this way when is has been ported
151 // to the new driver architecture - the special case here can then be
152 // removed.
153 int count = 0;
154 struct dirent *entry;
155 int current_card_fd = -1;
156 char path[PATH_MAX];
157 while (count < deviceNumber && (entry = readdir(directory)) != NULL) {
158 if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..") ||
159 !strcmp(entry->d_name, "stub") || !strcmp(entry->d_name, "vesa"))
160 continue;
162 if (current_card_fd >= 0) {
163 close(current_card_fd);
164 current_card_fd = -1;
167 sprintf(path, "/dev/graphics/%s", entry->d_name);
168 current_card_fd = open(path, B_READ_WRITE);
169 if (current_card_fd >= 0)
170 count++;
173 // Open VESA driver if we were not able to get a better one
174 if (count < deviceNumber) {
175 if (deviceNumber == 1) {
176 sprintf(path, "/dev/graphics/vesa");
177 current_card_fd = open(path, B_READ_WRITE);
178 } else {
179 close(current_card_fd);
180 current_card_fd = B_ENTRY_NOT_FOUND;
184 fCardNameInDevFS = entry->d_name;
186 return current_card_fd;
190 status_t
191 AccelerantHWInterface::_OpenAccelerant(int device)
193 char signature[1024];
194 if (ioctl(device, B_GET_ACCELERANT_SIGNATURE,
195 &signature, sizeof(signature)) != B_OK)
196 return B_ERROR;
198 ATRACE(("accelerant signature is: %s\n", signature));
200 struct stat accelerant_stat;
201 const static directory_which dirs[] = {
202 B_USER_NONPACKAGED_ADDONS_DIRECTORY,
203 B_USER_ADDONS_DIRECTORY,
204 B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY,
205 B_SYSTEM_ADDONS_DIRECTORY
208 fAccelerantImage = -1;
210 for (int32 i = 0; i < sizeof(dirs) / sizeof(directory_which); i++) {
211 char path[PATH_MAX];
212 if (find_directory(dirs[i], -1, false, path, PATH_MAX) != B_OK)
213 continue;
215 strcat(path, "/accelerants/");
216 strcat(path, signature);
217 if (stat(path, &accelerant_stat) != 0)
218 continue;
220 fAccelerantImage = load_add_on(path);
221 if (fAccelerantImage >= 0) {
222 if (get_image_symbol(fAccelerantImage, B_ACCELERANT_ENTRY_POINT,
223 B_SYMBOL_TYPE_ANY, (void**)(&fAccelerantHook)) != B_OK ) {
224 ATRACE(("unable to get B_ACCELERANT_ENTRY_POINT\n"));
225 unload_add_on(fAccelerantImage);
226 fAccelerantImage = -1;
227 return B_ERROR;
231 accelerant_clone_info_size cloneInfoSize;
232 cloneInfoSize = (accelerant_clone_info_size)fAccelerantHook(B_ACCELERANT_CLONE_INFO_SIZE, NULL);
233 if (!cloneInfoSize) {
234 ATRACE(("unable to get B_ACCELERANT_CLONE_INFO_SIZE (%s)\n", path));
235 unload_add_on(fAccelerantImage);
236 fAccelerantImage = -1;
237 return B_ERROR;
240 ssize_t cloneSize = cloneInfoSize();
241 void* cloneInfoData = malloc(cloneSize);
243 // get_accelerant_clone_info getCloneInfo;
244 // getCloneInfo = (get_accelerant_clone_info)fAccelerantHook(B_GET_ACCELERANT_CLONE_INFO, NULL);
245 // if (!getCloneInfo) {
246 // ATRACE(("unable to get B_GET_ACCELERANT_CLONE_INFO (%s)\n", path));
247 // unload_add_on(fAccelerantImage);
248 // fAccelerantImage = -1;
249 // return B_ERROR;
250 // }
251 // printf("getCloneInfo: %p\n", getCloneInfo);
253 // getCloneInfo(cloneInfoData);
254 // TODO: this is what works for the ATI Radeon driver...
255 sprintf((char*)cloneInfoData, "graphics/%s", fCardNameInDevFS.String());
257 clone_accelerant cloneAccelerant;
258 cloneAccelerant = (clone_accelerant)fAccelerantHook(B_CLONE_ACCELERANT, NULL);
259 if (!cloneAccelerant) {
260 ATRACE(("unable to get B_CLONE_ACCELERANT\n"));
261 unload_add_on(fAccelerantImage);
262 fAccelerantImage = -1;
263 return B_ERROR;
265 status_t ret = cloneAccelerant(cloneInfoData);
266 if (ret != B_OK) {
267 ATRACE(("Cloning accelerant unsuccessful: %s\n", strerror(ret)));
268 unload_add_on(fAccelerantImage);
269 fAccelerantImage = -1;
270 return B_ERROR;
273 break;
277 if (fAccelerantImage < B_OK)
278 return B_ERROR;
280 if (_SetupDefaultHooks() != B_OK) {
281 ATRACE(("cannot setup default hooks\n"));
283 uninit_accelerant uninitAccelerant = (uninit_accelerant)
284 fAccelerantHook(B_UNINIT_ACCELERANT, NULL);
285 if (uninitAccelerant != NULL)
286 uninitAccelerant();
288 unload_add_on(fAccelerantImage);
289 return B_ERROR;
292 return B_OK;
296 status_t
297 AccelerantHWInterface::_SetupDefaultHooks()
299 // required
300 fAccAcquireEngine = (acquire_engine)fAccelerantHook(B_ACQUIRE_ENGINE, NULL);
301 fAccReleaseEngine = (release_engine)fAccelerantHook(B_RELEASE_ENGINE, NULL);
302 fAccSyncToToken = (sync_to_token)fAccelerantHook(B_SYNC_TO_TOKEN, NULL);
303 fAccGetModeCount = (accelerant_mode_count)fAccelerantHook(B_ACCELERANT_MODE_COUNT, NULL);
304 fAccGetModeList = (get_mode_list)fAccelerantHook(B_GET_MODE_LIST, NULL);
305 fAccGetFrameBufferConfig = (get_frame_buffer_config)fAccelerantHook(B_GET_FRAME_BUFFER_CONFIG, NULL);
306 fAccSetDisplayMode = (set_display_mode)fAccelerantHook(B_SET_DISPLAY_MODE, NULL);
307 fAccGetDisplayMode = (get_display_mode)fAccelerantHook(B_GET_DISPLAY_MODE, NULL);
308 fAccGetPixelClockLimits = (get_pixel_clock_limits)fAccelerantHook(B_GET_PIXEL_CLOCK_LIMITS, NULL);
310 if (!fAccAcquireEngine || !fAccReleaseEngine || !fAccGetFrameBufferConfig
311 || !fAccGetModeCount || !fAccGetModeList || !fAccSetDisplayMode
312 || !fAccGetDisplayMode || !fAccGetPixelClockLimits) {
313 return B_ERROR;
316 // optional
317 fAccGetTimingConstraints = (get_timing_constraints)fAccelerantHook(B_GET_TIMING_CONSTRAINTS, NULL);
318 fAccProposeDisplayMode = (propose_display_mode)fAccelerantHook(B_PROPOSE_DISPLAY_MODE, NULL);
320 // cursor
321 fAccSetCursorShape = (set_cursor_shape)fAccelerantHook(B_SET_CURSOR_SHAPE, NULL);
322 fAccMoveCursor = (move_cursor)fAccelerantHook(B_MOVE_CURSOR, NULL);
323 fAccShowCursor = (show_cursor)fAccelerantHook(B_SHOW_CURSOR, NULL);
325 // dpms
326 // fAccDPMSCapabilities = (dpms_capabilities)fAccelerantHook(B_DPMS_CAPABILITIES, NULL);
327 // fAccDPMSMode = (dpms_mode)fAccelerantHook(B_DPMS_MODE, NULL);
328 // fAccSetDPMSMode = (set_dpms_mode)fAccelerantHook(B_SET_DPMS_MODE, NULL);
330 // update acceleration hooks
331 // TODO: would actually have to pass a valid display_mode!
332 fAccFillRect = (fill_rectangle)fAccelerantHook(B_FILL_RECTANGLE, NULL);
333 fAccInvertRect = (invert_rectangle)fAccelerantHook(B_INVERT_RECTANGLE, NULL);
334 fAccScreenBlit = (screen_to_screen_blit)fAccelerantHook(B_SCREEN_TO_SCREEN_BLIT, NULL);
336 return B_OK;
339 // Shutdown
340 status_t
341 AccelerantHWInterface::Shutdown()
343 if (fAccelerantHook) {
344 uninit_accelerant UninitAccelerant = (uninit_accelerant)fAccelerantHook(B_UNINIT_ACCELERANT, NULL);
345 if (UninitAccelerant)
346 UninitAccelerant();
349 if (fAccelerantImage >= 0)
350 unload_add_on(fAccelerantImage);
352 if (fCardFD >= 0)
353 close(fCardFD);
355 return B_OK;
358 // SetMode
359 status_t
360 AccelerantHWInterface::SetMode(const display_mode &mode)
362 AutoWriteLocker _(this);
363 // TODO: There are places this function can fail,
364 // maybe it needs to roll back changes in case of an
365 // error.
367 // prevent from doing the unnecessary
368 if (fModeCount > 0 && fBackBuffer && fFrontBuffer
369 && fDisplayMode == mode) {
370 // TODO: better comparison of display modes
371 return B_OK;
374 // just try to set the mode - we let the graphics driver
375 // approve or deny the request, as it should know best
377 fDisplayMode = mode;
379 if (fAccSetDisplayMode(&fDisplayMode) != B_OK) {
380 ATRACE(("setting display mode failed\n"));
381 fAccGetDisplayMode(&fDisplayMode);
382 // We just keep the current mode and continue.
383 // Note, on startup, this may be different from
384 // what we think is the current display mode
387 // update frontbuffer
388 fFrontBuffer->SetDisplayMode(fDisplayMode);
389 if (_UpdateFrameBufferConfig() != B_OK)
390 return B_ERROR;
392 // Update the frame buffer used by the on-screen KDL
393 #ifdef __HAIKU__
394 uint32 depth = (fFrameBufferConfig.bytes_per_row / fDisplayMode.virtual_width) << 3;
395 if (fDisplayMode.space == B_RGB15)
396 depth = 15;
398 _kern_frame_buffer_update(fFrameBufferConfig.frame_buffer,
399 fDisplayMode.virtual_width, fDisplayMode.virtual_height,
400 depth, fFrameBufferConfig.bytes_per_row);
401 #endif
403 // update backbuffer if neccessary
404 if (!fBackBuffer || fBackBuffer->Width() != fDisplayMode.virtual_width
405 || fBackBuffer->Height() != fDisplayMode.virtual_height) {
406 // NOTE: backbuffer is always B_RGBA32, this simplifies the
407 // drawing backend implementation tremendously for the time
408 // being. The color space conversion is handled in CopyBackToFront()
410 delete fBackBuffer;
411 fBackBuffer = NULL;
413 // TODO: Above not true anymore for single buffered mode!!!
414 // -> fall back to double buffer for fDisplayMode.space != B_RGB32
415 // as intermediate solution...
416 bool doubleBuffered = HWInterface::IsDoubleBuffered();
417 if ((color_space)fDisplayMode.space != B_RGB32 &&
418 (color_space)fDisplayMode.space != B_RGBA32)
419 doubleBuffered = true;
421 if (doubleBuffered) {
422 fBackBuffer = new(nothrow) MallocBuffer(fDisplayMode.virtual_width,
423 fDisplayMode.virtual_height);
425 status_t ret = fBackBuffer ? fBackBuffer->InitCheck() : B_NO_MEMORY;
426 if (ret < B_OK) {
427 delete fBackBuffer;
428 fBackBuffer = NULL;
429 return ret;
431 // clear out backbuffer, alpha is 255 this way
432 memset(fBackBuffer->Bits(), 255, fBackBuffer->BitsLength());
436 // update acceleration hooks
437 fAccFillRect = (fill_rectangle)fAccelerantHook(B_FILL_RECTANGLE, (void *)&fDisplayMode);
438 fAccInvertRect = (invert_rectangle)fAccelerantHook(B_INVERT_RECTANGLE,
439 (void *)&fDisplayMode);
440 fAccScreenBlit = (screen_to_screen_blit)fAccelerantHook(B_SCREEN_TO_SCREEN_BLIT,
441 (void *)&fDisplayMode);
443 return B_OK;
447 void
448 AccelerantHWInterface::GetMode(display_mode *mode)
450 if (mode && ReadLock()) {
451 *mode = fDisplayMode;
452 ReadUnlock();
457 status_t
458 AccelerantHWInterface::_UpdateModeList()
460 fModeCount = fAccGetModeCount();
461 if (fModeCount <= 0)
462 return B_ERROR;
464 delete[] fModeList;
465 fModeList = new(nothrow) display_mode[fModeCount];
466 if (!fModeList)
467 return B_NO_MEMORY;
469 if (fAccGetModeList(fModeList) != B_OK) {
470 ATRACE(("unable to get mode list\n"));
471 return B_ERROR;
474 return B_OK;
478 status_t
479 AccelerantHWInterface::_UpdateFrameBufferConfig()
481 if (fAccGetFrameBufferConfig(&fFrameBufferConfig) != B_OK) {
482 ATRACE(("unable to get frame buffer config\n"));
483 return B_ERROR;
486 fFrontBuffer->SetFrameBufferConfig(fFrameBufferConfig);
487 return B_OK;
491 status_t
492 AccelerantHWInterface::GetDeviceInfo(accelerant_device_info *info)
494 get_accelerant_device_info GetAccelerantDeviceInfo = (get_accelerant_device_info)fAccelerantHook(B_GET_ACCELERANT_DEVICE_INFO, NULL);
495 if (!GetAccelerantDeviceInfo) {
496 ATRACE(("No B_GET_ACCELERANT_DEVICE_INFO hook found\n"));
497 return B_UNSUPPORTED;
500 return GetAccelerantDeviceInfo(info);
504 status_t
505 AccelerantHWInterface::GetFrameBufferConfig(frame_buffer_config& config)
507 config = fFrameBufferConfig;
508 return B_OK;
512 status_t
513 AccelerantHWInterface::GetModeList(display_mode** modes, uint32 *count)
515 AutoReadLocker _(this);
517 if (!count || !modes)
518 return B_BAD_VALUE;
520 status_t ret = fModeList ? B_OK : _UpdateModeList();
522 if (ret >= B_OK) {
523 *modes = new(nothrow) display_mode[fModeCount];
524 if (*modes) {
525 *count = fModeCount;
526 memcpy(*modes, fModeList, sizeof(display_mode) * fModeCount);
527 } else {
528 *count = 0;
529 ret = B_NO_MEMORY;
532 return ret;
535 status_t
536 AccelerantHWInterface::GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *high)
538 AutoReadLocker _(this);
540 if (!mode || !low || !high)
541 return B_BAD_VALUE;
543 return fAccGetPixelClockLimits(mode, low, high);
546 status_t
547 AccelerantHWInterface::GetTimingConstraints(display_timing_constraints *dtc)
549 AutoReadLocker _(this);
551 if (!dtc)
552 return B_BAD_VALUE;
554 if (fAccGetTimingConstraints)
555 return fAccGetTimingConstraints(dtc);
557 return B_UNSUPPORTED;
560 status_t
561 AccelerantHWInterface::ProposeMode(display_mode *candidate, const display_mode *low, const display_mode *high)
563 AutoReadLocker _(this);
565 if (!candidate || !low || !high)
566 return B_BAD_VALUE;
568 if (!fAccProposeDisplayMode)
569 return B_UNSUPPORTED;
571 // avoid const issues
572 display_mode this_high, this_low;
573 this_high = *high;
574 this_low = *low;
576 return fAccProposeDisplayMode(candidate, &this_low, &this_high);
579 // RetraceSemaphore
580 sem_id
581 AccelerantHWInterface::RetraceSemaphore()
583 accelerant_retrace_semaphore AccelerantRetraceSemaphore = (accelerant_retrace_semaphore)fAccelerantHook(B_ACCELERANT_RETRACE_SEMAPHORE, NULL);
584 if (!AccelerantRetraceSemaphore)
585 return B_UNSUPPORTED;
587 return AccelerantRetraceSemaphore();
590 // WaitForRetrace
591 status_t
592 AccelerantHWInterface::WaitForRetrace(bigtime_t timeout)
594 AutoReadLocker _(this);
596 accelerant_retrace_semaphore AccelerantRetraceSemaphore = (accelerant_retrace_semaphore)fAccelerantHook(B_ACCELERANT_RETRACE_SEMAPHORE, NULL);
597 if (!AccelerantRetraceSemaphore)
598 return B_UNSUPPORTED;
600 sem_id sem = AccelerantRetraceSemaphore();
601 if (sem < 0)
602 return B_ERROR;
604 return acquire_sem_etc(sem, 1, B_RELATIVE_TIMEOUT, timeout);
607 // SetDPMSMode
608 status_t
609 AccelerantHWInterface::SetDPMSMode(const uint32 &state)
611 AutoWriteLocker _(this);
613 if (!fAccSetDPMSMode)
614 return B_UNSUPPORTED;
616 return fAccSetDPMSMode(state);
619 // DPMSMode
620 uint32
621 AccelerantHWInterface::DPMSMode()
623 AutoReadLocker _(this);
625 if (!fAccDPMSMode)
626 return B_UNSUPPORTED;
628 return fAccDPMSMode();
631 // DPMSCapabilities
632 uint32
633 AccelerantHWInterface::DPMSCapabilities()
635 AutoReadLocker _(this);
637 if (!fAccDPMSCapabilities)
638 return B_UNSUPPORTED;
640 return fAccDPMSCapabilities();
643 // AvailableHardwareAcceleration
644 uint32
645 AccelerantHWInterface::AvailableHWAcceleration() const
647 uint32 flags = 0;
649 /* if (!IsDoubleBuffered()) {
650 if (fAccScreenBlit)
651 flags |= HW_ACC_COPY_REGION;
652 if (fAccFillRect)
653 flags |= HW_ACC_FILL_REGION;
654 if (fAccInvertRect)
655 flags |= HW_ACC_INVERT_REGION;
658 return flags;
661 // CopyRegion
662 void
663 AccelerantHWInterface::CopyRegion(const clipping_rect* sortedRectList,
664 uint32 count, int32 xOffset, int32 yOffset)
666 if (fAccScreenBlit && fAccAcquireEngine) {
667 if (fAccAcquireEngine(B_2D_ACCELERATION, 0xff, &fSyncToken, &fEngineToken) >= B_OK) {
669 // convert the rects
670 blit_params* params = new blit_params[count];
671 for (uint32 i = 0; i < count; i++) {
672 params[i].src_left = (uint16)sortedRectList[i].left;
673 params[i].src_top = (uint16)sortedRectList[i].top;
675 params[i].dest_left = (uint16)sortedRectList[i].left + xOffset;
676 params[i].dest_top = (uint16)sortedRectList[i].top + yOffset;
678 // NOTE: width and height are expressed as distance, not pixel count!
679 params[i].width = (uint16)(sortedRectList[i].right - sortedRectList[i].left);
680 params[i].height = (uint16)(sortedRectList[i].bottom - sortedRectList[i].top);
683 // go
684 fAccScreenBlit(fEngineToken, params, count);
686 // done
687 if (fAccReleaseEngine)
688 fAccReleaseEngine(fEngineToken, &fSyncToken);
690 // sync
691 if (fAccSyncToToken)
692 fAccSyncToToken(&fSyncToken);
694 delete[] params;
699 // FillRegion
700 void
701 AccelerantHWInterface::FillRegion(/*const*/ BRegion& region, const rgb_color& color)
703 if (fAccFillRect && fAccAcquireEngine) {
704 if (fAccAcquireEngine(B_2D_ACCELERATION, 0xff, &fSyncToken, &fEngineToken) >= B_OK) {
706 // convert the region
707 uint32 count;
708 fill_rect_params* fillParams;
709 _RegionToRectParams(&region, &fillParams, &count);
711 // go
712 fAccFillRect(fEngineToken, _NativeColor(color), fillParams, count);
714 // done
715 if (fAccReleaseEngine)
716 fAccReleaseEngine(fEngineToken, &fSyncToken);
718 // sync
719 if (fAccSyncToToken)
720 fAccSyncToToken(&fSyncToken);
722 delete[] fillParams;
727 // InvertRegion
728 void
729 AccelerantHWInterface::InvertRegion(/*const*/ BRegion& region)
731 if (fAccInvertRect && fAccAcquireEngine) {
732 if (fAccAcquireEngine(B_2D_ACCELERATION, 0xff, &fSyncToken, &fEngineToken) >= B_OK) {
734 // convert the region
735 uint32 count;
736 fill_rect_params* fillParams;
737 _RegionToRectParams(&region, &fillParams, &count);
739 // go
740 fAccInvertRect(fEngineToken, fillParams, count);
742 // done
743 if (fAccReleaseEngine)
744 fAccReleaseEngine(fEngineToken, &fSyncToken);
746 // sync
747 if (fAccSyncToToken)
748 fAccSyncToToken(&fSyncToken);
750 delete[] fillParams;
751 } else {
752 fprintf(stderr, "AcquireEngine failed!\n");
754 } else {
755 fprintf(stderr, "AccelerantHWInterface::InvertRegion() called, but hook not available!\n");
759 // SetCursor
760 void
761 AccelerantHWInterface::SetCursor(ServerCursor* cursor)
763 HWInterface::SetCursor(cursor);
764 // if (WriteLock()) {
765 // TODO: implement setting the hard ware cursor
766 // NOTE: cursor should be always B_RGBA32
767 // NOTE: The HWInterface implementation should
768 // still be called, since it takes ownership of
769 // the cursor.
770 // WriteUnlock();
771 // }
774 // SetCursorVisible
775 void
776 AccelerantHWInterface::SetCursorVisible(bool visible)
778 HWInterface::SetCursorVisible(visible);
779 // if (WriteLock()) {
780 // TODO: update graphics hardware
781 // WriteUnlock();
782 // }
785 // MoveCursorTo
786 void
787 AccelerantHWInterface::MoveCursorTo(const float& x, const float& y)
789 HWInterface::MoveCursorTo(x, y);
790 // if (WriteLock()) {
791 // TODO: update graphics hardware
792 // WriteUnlock();
793 // }
796 // FrontBuffer
797 RenderingBuffer *
798 AccelerantHWInterface::FrontBuffer() const
800 if (!fModeList)
801 return NULL;
803 return fFrontBuffer;
806 // BackBuffer
807 RenderingBuffer *
808 AccelerantHWInterface::BackBuffer() const
810 if (!fModeList)
811 return NULL;
813 return fBackBuffer;
816 // IsDoubleBuffered
817 bool
818 AccelerantHWInterface::IsDoubleBuffered() const
820 if (fModeList)
821 return fBackBuffer != NULL;
823 return HWInterface::IsDoubleBuffered();
826 // _DrawCursor
827 void
828 AccelerantHWInterface::_DrawCursor(BRect area) const
830 // use the default implementation for now,
831 // until we have a hardware cursor
832 HWInterface::_DrawCursor(area);
833 // TODO: this would only be called, if we don't have
834 // a hardware cursor for some reason
837 // _RegionToRectParams
838 void
839 AccelerantHWInterface::_RegionToRectParams(/*const*/ BRegion* region,
840 fill_rect_params** params,
841 uint32* count) const
843 *count = region->CountRects();
844 *params = new fill_rect_params[*count];
846 for (uint32 i = 0; i < *count; i++) {
847 clipping_rect r = region->RectAtInt(i);
848 (*params)[i].left = (uint16)r.left;
849 (*params)[i].top = (uint16)r.top;
850 (*params)[i].right = (uint16)r.right;
851 (*params)[i].bottom = (uint16)r.bottom;
855 // _NativeColor
856 uint32
857 AccelerantHWInterface::_NativeColor(const rgb_color& c) const
859 // NOTE: This functions looks somehow suspicios to me.
860 // It assumes that all graphics cards have the same native endianess, no?
861 /* switch (fDisplayMode.space) {
862 case B_CMAP8:
863 case B_GRAY8:
864 return color.GetColor8();
866 case B_RGB15_BIG:
867 case B_RGBA15_BIG:
868 case B_RGB15_LITTLE:
869 case B_RGBA15_LITTLE:
870 return color.GetColor15();
872 case B_RGB16_BIG:
873 case B_RGB16_LITTLE:
874 return color.GetColor16();
876 case B_RGB32_BIG:
877 case B_RGBA32_BIG:
878 case B_RGB32_LITTLE:
879 case B_RGBA32_LITTLE: {
880 rgb_color c = color.GetColor32();
881 uint32 native = (c.alpha << 24) |
882 (c.red << 16) |
883 (c.green << 8) |
884 (c.blue);
885 return native;
888 return 0;*/
889 uint32 native = (c.alpha << 24) | (c.red << 16) | (c.green << 8) | (c.blue);
890 return native;