2 * Mesa 3-D graphics library
5 * Copyright (C) 2010 LunarG Inc.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
26 * Chia-I Wu <olv@lunarg.com>
30 #include <sys/ioctl.h>
33 #include "pipe/p_compiler.h"
34 #include "util/u_format.h"
35 #include "util/u_math.h"
36 #include "util/u_memory.h"
37 #include "state_tracker/sw_winsys.h"
39 #include "fbdev_sw_winsys.h"
41 struct fbdev_sw_displaytarget
43 enum pipe_format format
;
52 struct fbdev_sw_winsys
54 struct sw_winsys base
;
57 enum pipe_format format
;
59 struct fb_fix_screeninfo finfo
;
65 static INLINE
struct fbdev_sw_displaytarget
*
66 fbdev_sw_displaytarget(struct sw_displaytarget
*dt
)
68 return (struct fbdev_sw_displaytarget
*) dt
;
71 static INLINE
struct fbdev_sw_winsys
*
72 fbdev_sw_winsys(struct sw_winsys
*ws
)
74 return (struct fbdev_sw_winsys
*) ws
;
78 fbdev_displaytarget_display(struct sw_winsys
*ws
,
79 struct sw_displaytarget
*dt
,
80 void *context_private
)
82 struct fbdev_sw_winsys
*fbdev
= fbdev_sw_winsys(ws
);
83 struct fbdev_sw_displaytarget
*fbdt
= fbdev_sw_displaytarget(dt
);
84 unsigned rows
, len
, i
;
86 rows
= MIN2(fbdt
->height
, fbdev
->rows
);
87 len
= util_format_get_stride(fbdt
->format
, fbdt
->width
);
88 len
= MIN2(len
, fbdev
->stride
);
90 for (i
= 0; i
< rows
; i
++) {
91 void *dst
= fbdev
->fbmem
+ fbdev
->stride
* i
;
92 void *src
= fbdt
->data
+ fbdt
->stride
* i
;
94 memcpy(dst
, src
, len
);
99 fbdev_displaytarget_unmap(struct sw_winsys
*ws
,
100 struct sw_displaytarget
*dt
)
102 struct fbdev_sw_displaytarget
*fbdt
= fbdev_sw_displaytarget(dt
);
107 fbdev_displaytarget_map(struct sw_winsys
*ws
,
108 struct sw_displaytarget
*dt
,
111 struct fbdev_sw_displaytarget
*fbdt
= fbdev_sw_displaytarget(dt
);
112 fbdt
->mapped
= fbdt
->data
;
117 fbdev_displaytarget_destroy(struct sw_winsys
*ws
,
118 struct sw_displaytarget
*dt
)
120 struct fbdev_sw_displaytarget
*fbdt
= fbdev_sw_displaytarget(dt
);
123 align_free(fbdt
->data
);
128 static struct sw_displaytarget
*
129 fbdev_displaytarget_create(struct sw_winsys
*ws
,
131 enum pipe_format format
,
132 unsigned width
, unsigned height
,
136 struct fbdev_sw_winsys
*fbdev
= fbdev_sw_winsys(ws
);
137 struct fbdev_sw_displaytarget
*fbdt
;
138 unsigned nblocksy
, size
, format_stride
;
140 if (fbdev
->format
!= format
)
143 fbdt
= CALLOC_STRUCT(fbdev_sw_displaytarget
);
147 fbdt
->format
= format
;
149 fbdt
->height
= height
;
151 format_stride
= util_format_get_stride(format
, width
);
152 fbdt
->stride
= align(format_stride
, alignment
);
154 nblocksy
= util_format_get_nblocksy(format
, height
);
155 size
= fbdt
->stride
* nblocksy
;
157 fbdt
->data
= align_malloc(size
, alignment
);
163 *stride
= fbdt
->stride
;
165 return (struct sw_displaytarget
*) fbdt
;
169 fbdev_is_displaytarget_format_supported(struct sw_winsys
*ws
,
171 enum pipe_format format
)
173 struct fbdev_sw_winsys
*fbdev
= fbdev_sw_winsys(ws
);
174 return (fbdev
->format
== format
);
178 fbdev_destroy(struct sw_winsys
*ws
)
180 struct fbdev_sw_winsys
*fbdev
= fbdev_sw_winsys(ws
);
182 munmap(fbdev
->fbmem
, fbdev
->finfo
.smem_len
);
187 fbdev_create_sw_winsys(int fd
, enum pipe_format format
)
189 struct fbdev_sw_winsys
*fbdev
;
191 fbdev
= CALLOC_STRUCT(fbdev_sw_winsys
);
196 fbdev
->format
= format
;
197 if (ioctl(fbdev
->fd
, FBIOGET_FSCREENINFO
, &fbdev
->finfo
)) {
202 fbdev
->fbmem
= mmap(0, fbdev
->finfo
.smem_len
,
203 PROT_WRITE
, MAP_SHARED
, fbdev
->fd
, 0);
204 if (fbdev
->fbmem
== MAP_FAILED
) {
209 fbdev
->rows
= fbdev
->finfo
.smem_len
/ fbdev
->finfo
.line_length
;
210 fbdev
->stride
= fbdev
->finfo
.line_length
;
212 fbdev
->base
.destroy
= fbdev_destroy
;
213 fbdev
->base
.is_displaytarget_format_supported
=
214 fbdev_is_displaytarget_format_supported
;
216 fbdev
->base
.displaytarget_create
= fbdev_displaytarget_create
;
217 fbdev
->base
.displaytarget_destroy
= fbdev_displaytarget_destroy
;
218 fbdev
->base
.displaytarget_map
= fbdev_displaytarget_map
;
219 fbdev
->base
.displaytarget_unmap
= fbdev_displaytarget_unmap
;
221 fbdev
->base
.displaytarget_display
= fbdev_displaytarget_display
;