1e76d86d5SStephan Aßmus /*
2e76d86d5SStephan Aßmus * Copyright 2001-2005, Haiku.
3e76d86d5SStephan Aßmus * Distributed under the terms of the MIT License.
4e76d86d5SStephan Aßmus *
5e76d86d5SStephan Aßmus * Authors:
6e76d86d5SStephan Aßmus * Michael Lotz <mmlr@mlotz.ch>
7e76d86d5SStephan Aßmus * DarkWyrm <bpmagic@columbus.rr.com>
8e76d86d5SStephan Aßmus * Stephan Aßmus <superstippi@gmx.de>
9e76d86d5SStephan Aßmus */
10e76d86d5SStephan Aßmus
11e76d86d5SStephan Aßmus /** Accelerant based HWInterface implementation */
12e76d86d5SStephan Aßmus
13e76d86d5SStephan Aßmus #include <new>
14e76d86d5SStephan Aßmus #include <malloc.h>
15e76d86d5SStephan Aßmus #include <stdio.h>
16e76d86d5SStephan Aßmus #include <string.h>
17e76d86d5SStephan Aßmus
18e76d86d5SStephan Aßmus #include <Cursor.h>
19e76d86d5SStephan Aßmus
20e76d86d5SStephan Aßmus #include <graphic_driver.h>
21e76d86d5SStephan Aßmus #include <FindDirectory.h>
22e76d86d5SStephan Aßmus #include <image.h>
23e76d86d5SStephan Aßmus #include <dirent.h>
24e76d86d5SStephan Aßmus #include <sys/ioctl.h>
25e76d86d5SStephan Aßmus #include <unistd.h>
26e76d86d5SStephan Aßmus
27e76d86d5SStephan Aßmus #include "AccelerantHWInterface.h"
28e76d86d5SStephan Aßmus //#include "AccelerantBuffer.h"
29e76d86d5SStephan Aßmus //#include "MallocBuffer.h"
30e76d86d5SStephan Aßmus
31e76d86d5SStephan Aßmus using std::nothrow;
32e76d86d5SStephan Aßmus
33e76d86d5SStephan Aßmus #define DEBUG_DRIVER_MODULE
34e76d86d5SStephan Aßmus
35e76d86d5SStephan Aßmus #ifdef DEBUG_DRIVER_MODULE
36e76d86d5SStephan Aßmus # include <stdio.h>
37e76d86d5SStephan Aßmus # define ATRACE(x) printf x
38e76d86d5SStephan Aßmus #else
39e76d86d5SStephan Aßmus # define ATRACE(x) ;
40e76d86d5SStephan Aßmus #endif
41e76d86d5SStephan Aßmus
42e76d86d5SStephan Aßmus // constructor
AccelerantHWInterface()43e76d86d5SStephan Aßmus AccelerantHWInterface::AccelerantHWInterface()
44e76d86d5SStephan Aßmus : //HWInterface(),
45e76d86d5SStephan Aßmus fCardFD(-1),
46e76d86d5SStephan Aßmus fAccelerantImage(-1),
47e76d86d5SStephan Aßmus fAccelerantHook(NULL),
48e76d86d5SStephan Aßmus fEngineToken(NULL),
49e76d86d5SStephan Aßmus fSyncToken(),
50e76d86d5SStephan Aßmus
51e76d86d5SStephan Aßmus // required hooks
52e76d86d5SStephan Aßmus fAccAcquireEngine(NULL),
53e76d86d5SStephan Aßmus fAccReleaseEngine(NULL),
54e76d86d5SStephan Aßmus fAccSyncToToken(NULL),
55e76d86d5SStephan Aßmus fAccGetModeCount(NULL),
56e76d86d5SStephan Aßmus fAccGetModeList(NULL),
57e76d86d5SStephan Aßmus fAccGetFrameBufferConfig(NULL),
58e76d86d5SStephan Aßmus fAccSetDisplayMode(NULL),
59e76d86d5SStephan Aßmus fAccGetDisplayMode(NULL),
60e76d86d5SStephan Aßmus fAccGetPixelClockLimits(NULL),
61e76d86d5SStephan Aßmus
62e76d86d5SStephan Aßmus // optional accelerant hooks
63e76d86d5SStephan Aßmus fAccGetTimingConstraints(NULL),
64e76d86d5SStephan Aßmus fAccProposeDisplayMode(NULL),
65e76d86d5SStephan Aßmus fAccFillRect(NULL),
66e76d86d5SStephan Aßmus fAccInvertRect(NULL),
67e76d86d5SStephan Aßmus fAccScreenBlit(NULL),
68e76d86d5SStephan Aßmus fAccSetCursorShape(NULL),
69e76d86d5SStephan Aßmus fAccMoveCursor(NULL),
70e76d86d5SStephan Aßmus fAccShowCursor(NULL)//,
71e76d86d5SStephan Aßmus
72e76d86d5SStephan Aßmus // dpms hooks
73e76d86d5SStephan Aßmus /* fAccDPMSCapabilities(NULL),
74e76d86d5SStephan Aßmus fAccDPMSMode(NULL),
75e76d86d5SStephan Aßmus fAccSetDPMSMode(NULL),
76e76d86d5SStephan Aßmus
77e76d86d5SStephan Aßmus fModeCount(0),
78e76d86d5SStephan Aßmus fModeList(NULL),*/
79e76d86d5SStephan Aßmus
80e76d86d5SStephan Aßmus // fBackBuffer(NULL),
81e76d86d5SStephan Aßmus // fFrontBuffer(new(nothrow) AccelerantBuffer())
82e76d86d5SStephan Aßmus {
83e76d86d5SStephan Aßmus /* fDisplayMode.virtual_width = 640;
84e76d86d5SStephan Aßmus fDisplayMode.virtual_height = 480;
85e76d86d5SStephan Aßmus fDisplayMode.space = B_RGB32;*/
86e76d86d5SStephan Aßmus
87e76d86d5SStephan Aßmus // NOTE: I have no clue what I'm doing here.
88e76d86d5SStephan Aßmus // fSyncToken.counter = 0;
89e76d86d5SStephan Aßmus // fSyncToken.engine_id = 0;
90e76d86d5SStephan Aßmus memset(&fSyncToken, 0, sizeof(sync_token));
91e76d86d5SStephan Aßmus }
92e76d86d5SStephan Aßmus
93e76d86d5SStephan Aßmus // destructor
~AccelerantHWInterface()94e76d86d5SStephan Aßmus AccelerantHWInterface::~AccelerantHWInterface()
95e76d86d5SStephan Aßmus {
96e76d86d5SStephan Aßmus // delete fBackBuffer;
97e76d86d5SStephan Aßmus // delete fFrontBuffer;
98e76d86d5SStephan Aßmus // delete[] fModeList;
99e76d86d5SStephan Aßmus }
100e76d86d5SStephan Aßmus
101e76d86d5SStephan Aßmus
102e76d86d5SStephan Aßmus /*!
103e76d86d5SStephan Aßmus \brief Opens the first available graphics device and initializes it
104e76d86d5SStephan Aßmus \return B_OK on success or an appropriate error message on failure.
105e76d86d5SStephan Aßmus */
106e76d86d5SStephan Aßmus status_t
Initialize()107e76d86d5SStephan Aßmus AccelerantHWInterface::Initialize()
108e76d86d5SStephan Aßmus {
109e76d86d5SStephan Aßmus status_t ret = B_OK;//HWInterface::Initialize();
110e76d86d5SStephan Aßmus if (ret >= B_OK) {
111e76d86d5SStephan Aßmus for (int32 i = 1; fCardFD != B_ENTRY_NOT_FOUND; i++) {
112e76d86d5SStephan Aßmus fCardFD = _OpenGraphicsDevice(i);
113e76d86d5SStephan Aßmus if (fCardFD < 0) {
114e76d86d5SStephan Aßmus ATRACE(("Failed to open graphics device\n"));
115e76d86d5SStephan Aßmus continue;
116e76d86d5SStephan Aßmus }
117e76d86d5SStephan Aßmus
118e76d86d5SStephan Aßmus if (_OpenAccelerant(fCardFD) == B_OK)
119e76d86d5SStephan Aßmus break;
120e76d86d5SStephan Aßmus
121e76d86d5SStephan Aßmus close(fCardFD);
122e76d86d5SStephan Aßmus // _OpenAccelerant() failed, try to open next graphics card
123e76d86d5SStephan Aßmus }
124e76d86d5SStephan Aßmus
125e76d86d5SStephan Aßmus return fCardFD >= 0 ? B_OK : fCardFD;
126e76d86d5SStephan Aßmus }
127e76d86d5SStephan Aßmus return ret;
128e76d86d5SStephan Aßmus }
129e76d86d5SStephan Aßmus
130e76d86d5SStephan Aßmus
131e76d86d5SStephan Aßmus /*!
132e76d86d5SStephan Aßmus \brief Opens a graphics device for read-write access
133e76d86d5SStephan Aßmus \param deviceNumber Number identifying which graphics card to open (1 for first card)
134e76d86d5SStephan Aßmus \return The file descriptor for the opened graphics device
135e76d86d5SStephan Aßmus
136e76d86d5SStephan Aßmus The deviceNumber is relative to the number of graphics devices that can be successfully
137e76d86d5SStephan Aßmus opened. One represents the first card that can be successfully opened (not necessarily
138e76d86d5SStephan Aßmus the first one listed in the directory).
139e76d86d5SStephan Aßmus Graphics drivers must be able to be opened more than once, so we really get
140e76d86d5SStephan Aßmus the first working entry.
141e76d86d5SStephan Aßmus */
142e76d86d5SStephan Aßmus int
_OpenGraphicsDevice(int deviceNumber)143e76d86d5SStephan Aßmus AccelerantHWInterface::_OpenGraphicsDevice(int deviceNumber)
144e76d86d5SStephan Aßmus {
145e76d86d5SStephan Aßmus DIR *directory = opendir("/dev/graphics");
146e76d86d5SStephan Aßmus if (!directory)
147e76d86d5SStephan Aßmus return -1;
148e76d86d5SStephan Aßmus
149e76d86d5SStephan Aßmus // ToDo: the former R5 "stub" driver is called "vesa" under Haiku; however,
150e76d86d5SStephan Aßmus // we do not need to avoid this driver this way when is has been ported
151e76d86d5SStephan Aßmus // to the new driver architecture - the special case here can then be
152e76d86d5SStephan Aßmus // removed.
153e76d86d5SStephan Aßmus int count = 0;
154e76d86d5SStephan Aßmus struct dirent *entry;
155e76d86d5SStephan Aßmus int current_card_fd = -1;
156e76d86d5SStephan Aßmus char path[PATH_MAX];
157e76d86d5SStephan Aßmus while (count < deviceNumber && (entry = readdir(directory)) != NULL) {
158e76d86d5SStephan Aßmus if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..") ||
159e76d86d5SStephan Aßmus !strcmp(entry->d_name, "stub") || !strcmp(entry->d_name, "vesa"))
160e76d86d5SStephan Aßmus continue;
161e76d86d5SStephan Aßmus
162e76d86d5SStephan Aßmus if (current_card_fd >= 0) {
163e76d86d5SStephan Aßmus close(current_card_fd);
164e76d86d5SStephan Aßmus current_card_fd = -1;
165e76d86d5SStephan Aßmus }
166e76d86d5SStephan Aßmus
167e76d86d5SStephan Aßmus sprintf(path, "/dev/graphics/%s", entry->d_name);
168e76d86d5SStephan Aßmus current_card_fd = open(path, B_READ_WRITE);
169e76d86d5SStephan Aßmus if (current_card_fd >= 0)
170e76d86d5SStephan Aßmus count++;
171e76d86d5SStephan Aßmus }
172e76d86d5SStephan Aßmus
173e76d86d5SStephan Aßmus // Open VESA driver if we were not able to get a better one
174e76d86d5SStephan Aßmus if (count < deviceNumber) {
175e76d86d5SStephan Aßmus if (deviceNumber == 1) {
176e76d86d5SStephan Aßmus sprintf(path, "/dev/graphics/vesa");
177e76d86d5SStephan Aßmus current_card_fd = open(path, B_READ_WRITE);
178e76d86d5SStephan Aßmus } else {
179e76d86d5SStephan Aßmus close(current_card_fd);
180e76d86d5SStephan Aßmus current_card_fd = B_ENTRY_NOT_FOUND;
181e76d86d5SStephan Aßmus }
182e76d86d5SStephan Aßmus }
183e76d86d5SStephan Aßmus
184e76d86d5SStephan Aßmus fCardNameInDevFS = entry->d_name;
185e76d86d5SStephan Aßmus
186e76d86d5SStephan Aßmus return current_card_fd;
187e76d86d5SStephan Aßmus }
188e76d86d5SStephan Aßmus
189e76d86d5SStephan Aßmus
190e76d86d5SStephan Aßmus status_t
_OpenAccelerant(int device)191e76d86d5SStephan Aßmus AccelerantHWInterface::_OpenAccelerant(int device)
192e76d86d5SStephan Aßmus {
193e76d86d5SStephan Aßmus char signature[1024];
194e76d86d5SStephan Aßmus if (ioctl(device, B_GET_ACCELERANT_SIGNATURE,
195e76d86d5SStephan Aßmus &signature, sizeof(signature)) != B_OK)
196e76d86d5SStephan Aßmus return B_ERROR;
197e76d86d5SStephan Aßmus
198e76d86d5SStephan Aßmus ATRACE(("accelerant signature is: %s\n", signature));
199e76d86d5SStephan Aßmus
200e76d86d5SStephan Aßmus struct stat accelerant_stat;
201e76d86d5SStephan Aßmus const static directory_which dirs[] = {
2023dfd9cb9SOliver Tappe B_USER_NONPACKAGED_ADDONS_DIRECTORY,
203e76d86d5SStephan Aßmus B_USER_ADDONS_DIRECTORY,
204*4b7e2196SIngo Weinhold B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY,
2053dfd9cb9SOliver Tappe B_SYSTEM_ADDONS_DIRECTORY
206e76d86d5SStephan Aßmus };
207e76d86d5SStephan Aßmus
208e76d86d5SStephan Aßmus fAccelerantImage = -1;
209e76d86d5SStephan Aßmus
2103dfd9cb9SOliver Tappe for (int32 i = 0; i < sizeof(dirs) / sizeof(directory_which); i++) {
211e76d86d5SStephan Aßmus char path[PATH_MAX];
212e76d86d5SStephan Aßmus if (find_directory(dirs[i], -1, false, path, PATH_MAX) != B_OK)
213e76d86d5SStephan Aßmus continue;
214e76d86d5SStephan Aßmus
215e76d86d5SStephan Aßmus strcat(path, "/accelerants/");
216e76d86d5SStephan Aßmus strcat(path, signature);
217e76d86d5SStephan Aßmus if (stat(path, &accelerant_stat) != 0)
218e76d86d5SStephan Aßmus continue;
219e76d86d5SStephan Aßmus
220e76d86d5SStephan Aßmus fAccelerantImage = load_add_on(path);
221e76d86d5SStephan Aßmus if (fAccelerantImage >= 0) {
222e76d86d5SStephan Aßmus if (get_image_symbol(fAccelerantImage, B_ACCELERANT_ENTRY_POINT,
223e76d86d5SStephan Aßmus B_SYMBOL_TYPE_ANY, (void**)(&fAccelerantHook)) != B_OK ) {
224e76d86d5SStephan Aßmus ATRACE(("unable to get B_ACCELERANT_ENTRY_POINT\n"));
225e76d86d5SStephan Aßmus unload_add_on(fAccelerantImage);
226e76d86d5SStephan Aßmus fAccelerantImage = -1;
227e76d86d5SStephan Aßmus return B_ERROR;
228e76d86d5SStephan Aßmus }
229e76d86d5SStephan Aßmus
230e76d86d5SStephan Aßmus
231e76d86d5SStephan Aßmus accelerant_clone_info_size cloneInfoSize;
232e76d86d5SStephan Aßmus cloneInfoSize = (accelerant_clone_info_size)fAccelerantHook(B_ACCELERANT_CLONE_INFO_SIZE, NULL);
233e76d86d5SStephan Aßmus if (!cloneInfoSize) {
234e76d86d5SStephan Aßmus ATRACE(("unable to get B_ACCELERANT_CLONE_INFO_SIZE (%s)\n", path));
235e76d86d5SStephan Aßmus unload_add_on(fAccelerantImage);
236e76d86d5SStephan Aßmus fAccelerantImage = -1;
237e76d86d5SStephan Aßmus return B_ERROR;
238e76d86d5SStephan Aßmus }
239e76d86d5SStephan Aßmus
240e76d86d5SStephan Aßmus ssize_t cloneSize = cloneInfoSize();
241e76d86d5SStephan Aßmus void* cloneInfoData = malloc(cloneSize);
242e76d86d5SStephan Aßmus
243e76d86d5SStephan Aßmus // get_accelerant_clone_info getCloneInfo;
244e76d86d5SStephan Aßmus // getCloneInfo = (get_accelerant_clone_info)fAccelerantHook(B_GET_ACCELERANT_CLONE_INFO, NULL);
245e76d86d5SStephan Aßmus // if (!getCloneInfo) {
246e76d86d5SStephan Aßmus // ATRACE(("unable to get B_GET_ACCELERANT_CLONE_INFO (%s)\n", path));
247e76d86d5SStephan Aßmus // unload_add_on(fAccelerantImage);
248e76d86d5SStephan Aßmus // fAccelerantImage = -1;
249e76d86d5SStephan Aßmus // return B_ERROR;
250e76d86d5SStephan Aßmus // }
251e76d86d5SStephan Aßmus // printf("getCloneInfo: %p\n", getCloneInfo);
252e76d86d5SStephan Aßmus //
253e76d86d5SStephan Aßmus // getCloneInfo(cloneInfoData);
254e76d86d5SStephan Aßmus // TODO: this is what works for the ATI Radeon driver...
255e76d86d5SStephan Aßmus sprintf((char*)cloneInfoData, "graphics/%s", fCardNameInDevFS.String());
256e76d86d5SStephan Aßmus
257e76d86d5SStephan Aßmus clone_accelerant cloneAccelerant;
258e76d86d5SStephan Aßmus cloneAccelerant = (clone_accelerant)fAccelerantHook(B_CLONE_ACCELERANT, NULL);
259e76d86d5SStephan Aßmus if (!cloneAccelerant) {
260e76d86d5SStephan Aßmus ATRACE(("unable to get B_CLONE_ACCELERANT\n"));
261e76d86d5SStephan Aßmus unload_add_on(fAccelerantImage);
262e76d86d5SStephan Aßmus fAccelerantImage = -1;
263e76d86d5SStephan Aßmus return B_ERROR;
264e76d86d5SStephan Aßmus }
265e76d86d5SStephan Aßmus status_t ret = cloneAccelerant(cloneInfoData);
266e76d86d5SStephan Aßmus if (ret != B_OK) {
267e76d86d5SStephan Aßmus ATRACE(("Cloning accelerant unsuccessful: %s\n", strerror(ret)));
268e76d86d5SStephan Aßmus unload_add_on(fAccelerantImage);
269e76d86d5SStephan Aßmus fAccelerantImage = -1;
270e76d86d5SStephan Aßmus return B_ERROR;
271e76d86d5SStephan Aßmus }
272e76d86d5SStephan Aßmus
273e76d86d5SStephan Aßmus break;
274e76d86d5SStephan Aßmus }
275e76d86d5SStephan Aßmus }
276e76d86d5SStephan Aßmus
277e76d86d5SStephan Aßmus if (fAccelerantImage < B_OK)
278e76d86d5SStephan Aßmus return B_ERROR;
279e76d86d5SStephan Aßmus
280e76d86d5SStephan Aßmus if (_SetupDefaultHooks() != B_OK) {
281e76d86d5SStephan Aßmus ATRACE(("cannot setup default hooks\n"));
282e76d86d5SStephan Aßmus
283e76d86d5SStephan Aßmus uninit_accelerant uninitAccelerant = (uninit_accelerant)
284e76d86d5SStephan Aßmus fAccelerantHook(B_UNINIT_ACCELERANT, NULL);
285e76d86d5SStephan Aßmus if (uninitAccelerant != NULL)
286e76d86d5SStephan Aßmus uninitAccelerant();
287e76d86d5SStephan Aßmus
288e76d86d5SStephan Aßmus unload_add_on(fAccelerantImage);
289e76d86d5SStephan Aßmus return B_ERROR;
290e76d86d5SStephan Aßmus }
291e76d86d5SStephan Aßmus
292e76d86d5SStephan Aßmus return B_OK;
293e76d86d5SStephan Aßmus }
294e76d86d5SStephan Aßmus
295e76d86d5SStephan Aßmus
296e76d86d5SStephan Aßmus status_t
_SetupDefaultHooks()297e76d86d5SStephan Aßmus AccelerantHWInterface::_SetupDefaultHooks()
298e76d86d5SStephan Aßmus {
299e76d86d5SStephan Aßmus // required
300e76d86d5SStephan Aßmus fAccAcquireEngine = (acquire_engine)fAccelerantHook(B_ACQUIRE_ENGINE, NULL);
301e76d86d5SStephan Aßmus fAccReleaseEngine = (release_engine)fAccelerantHook(B_RELEASE_ENGINE, NULL);
302e76d86d5SStephan Aßmus fAccSyncToToken = (sync_to_token)fAccelerantHook(B_SYNC_TO_TOKEN, NULL);
303e76d86d5SStephan Aßmus fAccGetModeCount = (accelerant_mode_count)fAccelerantHook(B_ACCELERANT_MODE_COUNT, NULL);
304e76d86d5SStephan Aßmus fAccGetModeList = (get_mode_list)fAccelerantHook(B_GET_MODE_LIST, NULL);
305e76d86d5SStephan Aßmus fAccGetFrameBufferConfig = (get_frame_buffer_config)fAccelerantHook(B_GET_FRAME_BUFFER_CONFIG, NULL);
306e76d86d5SStephan Aßmus fAccSetDisplayMode = (set_display_mode)fAccelerantHook(B_SET_DISPLAY_MODE, NULL);
307e76d86d5SStephan Aßmus fAccGetDisplayMode = (get_display_mode)fAccelerantHook(B_GET_DISPLAY_MODE, NULL);
308e76d86d5SStephan Aßmus fAccGetPixelClockLimits = (get_pixel_clock_limits)fAccelerantHook(B_GET_PIXEL_CLOCK_LIMITS, NULL);
309e76d86d5SStephan Aßmus
310e76d86d5SStephan Aßmus if (!fAccAcquireEngine || !fAccReleaseEngine || !fAccGetFrameBufferConfig
311e76d86d5SStephan Aßmus || !fAccGetModeCount || !fAccGetModeList || !fAccSetDisplayMode
312e76d86d5SStephan Aßmus || !fAccGetDisplayMode || !fAccGetPixelClockLimits) {
313e76d86d5SStephan Aßmus return B_ERROR;
314e76d86d5SStephan Aßmus }
315e76d86d5SStephan Aßmus
316e76d86d5SStephan Aßmus // optional
317e76d86d5SStephan Aßmus fAccGetTimingConstraints = (get_timing_constraints)fAccelerantHook(B_GET_TIMING_CONSTRAINTS, NULL);
318e76d86d5SStephan Aßmus fAccProposeDisplayMode = (propose_display_mode)fAccelerantHook(B_PROPOSE_DISPLAY_MODE, NULL);
319e76d86d5SStephan Aßmus
320e76d86d5SStephan Aßmus // cursor
321e76d86d5SStephan Aßmus fAccSetCursorShape = (set_cursor_shape)fAccelerantHook(B_SET_CURSOR_SHAPE, NULL);
322e76d86d5SStephan Aßmus fAccMoveCursor = (move_cursor)fAccelerantHook(B_MOVE_CURSOR, NULL);
323e76d86d5SStephan Aßmus fAccShowCursor = (show_cursor)fAccelerantHook(B_SHOW_CURSOR, NULL);
324e76d86d5SStephan Aßmus
325e76d86d5SStephan Aßmus // dpms
326e76d86d5SStephan Aßmus // fAccDPMSCapabilities = (dpms_capabilities)fAccelerantHook(B_DPMS_CAPABILITIES, NULL);
327e76d86d5SStephan Aßmus // fAccDPMSMode = (dpms_mode)fAccelerantHook(B_DPMS_MODE, NULL);
328e76d86d5SStephan Aßmus // fAccSetDPMSMode = (set_dpms_mode)fAccelerantHook(B_SET_DPMS_MODE, NULL);
329e76d86d5SStephan Aßmus
330e76d86d5SStephan Aßmus // update acceleration hooks
331e76d86d5SStephan Aßmus // TODO: would actually have to pass a valid display_mode!
332e76d86d5SStephan Aßmus fAccFillRect = (fill_rectangle)fAccelerantHook(B_FILL_RECTANGLE, NULL);
333e76d86d5SStephan Aßmus fAccInvertRect = (invert_rectangle)fAccelerantHook(B_INVERT_RECTANGLE, NULL);
334e76d86d5SStephan Aßmus fAccScreenBlit = (screen_to_screen_blit)fAccelerantHook(B_SCREEN_TO_SCREEN_BLIT, NULL);
335e76d86d5SStephan Aßmus
336e76d86d5SStephan Aßmus return B_OK;
337e76d86d5SStephan Aßmus }
338e76d86d5SStephan Aßmus
339e76d86d5SStephan Aßmus // Shutdown
340e76d86d5SStephan Aßmus status_t
Shutdown()341e76d86d5SStephan Aßmus AccelerantHWInterface::Shutdown()
342e76d86d5SStephan Aßmus {
343e76d86d5SStephan Aßmus if (fAccelerantHook) {
344e76d86d5SStephan Aßmus uninit_accelerant UninitAccelerant = (uninit_accelerant)fAccelerantHook(B_UNINIT_ACCELERANT, NULL);
345e76d86d5SStephan Aßmus if (UninitAccelerant)
346e76d86d5SStephan Aßmus UninitAccelerant();
347e76d86d5SStephan Aßmus }
348e76d86d5SStephan Aßmus
349e76d86d5SStephan Aßmus if (fAccelerantImage >= 0)
350e76d86d5SStephan Aßmus unload_add_on(fAccelerantImage);
351e76d86d5SStephan Aßmus
352e76d86d5SStephan Aßmus if (fCardFD >= 0)
353e76d86d5SStephan Aßmus close(fCardFD);
354e76d86d5SStephan Aßmus
355e76d86d5SStephan Aßmus return B_OK;
356e76d86d5SStephan Aßmus }
357e76d86d5SStephan Aßmus /*
358e76d86d5SStephan Aßmus // SetMode
359e76d86d5SStephan Aßmus status_t
360e76d86d5SStephan Aßmus AccelerantHWInterface::SetMode(const display_mode &mode)
361e76d86d5SStephan Aßmus {
362e76d86d5SStephan Aßmus AutoWriteLocker _(this);
363e76d86d5SStephan Aßmus // TODO: There are places this function can fail,
364e76d86d5SStephan Aßmus // maybe it needs to roll back changes in case of an
365e76d86d5SStephan Aßmus // error.
366e76d86d5SStephan Aßmus
367e76d86d5SStephan Aßmus // prevent from doing the unnecessary
368e76d86d5SStephan Aßmus if (fModeCount > 0 && fBackBuffer && fFrontBuffer
369e76d86d5SStephan Aßmus && fDisplayMode == mode) {
370e76d86d5SStephan Aßmus // TODO: better comparison of display modes
371e76d86d5SStephan Aßmus return B_OK;
372e76d86d5SStephan Aßmus }
373e76d86d5SStephan Aßmus
374e76d86d5SStephan Aßmus // just try to set the mode - we let the graphics driver
375e76d86d5SStephan Aßmus // approve or deny the request, as it should know best
376e76d86d5SStephan Aßmus
377e76d86d5SStephan Aßmus fDisplayMode = mode;
378e76d86d5SStephan Aßmus
379e76d86d5SStephan Aßmus if (fAccSetDisplayMode(&fDisplayMode) != B_OK) {
380e76d86d5SStephan Aßmus ATRACE(("setting display mode failed\n"));
381e76d86d5SStephan Aßmus fAccGetDisplayMode(&fDisplayMode);
382e76d86d5SStephan Aßmus // We just keep the current mode and continue.
383e76d86d5SStephan Aßmus // Note, on startup, this may be different from
384e76d86d5SStephan Aßmus // what we think is the current display mode
385e76d86d5SStephan Aßmus }
386e76d86d5SStephan Aßmus
387e76d86d5SStephan Aßmus // update frontbuffer
388e76d86d5SStephan Aßmus fFrontBuffer->SetDisplayMode(fDisplayMode);
389e76d86d5SStephan Aßmus if (_UpdateFrameBufferConfig() != B_OK)
390e76d86d5SStephan Aßmus return B_ERROR;
391e76d86d5SStephan Aßmus
392e76d86d5SStephan Aßmus // Update the frame buffer used by the on-screen KDL
393e76d86d5SStephan Aßmus #ifdef __HAIKU__
394e76d86d5SStephan Aßmus uint32 depth = (fFrameBufferConfig.bytes_per_row / fDisplayMode.virtual_width) << 3;
395e76d86d5SStephan Aßmus if (fDisplayMode.space == B_RGB15)
396e76d86d5SStephan Aßmus depth = 15;
397e76d86d5SStephan Aßmus
398e76d86d5SStephan Aßmus _kern_frame_buffer_update(fFrameBufferConfig.frame_buffer,
399e76d86d5SStephan Aßmus fDisplayMode.virtual_width, fDisplayMode.virtual_height,
400e76d86d5SStephan Aßmus depth, fFrameBufferConfig.bytes_per_row);
401e76d86d5SStephan Aßmus #endif
402e76d86d5SStephan Aßmus
403e76d86d5SStephan Aßmus // update backbuffer if neccessary
404e76d86d5SStephan Aßmus if (!fBackBuffer || fBackBuffer->Width() != fDisplayMode.virtual_width
405e76d86d5SStephan Aßmus || fBackBuffer->Height() != fDisplayMode.virtual_height) {
406e76d86d5SStephan Aßmus // NOTE: backbuffer is always B_RGBA32, this simplifies the
407e76d86d5SStephan Aßmus // drawing backend implementation tremendously for the time
408e76d86d5SStephan Aßmus // being. The color space conversion is handled in CopyBackToFront()
409e76d86d5SStephan Aßmus
410e76d86d5SStephan Aßmus delete fBackBuffer;
411e76d86d5SStephan Aßmus fBackBuffer = NULL;
412e76d86d5SStephan Aßmus
413e76d86d5SStephan Aßmus // TODO: Above not true anymore for single buffered mode!!!
414e76d86d5SStephan Aßmus // -> fall back to double buffer for fDisplayMode.space != B_RGB32
415e76d86d5SStephan Aßmus // as intermediate solution...
416e76d86d5SStephan Aßmus bool doubleBuffered = HWInterface::IsDoubleBuffered();
417e76d86d5SStephan Aßmus if ((color_space)fDisplayMode.space != B_RGB32 &&
418e76d86d5SStephan Aßmus (color_space)fDisplayMode.space != B_RGBA32)
419e76d86d5SStephan Aßmus doubleBuffered = true;
420e76d86d5SStephan Aßmus
421e76d86d5SStephan Aßmus if (doubleBuffered) {
422e76d86d5SStephan Aßmus fBackBuffer = new(nothrow) MallocBuffer(fDisplayMode.virtual_width,
423e76d86d5SStephan Aßmus fDisplayMode.virtual_height);
424e76d86d5SStephan Aßmus
425e76d86d5SStephan Aßmus status_t ret = fBackBuffer ? fBackBuffer->InitCheck() : B_NO_MEMORY;
426e76d86d5SStephan Aßmus if (ret < B_OK) {
427e76d86d5SStephan Aßmus delete fBackBuffer;
428e76d86d5SStephan Aßmus fBackBuffer = NULL;
429e76d86d5SStephan Aßmus return ret;
430e76d86d5SStephan Aßmus }
431e76d86d5SStephan Aßmus // clear out backbuffer, alpha is 255 this way
432e76d86d5SStephan Aßmus memset(fBackBuffer->Bits(), 255, fBackBuffer->BitsLength());
433e76d86d5SStephan Aßmus }
434e76d86d5SStephan Aßmus }
435e76d86d5SStephan Aßmus
436e76d86d5SStephan Aßmus // update acceleration hooks
437e76d86d5SStephan Aßmus fAccFillRect = (fill_rectangle)fAccelerantHook(B_FILL_RECTANGLE, (void *)&fDisplayMode);
438e76d86d5SStephan Aßmus fAccInvertRect = (invert_rectangle)fAccelerantHook(B_INVERT_RECTANGLE,
439e76d86d5SStephan Aßmus (void *)&fDisplayMode);
440e76d86d5SStephan Aßmus fAccScreenBlit = (screen_to_screen_blit)fAccelerantHook(B_SCREEN_TO_SCREEN_BLIT,
441e76d86d5SStephan Aßmus (void *)&fDisplayMode);
442e76d86d5SStephan Aßmus
443e76d86d5SStephan Aßmus return B_OK;
444e76d86d5SStephan Aßmus }
445e76d86d5SStephan Aßmus
446e76d86d5SStephan Aßmus
447e76d86d5SStephan Aßmus void
448e76d86d5SStephan Aßmus AccelerantHWInterface::GetMode(display_mode *mode)
449e76d86d5SStephan Aßmus {
450e76d86d5SStephan Aßmus if (mode && ReadLock()) {
451e76d86d5SStephan Aßmus *mode = fDisplayMode;
452e76d86d5SStephan Aßmus ReadUnlock();
453e76d86d5SStephan Aßmus }
454e76d86d5SStephan Aßmus }
455e76d86d5SStephan Aßmus
456e76d86d5SStephan Aßmus
457e76d86d5SStephan Aßmus status_t
458e76d86d5SStephan Aßmus AccelerantHWInterface::_UpdateModeList()
459e76d86d5SStephan Aßmus {
460e76d86d5SStephan Aßmus fModeCount = fAccGetModeCount();
461e76d86d5SStephan Aßmus if (fModeCount <= 0)
462e76d86d5SStephan Aßmus return B_ERROR;
463e76d86d5SStephan Aßmus
464e76d86d5SStephan Aßmus delete[] fModeList;
465e76d86d5SStephan Aßmus fModeList = new(nothrow) display_mode[fModeCount];
466e76d86d5SStephan Aßmus if (!fModeList)
467e76d86d5SStephan Aßmus return B_NO_MEMORY;
468e76d86d5SStephan Aßmus
469e76d86d5SStephan Aßmus if (fAccGetModeList(fModeList) != B_OK) {
470e76d86d5SStephan Aßmus ATRACE(("unable to get mode list\n"));
471e76d86d5SStephan Aßmus return B_ERROR;
472e76d86d5SStephan Aßmus }
473e76d86d5SStephan Aßmus
474e76d86d5SStephan Aßmus return B_OK;
475e76d86d5SStephan Aßmus }
476e76d86d5SStephan Aßmus
477e76d86d5SStephan Aßmus
478e76d86d5SStephan Aßmus status_t
479e76d86d5SStephan Aßmus AccelerantHWInterface::_UpdateFrameBufferConfig()
480e76d86d5SStephan Aßmus {
481e76d86d5SStephan Aßmus if (fAccGetFrameBufferConfig(&fFrameBufferConfig) != B_OK) {
482e76d86d5SStephan Aßmus ATRACE(("unable to get frame buffer config\n"));
483e76d86d5SStephan Aßmus return B_ERROR;
484e76d86d5SStephan Aßmus }
485e76d86d5SStephan Aßmus
486e76d86d5SStephan Aßmus fFrontBuffer->SetFrameBufferConfig(fFrameBufferConfig);
487e76d86d5SStephan Aßmus return B_OK;
488e76d86d5SStephan Aßmus }
489e76d86d5SStephan Aßmus
490e76d86d5SStephan Aßmus
491e76d86d5SStephan Aßmus status_t
492e76d86d5SStephan Aßmus AccelerantHWInterface::GetDeviceInfo(accelerant_device_info *info)
493e76d86d5SStephan Aßmus {
494e76d86d5SStephan Aßmus get_accelerant_device_info GetAccelerantDeviceInfo = (get_accelerant_device_info)fAccelerantHook(B_GET_ACCELERANT_DEVICE_INFO, NULL);
495e76d86d5SStephan Aßmus if (!GetAccelerantDeviceInfo) {
496e76d86d5SStephan Aßmus ATRACE(("No B_GET_ACCELERANT_DEVICE_INFO hook found\n"));
497e76d86d5SStephan Aßmus return B_UNSUPPORTED;
498e76d86d5SStephan Aßmus }
499e76d86d5SStephan Aßmus
500e76d86d5SStephan Aßmus return GetAccelerantDeviceInfo(info);
501e76d86d5SStephan Aßmus }
502e76d86d5SStephan Aßmus
503e76d86d5SStephan Aßmus
504e76d86d5SStephan Aßmus status_t
505e76d86d5SStephan Aßmus AccelerantHWInterface::GetFrameBufferConfig(frame_buffer_config& config)
506e76d86d5SStephan Aßmus {
507e76d86d5SStephan Aßmus config = fFrameBufferConfig;
508e76d86d5SStephan Aßmus return B_OK;
509e76d86d5SStephan Aßmus }
510e76d86d5SStephan Aßmus
511e76d86d5SStephan Aßmus
512e76d86d5SStephan Aßmus status_t
513e76d86d5SStephan Aßmus AccelerantHWInterface::GetModeList(display_mode** modes, uint32 *count)
514e76d86d5SStephan Aßmus {
515e76d86d5SStephan Aßmus AutoReadLocker _(this);
516e76d86d5SStephan Aßmus
517e76d86d5SStephan Aßmus if (!count || !modes)
518e76d86d5SStephan Aßmus return B_BAD_VALUE;
519e76d86d5SStephan Aßmus
520e76d86d5SStephan Aßmus status_t ret = fModeList ? B_OK : _UpdateModeList();
521e76d86d5SStephan Aßmus
522e76d86d5SStephan Aßmus if (ret >= B_OK) {
523e76d86d5SStephan Aßmus *modes = new(nothrow) display_mode[fModeCount];
524e76d86d5SStephan Aßmus if (*modes) {
525e76d86d5SStephan Aßmus *count = fModeCount;
526e76d86d5SStephan Aßmus memcpy(*modes, fModeList, sizeof(display_mode) * fModeCount);
527e76d86d5SStephan Aßmus } else {
528e76d86d5SStephan Aßmus *count = 0;
529e76d86d5SStephan Aßmus ret = B_NO_MEMORY;
530e76d86d5SStephan Aßmus }
531e76d86d5SStephan Aßmus }
532e76d86d5SStephan Aßmus return ret;
533e76d86d5SStephan Aßmus }
534e76d86d5SStephan Aßmus
535e76d86d5SStephan Aßmus status_t
536e76d86d5SStephan Aßmus AccelerantHWInterface::GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *high)
537e76d86d5SStephan Aßmus {
538e76d86d5SStephan Aßmus AutoReadLocker _(this);
539e76d86d5SStephan Aßmus
540e76d86d5SStephan Aßmus if (!mode || !low || !high)
541e76d86d5SStephan Aßmus return B_BAD_VALUE;
542e76d86d5SStephan Aßmus
543e76d86d5SStephan Aßmus return fAccGetPixelClockLimits(mode, low, high);
544e76d86d5SStephan Aßmus }
545e76d86d5SStephan Aßmus
546e76d86d5SStephan Aßmus status_t
547e76d86d5SStephan Aßmus AccelerantHWInterface::GetTimingConstraints(display_timing_constraints *dtc)
548e76d86d5SStephan Aßmus {
549e76d86d5SStephan Aßmus AutoReadLocker _(this);
550e76d86d5SStephan Aßmus
551e76d86d5SStephan Aßmus if (!dtc)
552e76d86d5SStephan Aßmus return B_BAD_VALUE;
553e76d86d5SStephan Aßmus
554e76d86d5SStephan Aßmus if (fAccGetTimingConstraints)
555e76d86d5SStephan Aßmus return fAccGetTimingConstraints(dtc);
556e76d86d5SStephan Aßmus
557e76d86d5SStephan Aßmus return B_UNSUPPORTED;
558e76d86d5SStephan Aßmus }
559e76d86d5SStephan Aßmus
560e76d86d5SStephan Aßmus status_t
561e76d86d5SStephan Aßmus AccelerantHWInterface::ProposeMode(display_mode *candidate, const display_mode *low, const display_mode *high)
562e76d86d5SStephan Aßmus {
563e76d86d5SStephan Aßmus AutoReadLocker _(this);
564e76d86d5SStephan Aßmus
565e76d86d5SStephan Aßmus if (!candidate || !low || !high)
566e76d86d5SStephan Aßmus return B_BAD_VALUE;
567e76d86d5SStephan Aßmus
568e76d86d5SStephan Aßmus if (!fAccProposeDisplayMode)
569e76d86d5SStephan Aßmus return B_UNSUPPORTED;
570e76d86d5SStephan Aßmus
571e76d86d5SStephan Aßmus // avoid const issues
572e76d86d5SStephan Aßmus display_mode this_high, this_low;
573e76d86d5SStephan Aßmus this_high = *high;
574e76d86d5SStephan Aßmus this_low = *low;
575e76d86d5SStephan Aßmus
576e76d86d5SStephan Aßmus return fAccProposeDisplayMode(candidate, &this_low, &this_high);
577e76d86d5SStephan Aßmus }
578e76d86d5SStephan Aßmus
579e76d86d5SStephan Aßmus // RetraceSemaphore
580e76d86d5SStephan Aßmus sem_id
581e76d86d5SStephan Aßmus AccelerantHWInterface::RetraceSemaphore()
582e76d86d5SStephan Aßmus {
583e76d86d5SStephan Aßmus accelerant_retrace_semaphore AccelerantRetraceSemaphore = (accelerant_retrace_semaphore)fAccelerantHook(B_ACCELERANT_RETRACE_SEMAPHORE, NULL);
584e76d86d5SStephan Aßmus if (!AccelerantRetraceSemaphore)
585e76d86d5SStephan Aßmus return B_UNSUPPORTED;
586e76d86d5SStephan Aßmus
587e76d86d5SStephan Aßmus return AccelerantRetraceSemaphore();
588e76d86d5SStephan Aßmus }
589e76d86d5SStephan Aßmus
590e76d86d5SStephan Aßmus // WaitForRetrace
591e76d86d5SStephan Aßmus status_t
592e76d86d5SStephan Aßmus AccelerantHWInterface::WaitForRetrace(bigtime_t timeout)
593e76d86d5SStephan Aßmus {
594e76d86d5SStephan Aßmus AutoReadLocker _(this);
595e76d86d5SStephan Aßmus
596e76d86d5SStephan Aßmus accelerant_retrace_semaphore AccelerantRetraceSemaphore = (accelerant_retrace_semaphore)fAccelerantHook(B_ACCELERANT_RETRACE_SEMAPHORE, NULL);
597e76d86d5SStephan Aßmus if (!AccelerantRetraceSemaphore)
598e76d86d5SStephan Aßmus return B_UNSUPPORTED;
599e76d86d5SStephan Aßmus
600e76d86d5SStephan Aßmus sem_id sem = AccelerantRetraceSemaphore();
601e76d86d5SStephan Aßmus if (sem < 0)
602e76d86d5SStephan Aßmus return B_ERROR;
603e76d86d5SStephan Aßmus
604e76d86d5SStephan Aßmus return acquire_sem_etc(sem, 1, B_RELATIVE_TIMEOUT, timeout);
605e76d86d5SStephan Aßmus }
606e76d86d5SStephan Aßmus
607e76d86d5SStephan Aßmus // SetDPMSMode
608e76d86d5SStephan Aßmus status_t
609e76d86d5SStephan Aßmus AccelerantHWInterface::SetDPMSMode(const uint32 &state)
610e76d86d5SStephan Aßmus {
611e76d86d5SStephan Aßmus AutoWriteLocker _(this);
612e76d86d5SStephan Aßmus
613e76d86d5SStephan Aßmus if (!fAccSetDPMSMode)
614e76d86d5SStephan Aßmus return B_UNSUPPORTED;
615e76d86d5SStephan Aßmus
616e76d86d5SStephan Aßmus return fAccSetDPMSMode(state);
617e76d86d5SStephan Aßmus }
618e76d86d5SStephan Aßmus
619e76d86d5SStephan Aßmus // DPMSMode
620e76d86d5SStephan Aßmus uint32
621e76d86d5SStephan Aßmus AccelerantHWInterface::DPMSMode()
622e76d86d5SStephan Aßmus {
623e76d86d5SStephan Aßmus AutoReadLocker _(this);
624e76d86d5SStephan Aßmus
625e76d86d5SStephan Aßmus if (!fAccDPMSMode)
626e76d86d5SStephan Aßmus return B_UNSUPPORTED;
627e76d86d5SStephan Aßmus
628e76d86d5SStephan Aßmus return fAccDPMSMode();
629e76d86d5SStephan Aßmus }
630e76d86d5SStephan Aßmus
631e76d86d5SStephan Aßmus // DPMSCapabilities
632e76d86d5SStephan Aßmus uint32
633e76d86d5SStephan Aßmus AccelerantHWInterface::DPMSCapabilities()
634e76d86d5SStephan Aßmus {
635e76d86d5SStephan Aßmus AutoReadLocker _(this);
636e76d86d5SStephan Aßmus
637e76d86d5SStephan Aßmus if (!fAccDPMSCapabilities)
638e76d86d5SStephan Aßmus return B_UNSUPPORTED;
639e76d86d5SStephan Aßmus
640e76d86d5SStephan Aßmus return fAccDPMSCapabilities();
641e76d86d5SStephan Aßmus }
642e76d86d5SStephan Aßmus */
643e76d86d5SStephan Aßmus // AvailableHardwareAcceleration
644e76d86d5SStephan Aßmus uint32
AvailableHWAcceleration() const645e76d86d5SStephan Aßmus AccelerantHWInterface::AvailableHWAcceleration() const
646e76d86d5SStephan Aßmus {
647e76d86d5SStephan Aßmus uint32 flags = 0;
648e76d86d5SStephan Aßmus
649e76d86d5SStephan Aßmus /* if (!IsDoubleBuffered()) {
650e76d86d5SStephan Aßmus if (fAccScreenBlit)
651e76d86d5SStephan Aßmus flags |= HW_ACC_COPY_REGION;
652e76d86d5SStephan Aßmus if (fAccFillRect)
653e76d86d5SStephan Aßmus flags |= HW_ACC_FILL_REGION;
654e76d86d5SStephan Aßmus if (fAccInvertRect)
655e76d86d5SStephan Aßmus flags |= HW_ACC_INVERT_REGION;
656e76d86d5SStephan Aßmus }*/
657e76d86d5SStephan Aßmus
658e76d86d5SStephan Aßmus return flags;
659e76d86d5SStephan Aßmus }
660e76d86d5SStephan Aßmus
661e76d86d5SStephan Aßmus // CopyRegion
662e76d86d5SStephan Aßmus void
CopyRegion(const clipping_rect * sortedRectList,uint32 count,int32 xOffset,int32 yOffset)663e76d86d5SStephan Aßmus AccelerantHWInterface::CopyRegion(const clipping_rect* sortedRectList,
664e76d86d5SStephan Aßmus uint32 count, int32 xOffset, int32 yOffset)
665e76d86d5SStephan Aßmus {
666e76d86d5SStephan Aßmus if (fAccScreenBlit && fAccAcquireEngine) {
667e76d86d5SStephan Aßmus if (fAccAcquireEngine(B_2D_ACCELERATION, 0xff, &fSyncToken, &fEngineToken) >= B_OK) {
668e76d86d5SStephan Aßmus
669e76d86d5SStephan Aßmus // convert the rects
670e76d86d5SStephan Aßmus blit_params* params = new blit_params[count];
671e76d86d5SStephan Aßmus for (uint32 i = 0; i < count; i++) {
672e76d86d5SStephan Aßmus params[i].src_left = (uint16)sortedRectList[i].left;
673e76d86d5SStephan Aßmus params[i].src_top = (uint16)sortedRectList[i].top;
674e76d86d5SStephan Aßmus
675e76d86d5SStephan Aßmus params[i].dest_left = (uint16)sortedRectList[i].left + xOffset;
676e76d86d5SStephan Aßmus params[i].dest_top = (uint16)sortedRectList[i].top + yOffset;
677e76d86d5SStephan Aßmus
678e76d86d5SStephan Aßmus // NOTE: width and height are expressed as distance, not pixel count!
679e76d86d5SStephan Aßmus params[i].width = (uint16)(sortedRectList[i].right - sortedRectList[i].left);
680e76d86d5SStephan Aßmus params[i].height = (uint16)(sortedRectList[i].bottom - sortedRectList[i].top);
681e76d86d5SStephan Aßmus }
682e76d86d5SStephan Aßmus
683e76d86d5SStephan Aßmus // go
684e76d86d5SStephan Aßmus fAccScreenBlit(fEngineToken, params, count);
685e76d86d5SStephan Aßmus
686e76d86d5SStephan Aßmus // done
687e76d86d5SStephan Aßmus if (fAccReleaseEngine)
688e76d86d5SStephan Aßmus fAccReleaseEngine(fEngineToken, &fSyncToken);
689e76d86d5SStephan Aßmus
690e76d86d5SStephan Aßmus // sync
691e76d86d5SStephan Aßmus if (fAccSyncToToken)
692e76d86d5SStephan Aßmus fAccSyncToToken(&fSyncToken);
693e76d86d5SStephan Aßmus
694e76d86d5SStephan Aßmus delete[] params;
695e76d86d5SStephan Aßmus }
696e76d86d5SStephan Aßmus }
697e76d86d5SStephan Aßmus }
698e76d86d5SStephan Aßmus
699e76d86d5SStephan Aßmus // FillRegion
700e76d86d5SStephan Aßmus void
FillRegion(BRegion & region,const rgb_color & color)701e76d86d5SStephan Aßmus AccelerantHWInterface::FillRegion(/*const*/ BRegion& region, const rgb_color& color)
702e76d86d5SStephan Aßmus {
703e76d86d5SStephan Aßmus if (fAccFillRect && fAccAcquireEngine) {
704e76d86d5SStephan Aßmus if (fAccAcquireEngine(B_2D_ACCELERATION, 0xff, &fSyncToken, &fEngineToken) >= B_OK) {
705e76d86d5SStephan Aßmus
706e76d86d5SStephan Aßmus // convert the region
707e76d86d5SStephan Aßmus uint32 count;
708e76d86d5SStephan Aßmus fill_rect_params* fillParams;
709e76d86d5SStephan Aßmus _RegionToRectParams(®ion, &fillParams, &count);
710e76d86d5SStephan Aßmus
711e76d86d5SStephan Aßmus // go
712e76d86d5SStephan Aßmus fAccFillRect(fEngineToken, _NativeColor(color), fillParams, count);
713e76d86d5SStephan Aßmus
714e76d86d5SStephan Aßmus // done
715e76d86d5SStephan Aßmus if (fAccReleaseEngine)
716e76d86d5SStephan Aßmus fAccReleaseEngine(fEngineToken, &fSyncToken);
717e76d86d5SStephan Aßmus
718e76d86d5SStephan Aßmus // sync
719e76d86d5SStephan Aßmus if (fAccSyncToToken)
720e76d86d5SStephan Aßmus fAccSyncToToken(&fSyncToken);
721e76d86d5SStephan Aßmus
722e76d86d5SStephan Aßmus delete[] fillParams;
723e76d86d5SStephan Aßmus }
724e76d86d5SStephan Aßmus }
725e76d86d5SStephan Aßmus }
726e76d86d5SStephan Aßmus
727e76d86d5SStephan Aßmus // InvertRegion
728e76d86d5SStephan Aßmus void
InvertRegion(BRegion & region)729e76d86d5SStephan Aßmus AccelerantHWInterface::InvertRegion(/*const*/ BRegion& region)
730e76d86d5SStephan Aßmus {
731e76d86d5SStephan Aßmus if (fAccInvertRect && fAccAcquireEngine) {
732e76d86d5SStephan Aßmus if (fAccAcquireEngine(B_2D_ACCELERATION, 0xff, &fSyncToken, &fEngineToken) >= B_OK) {
733e76d86d5SStephan Aßmus
734e76d86d5SStephan Aßmus // convert the region
735e76d86d5SStephan Aßmus uint32 count;
736e76d86d5SStephan Aßmus fill_rect_params* fillParams;
737e76d86d5SStephan Aßmus _RegionToRectParams(®ion, &fillParams, &count);
738e76d86d5SStephan Aßmus
739e76d86d5SStephan Aßmus // go
740e76d86d5SStephan Aßmus fAccInvertRect(fEngineToken, fillParams, count);
741e76d86d5SStephan Aßmus
742e76d86d5SStephan Aßmus // done
743e76d86d5SStephan Aßmus if (fAccReleaseEngine)
744e76d86d5SStephan Aßmus fAccReleaseEngine(fEngineToken, &fSyncToken);
745e76d86d5SStephan Aßmus
746e76d86d5SStephan Aßmus // sync
747e76d86d5SStephan Aßmus if (fAccSyncToToken)
748e76d86d5SStephan Aßmus fAccSyncToToken(&fSyncToken);
749e76d86d5SStephan Aßmus
750e76d86d5SStephan Aßmus delete[] fillParams;
751e76d86d5SStephan Aßmus } else {
752e76d86d5SStephan Aßmus fprintf(stderr, "AcquireEngine failed!\n");
753e76d86d5SStephan Aßmus }
754e76d86d5SStephan Aßmus } else {
755e76d86d5SStephan Aßmus fprintf(stderr, "AccelerantHWInterface::InvertRegion() called, but hook not available!\n");
756e76d86d5SStephan Aßmus }
757e76d86d5SStephan Aßmus }
758e76d86d5SStephan Aßmus /*
759e76d86d5SStephan Aßmus // SetCursor
760e76d86d5SStephan Aßmus void
761e76d86d5SStephan Aßmus AccelerantHWInterface::SetCursor(ServerCursor* cursor)
762e76d86d5SStephan Aßmus {
763e76d86d5SStephan Aßmus HWInterface::SetCursor(cursor);
764e76d86d5SStephan Aßmus // if (WriteLock()) {
765e76d86d5SStephan Aßmus // TODO: implement setting the hard ware cursor
766e76d86d5SStephan Aßmus // NOTE: cursor should be always B_RGBA32
767e76d86d5SStephan Aßmus // NOTE: The HWInterface implementation should
768e76d86d5SStephan Aßmus // still be called, since it takes ownership of
769e76d86d5SStephan Aßmus // the cursor.
770e76d86d5SStephan Aßmus // WriteUnlock();
771e76d86d5SStephan Aßmus // }
772e76d86d5SStephan Aßmus }
773e76d86d5SStephan Aßmus
774e76d86d5SStephan Aßmus // SetCursorVisible
775e76d86d5SStephan Aßmus void
776e76d86d5SStephan Aßmus AccelerantHWInterface::SetCursorVisible(bool visible)
777e76d86d5SStephan Aßmus {
778e76d86d5SStephan Aßmus HWInterface::SetCursorVisible(visible);
779e76d86d5SStephan Aßmus // if (WriteLock()) {
780e76d86d5SStephan Aßmus // TODO: update graphics hardware
781e76d86d5SStephan Aßmus // WriteUnlock();
782e76d86d5SStephan Aßmus // }
783e76d86d5SStephan Aßmus }
784e76d86d5SStephan Aßmus
785e76d86d5SStephan Aßmus // MoveCursorTo
786e76d86d5SStephan Aßmus void
787e76d86d5SStephan Aßmus AccelerantHWInterface::MoveCursorTo(const float& x, const float& y)
788e76d86d5SStephan Aßmus {
789e76d86d5SStephan Aßmus HWInterface::MoveCursorTo(x, y);
790e76d86d5SStephan Aßmus // if (WriteLock()) {
791e76d86d5SStephan Aßmus // TODO: update graphics hardware
792e76d86d5SStephan Aßmus // WriteUnlock();
793e76d86d5SStephan Aßmus // }
794e76d86d5SStephan Aßmus }
795e76d86d5SStephan Aßmus
796e76d86d5SStephan Aßmus // FrontBuffer
797e76d86d5SStephan Aßmus RenderingBuffer *
798e76d86d5SStephan Aßmus AccelerantHWInterface::FrontBuffer() const
799e76d86d5SStephan Aßmus {
800e76d86d5SStephan Aßmus if (!fModeList)
801e76d86d5SStephan Aßmus return NULL;
802e76d86d5SStephan Aßmus
803e76d86d5SStephan Aßmus return fFrontBuffer;
804e76d86d5SStephan Aßmus }
805e76d86d5SStephan Aßmus
806e76d86d5SStephan Aßmus // BackBuffer
807e76d86d5SStephan Aßmus RenderingBuffer *
808e76d86d5SStephan Aßmus AccelerantHWInterface::BackBuffer() const
809e76d86d5SStephan Aßmus {
810e76d86d5SStephan Aßmus if (!fModeList)
811e76d86d5SStephan Aßmus return NULL;
812e76d86d5SStephan Aßmus
813e76d86d5SStephan Aßmus return fBackBuffer;
814e76d86d5SStephan Aßmus }
815e76d86d5SStephan Aßmus
816e76d86d5SStephan Aßmus // IsDoubleBuffered
817e76d86d5SStephan Aßmus bool
818e76d86d5SStephan Aßmus AccelerantHWInterface::IsDoubleBuffered() const
819e76d86d5SStephan Aßmus {
820e76d86d5SStephan Aßmus if (fModeList)
821e76d86d5SStephan Aßmus return fBackBuffer != NULL;
822e76d86d5SStephan Aßmus
823e76d86d5SStephan Aßmus return HWInterface::IsDoubleBuffered();
824e76d86d5SStephan Aßmus }
825e76d86d5SStephan Aßmus
826e76d86d5SStephan Aßmus // _DrawCursor
827e76d86d5SStephan Aßmus void
828e76d86d5SStephan Aßmus AccelerantHWInterface::_DrawCursor(BRect area) const
829e76d86d5SStephan Aßmus {
830e76d86d5SStephan Aßmus // use the default implementation for now,
831e76d86d5SStephan Aßmus // until we have a hardware cursor
832e76d86d5SStephan Aßmus HWInterface::_DrawCursor(area);
833e76d86d5SStephan Aßmus // TODO: this would only be called, if we don't have
834e76d86d5SStephan Aßmus // a hardware cursor for some reason
835e76d86d5SStephan Aßmus }
836e76d86d5SStephan Aßmus */
837e76d86d5SStephan Aßmus // _RegionToRectParams
838e76d86d5SStephan Aßmus void
_RegionToRectParams(BRegion * region,fill_rect_params ** params,uint32 * count) const839e76d86d5SStephan Aßmus AccelerantHWInterface::_RegionToRectParams(/*const*/ BRegion* region,
840e76d86d5SStephan Aßmus fill_rect_params** params,
841e76d86d5SStephan Aßmus uint32* count) const
842e76d86d5SStephan Aßmus {
843e76d86d5SStephan Aßmus *count = region->CountRects();
844e76d86d5SStephan Aßmus *params = new fill_rect_params[*count];
845e76d86d5SStephan Aßmus
846e76d86d5SStephan Aßmus for (uint32 i = 0; i < *count; i++) {
847e76d86d5SStephan Aßmus clipping_rect r = region->RectAtInt(i);
848e76d86d5SStephan Aßmus (*params)[i].left = (uint16)r.left;
849e76d86d5SStephan Aßmus (*params)[i].top = (uint16)r.top;
850e76d86d5SStephan Aßmus (*params)[i].right = (uint16)r.right;
851e76d86d5SStephan Aßmus (*params)[i].bottom = (uint16)r.bottom;
852e76d86d5SStephan Aßmus }
853e76d86d5SStephan Aßmus }
854e76d86d5SStephan Aßmus
855e76d86d5SStephan Aßmus // _NativeColor
856e76d86d5SStephan Aßmus uint32
_NativeColor(const rgb_color & c) const857e76d86d5SStephan Aßmus AccelerantHWInterface::_NativeColor(const rgb_color& c) const
858e76d86d5SStephan Aßmus {
859e76d86d5SStephan Aßmus // NOTE: This functions looks somehow suspicios to me.
860e76d86d5SStephan Aßmus // It assumes that all graphics cards have the same native endianess, no?
861e76d86d5SStephan Aßmus /* switch (fDisplayMode.space) {
862e76d86d5SStephan Aßmus case B_CMAP8:
863e76d86d5SStephan Aßmus case B_GRAY8:
864e76d86d5SStephan Aßmus return color.GetColor8();
865e76d86d5SStephan Aßmus
866e76d86d5SStephan Aßmus case B_RGB15_BIG:
867e76d86d5SStephan Aßmus case B_RGBA15_BIG:
868e76d86d5SStephan Aßmus case B_RGB15_LITTLE:
869e76d86d5SStephan Aßmus case B_RGBA15_LITTLE:
870e76d86d5SStephan Aßmus return color.GetColor15();
871e76d86d5SStephan Aßmus
872e76d86d5SStephan Aßmus case B_RGB16_BIG:
873e76d86d5SStephan Aßmus case B_RGB16_LITTLE:
874e76d86d5SStephan Aßmus return color.GetColor16();
875e76d86d5SStephan Aßmus
876e76d86d5SStephan Aßmus case B_RGB32_BIG:
877e76d86d5SStephan Aßmus case B_RGBA32_BIG:
878e76d86d5SStephan Aßmus case B_RGB32_LITTLE:
879e76d86d5SStephan Aßmus case B_RGBA32_LITTLE: {
880e76d86d5SStephan Aßmus rgb_color c = color.GetColor32();
881e76d86d5SStephan Aßmus uint32 native = (c.alpha << 24) |
882e76d86d5SStephan Aßmus (c.red << 16) |
883e76d86d5SStephan Aßmus (c.green << 8) |
884e76d86d5SStephan Aßmus (c.blue);
885e76d86d5SStephan Aßmus return native;
886e76d86d5SStephan Aßmus }
887e76d86d5SStephan Aßmus }
888e76d86d5SStephan Aßmus return 0;*/
889e76d86d5SStephan Aßmus uint32 native = (c.alpha << 24) | (c.red << 16) | (c.green << 8) | (c.blue);
890e76d86d5SStephan Aßmus return native;
891e76d86d5SStephan Aßmus }
892