1/*
2 * Copyright 2006-2012, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Artur Wyszynski, harakash@gmail.com
7 *		Alexander von Gluck IV, kallisti5@unixzen.com
8 */
9
10
11#include "SoftwareWinsys.h"
12
13#include <stdio.h>
14
15#include "bitmap_wrapper.h"
16extern "C" {
17#include "state_tracker/st_api.h"
18#include "state_tracker/sw_winsys.h"
19#include "util/u_format.h"
20#include "util/u_math.h"
21#include "util/u_memory.h"
22}
23
24
25#define TRACE_WINSYS
26#ifdef TRACE_WINSYS
27#	define TRACE(x...) printf("GalliumWinsys: " x)
28#	define CALLED() TRACE("CALLED: %s\n", __PRETTY_FUNCTION__)
29#else
30#	define TRACE(x...)
31#	define CALLED()
32#endif
33#define ERROR(x...) printf("GalliumWinsys: " x)
34
35
36// Cast
37static INLINE struct haiku_displaytarget*
38cast_haiku_displaytarget(struct sw_displaytarget* target)
39{
40	return (struct haiku_displaytarget *)target;
41}
42
43
44static void
45hook_winsys_destroy(struct sw_winsys* winsys)
46{
47	CALLED();
48	FREE(winsys);
49}
50
51
52static boolean
53hook_winsys_is_displaytarget_format_supported(struct sw_winsys* winsys,
54	unsigned textureUsage, enum pipe_format format)
55{
56	CALLED();
57	// TODO STUB
58	return true;
59}
60
61
62static struct sw_displaytarget*
63hook_winsys_displaytarget_create(struct sw_winsys* winsys,
64	unsigned textureUsage, enum pipe_format format, unsigned width,
65	unsigned height, unsigned alignment, unsigned* stride)
66{
67	CALLED();
68
69	struct haiku_displaytarget* haikuDisplayTarget
70		= CALLOC_STRUCT(haiku_displaytarget);
71
72	if (!haikuDisplayTarget) {
73		ERROR("%s: Couldn't allocate Haiku display target!\n",
74			__func__);
75		return NULL;
76	}
77
78	haikuDisplayTarget->format = format;
79	haikuDisplayTarget->width = width;
80	haikuDisplayTarget->height = height;
81
82	//unsigned bitsPerPixel = util_format_get_blocksizebits(format);
83	unsigned colorsPerPalette = util_format_get_blocksize(format);
84
85	haikuDisplayTarget->stride = align(width * colorsPerPalette, alignment);
86	haikuDisplayTarget->size = haikuDisplayTarget->stride * height;
87
88	haikuDisplayTarget->data
89		= align_malloc(haikuDisplayTarget->size, alignment);
90
91	if (!haikuDisplayTarget->data) {
92		ERROR("%s: Couldn't allocate Haiku display target data!\n",
93			__func__);
94		FREE(haikuDisplayTarget);
95		return NULL;
96	}
97
98	*stride = haikuDisplayTarget->stride;
99
100	// Cast to ghost sw_displaytarget type
101	return (struct sw_displaytarget*)haikuDisplayTarget;
102}
103
104
105static void
106hook_winsys_displaytarget_destroy(struct sw_winsys* winsys,
107	struct sw_displaytarget* displayTarget)
108{
109	CALLED();
110
111	struct haiku_displaytarget* haikuDisplayTarget
112		= cast_haiku_displaytarget(displayTarget);
113
114	if (!haikuDisplayTarget) {
115		ERROR("%s: Attempt to destroy non-existant display target!\n",
116			__func__);
117		return;
118	}
119
120	if (haikuDisplayTarget->data != NULL)
121		align_free(haikuDisplayTarget->data);
122
123	FREE(haikuDisplayTarget);
124}
125
126
127static struct sw_displaytarget*
128hook_winsys_displaytarget_from_handle(struct sw_winsys* winsys,
129	const struct pipe_resource* templat, struct winsys_handle* whandle,
130	unsigned* stride)
131{
132	CALLED();
133	return NULL;
134}
135
136
137static boolean
138hook_winsys_displaytarget_get_handle(struct sw_winsys* winsys,
139	struct sw_displaytarget* displayTarget, struct winsys_handle* whandle)
140{
141	CALLED();
142	return FALSE;
143}
144
145
146static void*
147hook_winsys_displaytarget_map(struct sw_winsys* winsys,
148	struct sw_displaytarget* displayTarget, unsigned flags)
149{
150	CALLED();
151	struct haiku_displaytarget* haikuDisplayTarget
152		= cast_haiku_displaytarget(displayTarget);
153
154	return haikuDisplayTarget->data;
155}
156
157
158static void
159hook_winsys_displaytarget_unmap(struct sw_winsys* winsys,
160	struct sw_displaytarget* disptarget)
161{
162	return;
163}
164
165
166static void
167hook_winsys_displaytarget_display(struct sw_winsys* winsys,
168	struct sw_displaytarget* displayTarget, void* contextPrivate)
169{
170	CALLED();
171
172	if (!contextPrivate) {
173		ERROR("%s: Passed invalid private pointer!\n", __func__);
174		return;
175	}
176
177	Bitmap* bitmap = (Bitmap*)contextPrivate;
178
179	struct haiku_displaytarget* haikuDisplayTarget
180		= cast_haiku_displaytarget(displayTarget);
181
182	copy_bitmap_bits(bitmap, haikuDisplayTarget->data,
183		haikuDisplayTarget->size);
184
185	return;
186}
187
188
189struct sw_winsys*
190winsys_connect_hooks()
191{
192	CALLED();
193
194	struct sw_winsys* winsys = CALLOC_STRUCT(sw_winsys);
195
196	if (!winsys)
197		return NULL;
198
199	// Attach winsys hooks for Haiku
200	winsys->destroy = hook_winsys_destroy;
201	winsys->is_displaytarget_format_supported
202		= hook_winsys_is_displaytarget_format_supported;
203	winsys->displaytarget_create = hook_winsys_displaytarget_create;
204	winsys->displaytarget_from_handle = hook_winsys_displaytarget_from_handle;
205	winsys->displaytarget_get_handle = hook_winsys_displaytarget_get_handle;
206	winsys->displaytarget_map = hook_winsys_displaytarget_map;
207	winsys->displaytarget_unmap = hook_winsys_displaytarget_unmap;
208	winsys->displaytarget_display = hook_winsys_displaytarget_display;
209	winsys->displaytarget_destroy = hook_winsys_displaytarget_destroy;
210
211	return winsys;
212}
213