Imported Upstream version 0.1.0+git20131207+e452e83
[deb_libhybris.git] / hybris / egl / platforms / common / server_wlegl.cpp
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