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
;
58 struct fb_fix_screeninfo finfo
;
63 static INLINE
struct fbdev_sw_displaytarget
*
64 fbdev_sw_displaytarget(struct sw_displaytarget
*dt
)
66 return (struct fbdev_sw_displaytarget
*) dt
;
69 static INLINE
struct fbdev_sw_winsys
*
70 fbdev_sw_winsys(struct sw_winsys
*ws
)
72 return (struct fbdev_sw_winsys
*) ws
;
76 fbdev_displaytarget_display(struct sw_winsys
*ws
,
77 struct sw_displaytarget
*dt
,
80 struct fbdev_sw_winsys
*fbdev
= fbdev_sw_winsys(ws
);
81 struct fbdev_sw_displaytarget
*src
= fbdev_sw_displaytarget(dt
);
82 const struct fbdev_sw_drawable
*dst
=
83 (const struct fbdev_sw_drawable
*) winsys_private
;
84 unsigned height
, row_offset
, row_len
, i
;
87 /* FIXME format conversion */
88 if (dst
->format
!= src
->format
) {
94 if (dst
->y
+ dst
->height
> fbdev
->rows
) {
96 if (dst
->y
>= fbdev
->rows
)
99 height
= fbdev
->rows
- dst
->y
;
102 row_offset
= util_format_get_stride(dst
->format
, dst
->x
);
103 row_len
= util_format_get_stride(dst
->format
, dst
->width
);
104 if (row_offset
+ row_len
> fbdev
->stride
) {
105 /* nothing to copy */
106 if (row_offset
>= fbdev
->stride
)
109 row_len
= fbdev
->stride
- row_offset
;
112 fbmem
= mmap(0, fbdev
->finfo
.smem_len
,
113 PROT_WRITE
, MAP_SHARED
, fbdev
->fd
, 0);
114 if (fbmem
== MAP_FAILED
)
117 for (i
= 0; i
< height
; i
++) {
118 char *from
= (char *) src
->data
+ src
->stride
* i
;
119 char *to
= (char *) fbmem
+ fbdev
->stride
* (dst
->y
+ i
) + row_offset
;
121 memcpy(to
, from
, row_len
);
124 munmap(fbmem
, fbdev
->finfo
.smem_len
);
128 fbdev_displaytarget_unmap(struct sw_winsys
*ws
,
129 struct sw_displaytarget
*dt
)
131 struct fbdev_sw_displaytarget
*fbdt
= fbdev_sw_displaytarget(dt
);
136 fbdev_displaytarget_map(struct sw_winsys
*ws
,
137 struct sw_displaytarget
*dt
,
140 struct fbdev_sw_displaytarget
*fbdt
= fbdev_sw_displaytarget(dt
);
141 fbdt
->mapped
= fbdt
->data
;
146 fbdev_displaytarget_destroy(struct sw_winsys
*ws
,
147 struct sw_displaytarget
*dt
)
149 struct fbdev_sw_displaytarget
*fbdt
= fbdev_sw_displaytarget(dt
);
152 align_free(fbdt
->data
);
157 static struct sw_displaytarget
*
158 fbdev_displaytarget_create(struct sw_winsys
*ws
,
160 enum pipe_format format
,
161 unsigned width
, unsigned height
,
165 struct fbdev_sw_displaytarget
*fbdt
;
166 unsigned nblocksy
, size
, format_stride
;
168 fbdt
= CALLOC_STRUCT(fbdev_sw_displaytarget
);
172 fbdt
->format
= format
;
174 fbdt
->height
= height
;
176 format_stride
= util_format_get_stride(format
, width
);
177 fbdt
->stride
= align(format_stride
, alignment
);
179 nblocksy
= util_format_get_nblocksy(format
, height
);
180 size
= fbdt
->stride
* nblocksy
;
182 fbdt
->data
= align_malloc(size
, alignment
);
188 *stride
= fbdt
->stride
;
190 return (struct sw_displaytarget
*) fbdt
;
194 fbdev_is_displaytarget_format_supported(struct sw_winsys
*ws
,
196 enum pipe_format format
)
202 fbdev_destroy(struct sw_winsys
*ws
)
204 struct fbdev_sw_winsys
*fbdev
= fbdev_sw_winsys(ws
);
210 fbdev_create_sw_winsys(int fd
)
212 struct fbdev_sw_winsys
*fbdev
;
214 fbdev
= CALLOC_STRUCT(fbdev_sw_winsys
);
219 if (ioctl(fbdev
->fd
, FBIOGET_FSCREENINFO
, &fbdev
->finfo
)) {
224 fbdev
->rows
= fbdev
->finfo
.smem_len
/ fbdev
->finfo
.line_length
;
225 fbdev
->stride
= fbdev
->finfo
.line_length
;
227 fbdev
->base
.destroy
= fbdev_destroy
;
228 fbdev
->base
.is_displaytarget_format_supported
=
229 fbdev_is_displaytarget_format_supported
;
231 fbdev
->base
.displaytarget_create
= fbdev_displaytarget_create
;
232 fbdev
->base
.displaytarget_destroy
= fbdev_displaytarget_destroy
;
233 fbdev
->base
.displaytarget_map
= fbdev_displaytarget_map
;
234 fbdev
->base
.displaytarget_unmap
= fbdev_displaytarget_unmap
;
236 fbdev
->base
.displaytarget_display
= fbdev_displaytarget_display
;