Commit | Line | Data |
---|---|---|
d42e7319 JB |
1 | /* |
2 | * Copyright © 2012 Collabora, Ltd. | |
3 | * | |
4 | * Permission to use, copy, modify, distribute, and sell this software and | |
5 | * its documentation for any purpose is hereby granted without fee, provided | |
6 | * that the above copyright notice appear in all copies and that both that | |
7 | * copyright notice and this permission notice appear in supporting | |
8 | * documentation, and that the name of the copyright holders not be used in | |
9 | * advertising or publicity pertaining to distribution of the software | |
10 | * without specific, written prior permission. The copyright holders make | |
11 | * no representations about the suitability of this software for any | |
12 | * purpose. It is provided "as is" without express or implied warranty. | |
13 | * | |
14 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | |
15 | * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |
16 | * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY | |
17 | * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER | |
18 | * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF | |
19 | * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |
20 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
21 | */ | |
22 | ||
23 | #include <cstring> | |
24 | ||
25 | #include <EGL/egl.h> | |
26 | #include <EGL/eglext.h> | |
27 | ||
28 | extern "C" { | |
29 | #include <cutils/native_handle.h> | |
30 | #include <hardware/gralloc.h> | |
31 | } | |
32 | ||
33 | #include <wayland-server.h> | |
34 | #include "wayland-android-server-protocol.h" | |
35 | #include "server_wlegl_private.h" | |
36 | #include "server_wlegl_handle.h" | |
37 | #include "server_wlegl_buffer.h" | |
38 | ||
39 | static inline server_wlegl * | |
40 | server_wlegl_from(struct wl_resource *resource) | |
41 | { | |
42 | return reinterpret_cast<server_wlegl *>(resource->data); | |
43 | } | |
44 | ||
45 | static void | |
46 | server_wlegl_create_handle(struct wl_client *client, | |
47 | struct wl_resource *resource, | |
48 | uint32_t id, | |
49 | int32_t num_fds, | |
50 | struct wl_array *ints) | |
51 | { | |
52 | server_wlegl *wlegl = server_wlegl_from(resource); | |
53 | server_wlegl_handle *handle; | |
54 | ||
55 | if (num_fds < 0) { | |
56 | wl_resource_post_error(resource, | |
57 | ANDROID_WLEGL_ERROR_BAD_VALUE, | |
58 | "num_fds is negative: %d", num_fds); | |
59 | return; | |
60 | } | |
61 | ||
62 | handle = server_wlegl_handle_create(id); | |
63 | wl_array_copy(&handle->ints, ints); | |
64 | handle->num_fds = num_fds; | |
65 | wl_client_add_resource(client, &handle->resource); | |
66 | } | |
67 | ||
68 | static void | |
69 | server_wlegl_create_buffer(struct wl_client *client, | |
70 | struct wl_resource *resource, | |
71 | uint32_t id, | |
72 | int32_t width, | |
73 | int32_t height, | |
74 | int32_t stride, | |
75 | int32_t format, | |
76 | int32_t usage, | |
77 | struct wl_resource *hnd) | |
78 | { | |
79 | server_wlegl *wlegl = server_wlegl_from(resource); | |
80 | server_wlegl_handle *handle = server_wlegl_handle_from(hnd); | |
81 | server_wlegl_buffer *buffer; | |
82 | buffer_handle_t native; | |
83 | ||
84 | if (width < 1 || height < 1) { | |
85 | wl_resource_post_error(resource, | |
86 | ANDROID_WLEGL_ERROR_BAD_VALUE, | |
87 | "bad width (%d) or height (%d)", | |
88 | width, height); | |
89 | return; | |
90 | } | |
91 | ||
92 | native = server_wlegl_handle_to_native(handle); | |
93 | if (!native) { | |
94 | wl_resource_post_error(resource, | |
95 | ANDROID_WLEGL_ERROR_BAD_HANDLE, | |
96 | "fd count mismatch"); | |
97 | return; | |
98 | } | |
99 | ||
100 | buffer = server_wlegl_buffer_create(id, width, height, stride, | |
101 | format, usage, native, wlegl); | |
102 | if (!buffer) { | |
103 | native_handle_close((native_handle_t *)native); | |
104 | native_handle_delete((native_handle_t *)native); | |
105 | wl_resource_post_error(resource, | |
106 | ANDROID_WLEGL_ERROR_BAD_HANDLE, | |
107 | "invalid native handle"); | |
108 | return; | |
109 | } | |
110 | ||
111 | wl_client_add_resource(client, &buffer->base.resource); | |
112 | } | |
113 | ||
114 | static const struct android_wlegl_interface server_wlegl_impl = { | |
115 | server_wlegl_create_handle, | |
116 | server_wlegl_create_buffer, | |
117 | }; | |
118 | ||
119 | static void | |
120 | server_wlegl_bind(struct wl_client *client, void *data, | |
121 | uint32_t version, uint32_t id) | |
122 | { | |
123 | server_wlegl *wlegl = reinterpret_cast<server_wlegl *>(data); | |
124 | struct wl_resource *resource; | |
125 | ||
126 | resource = wl_client_add_object(client, &android_wlegl_interface, | |
127 | &server_wlegl_impl, id, wlegl); | |
128 | } | |
129 | ||
130 | server_wlegl * | |
131 | server_wlegl_create(struct wl_display *display, gralloc_module_t *gralloc) | |
132 | { | |
133 | struct server_wlegl *wlegl; | |
134 | int ret; | |
135 | ||
136 | wlegl = new server_wlegl; | |
137 | ||
138 | wlegl->display = display; | |
139 | wlegl->global = wl_display_add_global(display, | |
140 | &android_wlegl_interface, | |
141 | wlegl, server_wlegl_bind); | |
142 | wlegl->gralloc = (const gralloc_module_t *)gralloc; | |
143 | ||
144 | return wlegl; | |
145 | } | |
146 | ||
147 | void | |
148 | server_wlegl_destroy(server_wlegl *wlegl) | |
149 | { | |
150 | /* FIXME: server_wlegl_buffer objects may exist */ | |
151 | ||
152 | /* no way to release wlegl->gralloc */ | |
153 | ||
154 | /* FIXME: remove global_ */ | |
155 | ||
156 | /* Better to leak than expose dtor segfaults, the server | |
157 | * supposedly exits soon after. */ | |
158 | //LOGW("server_wlegl object leaked on UnbindWaylandDisplayWL"); | |
159 | /* delete wlegl; */ | |
160 | } | |
161 |