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