1/*
2 * Copyright 2005-2012, Axel D��rfler, axeld@pinc-software.de.
3 * All rights reserved. Distributed under the terms of the MIT License.
4 */
5
6
7#include "accelerant_protos.h"
8#include "accelerant.h"
9
10#include <new>
11
12
13#define FAKE_OVERLAY_SUPPORT 0
14	// Enables a fake overlay support, making the app_server believe it can
15	// use overlays with this driver; the actual buffers are in the frame
16	// buffer so the on-screen graphics will be messed up.
17
18#define FAKE_HARDWARE_CURSOR_SUPPORT 0
19	// Enables the faking of a hardware cursor. The cursor will not be
20	// visible, but it will still function.
21
22
23#if FAKE_OVERLAY_SUPPORT
24static int32 sOverlayToken;
25static int32 sOverlayChannelUsed;
26
27
28static uint32
29vesa_overlay_count(const display_mode* mode)
30{
31	return 1;
32}
33
34
35static const uint32*
36vesa_overlay_supported_spaces(const display_mode* mode)
37{
38	static const uint32 kSupportedSpaces[] = {B_RGB15, B_RGB16, B_RGB32,
39		B_YCbCr422, 0};
40
41	return kSupportedSpaces;
42}
43
44
45static uint32
46vesa_overlay_supported_features(uint32 colorSpace)
47{
48	return B_OVERLAY_COLOR_KEY
49		| B_OVERLAY_HORIZONTAL_FILTERING
50		| B_OVERLAY_VERTICAL_FILTERING
51		| B_OVERLAY_HORIZONTAL_MIRRORING;
52}
53
54
55static const overlay_buffer*
56vesa_allocate_overlay_buffer(color_space colorSpace, uint16 width,
57	uint16 height)
58{
59	debug_printf("allocate_overlay_buffer(width %u, height %u, colorSpace %u)\n",
60		width, height, colorSpace);
61
62	overlay_buffer* buffer = new(std::nothrow) overlay_buffer;
63	if (buffer == NULL)
64		return NULL;
65
66	buffer->space = colorSpace;
67	buffer->width = width;
68	buffer->height = height;
69	buffer->bytes_per_row = gInfo->shared_info->bytes_per_row;
70
71	buffer->buffer = gInfo->shared_info->frame_buffer;
72	buffer->buffer_dma = (uint8*)gInfo->shared_info->physical_frame_buffer;
73
74	return buffer;
75}
76
77
78static status_t
79vesa_release_overlay_buffer(const overlay_buffer* buffer)
80{
81	debug_printf("release_overlay_buffer(buffer %p)\n", buffer);
82
83	delete buffer;
84	return B_OK;
85}
86
87
88static status_t
89vesa_get_overlay_constraints(const display_mode* mode,
90	const overlay_buffer* buffer, overlay_constraints* constraints)
91{
92	debug_printf("get_overlay_constraints(buffer %p)\n", buffer);
93
94	// position
95	constraints->view.h_alignment = 0;
96	constraints->view.v_alignment = 0;
97
98	// alignment
99	constraints->view.width_alignment = 7;
100	constraints->view.height_alignment = 0;
101
102	// size
103	constraints->view.width.min = 4;
104	constraints->view.height.min = 4;
105	constraints->view.width.max = buffer->width;
106	constraints->view.height.max = buffer->height;
107
108	// scaler output restrictions
109	constraints->window.h_alignment = 0;
110	constraints->window.v_alignment = 0;
111	constraints->window.width_alignment = 0;
112	constraints->window.height_alignment = 0;
113	constraints->window.width.min = 2;
114	constraints->window.width.max = mode->virtual_width;
115	constraints->window.height.min = 2;
116	constraints->window.height.max = mode->virtual_height;
117
118	constraints->h_scale.min = 1.0f / (1 << 4);
119	constraints->h_scale.max = buffer->width * 7;
120	constraints->v_scale.min = 1.0f / (1 << 4);
121	constraints->v_scale.max = buffer->height * 7;
122
123	return B_OK;
124}
125
126
127static overlay_token
128vesa_allocate_overlay()
129{
130	debug_printf("allocate_overlay()\n");
131
132	// we only use a single overlay channel
133	if (atomic_or(&sOverlayChannelUsed, 1) != 0)
134		return NULL;
135
136	return (overlay_token)++sOverlayToken;
137}
138
139
140static status_t
141vesa_release_overlay(overlay_token overlayToken)
142{
143	debug_printf("allocate_overlay(token %ld)\n", (uint32)overlayToken);
144
145	if (overlayToken != (overlay_token)sOverlayToken)
146		return B_BAD_VALUE;
147
148	atomic_and(&sOverlayChannelUsed, 0);
149
150	return B_OK;
151}
152
153
154static status_t
155vesa_configure_overlay(overlay_token overlayToken, const overlay_buffer* buffer,
156	const overlay_window* window, const overlay_view* view)
157{
158	debug_printf("configure_overlay: buffer %p, window %p, view %p\n",
159		buffer, window, view);
160	return B_OK;
161}
162#endif	// FAKE_OVERLAY_SUPPORT
163
164
165#if FAKE_HARDWARE_CURSOR_SUPPORT
166status_t
167vesa_set_cursor_shape(uint16 width, uint16 height, uint16 hotX, uint16 hotY,
168	const uint8* andMask, const uint8* xorMask)
169{
170	return B_OK;
171}
172
173
174status_t
175vesa_set_cursor_bitmap(uint16 width, uint16 height, uint16 hotX, uint16 hotY,
176	color_space colorSpace, uint16 bytesPerRow, const uint8* bitmapData)
177{
178	return B_OK;
179}
180
181
182void
183vesa_move_cursor(uint16 x, uint16 y)
184{
185}
186
187
188void
189vesa_show_cursor(bool isVisible)
190{
191}
192#endif	// # FAKE_HARDWARE_CURSOR_SUPPORT
193
194
195extern "C" void*
196get_accelerant_hook(uint32 feature, void* data)
197{
198	switch (feature) {
199		/* general */
200		case B_INIT_ACCELERANT:
201			return (void*)vesa_init_accelerant;
202		case B_UNINIT_ACCELERANT:
203			return (void*)vesa_uninit_accelerant;
204		case B_CLONE_ACCELERANT:
205			return (void*)vesa_clone_accelerant;
206		case B_ACCELERANT_CLONE_INFO_SIZE:
207			return (void*)vesa_accelerant_clone_info_size;
208		case B_GET_ACCELERANT_CLONE_INFO:
209			return (void*)vesa_get_accelerant_clone_info;
210		case B_GET_ACCELERANT_DEVICE_INFO:
211			return (void*)vesa_get_accelerant_device_info;
212		case B_ACCELERANT_RETRACE_SEMAPHORE:
213			return (void*)vesa_accelerant_retrace_semaphore;
214
215		/* mode configuration */
216		case B_ACCELERANT_MODE_COUNT:
217			return (void*)vesa_accelerant_mode_count;
218		case B_GET_MODE_LIST:
219			return (void*)vesa_get_mode_list;
220		case B_PROPOSE_DISPLAY_MODE:
221			return (void*)vesa_propose_display_mode;
222		case B_SET_DISPLAY_MODE:
223			return (void*)vesa_set_display_mode;
224		case B_GET_DISPLAY_MODE:
225			return (void*)vesa_get_display_mode;
226		case B_GET_EDID_INFO:
227			return (void*)vesa_get_edid_info;
228		case B_GET_FRAME_BUFFER_CONFIG:
229			return (void*)vesa_get_frame_buffer_config;
230		case B_GET_PIXEL_CLOCK_LIMITS:
231			return (void*)vesa_get_pixel_clock_limits;
232		case B_MOVE_DISPLAY:
233			return (void*)vesa_move_display;
234		case B_SET_INDEXED_COLORS:
235			return (void*)vesa_set_indexed_colors;
236		case B_GET_TIMING_CONSTRAINTS:
237			return (void*)vesa_get_timing_constraints;
238
239		/* DPMS */
240		case B_DPMS_CAPABILITIES:
241			return (void*)vesa_dpms_capabilities;
242		case B_DPMS_MODE:
243			return (void*)vesa_dpms_mode;
244		case B_SET_DPMS_MODE:
245			return (void*)vesa_set_dpms_mode;
246
247		/* cursor managment */
248#if FAKE_HARDWARE_CURSOR_SUPPORT
249		case B_SET_CURSOR_SHAPE:
250			return (void*)vesa_set_cursor_shape;
251		case B_MOVE_CURSOR:
252			return (void*)vesa_move_cursor;
253		case B_SHOW_CURSOR:
254			return (void*)vesa_show_cursor;
255		case B_SET_CURSOR_BITMAP:
256			return (void*)vesa_set_cursor_bitmap;
257#endif
258
259#if FAKE_OVERLAY_SUPPORT
260		// overlay
261		case B_OVERLAY_COUNT:
262			return (void*)vesa_overlay_count;
263		case B_OVERLAY_SUPPORTED_SPACES:
264			return (void*)vesa_overlay_supported_spaces;
265		case B_OVERLAY_SUPPORTED_FEATURES:
266			return (void*)vesa_overlay_supported_features;
267		case B_ALLOCATE_OVERLAY_BUFFER:
268			return (void*)vesa_allocate_overlay_buffer;
269		case B_RELEASE_OVERLAY_BUFFER:
270			return (void*)vesa_release_overlay_buffer;
271		case B_GET_OVERLAY_CONSTRAINTS:
272			return (void*)vesa_get_overlay_constraints;
273		case B_ALLOCATE_OVERLAY:
274			return (void*)vesa_allocate_overlay;
275		case B_RELEASE_OVERLAY:
276			return (void*)vesa_release_overlay;
277		case B_CONFIGURE_OVERLAY:
278			return (void*)vesa_configure_overlay;
279#endif	// FAKE_OVERLAY_SUPPORT
280	}
281
282	return NULL;
283}
284
285