Imported Upstream version 0.1.0+git20131207+e452e83
[deb_libhybris.git] / hybris / egl / platforms / common / eglplatformcommon.cpp
1 #include <ws.h>
2 #include <stdlib.h>
3 #include <dlfcn.h>
4 #include <string.h>
5 #include <android/hardware/gralloc.h>
6 #include <stdio.h>
7 #include <assert.h>
8 #include "config.h"
9 #include <time.h>
10 #include <sys/types.h>
11 #include <sys/stat.h>
12 #include <fcntl.h>
13 #include <unistd.h>
14 #include "logging.h"
15
16 #ifdef WANT_WAYLAND
17 #include <wayland-client.h>
18 #include "server_wlegl.h"
19 #include "server_wlegl_buffer.h"
20 #endif
21
22 #include "windowbuffer.h"
23
24 static gralloc_module_t *my_gralloc = 0;
25 static alloc_device_t *my_alloc = 0;
26
27 extern "C" void eglplatformcommon_init(gralloc_module_t *gralloc, alloc_device_t *allocdevice)
28 {
29 my_gralloc = gralloc;
30 my_alloc = allocdevice;
31 }
32
33 extern "C" int hybris_register_buffer_handle(buffer_handle_t handle)
34 {
35 if (!my_gralloc)
36 return -1;
37
38 return my_gralloc->registerBuffer(my_gralloc, handle);
39 }
40
41 extern "C" int hybris_unregister_buffer_handle(buffer_handle_t handle)
42 {
43 if (!my_gralloc)
44 return -1;
45
46 return my_gralloc->unregisterBuffer(my_gralloc, handle);
47 }
48
49 extern "C" void hybris_dump_buffer_to_file(ANativeWindowBuffer *buf)
50 {
51 static int cnt = 0;
52 void *vaddr;
53 int ret = my_gralloc->lock(my_gralloc, buf->handle, buf->usage, 0, 0, buf->width, buf->height, &vaddr);
54 TRACE("buf:%p gralloc lock returns %i", buf, ret);
55 TRACE("buf:%p lock to vaddr %p", buf, vaddr);
56 char b[1024];
57 int bytes_pp = 0;
58
59 if (buf->format == HAL_PIXEL_FORMAT_RGBA_8888)
60 bytes_pp = 4;
61 else if (buf->format == HAL_PIXEL_FORMAT_RGB_565)
62 bytes_pp = 2;
63
64 snprintf(b, 1020, "vaddr.%p.%p.%i.%is%ix%ix%i", buf, vaddr, cnt, buf->width, buf->stride, buf->height, bytes_pp);
65 cnt++;
66 int fd = ::open(b, O_WRONLY|O_CREAT, S_IRWXU);
67
68 ::write(fd, vaddr, buf->stride * buf->height * bytes_pp);
69 ::close(fd);
70 my_gralloc->unlock(my_gralloc, buf->handle);
71 }
72
73 #ifdef WANT_WAYLAND
74
75 extern "C" EGLBoolean eglplatformcommon_eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
76 {
77 assert(my_gralloc != NULL);
78 server_wlegl_create(display, my_gralloc);
79 return EGL_TRUE;
80 }
81
82 extern "C" EGLBoolean eglplatformcommon_eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
83 {
84 return EGL_TRUE;
85 }
86
87 extern "C" EGLBoolean eglplatformcommon_eglQueryWaylandBufferWL(EGLDisplay dpy,
88 struct wl_buffer *buffer, EGLint attribute, EGLint *value)
89 {
90 server_wlegl_buffer *buf = server_wlegl_buffer_from(buffer);
91 ANativeWindowBuffer* anwb = (ANativeWindowBuffer *) buf->buf;
92
93 if (attribute == EGL_TEXTURE_FORMAT) {
94 switch(anwb->format) {
95 case HAL_PIXEL_FORMAT_RGB_565:
96 *value = EGL_TEXTURE_RGB;
97 break;
98 case HAL_PIXEL_FORMAT_RGBA_8888:
99 *value = EGL_TEXTURE_RGBA;
100 break;
101 default:
102 *value = EGL_TEXTURE_EXTERNAL_WL;
103 }
104 return EGL_TRUE;
105 }
106 if (attribute == EGL_WIDTH) {
107 *value = anwb->width;
108 return EGL_TRUE;
109 }
110 if (attribute == EGL_HEIGHT) {
111 *value = anwb->height;
112 return EGL_TRUE;
113 }
114 return EGL_FALSE ;
115 }
116
117 #endif
118
119 extern "C" EGLBoolean eglplatformcommon_eglHybrisCreateNativeBuffer(EGLint width, EGLint height, EGLint usage, EGLint format, EGLint *stride, EGLClientBuffer *buffer)
120 {
121 int ret;
122 buffer_handle_t _handle;
123 int _stride;
124
125 assert(my_gralloc != NULL);
126 assert(my_alloc != NULL);
127
128 ret = my_alloc->alloc(my_alloc, width, height, format, usage, &_handle, &_stride);
129
130 if (ret == 0)
131 {
132 RemoteWindowBuffer *buf = new RemoteWindowBuffer(width, height, _stride, format, usage, _handle, my_gralloc);
133 buf->common.incRef(&buf->common);
134 *buffer = (EGLClientBuffer) static_cast<ANativeWindowBuffer *>(buf);
135 *stride = _stride;
136 return EGL_TRUE;
137 }
138 else
139 return EGL_FALSE;
140 }
141
142 extern "C" EGLBoolean eglplatformcommon_eglHybrisLockNativeBuffer(EGLClientBuffer buffer, EGLint usage, EGLint l, EGLint t, EGLint w, EGLint h, void **vaddr)
143 {
144 int ret;
145 RemoteWindowBuffer *buf = static_cast<RemoteWindowBuffer *>((ANativeWindowBuffer *) buffer);
146
147 assert(my_gralloc != NULL);
148
149 ret = my_gralloc->lock(my_gralloc, buf->handle, usage, l, t, w, h, vaddr);
150 if (ret == 0)
151 return EGL_TRUE;
152 else
153 return EGL_FALSE;
154 }
155
156 extern "C" EGLBoolean eglplatformcommon_eglHybrisUnlockNativeBuffer(EGLClientBuffer buffer)
157 {
158 int ret;
159 RemoteWindowBuffer *buf = static_cast<RemoteWindowBuffer *>((ANativeWindowBuffer *) buffer);
160
161 assert(my_gralloc != NULL);
162
163 ret = my_gralloc->unlock(my_gralloc, buf->handle);
164 if (ret == 0)
165 return EGL_TRUE;
166 else
167 return EGL_FALSE;
168 }
169
170
171 extern "C" EGLBoolean eglplatformcommon_eglHybrisReleaseNativeBuffer(EGLClientBuffer buffer)
172 {
173 RemoteWindowBuffer *buf = static_cast<RemoteWindowBuffer *>((ANativeWindowBuffer *) buffer);
174
175 buf->common.decRef(&buf->common);
176 return EGL_TRUE;
177 }
178
179
180
181 extern "C" void
182 eglplatformcommon_passthroughImageKHR(EGLContext *ctx, EGLenum *target, EGLClientBuffer *buffer, const EGLint **attrib_list)
183 {
184 #ifdef WANT_WAYLAND
185 static int debugenvchecked = 0;
186 if (*target == EGL_WAYLAND_BUFFER_WL)
187 {
188 server_wlegl_buffer *buf = server_wlegl_buffer_from((struct wl_buffer *)*buffer);
189 HYBRIS_TRACE_BEGIN("eglplatformcommon", "Wayland_eglImageKHR", "-resource@%i", ((struct wl_buffer *)*buffer)->resource.object.id);
190 HYBRIS_TRACE_END("eglplatformcommon", "Wayland_eglImageKHR", "-resource@%i", ((struct wl_buffer *)*buffer)->resource.object.id);
191 if (debugenvchecked == 0)
192 {
193 if (getenv("HYBRIS_WAYLAND_KHR_DUMP_BUFFERS") != NULL)
194 debugenvchecked = 2;
195 else
196 debugenvchecked = 1;
197 } else if (debugenvchecked == 2)
198 {
199 hybris_dump_buffer_to_file((ANativeWindowBuffer *) buf->buf);
200 }
201 *buffer = (EGLClientBuffer) (ANativeWindowBuffer *) buf->buf;
202 *target = EGL_NATIVE_BUFFER_ANDROID;
203 *ctx = EGL_NO_CONTEXT;
204 *attrib_list = NULL;
205 }
206 #endif
207 }
208
209 extern "C" __eglMustCastToProperFunctionPointerType eglplatformcommon_eglGetProcAddress(const char *procname)
210 {
211 #ifdef WANT_WAYLAND
212 if (strcmp(procname, "eglBindWaylandDisplayWL") == 0)
213 {
214 return (__eglMustCastToProperFunctionPointerType)eglplatformcommon_eglBindWaylandDisplayWL;
215 }
216 else
217 if (strcmp(procname, "eglUnbindWaylandDisplayWL") == 0)
218 {
219 return (__eglMustCastToProperFunctionPointerType)eglplatformcommon_eglUnbindWaylandDisplayWL;
220 }else
221 if (strcmp(procname, "eglQueryWaylandBufferWL") == 0)
222 {
223 return (__eglMustCastToProperFunctionPointerType)eglplatformcommon_eglQueryWaylandBufferWL;
224 }
225 else
226 #endif
227 if (strcmp(procname, "eglHybrisCreateNativeBuffer") == 0)
228 {
229 return (__eglMustCastToProperFunctionPointerType)eglplatformcommon_eglHybrisCreateNativeBuffer;
230 }
231 else
232 if (strcmp(procname, "eglHybrisLockNativeBuffer") == 0)
233 {
234 return (__eglMustCastToProperFunctionPointerType)eglplatformcommon_eglHybrisLockNativeBuffer;
235 }
236 else
237 if (strcmp(procname, "eglHybrisUnlockNativeBuffer") == 0)
238 {
239 return (__eglMustCastToProperFunctionPointerType)eglplatformcommon_eglHybrisUnlockNativeBuffer;
240 }
241 else
242 if (strcmp(procname, "eglHybrisReleaseNativeBuffer") == 0)
243 {
244 return (__eglMustCastToProperFunctionPointerType)eglplatformcommon_eglHybrisReleaseNativeBuffer;
245 }
246 return NULL;
247 }
248
249 extern "C" const char *eglplatformcommon_eglQueryString(EGLDisplay dpy, EGLint name, const char *(*real_eglQueryString)(EGLDisplay dpy, EGLint name))
250 {
251 #ifdef WANT_WAYLAND
252 if (name == EGL_EXTENSIONS)
253 {
254 const char *ret = (*real_eglQueryString)(dpy, name);
255 static char eglextensionsbuf[512];
256 assert(ret != NULL);
257 snprintf(eglextensionsbuf, 510, "%sEGL_HYBRIS_native_buffer %s", ret,
258 #ifdef WANT_WAYLAND
259 "EGL_WL_bind_wayland_display "
260 #else
261 ""
262 #endif
263 );
264 ret = eglextensionsbuf;
265 return ret;
266 }
267 #endif
268 return (*real_eglQueryString)(dpy, name);
269 }