2 * Copyright 2001-2009, Haiku.
3 * Distributed under the terms of the MIT License.
6 * DarkWyrm <bpmagic@columbus.rr.com>
7 * Michael Lotz <mmlr@mlotz.ch>
8 * Stephan Aßmus <superstippi@gmx.de>
12 /*! BView/BDirectWindow/Accelerant combination HWInterface implementation
16 #include "DWindowHWInterface.h"
22 #include <Application.h>
25 #include <DirectWindow.h>
28 #include <MessageFilter.h>
29 #include <MessageRunner.h>
35 #include <Accelerant.h>
36 #include <graphic_driver.h>
37 #include <FindDirectory.h>
40 #include <sys/ioctl.h>
43 #include <ServerProtocol.h>
45 #include "DWindowBuffer.h"
48 #include "ServerConfig.h"
49 #include "ServerCursor.h"
50 #include "UpdateQueue.h"
53 #ifdef DEBUG_DRIVER_MODULE
55 # define STRACE(x) printf x
61 const unsigned char kEmptyCursor
[] = { 16, 1, 0, 0,
62 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
63 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
64 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
65 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
69 run_app_thread(void* cookie
)
71 if (BApplication
* app
= (BApplication
*)cookie
) {
79 //#define INPUTSERVER_TEST_MODE 1
82 class DView
: public BView
{
88 void ForwardMessage(BMessage
* message
= NULL
);
94 class DWindow
: public BWindow
{
97 DWindowHWInterface
* interface
,
98 DWindowBuffer
* buffer
);
101 virtual bool QuitRequested();
103 // virtual void DirectConnected(direct_buffer_info* info);
105 virtual void FrameMoved(BPoint newOffset
);
108 DWindowHWInterface
* fHWInterface
;
109 DWindowBuffer
* fBuffer
;
112 class DirectMessageFilter
: public BMessageFilter
{
114 DirectMessageFilter(DView
* view
);
116 virtual filter_result
Filter(BMessage
*message
, BHandler
** _target
);
126 DView::DView(BRect bounds
)
128 BView(bounds
, "graphics card view", B_FOLLOW_ALL
, 0)
130 SetViewColor(B_TRANSPARENT_COLOR
);
131 #ifndef INPUTSERVER_TEST_MODE
132 fInputPort
= create_port(200, SERVER_INPUT_PORT
);
134 fInputPort
= create_port(100, "ViewInputDevice");
137 #ifdef ENABLE_INPUT_SERVER_EMULATION
138 AddFilter(new DirectMessageFilter(this));
148 /*! This function emulates the Input Server by sending the *exact* same kind of
149 messages to the server's port. Being we're using a regular window, it would
150 make little sense to do anything else.
153 DView::ForwardMessage(BMessage
* message
)
156 message
= Window()->CurrentMessage();
160 // remove some fields that potentially mess up our own message processing
161 BMessage copy
= *message
;
162 copy
.RemoveName("screen_where");
163 copy
.RemoveName("be:transit");
164 copy
.RemoveName("be:view_where");
165 copy
.RemoveName("be:cursor_needed");
167 size_t length
= copy
.FlattenedSize();
170 if (copy
.Flatten(stream
, length
) == B_OK
)
171 write_port(fInputPort
, 0, stream
, length
);
178 DirectMessageFilter::DirectMessageFilter(DView
* view
)
180 BMessageFilter(B_ANY_DELIVERY
, B_ANY_SOURCE
),
187 DirectMessageFilter::Filter(BMessage
* message
, BHandler
** target
)
189 switch (message
->what
) {
191 case B_UNMAPPED_KEY_DOWN
:
193 case B_UNMAPPED_KEY_UP
:
196 case B_MOUSE_WHEEL_CHANGED
:
197 fView
->ForwardMessage(message
);
198 return B_SKIP_MESSAGE
;
203 if (message
->FindInt32("be:transit", &transit
) == B_OK
204 && transit
== B_ENTERED_VIEW
) {
205 // A bug in R5 prevents this call from having an effect if
206 // called elsewhere, and calling it here works, if we're lucky :-)
207 BCursor
cursor(kEmptyCursor
);
208 fView
->SetViewCursor(&cursor
, true);
210 fView
->ForwardMessage(message
);
211 return B_SKIP_MESSAGE
;
215 return B_DISPATCH_MESSAGE
;
222 DWindow::DWindow(BRect frame
, DWindowHWInterface
* interface
,
223 DWindowBuffer
* buffer
)
225 BWindow(frame
, "Haiku App Server", B_TITLED_WINDOW_LOOK
,
226 B_NORMAL_WINDOW_FEEL
,
227 B_NOT_ZOOMABLE
| B_NOT_RESIZABLE
| B_NOT_MOVABLE
),
228 fHWInterface(interface
),
231 DView
* view
= new DView(Bounds());
234 // make it receive key events
244 DWindow::QuitRequested()
246 port_id serverport
= find_port(SERVER_PORT_NAME
);
248 if (serverport
>= 0) {
249 BPrivate::PortLink
link(serverport
);
250 link
.StartMessage(B_QUIT_REQUESTED
);
253 printf("ERROR: couldn't find the app_server's main port!");
255 // we don't quit on ourself, we let us be Quit()!
262 DWindow::DirectConnected(direct_buffer_info* info)
264 // fDesktop->LockClipping();
268 switch(info->buffer_state & B_DIRECT_MODE_MASK) {
270 case B_DIRECT_MODIFY:
271 fBuffer->SetTo(info);
272 // fDesktop->SetOffset(info->window_bounds.left, info->window_bounds.top);
275 fBuffer->SetTo(NULL);
279 // fDesktop->SetMasterClipping(&fBuffer.WindowClipping());
283 // fDesktop->UnlockClipping();
289 DWindow::FrameMoved(BPoint newOffset
)
291 fHWInterface
->SetOffset((int32
)newOffset
.x
, (int32
)newOffset
.y
);
298 const int32 kDefaultParamsCount
= 64;
300 DWindowHWInterface::DWindowHWInterface()
303 fFrontBuffer(new DWindowBuffer()),
310 fAccelerantImage(-1),
311 fAccelerantHook(NULL
),
316 fAccAcquireEngine(NULL
),
317 fAccReleaseEngine(NULL
),
318 fAccSyncToToken(NULL
),
319 fAccGetModeCount(NULL
),
320 fAccGetModeList(NULL
),
321 fAccGetFrameBufferConfig(NULL
),
322 fAccSetDisplayMode(NULL
),
323 fAccGetDisplayMode(NULL
),
324 fAccGetPixelClockLimits(NULL
),
326 // optional accelerant hooks
327 fAccGetTimingConstraints(NULL
),
328 fAccProposeDisplayMode(NULL
),
330 fAccInvertRect(NULL
),
331 fAccScreenBlit(NULL
),
332 fAccSetCursorShape(NULL
),
333 fAccMoveCursor(NULL
),
334 fAccShowCursor(NULL
),
336 fRectParams(new (std::nothrow
) fill_rect_params
[kDefaultParamsCount
]),
337 fRectParamsCount(kDefaultParamsCount
),
338 fBlitParams(new (std::nothrow
) blit_params
[kDefaultParamsCount
]),
339 fBlitParamsCount(kDefaultParamsCount
)
341 fDisplayMode
.virtual_width
= 800;
342 fDisplayMode
.virtual_height
= 600;
343 fDisplayMode
.space
= B_RGBA32
;
345 memset(&fSyncToken
, 0, sizeof(sync_token
));
349 DWindowHWInterface::~DWindowHWInterface()
356 delete[] fRectParams
;
357 delete[] fBlitParams
;
368 DWindowHWInterface::Initialize()
370 status_t ret
= HWInterface::Initialize();
372 if (!fRectParams
|| !fBlitParams
)
376 for (int32 i
= 1; fCardFD
!= B_ENTRY_NOT_FOUND
; i
++) {
377 fCardFD
= _OpenGraphicsDevice(i
);
379 STRACE(("Failed to open graphics device\n"));
383 if (_OpenAccelerant(fCardFD
) == B_OK
)
387 // _OpenAccelerant() failed, try to open next graphics card
390 return fCardFD
>= 0 ? B_OK
: fCardFD
;
396 /*! \brief Opens a graphics device for read-write access
397 \param deviceNumber Number identifying which graphics card to open (1 for
399 \return The file descriptor for the opened graphics device
401 The deviceNumber is relative to the number of graphics devices that can be
402 successfully opened. One represents the first card that can be successfully
403 opened (not necessarily the first one listed in the directory).
404 Graphics drivers must be able to be opened more than once, so we really get
405 the first working entry.
408 DWindowHWInterface::_OpenGraphicsDevice(int deviceNumber
)
410 DIR *directory
= opendir("/dev/graphics");
414 // ToDo: the former R5 "stub" driver is called "vesa" under Haiku; however,
415 // we do not need to avoid this driver this way when is has been ported
416 // to the new driver architecture - the special case here can then be
419 struct dirent
*entry
= NULL
;
420 int current_card_fd
= -1;
422 while (count
< deviceNumber
&& (entry
= readdir(directory
)) != NULL
) {
423 if (!strcmp(entry
->d_name
, ".") || !strcmp(entry
->d_name
, "..") ||
424 !strcmp(entry
->d_name
, "stub") || !strcmp(entry
->d_name
, "vesa"))
427 if (current_card_fd
>= 0) {
428 close(current_card_fd
);
429 current_card_fd
= -1;
432 sprintf(path
, "/dev/graphics/%s", entry
->d_name
);
433 current_card_fd
= open(path
, B_READ_WRITE
);
434 if (current_card_fd
>= 0)
438 // Open VESA driver if we were not able to get a better one
439 if (count
< deviceNumber
) {
440 if (deviceNumber
== 1) {
441 sprintf(path
, "/dev/graphics/vesa");
442 current_card_fd
= open(path
, B_READ_WRITE
);
444 close(current_card_fd
);
445 current_card_fd
= B_ENTRY_NOT_FOUND
;
450 fCardNameInDevFS
= entry
->d_name
;
452 return current_card_fd
;
457 DWindowHWInterface::_OpenAccelerant(int device
)
459 char signature
[1024];
460 if (ioctl(device
, B_GET_ACCELERANT_SIGNATURE
,
461 &signature
, sizeof(signature
)) != B_OK
)
464 STRACE(("accelerant signature is: %s\n", signature
));
466 struct stat accelerant_stat
;
467 const static directory_which dirs
[] = {
468 B_USER_NONPACKAGED_ADDONS_DIRECTORY
,
469 B_USER_ADDONS_DIRECTORY
,
470 B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY
,
471 B_SYSTEM_ADDONS_DIRECTORY
474 fAccelerantImage
= -1;
476 for (uint32 i
= 0; i
< sizeof(dirs
) / sizeof(directory_which
); i
++) {
478 if (find_directory(dirs
[i
], -1, false, path
, PATH_MAX
) != B_OK
)
481 strcat(path
, "/accelerants/");
482 strcat(path
, signature
);
483 if (stat(path
, &accelerant_stat
) != 0)
486 fAccelerantImage
= load_add_on(path
);
487 if (fAccelerantImage
>= 0) {
488 if (get_image_symbol(fAccelerantImage
, B_ACCELERANT_ENTRY_POINT
,
489 B_SYMBOL_TYPE_ANY
, (void**)(&fAccelerantHook
)) != B_OK
) {
490 STRACE(("unable to get B_ACCELERANT_ENTRY_POINT\n"));
491 unload_add_on(fAccelerantImage
);
492 fAccelerantImage
= -1;
497 accelerant_clone_info_size cloneInfoSize
;
498 cloneInfoSize
= (accelerant_clone_info_size
)fAccelerantHook(
499 B_ACCELERANT_CLONE_INFO_SIZE
, NULL
);
500 if (!cloneInfoSize
) {
501 STRACE(("unable to get B_ACCELERANT_CLONE_INFO_SIZE (%s)\n", path
));
502 unload_add_on(fAccelerantImage
);
503 fAccelerantImage
= -1;
507 ssize_t cloneSize
= cloneInfoSize();
508 void* cloneInfoData
= malloc(cloneSize
);
510 // get_accelerant_clone_info getCloneInfo;
511 // getCloneInfo = (get_accelerant_clone_info)fAccelerantHook(B_GET_ACCELERANT_CLONE_INFO, NULL);
512 // if (!getCloneInfo) {
513 // STRACE(("unable to get B_GET_ACCELERANT_CLONE_INFO (%s)\n", path));
514 // unload_add_on(fAccelerantImage);
515 // fAccelerantImage = -1;
518 // printf("getCloneInfo: %p\n", getCloneInfo);
520 // getCloneInfo(cloneInfoData);
521 // TODO: this is what works for the ATI Radeon driver...
522 sprintf((char*)cloneInfoData
, "graphics/%s", fCardNameInDevFS
.String());
524 clone_accelerant cloneAccelerant
;
525 cloneAccelerant
= (clone_accelerant
)fAccelerantHook(B_CLONE_ACCELERANT
, NULL
);
526 if (!cloneAccelerant
) {
527 STRACE(("unable to get B_CLONE_ACCELERANT\n"));
528 unload_add_on(fAccelerantImage
);
529 fAccelerantImage
= -1;
533 status_t ret
= cloneAccelerant(cloneInfoData
);
535 STRACE(("Cloning accelerant unsuccessful: %s\n", strerror(ret
)));
536 unload_add_on(fAccelerantImage
);
537 fAccelerantImage
= -1;
545 if (fAccelerantImage
< B_OK
)
548 if (_SetupDefaultHooks() != B_OK
) {
549 STRACE(("cannot setup default hooks\n"));
551 uninit_accelerant uninitAccelerant
= (uninit_accelerant
)
552 fAccelerantHook(B_UNINIT_ACCELERANT
, NULL
);
553 if (uninitAccelerant
!= NULL
)
556 unload_add_on(fAccelerantImage
);
559 _UpdateFrameBufferConfig();
567 DWindowHWInterface::_SetupDefaultHooks()
570 fAccAcquireEngine
= (acquire_engine
)fAccelerantHook(B_ACQUIRE_ENGINE
, NULL
);
571 fAccReleaseEngine
= (release_engine
)fAccelerantHook(B_RELEASE_ENGINE
, NULL
);
572 fAccSyncToToken
= (sync_to_token
)fAccelerantHook(B_SYNC_TO_TOKEN
, NULL
);
573 fAccGetModeCount
= (accelerant_mode_count
)fAccelerantHook(
574 B_ACCELERANT_MODE_COUNT
, NULL
);
575 fAccGetModeList
= (get_mode_list
)fAccelerantHook(B_GET_MODE_LIST
, NULL
);
576 fAccGetFrameBufferConfig
= (get_frame_buffer_config
)fAccelerantHook(
577 B_GET_FRAME_BUFFER_CONFIG
, NULL
);
578 fAccSetDisplayMode
= (set_display_mode
)fAccelerantHook(
579 B_SET_DISPLAY_MODE
, NULL
);
580 fAccGetDisplayMode
= (get_display_mode
)fAccelerantHook(
581 B_GET_DISPLAY_MODE
, NULL
);
582 fAccGetPixelClockLimits
= (get_pixel_clock_limits
)fAccelerantHook(
583 B_GET_PIXEL_CLOCK_LIMITS
, NULL
);
585 if (!fAccAcquireEngine
|| !fAccReleaseEngine
|| !fAccGetFrameBufferConfig
586 || !fAccGetModeCount
|| !fAccGetModeList
|| !fAccSetDisplayMode
587 || !fAccGetDisplayMode
|| !fAccGetPixelClockLimits
) {
592 fAccGetTimingConstraints
= (get_timing_constraints
)fAccelerantHook(
593 B_GET_TIMING_CONSTRAINTS
, NULL
);
594 fAccProposeDisplayMode
= (propose_display_mode
)fAccelerantHook(
595 B_PROPOSE_DISPLAY_MODE
, NULL
);
598 fAccSetCursorShape
= (set_cursor_shape
)fAccelerantHook(
599 B_SET_CURSOR_SHAPE
, NULL
);
600 fAccMoveCursor
= (move_cursor
)fAccelerantHook(B_MOVE_CURSOR
, NULL
);
601 fAccShowCursor
= (show_cursor
)fAccelerantHook(B_SHOW_CURSOR
, NULL
);
603 // update acceleration hooks
604 // TODO: would actually have to pass a valid display_mode!
605 fAccFillRect
= (fill_rectangle
)fAccelerantHook(B_FILL_RECTANGLE
, NULL
);
606 fAccInvertRect
= (invert_rectangle
)fAccelerantHook(B_INVERT_RECTANGLE
, NULL
);
607 fAccScreenBlit
= (screen_to_screen_blit
)fAccelerantHook(
608 B_SCREEN_TO_SCREEN_BLIT
, NULL
);
615 DWindowHWInterface::_UpdateFrameBufferConfig()
617 frame_buffer_config config
;
618 if (fAccGetFrameBufferConfig(&config
) != B_OK
) {
619 STRACE(("unable to get frame buffer config\n"));
623 fFrontBuffer
->SetTo(&config
, fXOffset
, fYOffset
, fDisplayMode
.virtual_width
,
624 fDisplayMode
.virtual_height
, (color_space
)fDisplayMode
.space
);
631 DWindowHWInterface::Shutdown()
633 printf("DWindowHWInterface::Shutdown()\n");
634 if (fAccelerantHook
) {
635 uninit_accelerant UninitAccelerant
636 = (uninit_accelerant
)fAccelerantHook(B_UNINIT_ACCELERANT
, NULL
);
637 if (UninitAccelerant
)
641 if (fAccelerantImage
>= 0)
642 unload_add_on(fAccelerantImage
);
652 DWindowHWInterface::SetMode(const display_mode
& mode
)
654 AutoWriteLocker
_(this);
657 // prevent from doing the unnecessary
659 && fDisplayMode
.virtual_width
== mode
.virtual_width
660 && fDisplayMode
.virtual_height
== mode
.virtual_height
661 && fDisplayMode
.space
== mode
.space
)
664 // check if we support the mode
668 if (GetModeList(&modes
, &modeCount
) != B_OK
)
671 for (i
= 0; i
< modeCount
; i
++) {
672 // we only care for the bare minimum
673 if (modes
[i
].virtual_width
== mode
.virtual_width
674 && modes
[i
].virtual_height
== mode
.virtual_height
675 && modes
[i
].space
== mode
.space
) {
676 // take over settings
677 fDisplayMode
= modes
[i
];
687 BRect
frame(0.0, 0.0,
688 fDisplayMode
.virtual_width
- 1,
689 fDisplayMode
.virtual_height
- 1);
691 // create the window if we don't have one already
693 // if the window has not been created yet, the BApplication
694 // has not been created either, but we need one to display
695 // a real BWindow in the test environment.
696 // be_app->Run() needs to be called in another thread
697 BApplication
* app
= new BApplication(
698 "application/x-vnd.Haiku-test-app_server");
701 thread_id appThread
= spawn_thread(run_app_thread
, "app thread",
702 B_NORMAL_PRIORITY
, app
);
703 if (appThread
>= B_OK
)
704 ret
= resume_thread(appThread
);
711 fWindow
= new DWindow(frame
.OffsetByCopy(fXOffset
, fYOffset
), this,
714 // fire up the window thread but don't show it on screen yet
719 if (fWindow
->Lock()) {
720 // free and reallocate the bitmaps while the window is locked,
721 // so that the view does not accidentally draw a freed bitmap
724 // change the window size and update the bitmap used for drawing
725 fWindow
->ResizeTo(frame
.Width(), frame
.Height());
728 // window is hidden when this function is called the first time
729 if (fWindow
->IsHidden())
737 _UpdateFrameBufferConfig();
738 _NotifyFrameBufferChanged();
745 DWindowHWInterface::GetMode(display_mode
* mode
)
747 if (mode
&& ReadLock()) {
748 *mode
= fDisplayMode
;
755 DWindowHWInterface::GetDeviceInfo(accelerant_device_info
* info
)
757 // We really don't have to provide anything here because this is strictly
758 // a software-only driver, but we'll have some fun, anyway.
761 sprintf(info
->name
, "Haiku, Inc. DWindowHWInterface");
762 sprintf(info
->chipset
, "Haiku, Inc. Chipset");
763 sprintf(info
->serial_no
, "3.14159265358979323846");
764 info
->memory
= 134217728; // 128 MB, not that we really have that much. :)
765 info
->dac_speed
= 0xFFFFFFFF; // *heh*
775 DWindowHWInterface::GetFrameBufferConfig(frame_buffer_config
& config
)
777 if (fFrontBuffer
== NULL
)
780 config
.frame_buffer
= fFrontBuffer
->Bits();
781 config
.frame_buffer_dma
= NULL
;
782 config
.bytes_per_row
= fFrontBuffer
->BytesPerRow();
789 DWindowHWInterface::GetModeList(display_mode
** _modes
, uint32
* _count
)
791 AutoReadLocker
_(this);
794 // setup a whole bunch of different modes
795 const struct resolution
{ int32 width
, height
; } resolutions
[] = {
796 {640, 480}, {800, 600}, {1024, 768}, {1152, 864}, {1280, 960},
797 {1280, 1024}, {1400, 1050}, {1600, 1200}
799 uint32 resolutionCount
= sizeof(resolutions
) / sizeof(resolutions
[0]);
800 // const uint32 colors[] = {B_CMAP8, B_RGB15, B_RGB16, B_RGB32};
801 uint32 count
= resolutionCount
/* * 4*/;
803 display_mode
* modes
= new(std::nothrow
) display_mode
[count
];
811 for (uint32 i
= 0; i
< resolutionCount
; i
++) {
812 modes
[index
].virtual_width
= resolutions
[i
].width
;
813 modes
[index
].virtual_height
= resolutions
[i
].height
;
814 modes
[index
].space
= B_RGB32
;
816 modes
[index
].h_display_start
= 0;
817 modes
[index
].v_display_start
= 0;
818 modes
[index
].timing
.h_display
= resolutions
[i
].width
;
819 modes
[index
].timing
.v_display
= resolutions
[i
].height
;
820 modes
[index
].timing
.h_total
= 22000;
821 modes
[index
].timing
.v_total
= 22000;
822 modes
[index
].timing
.pixel_clock
= ((uint32
)modes
[index
].timing
.h_total
823 * modes
[index
].timing
.v_total
* 60) / 1000;
824 modes
[index
].flags
= B_PARALLEL_ACCESS
;
829 // support only a single mode, useful
830 // for testing a specific mode
831 display_mode
*modes
= new(std::nothrow
) display_mode
[1];
832 modes
[0].virtual_width
= 800;
833 modes
[0].virtual_height
= 600;
834 modes
[0].space
= B_BRGB32
;
845 DWindowHWInterface::GetPixelClockLimits(display_mode
* mode
, uint32
* low
,
853 DWindowHWInterface::GetTimingConstraints(
854 display_timing_constraints
* constraints
)
861 DWindowHWInterface::ProposeMode(display_mode
* candidate
,
862 const display_mode
* low
, const display_mode
* high
)
864 // We should be able to get away with this because we're not dealing with
865 // any specific hardware. This is a Good Thing(TM) because we can support
866 // any hardware we wish within reasonable expectaions and programmer
873 DWindowHWInterface::RetraceSemaphore()
880 DWindowHWInterface::WaitForRetrace(bigtime_t timeout
)
882 // Locking shouldn't be necessary here - R5 should handle this for us. :)
884 return screen
.WaitForRetrace(timeout
);
889 DWindowHWInterface::SetDPMSMode(uint32 state
)
891 AutoWriteLocker
_(this);
893 return BScreen().SetDPMS(state
);
898 DWindowHWInterface::DPMSMode()
900 AutoReadLocker
_(this);
902 return BScreen().DPMSState();
907 DWindowHWInterface::DPMSCapabilities()
909 AutoReadLocker
_(this);
911 return BScreen().DPMSCapabilites();
916 DWindowHWInterface::SetBrightness(float brightness
)
918 AutoReadLocker
_(this);
920 return BScreen().SetBrightness(brightness
);
925 DWindowHWInterface::GetBrightness(float* brightness
)
927 AutoReadLocker
_(this);
929 return BScreen().GetBrightness(brightness
);
934 DWindowHWInterface::AvailableHWAcceleration() const
938 if (!IsDoubleBuffered()) {
940 flags
|= HW_ACC_COPY_REGION
;
942 flags
|= HW_ACC_FILL_REGION
;
944 flags
|= HW_ACC_INVERT_REGION
;
952 DWindowHWInterface::CopyRegion(const clipping_rect
* sortedRectList
,
953 uint32 count
, int32 xOffset
, int32 yOffset
)
955 if (fAccScreenBlit
&& fAccAcquireEngine
) {
956 if (fAccAcquireEngine(B_2D_ACCELERATION
, 0xff, &fSyncToken
,
957 &fEngineToken
) >= B_OK
) {
958 // make sure the blit_params cache is large enough
959 if (fBlitParamsCount
< count
) {
960 fBlitParamsCount
= (count
/ kDefaultParamsCount
+ 1)
961 * kDefaultParamsCount
;
962 // NOTE: realloc() could be used instead...
964 = new(std::nothrow
) blit_params
[fBlitParamsCount
];
966 delete[] fBlitParams
;
967 fBlitParams
= params
;
969 count
= fBlitParamsCount
;
973 for (uint32 i
= 0; i
< count
; i
++) {
974 fBlitParams
[i
].src_left
975 = (uint16
)sortedRectList
[i
].left
+ fXOffset
;
976 fBlitParams
[i
].src_top
977 = (uint16
)sortedRectList
[i
].top
+ fYOffset
;
979 fBlitParams
[i
].dest_left
980 = (uint16
)sortedRectList
[i
].left
+ xOffset
+ fXOffset
;
981 fBlitParams
[i
].dest_top
982 = (uint16
)sortedRectList
[i
].top
+ yOffset
+ fYOffset
;
984 // NOTE: width and height are expressed as distance, not count!
985 fBlitParams
[i
].width
= (uint16
)(sortedRectList
[i
].right
986 - sortedRectList
[i
].left
);
987 fBlitParams
[i
].height
= (uint16
)(sortedRectList
[i
].bottom
988 - sortedRectList
[i
].top
);
992 fAccScreenBlit(fEngineToken
, fBlitParams
, count
);
995 if (fAccReleaseEngine
)
996 fAccReleaseEngine(fEngineToken
, &fSyncToken
);
1000 fAccSyncToToken(&fSyncToken
);
1007 DWindowHWInterface::FillRegion(/*const*/ BRegion
& region
,
1008 const rgb_color
& color
, bool autoSync
)
1010 if (fAccFillRect
&& fAccAcquireEngine
) {
1011 if (fAccAcquireEngine(B_2D_ACCELERATION
, 0xff, &fSyncToken
,
1012 &fEngineToken
) >= B_OK
) {
1013 // convert the region
1015 _RegionToRectParams(®ion
, &count
);
1018 fAccFillRect(fEngineToken
, _NativeColor(color
), fRectParams
, count
);
1021 if (fAccReleaseEngine
)
1022 fAccReleaseEngine(fEngineToken
, &fSyncToken
);
1025 if (autoSync
&& fAccSyncToToken
)
1026 fAccSyncToToken(&fSyncToken
);
1033 DWindowHWInterface::InvertRegion(/*const*/ BRegion
& region
)
1035 if (fAccInvertRect
&& fAccAcquireEngine
) {
1036 if (fAccAcquireEngine(B_2D_ACCELERATION
, 0xff, &fSyncToken
,
1037 &fEngineToken
) >= B_OK
) {
1038 // convert the region
1040 _RegionToRectParams(®ion
, &count
);
1043 fAccInvertRect(fEngineToken
, fRectParams
, count
);
1046 if (fAccReleaseEngine
)
1047 fAccReleaseEngine(fEngineToken
, &fSyncToken
);
1050 if (fAccSyncToToken
)
1051 fAccSyncToToken(&fSyncToken
);
1054 fprintf(stderr
, "AcquireEngine failed!\n");
1057 fprintf(stderr
, "AccelerantHWInterface::InvertRegion() called, but "
1058 "hook not available!\n");
1064 DWindowHWInterface::Sync()
1066 if (fAccSyncToToken
)
1067 fAccSyncToToken(&fSyncToken
);
1072 DWindowHWInterface::FrontBuffer() const
1074 return fFrontBuffer
;
1079 DWindowHWInterface::BackBuffer() const
1081 return fFrontBuffer
;
1086 DWindowHWInterface::IsDoubleBuffered() const
1093 DWindowHWInterface::Invalidate(const BRect
& frame
)
1095 return HWInterface::Invalidate(frame
);
1100 DWindowHWInterface::SetOffset(int32 left
, int32 top
)
1108 _UpdateFrameBufferConfig();
1110 // TODO: someone would have to call DrawingEngine::Update() now!
1117 DWindowHWInterface::_RegionToRectParams(/*const*/ BRegion
* region
,
1118 uint32
* count
) const
1120 *count
= region
->CountRects();
1121 if (fRectParamsCount
< *count
) {
1122 fRectParamsCount
= (*count
/ kDefaultParamsCount
+ 1)
1123 * kDefaultParamsCount
;
1124 // NOTE: realloc() could be used instead...
1125 fill_rect_params
* params
1126 = new(std::nothrow
) fill_rect_params
[fRectParamsCount
];
1128 delete[] fRectParams
;
1129 fRectParams
= params
;
1131 *count
= fRectParamsCount
;
1135 for (uint32 i
= 0; i
< *count
; i
++) {
1136 clipping_rect r
= region
->RectAtInt(i
);
1137 fRectParams
[i
].left
= (uint16
)r
.left
+ fXOffset
;
1138 fRectParams
[i
].top
= (uint16
)r
.top
+ fYOffset
;
1139 fRectParams
[i
].right
= (uint16
)r
.right
+ fXOffset
;
1140 fRectParams
[i
].bottom
= (uint16
)r
.bottom
+ fYOffset
;
1146 DWindowHWInterface::_NativeColor(const rgb_color
& color
) const
1148 // NOTE: This functions looks somehow suspicios to me.
1149 // It assumes that all graphics cards have the same native endianess, no?
1150 switch (fDisplayMode
.space
) {
1153 return RGBColor(color
).GetColor8();
1157 case B_RGB15_LITTLE
:
1158 case B_RGBA15_LITTLE
:
1159 return RGBColor(color
).GetColor15();
1162 case B_RGB16_LITTLE
:
1163 return RGBColor(color
).GetColor16();
1167 case B_RGB32_LITTLE
:
1168 case B_RGBA32_LITTLE
: {
1169 uint32 native
= (color
.alpha
<< 24) | (color
.red
<< 16)
1170 | (color
.green
<< 8) | (color
.blue
);