xref: /haiku/src/tests/servers/app/newerClipping/drawing/AccelerantHWInterface.cpp (revision 4b7e219688450694efc9d1890f83f816758c16d3)
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(&region, &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(&region, &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