Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 1
/*
2
 * Mesa 3-D graphics library
3
 *
4
 * Copyright (C) 2010 LunarG Inc.
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the "Software"),
8
 * to deal in the Software without restriction, including without limitation
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
 * and/or sell copies of the Software, and to permit persons to whom the
11
 * Software is furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included
14
 * in all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
 * DEALINGS IN THE SOFTWARE.
23
 *
24
 * Authors:
25
 *    Chia-I Wu 
26
 */
27
 
28
#include 
29
#include 
30
#include 
31
 
32
#include "pipe/p_compiler.h"
33
#include "util/u_format.h"
34
#include "util/u_math.h"
35
#include "util/u_memory.h"
36
#include "state_tracker/sw_winsys.h"
37
 
38
#include "fbdev_sw_winsys.h"
39
 
40
struct fbdev_sw_displaytarget
41
{
42
   enum pipe_format format;
43
   unsigned width;
44
   unsigned height;
45
   unsigned stride;
46
 
47
   void *data;
48
   void *mapped;
49
};
50
 
51
struct fbdev_sw_winsys
52
{
53
   struct sw_winsys base;
54
 
55
   int fd;
56
 
57
   struct fb_fix_screeninfo finfo;
58
   unsigned rows;
59
   unsigned stride;
60
};
61
 
62
static INLINE struct fbdev_sw_displaytarget *
63
fbdev_sw_displaytarget(struct sw_displaytarget *dt)
64
{
65
   return (struct fbdev_sw_displaytarget *) dt;
66
}
67
 
68
static INLINE struct fbdev_sw_winsys *
69
fbdev_sw_winsys(struct sw_winsys *ws)
70
{
71
   return (struct fbdev_sw_winsys *) ws;
72
}
73
 
74
static void
75
fbdev_displaytarget_display(struct sw_winsys *ws,
76
                            struct sw_displaytarget *dt,
77
                            void *winsys_private)
78
{
79
   struct fbdev_sw_winsys *fbdev = fbdev_sw_winsys(ws);
80
   struct fbdev_sw_displaytarget *src = fbdev_sw_displaytarget(dt);
81
   const struct fbdev_sw_drawable *dst =
82
      (const struct fbdev_sw_drawable *) winsys_private;
83
   unsigned height, row_offset, row_len, i;
84
   void *fbmem;
85
 
86
   /* FIXME format conversion */
87
   if (dst->format != src->format) {
88
      assert(0);
89
      return;
90
   }
91
 
92
   height = dst->height;
93
   if (dst->y + dst->height > fbdev->rows) {
94
      /* nothing to copy */
95
      if (dst->y >= fbdev->rows)
96
         return;
97
 
98
      height = fbdev->rows - dst->y;
99
   }
100
 
101
   row_offset = util_format_get_stride(dst->format, dst->x);
102
   row_len = util_format_get_stride(dst->format, dst->width);
103
   if (row_offset + row_len > fbdev->stride) {
104
      /* nothing to copy */
105
      if (row_offset >= fbdev->stride)
106
         return;
107
 
108
      row_len = fbdev->stride - row_offset;
109
   }
110
 
111
   fbmem = mmap(0, fbdev->finfo.smem_len,
112
         PROT_WRITE, MAP_SHARED, fbdev->fd, 0);
113
   if (fbmem == MAP_FAILED)
114
      return;
115
 
116
   for (i = 0; i < height; i++) {
117
      char *from = (char *) src->data + src->stride * i;
118
      char *to = (char *) fbmem + fbdev->stride * (dst->y + i) + row_offset;
119
 
120
      memcpy(to, from, row_len);
121
   }
122
 
123
   munmap(fbmem, fbdev->finfo.smem_len);
124
}
125
 
126
static void
127
fbdev_displaytarget_unmap(struct sw_winsys *ws,
128
                           struct sw_displaytarget *dt)
129
{
130
   struct fbdev_sw_displaytarget *fbdt = fbdev_sw_displaytarget(dt);
131
   fbdt->mapped = NULL;
132
}
133
 
134
static void *
135
fbdev_displaytarget_map(struct sw_winsys *ws,
136
                        struct sw_displaytarget *dt,
137
                        unsigned flags)
138
{
139
   struct fbdev_sw_displaytarget *fbdt = fbdev_sw_displaytarget(dt);
140
   fbdt->mapped = fbdt->data;
141
   return fbdt->mapped;
142
}
143
 
144
static void
145
fbdev_displaytarget_destroy(struct sw_winsys *ws,
146
                            struct sw_displaytarget *dt)
147
{
148
   struct fbdev_sw_displaytarget *fbdt = fbdev_sw_displaytarget(dt);
149
 
150
   if (fbdt->data)
151
      align_free(fbdt->data);
152
 
153
   FREE(fbdt);
154
}
155
 
156
static struct sw_displaytarget *
157
fbdev_displaytarget_create(struct sw_winsys *ws,
158
                           unsigned tex_usage,
159
                           enum pipe_format format,
160
                           unsigned width, unsigned height,
161
                           unsigned alignment,
162
                           unsigned *stride)
163
{
164
   struct fbdev_sw_displaytarget *fbdt;
165
   unsigned nblocksy, size, format_stride;
166
 
167
   fbdt = CALLOC_STRUCT(fbdev_sw_displaytarget);
168
   if (!fbdt)
169
      return NULL;
170
 
171
   fbdt->format = format;
172
   fbdt->width = width;
173
   fbdt->height = height;
174
 
175
   format_stride = util_format_get_stride(format, width);
176
   fbdt->stride = align(format_stride, alignment);
177
 
178
   nblocksy = util_format_get_nblocksy(format, height);
179
   size = fbdt->stride * nblocksy;
180
 
181
   fbdt->data = align_malloc(size, alignment);
182
   if (!fbdt->data) {
183
      FREE(fbdt);
184
      return NULL;
185
   }
186
 
187
   *stride = fbdt->stride;
188
 
189
   return (struct sw_displaytarget *) fbdt;
190
}
191
 
192
static boolean
193
fbdev_is_displaytarget_format_supported(struct sw_winsys *ws,
194
                                        unsigned tex_usage,
195
                                        enum pipe_format format)
196
{
197
   return TRUE;
198
}
199
 
200
static void
201
fbdev_destroy(struct sw_winsys *ws)
202
{
203
   struct fbdev_sw_winsys *fbdev = fbdev_sw_winsys(ws);
204
 
205
   FREE(fbdev);
206
}
207
 
208
struct sw_winsys *
209
fbdev_create_sw_winsys(int fd)
210
{
211
   struct fbdev_sw_winsys *fbdev;
212
 
213
   fbdev = CALLOC_STRUCT(fbdev_sw_winsys);
214
   if (!fbdev)
215
      return NULL;
216
 
217
   fbdev->fd = fd;
218
   if (ioctl(fbdev->fd, FBIOGET_FSCREENINFO, &fbdev->finfo)) {
219
      FREE(fbdev);
220
      return NULL;
221
   }
222
 
223
   fbdev->rows = fbdev->finfo.smem_len / fbdev->finfo.line_length;
224
   fbdev->stride = fbdev->finfo.line_length;
225
 
226
   fbdev->base.destroy = fbdev_destroy;
227
   fbdev->base.is_displaytarget_format_supported =
228
      fbdev_is_displaytarget_format_supported;
229
 
230
   fbdev->base.displaytarget_create = fbdev_displaytarget_create;
231
   fbdev->base.displaytarget_destroy = fbdev_displaytarget_destroy;
232
   fbdev->base.displaytarget_map = fbdev_displaytarget_map;
233
   fbdev->base.displaytarget_unmap = fbdev_displaytarget_unmap;
234
 
235
   fbdev->base.displaytarget_display = fbdev_displaytarget_display;
236
 
237
   return &fbdev->base;
238
}