source: mainline/uspace/drv/fb/kfb/port.c@ fa77af7

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since fa77af7 was fa77af7, checked in by jzr <zarevucky.jiri@…>, 8 years ago

Remove some color-related dead code.

  • Property mode set to 100644
File size: 8.1 KB
Line 
1/*
2 * Copyright (c) 2006 Jakub Vana
3 * Copyright (c) 2006 Ondrej Palkovsky
4 * Copyright (c) 2008 Martin Decky
5 * Copyright (c) 2011 Petr Koupy
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * - Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * - Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * - The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32/** @addtogroup kfb
33 * @{
34 */
35/**
36 * @file
37 */
38
39#include <abi/fb/visuals.h>
40#include <stddef.h>
41#include <stdint.h>
42#include <errno.h>
43
44#include <malloc.h>
45#include <mem.h>
46#include <as.h>
47#include <align.h>
48
49#include <sysinfo.h>
50#include <ddi.h>
51
52#include <adt/list.h>
53
54#include <io/mode.h>
55#include <io/pixelmap.h>
56#include <io/chargrid.h>
57
58#include <pixconv.h>
59
60#include <graph.h>
61
62#include "kfb.h"
63#include "port.h"
64
65#define FB_POS(x, y) ((y) * kfb.scanline + (x) * kfb.pixel_bytes)
66
67typedef struct {
68 sysarg_t width;
69 sysarg_t height;
70 size_t offset;
71 size_t scanline;
72 visual_t visual;
73
74 pixel2visual_t pixel2visual;
75 visual2pixel_t visual2pixel;
76 visual_mask_t visual_mask;
77 size_t pixel_bytes;
78
79 size_t size;
80 uint8_t *addr;
81} kfb_t;
82
83static kfb_t kfb;
84
85static vslmode_list_element_t pixel_mode;
86
87static int kfb_claim(visualizer_t *vs)
88{
89 return EOK;
90}
91
92static int kfb_yield(visualizer_t *vs)
93{
94 if (vs->mode_set) {
95 vs->ops.handle_damage = NULL;
96 }
97
98 return EOK;
99}
100
101static int kfb_handle_damage_pixels(visualizer_t *vs,
102 sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height,
103 sysarg_t x_offset, sysarg_t y_offset)
104{
105 pixelmap_t *map = &vs->cells;
106
107 if (x_offset == 0 && y_offset == 0) {
108 /* Faster damage routine ignoring offsets. */
109 for (sysarg_t y = y0; y < height + y0; ++y) {
110 pixel_t *pixel = pixelmap_pixel_at(map, x0, y);
111 for (sysarg_t x = x0; x < width + x0; ++x) {
112 kfb.pixel2visual(kfb.addr + FB_POS(x, y), *pixel++);
113 }
114 }
115 } else {
116 for (sysarg_t y = y0; y < height + y0; ++y) {
117 for (sysarg_t x = x0; x < width + x0; ++x) {
118 kfb.pixel2visual(kfb.addr + FB_POS(x, y),
119 *pixelmap_pixel_at(map,
120 (x + x_offset) % map->width,
121 (y + y_offset) % map->height));
122 }
123 }
124 }
125
126 return EOK;
127}
128
129static int kfb_change_mode(visualizer_t *vs, vslmode_t new_mode)
130{
131 vs->ops.handle_damage = kfb_handle_damage_pixels;
132 return EOK;
133}
134
135static int kfb_suspend(visualizer_t *vs)
136{
137 return EOK;
138}
139
140static int kfb_wakeup(visualizer_t *vs)
141{
142 return EOK;
143}
144
145static visualizer_ops_t kfb_ops = {
146 .claim = kfb_claim,
147 .yield = kfb_yield,
148 .change_mode = kfb_change_mode,
149 .handle_damage = NULL,
150 .suspend = kfb_suspend,
151 .wakeup = kfb_wakeup
152};
153
154static void graph_vsl_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
155{
156 visualizer_t *vsl;
157
158 vsl = (visualizer_t *) ddf_fun_data_get((ddf_fun_t *)arg);
159 graph_visualizer_connection(vsl, iid, icall, NULL);
160}
161
162int port_init(ddf_dev_t *dev)
163{
164 sysarg_t present;
165 int rc = sysinfo_get_value("fb", &present);
166 if (rc != EOK)
167 present = false;
168
169 if (!present)
170 return ENOENT;
171
172 sysarg_t kind;
173 rc = sysinfo_get_value("fb.kind", &kind);
174 if (rc != EOK)
175 kind = (sysarg_t) -1;
176
177 if (kind != 1)
178 return EINVAL;
179
180 sysarg_t paddr;
181 rc = sysinfo_get_value("fb.address.physical", &paddr);
182 if (rc != EOK)
183 return rc;
184
185 sysarg_t offset;
186 rc = sysinfo_get_value("fb.offset", &offset);
187 if (rc != EOK)
188 offset = 0;
189
190 sysarg_t width;
191 rc = sysinfo_get_value("fb.width", &width);
192 if (rc != EOK)
193 return rc;
194
195 sysarg_t height;
196 rc = sysinfo_get_value("fb.height", &height);
197 if (rc != EOK)
198 return rc;
199
200 sysarg_t scanline;
201 rc = sysinfo_get_value("fb.scanline", &scanline);
202 if (rc != EOK)
203 return rc;
204
205 sysarg_t visual;
206 rc = sysinfo_get_value("fb.visual", &visual);
207 if (rc != EOK)
208 return rc;
209
210 kfb.width = width;
211 kfb.height = height;
212 kfb.offset = offset;
213 kfb.scanline = scanline;
214 kfb.visual = visual;
215
216 switch (visual) {
217 case VISUAL_INDIRECT_8:
218 kfb.pixel2visual = pixel2bgr_323;
219 kfb.visual2pixel = bgr_323_2pixel;
220 kfb.visual_mask = visual_mask_323;
221 kfb.pixel_bytes = 1;
222 break;
223 case VISUAL_RGB_5_5_5_LE:
224 kfb.pixel2visual = pixel2rgb_555_le;
225 kfb.visual2pixel = rgb_555_le_2pixel;
226 kfb.visual_mask = visual_mask_555;
227 kfb.pixel_bytes = 2;
228 break;
229 case VISUAL_RGB_5_5_5_BE:
230 kfb.pixel2visual = pixel2rgb_555_be;
231 kfb.visual2pixel = rgb_555_be_2pixel;
232 kfb.visual_mask = visual_mask_555;
233 kfb.pixel_bytes = 2;
234 break;
235 case VISUAL_RGB_5_6_5_LE:
236 kfb.pixel2visual = pixel2rgb_565_le;
237 kfb.visual2pixel = rgb_565_le_2pixel;
238 kfb.visual_mask = visual_mask_565;
239 kfb.pixel_bytes = 2;
240 break;
241 case VISUAL_RGB_5_6_5_BE:
242 kfb.pixel2visual = pixel2rgb_565_be;
243 kfb.visual2pixel = rgb_565_be_2pixel;
244 kfb.visual_mask = visual_mask_565;
245 kfb.pixel_bytes = 2;
246 break;
247 case VISUAL_RGB_8_8_8:
248 kfb.pixel2visual = pixel2rgb_888;
249 kfb.visual2pixel = rgb_888_2pixel;
250 kfb.visual_mask = visual_mask_888;
251 kfb.pixel_bytes = 3;
252 break;
253 case VISUAL_BGR_8_8_8:
254 kfb.pixel2visual = pixel2bgr_888;
255 kfb.visual2pixel = bgr_888_2pixel;
256 kfb.visual_mask = visual_mask_888;
257 kfb.pixel_bytes = 3;
258 break;
259 case VISUAL_RGB_8_8_8_0:
260 kfb.pixel2visual = pixel2rgb_8880;
261 kfb.visual2pixel = rgb_8880_2pixel;
262 kfb.visual_mask = visual_mask_8880;
263 kfb.pixel_bytes = 4;
264 break;
265 case VISUAL_RGB_0_8_8_8:
266 kfb.pixel2visual = pixel2rgb_0888;
267 kfb.visual2pixel = rgb_0888_2pixel;
268 kfb.visual_mask = visual_mask_0888;
269 kfb.pixel_bytes = 4;
270 break;
271 case VISUAL_BGR_0_8_8_8:
272 kfb.pixel2visual = pixel2bgr_0888;
273 kfb.visual2pixel = bgr_0888_2pixel;
274 kfb.visual_mask = visual_mask_0888;
275 kfb.pixel_bytes = 4;
276 break;
277 case VISUAL_BGR_8_8_8_0:
278 kfb.pixel2visual = pixel2bgr_8880;
279 kfb.visual2pixel = bgr_8880_2pixel;
280 kfb.visual_mask = visual_mask_8880;
281 kfb.pixel_bytes = 4;
282 break;
283 default:
284 return EINVAL;
285 }
286
287 kfb.size = scanline * height;
288 kfb.addr = AS_AREA_ANY;
289
290 rc = physmem_map(paddr + offset,
291 ALIGN_UP(kfb.size, PAGE_SIZE) >> PAGE_WIDTH,
292 AS_AREA_READ | AS_AREA_WRITE, (void *) &kfb.addr);
293 if (rc != EOK)
294 return rc;
295
296 ddf_fun_t *fun_vs = ddf_fun_create(dev, fun_exposed, "vsl0");
297 if (fun_vs == NULL) {
298 as_area_destroy(kfb.addr);
299 return ENOMEM;
300 }
301 ddf_fun_set_conn_handler(fun_vs, &graph_vsl_connection);
302
303 visualizer_t *vs = ddf_fun_data_alloc(fun_vs, sizeof(visualizer_t));
304 if (vs == NULL) {
305 as_area_destroy(kfb.addr);
306 return ENOMEM;
307 }
308 graph_init_visualizer(vs);
309
310 pixel_mode.mode.index = 0;
311 pixel_mode.mode.version = 0;
312 pixel_mode.mode.refresh_rate = 0;
313 pixel_mode.mode.screen_aspect.width = width;
314 pixel_mode.mode.screen_aspect.height = height;
315 pixel_mode.mode.screen_width = width;
316 pixel_mode.mode.screen_height = height;
317 pixel_mode.mode.cell_aspect.width = 1;
318 pixel_mode.mode.cell_aspect.height = 1;
319 pixel_mode.mode.cell_visual.pixel_visual = visual;
320
321 link_initialize(&pixel_mode.link);
322 list_append(&pixel_mode.link, &vs->modes);
323
324 vs->def_mode_idx = 0;
325
326 vs->ops = kfb_ops;
327 vs->dev_ctx = NULL;
328
329 rc = ddf_fun_bind(fun_vs);
330 if (rc != EOK) {
331 list_remove(&pixel_mode.link);
332 ddf_fun_destroy(fun_vs);
333 as_area_destroy(kfb.addr);
334 return rc;
335 }
336
337 vs->reg_svc_handle = ddf_fun_get_handle(fun_vs);
338 ddf_fun_add_to_category(fun_vs, "visualizer");
339
340 return EOK;
341}
342
343/** @}
344 */
Note: See TracBrowser for help on using the repository browser.