1/**************************************************************************
2 *
3 * Copyright 2009 Artur Wyszynski <harakash@gmail.com>
4 * Copyright 2013-2014 Alexander von Gluck IV <kallisti5@unixzen.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
24 * of the Software.
25 *
26 **************************************************************************/
27
28#include <stdio.h>
29
30#include "pipe/p_compiler.h"
31#include "pipe/p_defines.h"
32#include "pipe/p_format.h"
33#include "util/u_inlines.h"
34#include "util/u_format.h"
35#include "util/u_math.h"
36#include "util/u_memory.h"
37#include "state_tracker/st_api.h"
38#include "state_tracker/sw_winsys.h"
39
40#include "bitmap_wrapper.h"
41#include "hgl_sw_winsys.h"
42
43
44#ifdef DEBUG
45#   define TRACE(x...) printf("hgl:winsys: " x)
46#   define CALLED() TRACE("CALLED: %s\n", __PRETTY_FUNCTION__)
47#else
48#   define TRACE(x...)
49#   define CALLED()
50#endif
51#define ERROR(x...) printf("hgl:winsys: " x)
52
53
54struct haiku_displaytarget
55{
56	enum pipe_format format;
57	color_space colorSpace;
58
59	unsigned width;
60	unsigned height;
61	unsigned stride;
62
63	unsigned size;
64
65	void* data;
66};
67
68
69// Cast
70static inline struct haiku_displaytarget*
71hgl_sw_displaytarget(struct sw_displaytarget* target)
72{
73	return (struct haiku_displaytarget *)target;
74}
75
76
77static void
78hgl_winsys_destroy(struct sw_winsys* winsys)
79{
80	FREE(winsys);
81}
82
83
84static boolean
85hgl_winsys_is_displaytarget_format_supported(struct sw_winsys* winsys,
86	unsigned textureUsage, enum pipe_format format)
87{
88	// TODO STUB
89	return TRUE;
90}
91
92static color_space
93hgl_winsys_convert_cs(enum pipe_format format)
94{
95	// TODO: B_RGB24, B_RGB16, B_RGB15?
96	switch(format) {
97		case PIPE_FORMAT_B5G6R5_UNORM:
98			return B_CMAP8;
99		case PIPE_FORMAT_A8B8G8R8_UNORM:
100		case PIPE_FORMAT_X8B8G8R8_UNORM:
101		default:
102			return B_RGB32;
103	}
104}
105
106static struct sw_displaytarget*
107hgl_winsys_displaytarget_create(struct sw_winsys* winsys,
108	unsigned textureUsage, enum pipe_format format, unsigned width,
109	unsigned height, unsigned alignment, const void *front_private,
110	unsigned* stride)
111{
112	struct haiku_displaytarget* haikuDisplayTarget
113		= CALLOC_STRUCT(haiku_displaytarget);
114	assert(haikuDisplayTarget);
115
116	TRACE("%s: %d x %d\n", __func__, width, height);
117
118	haikuDisplayTarget->colorSpace = hgl_winsys_convert_cs(format);
119	haikuDisplayTarget->format = format;
120	haikuDisplayTarget->width = width;
121	haikuDisplayTarget->height = height;
122
123	size_t formatStride = util_format_get_stride(format, width);
124	unsigned blockSize = util_format_get_nblocksy(format, height);
125
126	haikuDisplayTarget->stride = align(formatStride, alignment);
127	haikuDisplayTarget->size = haikuDisplayTarget->stride * blockSize;
128
129	haikuDisplayTarget->data
130		= align_malloc(haikuDisplayTarget->size, alignment);
131
132	assert(haikuDisplayTarget->data);
133
134	*stride = haikuDisplayTarget->stride;
135
136	// Cast to ghost sw_displaytarget type
137	return (struct sw_displaytarget*)haikuDisplayTarget;
138}
139
140
141static void
142hgl_winsys_displaytarget_destroy(struct sw_winsys* winsys,
143	struct sw_displaytarget* displayTarget)
144{
145	struct haiku_displaytarget* haikuDisplayTarget
146		= hgl_sw_displaytarget(displayTarget);
147
148	if (!haikuDisplayTarget)
149		return;
150
151	if (haikuDisplayTarget->data != NULL)
152		align_free(haikuDisplayTarget->data);
153
154	FREE(haikuDisplayTarget);
155}
156
157
158static struct sw_displaytarget*
159hgl_winsys_displaytarget_from_handle(struct sw_winsys* winsys,
160	const struct pipe_resource* templat, struct winsys_handle* whandle,
161	unsigned* stride)
162{
163	return NULL;
164}
165
166
167static boolean
168hgl_winsys_displaytarget_get_handle(struct sw_winsys* winsys,
169	struct sw_displaytarget* displayTarget, struct winsys_handle* whandle)
170{
171	return FALSE;
172}
173
174
175static void*
176hgl_winsys_displaytarget_map(struct sw_winsys* winsys,
177	struct sw_displaytarget* displayTarget, unsigned flags)
178{
179	struct haiku_displaytarget* haikuDisplayTarget
180		= hgl_sw_displaytarget(displayTarget);
181
182	return haikuDisplayTarget->data;
183}
184
185
186static void
187hgl_winsys_displaytarget_unmap(struct sw_winsys* winsys,
188	struct sw_displaytarget* disptarget)
189{
190	return;
191}
192
193
194static void
195hgl_winsys_displaytarget_display(struct sw_winsys* winsys,
196	struct sw_displaytarget* displayTarget, void* contextPrivate,
197	struct pipe_box *box)
198{
199	assert(contextPrivate);
200
201	Bitmap* bitmap = (Bitmap*)contextPrivate;
202
203	struct haiku_displaytarget* haikuDisplayTarget
204		= hgl_sw_displaytarget(displayTarget);
205
206	import_bitmap_bits(bitmap, haikuDisplayTarget->data,
207		haikuDisplayTarget->size, haikuDisplayTarget->stride,
208		haikuDisplayTarget->colorSpace);
209
210	// Dump the rendered bitmap to disk for debugging
211	//dump_bitmap(bitmap);
212
213	return;
214}
215
216
217struct sw_winsys*
218hgl_create_sw_winsys()
219{
220	struct sw_winsys* winsys = CALLOC_STRUCT(sw_winsys);
221
222	if (!winsys)
223		return NULL;
224
225	// Attach winsys hooks for Haiku
226	winsys->destroy = hgl_winsys_destroy;
227	winsys->is_displaytarget_format_supported
228		= hgl_winsys_is_displaytarget_format_supported;
229	winsys->displaytarget_create = hgl_winsys_displaytarget_create;
230	winsys->displaytarget_from_handle = hgl_winsys_displaytarget_from_handle;
231	winsys->displaytarget_get_handle = hgl_winsys_displaytarget_get_handle;
232	winsys->displaytarget_map = hgl_winsys_displaytarget_map;
233	winsys->displaytarget_unmap = hgl_winsys_displaytarget_unmap;
234	winsys->displaytarget_display = hgl_winsys_displaytarget_display;
235	winsys->displaytarget_destroy = hgl_winsys_displaytarget_destroy;
236
237	return winsys;
238}
239