2 * Copyright 2001-2005, Haiku.
3 * Distributed under the terms of the MIT License.
6 * Michael Lotz <mmlr@mlotz.ch>
7 * DarkWyrm <bpmagic@columbus.rr.com>
8 * Stephan Aßmus <superstippi@gmx.de>
11 /** Accelerant based HWInterface implementation */
20 #include <graphic_driver.h>
21 #include <FindDirectory.h>
24 #include <sys/ioctl.h>
27 #include "AccelerantHWInterface.h"
28 //#include "AccelerantBuffer.h"
29 //#include "MallocBuffer.h"
33 #define DEBUG_DRIVER_MODULE
35 #ifdef DEBUG_DRIVER_MODULE
37 # define ATRACE(x) printf x
43 AccelerantHWInterface::AccelerantHWInterface()
47 fAccelerantHook(NULL
),
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
),
68 fAccSetCursorShape(NULL
),
70 fAccShowCursor(NULL
)//,
73 /* fAccDPMSCapabilities(NULL),
75 fAccSetDPMSMode(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
));
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.
107 AccelerantHWInterface::Initialize()
109 status_t ret
= B_OK
;//HWInterface::Initialize();
111 for (int32 i
= 1; fCardFD
!= B_ENTRY_NOT_FOUND
; i
++) {
112 fCardFD
= _OpenGraphicsDevice(i
);
114 ATRACE(("Failed to open graphics device\n"));
118 if (_OpenAccelerant(fCardFD
) == B_OK
)
122 // _OpenAccelerant() failed, try to open next graphics card
125 return fCardFD
>= 0 ? B_OK
: fCardFD
;
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");
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
154 struct dirent
*entry
;
155 int current_card_fd
= -1;
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"))
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)
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
);
179 close(current_card_fd
);
180 current_card_fd
= B_ENTRY_NOT_FOUND
;
184 fCardNameInDevFS
= entry
->d_name
;
186 return current_card_fd
;
191 AccelerantHWInterface::_OpenAccelerant(int device
)
193 char signature
[1024];
194 if (ioctl(device
, B_GET_ACCELERANT_SIGNATURE
,
195 &signature
, sizeof(signature
)) != B_OK
)
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
++) {
212 if (find_directory(dirs
[i
], -1, false, path
, PATH_MAX
) != B_OK
)
215 strcat(path
, "/accelerants/");
216 strcat(path
, signature
);
217 if (stat(path
, &accelerant_stat
) != 0)
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;
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;
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;
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;
265 status_t ret
= cloneAccelerant(cloneInfoData
);
267 ATRACE(("Cloning accelerant unsuccessful: %s\n", strerror(ret
)));
268 unload_add_on(fAccelerantImage
);
269 fAccelerantImage
= -1;
277 if (fAccelerantImage
< B_OK
)
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
)
288 unload_add_on(fAccelerantImage
);
297 AccelerantHWInterface::_SetupDefaultHooks()
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
) {
317 fAccGetTimingConstraints
= (get_timing_constraints
)fAccelerantHook(B_GET_TIMING_CONSTRAINTS
, NULL
);
318 fAccProposeDisplayMode
= (propose_display_mode
)fAccelerantHook(B_PROPOSE_DISPLAY_MODE
, NULL
);
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
);
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
);
341 AccelerantHWInterface::Shutdown()
343 if (fAccelerantHook
) {
344 uninit_accelerant UninitAccelerant
= (uninit_accelerant
)fAccelerantHook(B_UNINIT_ACCELERANT
, NULL
);
345 if (UninitAccelerant
)
349 if (fAccelerantImage
>= 0)
350 unload_add_on(fAccelerantImage
);
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
367 // prevent from doing the unnecessary
368 if (fModeCount > 0 && fBackBuffer && fFrontBuffer
369 && fDisplayMode == mode) {
370 // TODO: better comparison of display modes
374 // just try to set the mode - we let the graphics driver
375 // approve or deny the request, as it should know best
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)
392 // Update the frame buffer used by the on-screen KDL
394 uint32 depth = (fFrameBufferConfig.bytes_per_row / fDisplayMode.virtual_width) << 3;
395 if (fDisplayMode.space == B_RGB15)
398 _kern_frame_buffer_update(fFrameBufferConfig.frame_buffer,
399 fDisplayMode.virtual_width, fDisplayMode.virtual_height,
400 depth, fFrameBufferConfig.bytes_per_row);
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()
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;
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);
448 AccelerantHWInterface::GetMode(display_mode *mode)
450 if (mode && ReadLock()) {
451 *mode = fDisplayMode;
458 AccelerantHWInterface::_UpdateModeList()
460 fModeCount = fAccGetModeCount();
465 fModeList = new(nothrow) display_mode[fModeCount];
469 if (fAccGetModeList(fModeList) != B_OK) {
470 ATRACE(("unable to get mode list\n"));
479 AccelerantHWInterface::_UpdateFrameBufferConfig()
481 if (fAccGetFrameBufferConfig(&fFrameBufferConfig) != B_OK) {
482 ATRACE(("unable to get frame buffer config\n"));
486 fFrontBuffer->SetFrameBufferConfig(fFrameBufferConfig);
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);
505 AccelerantHWInterface::GetFrameBufferConfig(frame_buffer_config& config)
507 config = fFrameBufferConfig;
513 AccelerantHWInterface::GetModeList(display_mode** modes, uint32 *count)
515 AutoReadLocker _(this);
517 if (!count || !modes)
520 status_t ret = fModeList ? B_OK : _UpdateModeList();
523 *modes = new(nothrow) display_mode[fModeCount];
526 memcpy(*modes, fModeList, sizeof(display_mode) * fModeCount);
536 AccelerantHWInterface::GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *high)
538 AutoReadLocker _(this);
540 if (!mode || !low || !high)
543 return fAccGetPixelClockLimits(mode, low, high);
547 AccelerantHWInterface::GetTimingConstraints(display_timing_constraints *dtc)
549 AutoReadLocker _(this);
554 if (fAccGetTimingConstraints)
555 return fAccGetTimingConstraints(dtc);
557 return B_UNSUPPORTED;
561 AccelerantHWInterface::ProposeMode(display_mode *candidate, const display_mode *low, const display_mode *high)
563 AutoReadLocker _(this);
565 if (!candidate || !low || !high)
568 if (!fAccProposeDisplayMode)
569 return B_UNSUPPORTED;
571 // avoid const issues
572 display_mode this_high, this_low;
576 return fAccProposeDisplayMode(candidate, &this_low, &this_high);
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();
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();
604 return acquire_sem_etc(sem, 1, B_RELATIVE_TIMEOUT, timeout);
609 AccelerantHWInterface::SetDPMSMode(const uint32 &state)
611 AutoWriteLocker _(this);
613 if (!fAccSetDPMSMode)
614 return B_UNSUPPORTED;
616 return fAccSetDPMSMode(state);
621 AccelerantHWInterface::DPMSMode()
623 AutoReadLocker _(this);
626 return B_UNSUPPORTED;
628 return fAccDPMSMode();
633 AccelerantHWInterface::DPMSCapabilities()
635 AutoReadLocker _(this);
637 if (!fAccDPMSCapabilities)
638 return B_UNSUPPORTED;
640 return fAccDPMSCapabilities();
643 // AvailableHardwareAcceleration
645 AccelerantHWInterface::AvailableHWAcceleration() const
649 /* if (!IsDoubleBuffered()) {
651 flags |= HW_ACC_COPY_REGION;
653 flags |= HW_ACC_FILL_REGION;
655 flags |= HW_ACC_INVERT_REGION;
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
) {
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
);
684 fAccScreenBlit(fEngineToken
, params
, count
);
687 if (fAccReleaseEngine
)
688 fAccReleaseEngine(fEngineToken
, &fSyncToken
);
692 fAccSyncToToken(&fSyncToken
);
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
708 fill_rect_params
* fillParams
;
709 _RegionToRectParams(®ion
, &fillParams
, &count
);
712 fAccFillRect(fEngineToken
, _NativeColor(color
), fillParams
, count
);
715 if (fAccReleaseEngine
)
716 fAccReleaseEngine(fEngineToken
, &fSyncToken
);
720 fAccSyncToToken(&fSyncToken
);
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
736 fill_rect_params
* fillParams
;
737 _RegionToRectParams(®ion
, &fillParams
, &count
);
740 fAccInvertRect(fEngineToken
, fillParams
, count
);
743 if (fAccReleaseEngine
)
744 fAccReleaseEngine(fEngineToken
, &fSyncToken
);
748 fAccSyncToToken(&fSyncToken
);
752 fprintf(stderr
, "AcquireEngine failed!\n");
755 fprintf(stderr
, "AccelerantHWInterface::InvertRegion() called, but hook not available!\n");
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
776 AccelerantHWInterface::SetCursorVisible(bool visible)
778 HWInterface::SetCursorVisible(visible);
779 // if (WriteLock()) {
780 // TODO: update graphics hardware
787 AccelerantHWInterface::MoveCursorTo(const float& x, const float& y)
789 HWInterface::MoveCursorTo(x, y);
790 // if (WriteLock()) {
791 // TODO: update graphics hardware
798 AccelerantHWInterface::FrontBuffer() const
808 AccelerantHWInterface::BackBuffer() const
818 AccelerantHWInterface::IsDoubleBuffered() const
821 return fBackBuffer != NULL;
823 return HWInterface::IsDoubleBuffered();
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
839 AccelerantHWInterface::_RegionToRectParams(/*const*/ BRegion
* region
,
840 fill_rect_params
** params
,
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
;
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) {
864 return color.GetColor8();
869 case B_RGBA15_LITTLE:
870 return color.GetColor15();
874 return color.GetColor16();
879 case B_RGBA32_LITTLE: {
880 rgb_color c = color.GetColor32();
881 uint32 native = (c.alpha << 24) |
889 uint32 native
= (c
.alpha
<< 24) | (c
.red
<< 16) | (c
.green
<< 8) | (c
.blue
);