source: mainline/uspace/srv/hid/display/main.c@ 84e74ea

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 84e74ea was 8aef01c, checked in by Jiri Svoboda <jiri@…>, 5 years ago

Configurable display double-buffering

On by default (since turning off creates flicker in the absence of
front-to-back rendering). This is the quick and dirty way: display
server renders locally to a bitmap (using mem GC) and renders the
bitmap when ready.

The more sophisticated way would be to implement buffering in the
display device. That would require, however, enhancing the protocols
to communicate frame boundaries.

  • Property mode set to 100644
File size: 5.4 KB
Line 
1/*
2 * Copyright (c) 2019 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistribution1s of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup display
30 * @{
31 */
32/**
33 * @file Display server main
34 */
35
36#include <async.h>
37#include <disp_srv.h>
38#include <errno.h>
39#include <gfx/context.h>
40#include <str_error.h>
41#include <io/log.h>
42#include <io/kbd_event.h>
43#include <io/pos_event.h>
44#include <ipc/services.h>
45#include <ipcgfx/server.h>
46#include <loc.h>
47#include <stdio.h>
48#include <task.h>
49#include "client.h"
50#include "display.h"
51#include "dsops.h"
52#include "input.h"
53#include "main.h"
54#include "output.h"
55#include "seat.h"
56#include "window.h"
57
58static void display_client_conn(ipc_call_t *, void *);
59static void display_client_ev_pending(void *);
60
61#ifdef CONFIG_DISP_DOUBLE_BUF
62/*
63 * Double buffering is one way to provide flicker-free display.
64 */
65static ds_display_flags_t disp_flags = df_disp_double_buf;
66#else
67/*
68 * With double buffering disabled, wet screen flicker since front-to-back
69 * rendering is not implemented.
70 */
71static ds_display_flags_t disp_flags = df_none;
72#endif
73
74static ds_client_cb_t display_client_cb = {
75 .ev_pending = display_client_ev_pending
76};
77
78static void display_client_ev_pending(void *arg)
79{
80 display_srv_t *srv = (display_srv_t *) arg;
81
82 display_srv_ev_pending(srv);
83}
84
85/** Initialize display server */
86static errno_t display_srv_init(ds_output_t **routput)
87{
88 ds_display_t *disp = NULL;
89 ds_seat_t *seat = NULL;
90 ds_output_t *output = NULL;
91 gfx_context_t *gc = NULL;
92 errno_t rc;
93
94 log_msg(LOG_DEFAULT, LVL_DEBUG, "display_srv_init()");
95
96 rc = ds_display_create(NULL, disp_flags, &disp);
97 if (rc != EOK)
98 goto error;
99
100 rc = ds_seat_create(disp, &seat);
101 if (rc != EOK)
102 goto error;
103
104 rc = ds_input_open(disp);
105 if (rc != EOK)
106 goto error;
107
108 rc = ds_output_create(&output);
109 if (rc != EOK)
110 goto error;
111
112 output->def_display = disp;
113 rc = ds_output_start_discovery(output);
114 if (rc != EOK)
115 goto error;
116
117 async_set_fallback_port_handler(display_client_conn, disp);
118
119 rc = loc_server_register(NAME);
120 if (rc != EOK) {
121 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering server: %s.", str_error(rc));
122 rc = EEXIST;
123 }
124
125 service_id_t sid;
126 rc = loc_service_register(SERVICE_NAME_DISPLAY, &sid);
127 if (rc != EOK) {
128 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering service: %s.", str_error(rc));
129 rc = EEXIST;
130 goto error;
131 }
132
133 *routput = output;
134 return EOK;
135error:
136#if 0
137 if (disp->input != NULL)
138 ds_input_close(disp);
139#endif
140 if (output != NULL)
141 ds_output_destroy(output);
142 if (gc != NULL)
143 gfx_context_delete(gc);
144 if (seat != NULL)
145 ds_seat_destroy(seat);
146 if (disp != NULL)
147 ds_display_destroy(disp);
148 return rc;
149}
150
151/** Handle client connection to display server */
152static void display_client_conn(ipc_call_t *icall, void *arg)
153{
154 display_srv_t srv;
155 sysarg_t wnd_id;
156 sysarg_t svc_id;
157 ds_client_t *client = NULL;
158 ds_window_t *wnd;
159 ds_display_t *disp = (ds_display_t *) arg;
160 gfx_context_t *gc;
161 errno_t rc;
162
163 log_msg(LOG_DEFAULT, LVL_NOTE, "display_client_conn arg1=%zu arg2=%zu arg3=%zu arg4=%zu.",
164 ipc_get_arg1(icall), ipc_get_arg2(icall), ipc_get_arg3(icall),
165 ipc_get_arg4(icall));
166
167 (void) icall;
168 (void) arg;
169
170 svc_id = ipc_get_arg2(icall);
171 wnd_id = ipc_get_arg3(icall);
172
173 if (svc_id != 0) {
174 /* Create client object */
175 rc = ds_client_create(disp, &display_client_cb, &srv, &client);
176 if (rc != EOK) {
177 async_answer_0(icall, ENOMEM);
178 return;
179 }
180
181 /* Set up protocol structure */
182 display_srv_initialize(&srv);
183 srv.ops = &display_srv_ops;
184 srv.arg = client;
185
186 /* Handle connection */
187 display_conn(icall, &srv);
188
189 ds_client_destroy(client);
190 } else {
191 /* Window GC connection */
192
193 wnd = ds_display_find_window(disp, wnd_id);
194 if (wnd == NULL) {
195 async_answer_0(icall, ENOENT);
196 return;
197 }
198
199 gc = ds_window_get_ctx(wnd);
200 gc_conn(icall, gc);
201 }
202}
203
204int main(int argc, char *argv[])
205{
206 errno_t rc;
207 ds_output_t *output;
208
209 printf("%s: Display server\n", NAME);
210
211 if (log_init(NAME) != EOK) {
212 printf(NAME ": Failed to initialize logging.\n");
213 return 1;
214 }
215
216 rc = display_srv_init(&output);
217 if (rc != EOK)
218 return 1;
219
220 printf(NAME ": Accepting connections.\n");
221 task_retval(0);
222 async_manager();
223
224 return 0;
225}
226
227/** @}
228 */
Note: See TracBrowser for help on using the repository browser.