Merge ~morphis/libhybris/+git/libhybris-ubuntu:wip into ~libhybris-maintainers/libhybris/+git/libhybris:master

Proposed by Simon Fels on 2015-11-11
Status: Merged
Approved by: Simon Fels on 2015-11-17
Approved revision: c587332285a7a81153da56b9501ed99647ab3224
Merged at revision: c587332285a7a81153da56b9501ed99647ab3224
Proposed branch: ~morphis/libhybris/+git/libhybris-ubuntu:wip
Merge into: ~libhybris-maintainers/libhybris/+git/libhybris:master
Diff against target: 8185 lines (+3080/-875)
126 files modified
.gitignore (+33/-0)
compat/camera/camera_compatibility_layer.cpp (+26/-4)
compat/input/Android.mk (+16/-4)
compat/input/input_compatibility_layer.cpp (+28/-2)
compat/media/Android.mk (+19/-0)
compat/media/decoding_service.cpp (+21/-2)
compat/media/decoding_service_priv.h (+5/-0)
compat/media/media_codec_list.cpp (+56/-3)
compat/media/media_compatibility_layer.cpp (+32/-4)
compat/media/media_recorder_client.cpp (+12/-0)
compat/media/media_recorder_client.h (+1/-0)
compat/media/surface_texture_client_hybris.cpp (+18/-3)
compat/media/surface_texture_client_hybris_priv.h (+4/-0)
compat/surface_flinger/Android.mk (+1/-0)
compat/surface_flinger/surface_flinger_compatibility_layer.cpp (+11/-0)
debian/changelog (+15/-0)
debian/copyright (+1/-1)
debian/libhybris-dev.install (+6/-0)
debian/libhybris.install.in (+3/-0)
dev/null (+0/-42)
hybris/Makefile.am (+4/-1)
hybris/camera/Makefile.am (+1/-1)
hybris/camera/camera.c (+2/-1)
hybris/common/Makefile.am (+7/-1)
hybris/common/dlfcn.c (+1/-1)
hybris/common/gingerbread/Makefile.am (+1/-0)
hybris/common/hooks.c (+162/-40)
hybris/common/ics/Makefile.am (+1/-0)
hybris/common/jb/Makefile.am (+1/-0)
hybris/common/jb/dlfcn.c (+2/-2)
hybris/common/jb/linker.c (+1/-2)
hybris/common/logging.c (+12/-0)
hybris/common/logging.h (+13/-10)
hybris/configure.ac (+66/-34)
hybris/egl/Makefile.am (+2/-2)
hybris/egl/egl.c (+160/-42)
hybris/egl/eglhybris.h (+8/-2)
hybris/egl/helper.cpp (+11/-0)
hybris/egl/helper.h (+3/-0)
hybris/egl/platforms/Makefile.am (+3/-0)
hybris/egl/platforms/common/Makefile.am (+15/-6)
hybris/egl/platforms/common/eglplatformcommon.cpp (+120/-10)
hybris/egl/platforms/common/eglplatformcommon.h (+2/-2)
hybris/egl/platforms/common/hybris_nativebufferext.h (+6/-0)
hybris/egl/platforms/common/native_handle.c (+2/-1)
hybris/egl/platforms/common/nativewindowbase.cpp (+25/-7)
hybris/egl/platforms/common/nativewindowbase.h (+1/-1)
hybris/egl/platforms/common/server_wlegl.cpp (+45/-8)
hybris/egl/platforms/common/server_wlegl.h (+1/-6)
hybris/egl/platforms/common/server_wlegl_buffer.cpp (+34/-25)
hybris/egl/platforms/common/server_wlegl_buffer.h (+8/-3)
hybris/egl/platforms/common/server_wlegl_handle.cpp (+1/-0)
hybris/egl/platforms/common/server_wlegl_private.h (+1/-0)
hybris/egl/platforms/common/wayland-android.xml (+34/-1)
hybris/egl/platforms/common/wayland-egl-priv.h (+1/-0)
hybris/egl/platforms/common/wayland-egl.c (+4/-0)
hybris/egl/platforms/common/windowbuffer.cpp (+5/-0)
hybris/egl/platforms/common/windowbuffer.h (+10/-1)
hybris/egl/platforms/fbdev/Makefile.am (+1/-1)
hybris/egl/platforms/fbdev/eglplatform_fbdev.cpp (+53/-31)
hybris/egl/platforms/fbdev/fbdev_window.cpp (+23/-20)
hybris/egl/platforms/fbdev/fbdev_window.h (+7/-3)
hybris/egl/platforms/hwcomposer/Makefile.am (+5/-3)
hybris/egl/platforms/hwcomposer/eglplatform_hwcomposer.cpp (+33/-21)
hybris/egl/platforms/hwcomposer/hwcomposer_window.cpp (+32/-86)
hybris/egl/platforms/hwcomposer/hwcomposer_window.h (+4/-5)
hybris/egl/platforms/null/Makefile.am (+19/-2)
hybris/egl/platforms/null/eglplatform_null.c (+30/-23)
hybris/egl/platforms/wayland/Makefile.am (+10/-2)
hybris/egl/platforms/wayland/eglplatform_wayland.cpp (+208/-16)
hybris/egl/platforms/wayland/wayland_window.cpp (+317/-142)
hybris/egl/platforms/wayland/wayland_window.h (+85/-27)
hybris/egl/ws.c (+31/-3)
hybris/egl/ws.h (+36/-4)
hybris/glesv1/Makefile.am (+1/-1)
hybris/glesv1/glesv1_cm.c (+1/-1)
hybris/glesv2/Makefile.am (+1/-1)
hybris/glesv2/glesv2.c (+10/-4)
hybris/hardware/Makefile.am (+1/-1)
hybris/hardware/hardware.c (+4/-3)
hybris/include/EGL/eglext.h (+16/-0)
hybris/include/Makefile.am (+6/-0)
hybris/include/hybris/common/binding.h (+448/-0)
hybris/include/hybris/common/dlfcn.h (+36/-0)
hybris/include/hybris/common/floating_point_abi.h (+42/-0)
hybris/include/hybris/dlfcn/dlfcn.h (+2/-17)
hybris/include/hybris/internal/camera_control.h (+4/-0)
hybris/input/Makefile.am (+1/-1)
hybris/input/is.c (+1/-1)
hybris/libnfc_ndef_nxp/Makefile.am (+1/-1)
hybris/libnfc_ndef_nxp/libnfc_ndef_nxp.c (+1/-1)
hybris/libnfc_nxp/Makefile.am (+1/-1)
hybris/libnfc_nxp/libnfc_nxp.c (+3/-3)
hybris/libsync/Makefile.am (+1/-1)
hybris/media/media.c (+1/-1)
hybris/properties/Makefile.am (+1/-1)
hybris/properties/cache.c (+32/-6)
hybris/properties/properties.c (+4/-6)
hybris/properties/properties_p.h (+3/-0)
hybris/sf/Makefile.am (+1/-1)
hybris/sf/sf.c (+1/-1)
hybris/tests/Makefile.am (+32/-17)
hybris/tests/test_audio.c (+3/-2)
hybris/tests/test_camera.c (+2/-0)
hybris/tests/test_egl.c (+1/-0)
hybris/tests/test_glesv2.c (+10/-1)
hybris/tests/test_gps.c (+24/-6)
hybris/tests/test_hwcomposer.cpp (+75/-66)
hybris/tests/test_input.c (+1/-0)
hybris/tests/test_lights.c (+2/-1)
hybris/tests/test_nfc.c (+1/-0)
hybris/tests/test_sensors.c (+110/-1)
hybris/tests/test_sf.c (+1/-0)
hybris/tests/test_ui.c (+3/-2)
hybris/tests/test_vibrator.c (+38/-0)
hybris/tests/test_wifi.c (+1/-0)
hybris/ui/Makefile.am (+1/-1)
hybris/ui/ui.c (+1/-1)
hybris/utils/Makefile.am (+1/-1)
hybris/utils/getprop.c (+1/-1)
hybris/vibrator/Makefile.am (+17/-0)
hybris/vibrator/libvibrator.pc.in (+10/-0)
hybris/vibrator/vibrator.c (+29/-0)
hybris/wifi/wifi.c (+4/-4)
utils/extract-headers.sh (+109/-53)
utils/generate_wrapper_macros.py (+1/-1)
Reviewer Review Type Date Requested Status
Simon Fels Approve on 2015-11-17
Review via email: mp+277220@code.launchpad.net

Description of the Change

Merge with a more recent upstream version and rebase all our changes. This also includes changes needed in the compat layer to add Android 5.x support.

To post a comment you must log in.
Simon Fels (morphis) wrote :

LGTM but waiting until package is released to overlay ppa before merging

Simon Fels (morphis) :
review: Approve
Alex Tu (alextu) wrote :

~morphis/libhybris/+git/libhybris-ubuntu:wip gets a build failure which caused by building test_audio binary.

Alex Tu (alextu) wrote :

revise my latest comment:
Because of this MP is target to android 4.4.2 for merging all changes in github upstream.
So, it can build passed with android 4.4.2 headers[1].

And what I did is to build it with android 5, that's not the target of this MP, so please ignore my last comment for build error.

Detail information about this task : https://wiki.canonical.com/PES/Engineering/Premium/PhoneArticles/LibhybrisRelated

[1] https://launchpad.net/ubuntu/+source/android-headers

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/.gitignore b/.gitignore
2index 1a947ad..ac54812 100644
3--- a/.gitignore
4+++ b/.gitignore
5@@ -28,9 +28,42 @@ stamp-h1
6 aclocal-copy
7 arm-*-linux-gnueabi-libtool
8
9+# Generated .pc, .h and .c files
10+hybris/camera/libcamera.pc
11+hybris/documentation.list
12+hybris/egl/egl.pc
13+hybris/egl/platforms/common/hybris-egl-platform.pc
14+hybris/egl/platforms/common/wayland-android-client-protocol.h
15+hybris/egl/platforms/common/wayland-android-protocol.c
16+hybris/egl/platforms/common/wayland-android-server-protocol.h
17+hybris/egl/platforms/common/wayland-egl.pc
18+hybris/egl/platforms/hwcomposer/hwcomposer-egl.pc
19+hybris/glesv1/glesv1_cm.pc
20+hybris/glesv2/glesv2.pc
21+hybris/hardware/libhardware.pc
22+hybris/input/libis.pc
23+hybris/libnfc_ndef_nxp/libnfc_ndef_nxp.pc
24+hybris/libnfc_nxp/libnfc_nxp.pc
25+hybris/libsync/libsync.pc
26+hybris/properties/libandroid-properties.pc
27+hybris/sf/libsf.pc
28+hybris/vibrator/libvibrator.pc
29+
30+# Util binaries
31+hybris/utils/getprop
32+hybris/utils/setprop
33+
34+# Test binaries
35+hybris/tests/test_camera
36+hybris/tests/test_egl_configs
37+hybris/tests/test_gps
38+hybris/tests/test_input
39+hybris/tests/test_nfc
40+hybris/tests/test_sf
41 hybris/tests/test_egl
42 hybris/tests/test_glesv2
43 hybris/tests/test_lights
44 hybris/tests/test_offscreen_rendering
45 hybris/tests/test_sensors
46 hybris/tests/test_ui
47+
48diff --git a/compat/camera/camera_compatibility_layer.cpp b/compat/camera/camera_compatibility_layer.cpp
49index 55cd79e..3d8e5bc 100644
50--- a/compat/camera/camera_compatibility_layer.cpp
51+++ b/compat/camera/camera_compatibility_layer.cpp
52@@ -35,6 +35,9 @@
53 #else
54 #include <gui/GLConsumer.h>
55 #endif
56+#if ANDROID_VERSION_MAJOR==5
57+#include <gui/IGraphicBufferProducer.h>
58+#endif
59 #include <ui/GraphicBuffer.h>
60
61 #include <GLES2/gl2.h>
62@@ -53,7 +56,11 @@
63 #define REPORT_FUNCTION() ALOGV("%s \n", __PRETTY_FUNCTION__)
64
65 // From android::GLConsumer::FrameAvailableListener
66-void CameraControl::onFrameAvailable()
67+#if ANDROID_VERSION_MAJOR==5 && ANDROID_VERSION_MINOR>=1
68+ void CameraControl::onFrameAvailable(const android::BufferItem& item)
69+#else
70+ void CameraControl::onFrameAvailable()
71+#endif
72 {
73 REPORT_FUNCTION();
74 if (listener)
75@@ -185,7 +192,7 @@ CameraControl* android_camera_connect_to(CameraType camera_type, CameraControlLi
76
77 CameraControl* cc = new CameraControl();
78 cc->listener = listener;
79-#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR>=3
80+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR>=3 || ANDROID_VERSION_MAJOR==5
81 cc->camera = android::Camera::connect(camera_id, android::String16("hybris"), android::Camera::USE_CALLING_UID);
82 #else
83 cc->camera = android::Camera::connect(camera_id);
84@@ -651,6 +658,11 @@ void android_camera_set_preview_texture(CameraControl* control, int texture_id)
85 new android::NativeBufferAlloc()
86 );
87
88+#if ANDROID_VERSION_MAJOR==5
89+ android::sp<android::IGraphicBufferProducer> producer;
90+ android::sp<android::IGraphicBufferConsumer> consumer;
91+ android::BufferQueue::createBufferQueue(&producer, &consumer);
92+#else
93 android::sp<android::BufferQueue> buffer_queue(
94 #if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
95 new android::BufferQueue(false, NULL, native_alloc)
96@@ -658,6 +670,7 @@ void android_camera_set_preview_texture(CameraControl* control, int texture_id)
97 new android::BufferQueue(NULL)
98 #endif
99 );
100+#endif
101
102 if (control->preview_texture == NULL) {
103 #if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
104@@ -667,7 +680,13 @@ void android_camera_set_preview_texture(CameraControl* control, int texture_id)
105 control->preview_texture = android::sp<android::GLConsumer>(
106 new android::GLConsumer(
107 #endif
108-#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
109+#if ANDROID_VERSION_MAJOR==5
110+ consumer,
111+ texture_id,
112+ GL_TEXTURE_EXTERNAL_OES,
113+ true,
114+ is_controlled_by_app));
115+#elif ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
116 texture_id,
117 allow_synchronous_mode,
118 GL_TEXTURE_EXTERNAL_OES,
119@@ -688,7 +707,10 @@ void android_camera_set_preview_texture(CameraControl* control, int texture_id)
120 #else
121 android::sp<android::GLConsumer::FrameAvailableListener>(control));
122 #endif
123-#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
124+
125+#if ANDROID_VERSION_MAJOR==5
126+ control->camera->setPreviewTarget(producer);
127+#elif ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
128 control->camera->setPreviewTexture(control->preview_texture->getBufferQueue());
129 #else
130 control->camera->setPreviewTarget(buffer_queue);
131diff --git a/compat/input/Android.mk b/compat/input/Android.mk
132index 813c009..06e732d 100644
133--- a/compat/input/Android.mk
134+++ b/compat/input/Android.mk
135@@ -1,5 +1,6 @@
136 LOCAL_PATH := $(call my-dir)
137 include $(CLEAR_VARS)
138+include $(LOCAL_PATH)/../Android.common.mk
139
140 HYBRIS_PATH := $(LOCAL_PATH)/../../hybris
141
142@@ -18,15 +19,26 @@ LOCAL_SHARED_LIBRARIES := \
143 libgui \
144 libandroidfw
145
146+LOCAL_C_INCLUDES := \
147+ $(HYBRIS_PATH)/include \
148+ external/skia/include/core
149+
150 HAS_LIBINPUTSERVICE := $(shell test $(ANDROID_VERSION_MAJOR) -eq 4 -a $(ANDROID_VERSION_MINOR) -gt 2 && echo true)
151 ifeq ($(HAS_LIBINPUTSERVICE),true)
152 LOCAL_SHARED_LIBRARIES += libinputservice
153+LOCAL_C_INCLUDES += frameworks/base/services/input
154 endif
155
156-LOCAL_C_INCLUDES := \
157- $(HYBRIS_PATH)/include \
158- external/skia/include/core \
159- frameworks/base/services/input
160+HAS_LIBINPUTFLINGER := $(shell test $(ANDROID_VERSION_MAJOR) -eq 5 && echo true)
161+ifeq ($(HAS_LIBINPUTFLINGER),true)
162+LOCAL_SHARED_LIBRARIES += libinputflinger libinputservice
163+LOCAL_C_INCLUDES += \
164+ frameworks/base/libs/input \
165+ frameworks/native/services
166+endif
167+
168+
169+
170
171 include $(BUILD_SHARED_LIBRARY)
172
173diff --git a/compat/input/input_compatibility_layer.cpp b/compat/input/input_compatibility_layer.cpp
174index bf902d9..0e0db21 100644
175--- a/compat/input/input_compatibility_layer.cpp
176+++ b/compat/input/input_compatibility_layer.cpp
177@@ -19,8 +19,14 @@
178
179 #include <hybris/input/input_stack_compatibility_layer.h>
180
181-#include "InputListener.h"
182-#include "InputReader.h"
183+#if ANDROID_VERSION_MAJOR<=4
184+ #include "InputListener.h"
185+ #include "InputReader.h"
186+#elif ANDROID_VERSION_MAJOR==5
187+ #include "inputflinger/InputListener.h"
188+ #include "inputflinger/InputReader.h"
189+#endif
190+
191 #include "PointerController.h"
192 #include "SpriteController.h"
193 #include <gui/ISurfaceComposer.h>
194@@ -48,10 +54,20 @@ public:
195
196 DefaultPointerControllerPolicy()
197 {
198+#if ANDROID_VERSION_MAJOR<=4
199 bitmap.setConfig(
200 SkBitmap::kARGB_8888_Config,
201 bitmap_width,
202 bitmap_height);
203+#elif ANDROID_VERSION_MAJOR==5
204+ SkColorType ct = SkBitmapConfigToColorType(SkBitmap::kARGB_8888_Config);
205+ bitmap.setInfo(
206+ SkImageInfo::Make(bitmap_width,
207+ bitmap_height,
208+ ct,
209+ SkAlphaType::kPremul_SkAlphaType),
210+ 0);
211+#endif
212 bitmap.allocPixels();
213
214 // Icon for spot touches
215@@ -142,7 +158,11 @@ public:
216 mInputDevices = inputDevices;
217 }
218
219+#if ANDROID_VERSION_MAJOR<=4
220 virtual android::sp<android::KeyCharacterMap> getKeyboardLayoutOverlay(const android::String8& inputDeviceDescriptor) {
221+#elif ANDROID_VERSION_MAJOR==5
222+ virtual android::sp<android::KeyCharacterMap> getKeyboardLayoutOverlay(const android::InputDeviceIdentifier& identifier) {
223+#endif
224 return NULL;
225 }
226
227@@ -150,6 +170,12 @@ public:
228 return android::String8::empty();
229 }
230
231+#if ANDROID_VERSION_MAJOR==5
232+ virtual android::TouchAffineTransformation getTouchAffineTransformation(const android::String8& inputDeviceDescriptor, int32_t surfaceRotation) {
233+ return android::TouchAffineTransformation();
234+ }
235+#endif
236+
237 private:
238 android::sp<android::Looper> looper;
239 int default_layer_for_touch_point_visualization;
240diff --git a/compat/media/Android.mk b/compat/media/Android.mk
241index cd3995c..c73fbc4 100644
242--- a/compat/media/Android.mk
243+++ b/compat/media/Android.mk
244@@ -1,5 +1,6 @@
245 LOCAL_PATH:= $(call my-dir)
246 include $(CLEAR_VARS)
247+include $(LOCAL_PATH)/../Android.common.mk
248
249 LOCAL_SRC_FILES := \
250 camera_service.cpp
251@@ -20,8 +21,15 @@ LOCAL_C_INCLUDES := \
252 frameworks/av/services/medialog \
253 frameworks/av/services/camera/libcameraservice
254
255+IS_ANDROID_5 := $(shell test $(ANDROID_VERSION_MAJOR) -eq 5 && echo true)
256+ifeq ($(IS_ANDROID_5),true)
257+LOCAL_C_INCLUDES += system/media/camera/include
258+endif
259+
260 LOCAL_MODULE := camera_service
261
262+LOCAL_32_BIT_ONLY := true
263+
264 include $(BUILD_EXECUTABLE)
265
266 # -------------------------------------------------
267@@ -76,6 +84,11 @@ LOCAL_C_INCLUDES := \
268 system/media/audio_utils/include \
269 frameworks/av/services/camera/libcameraservice
270
271+IS_ANDROID_5 := $(shell test $(ANDROID_VERSION_MAJOR) -eq 5 && echo true)
272+ifeq ($(IS_ANDROID_5),true)
273+LOCAL_C_INCLUDES += frameworks/native/include/media/openmax
274+endif
275+
276 ifeq ($(strip $(MTK_CAMERA_BSP_SUPPORT)),yes)
277 LOCAL_C_INCLUDES += $(TOP)/mediatek/kernel/include/linux/vcodec
278 LOCAL_SHARED_LIBRARIES += \
279@@ -89,6 +102,8 @@ LOCAL_C_INCLUDES+= \
280 $(TOP)/$(MTK_PATH_SOURCE)/frameworks/av/include
281 endif
282
283+LOCAL_32_BIT_ONLY := true
284+
285 include $(BUILD_SHARED_LIBRARY)
286
287 # -------------------------------------------------
288@@ -124,6 +139,8 @@ LOCAL_SHARED_LIBRARIES := \
289 libEGL \
290 libGLESv2
291
292+LOCAL_32_BIT_ONLY := true
293+
294 include $(BUILD_EXECUTABLE)
295
296 include $(CLEAR_VARS)
297@@ -160,4 +177,6 @@ LOCAL_C_INCLUDES:= \
298 LOCAL_MODULE:= codec
299 LOCAL_MODULE_TAGS := optional
300
301+LOCAL_32_BIT_ONLY := true
302+
303 include $(BUILD_EXECUTABLE)
304diff --git a/compat/media/decoding_service.cpp b/compat/media/decoding_service.cpp
305index 3a9a8a4..96c62b0 100644
306--- a/compat/media/decoding_service.cpp
307+++ b/compat/media/decoding_service.cpp
308@@ -195,7 +195,11 @@ status_t DecodingService::getIGraphicBufferConsumer(sp<IGraphicBufferConsumer>*
309 pid_t pid = IPCThreadState::self()->getCallingPid();
310 ALOGD("Calling Pid: %d", pid);
311
312+#if ANDROID_VERSION_MAJOR==5
313+ *gbc = consumer;
314+#else
315 *gbc = buffer_queue;
316+#endif
317
318 return OK;
319 }
320@@ -205,7 +209,11 @@ status_t DecodingService::getIGraphicBufferProducer(sp<IGraphicBufferProducer>*
321 pid_t pid = IPCThreadState::self()->getCallingPid();
322 ALOGD("Calling Pid: %d", pid);
323
324+#if ANDROID_VERSION_MAJOR==5
325+ *gbp = producer;
326+#else
327 *gbp = buffer_queue;
328+#endif
329 ALOGD("producer(gbp): %p", (void*)gbp->get());
330 return OK;
331 }
332@@ -235,7 +243,12 @@ status_t DecodingService::unregisterSession()
333 session.clear();
334 // Reset the BufferQueue instance so that the next created client plays
335 // video correctly
336+#if ANDROID_VERSION_MAJOR==5
337+ producer.clear();
338+ consumer.clear();
339+#else
340 buffer_queue.clear();
341+#endif
342 }
343
344 return OK;
345@@ -248,14 +261,20 @@ void DecodingService::createBufferQueue()
346 sp<IGraphicBufferAlloc> g_buffer_alloc(new GraphicBufferAlloc());
347
348 // This BuferQueue is shared between the client and the service
349-#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
350+#if ANDROID_VERSION_MAJOR==5
351+ BufferQueue::createBufferQueue(&producer, &consumer);
352+#elif ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
353 sp<NativeBufferAlloc> native_alloc(new NativeBufferAlloc());
354 buffer_queue = new BufferQueue(false, NULL, native_alloc);
355 #else
356 buffer_queue = new BufferQueue(NULL);
357-#endif
358 ALOGD("buffer_queue: %p", (void*)buffer_queue.get());
359+#endif
360+#if ANDROID_VERSION_MAJOR==5
361+ producer->setBufferCount(5);
362+#else
363 buffer_queue->setBufferCount(5);
364+#endif
365 }
366
367 void DecodingService::binderDied(const wp<IBinder>& who)
368diff --git a/compat/media/decoding_service_priv.h b/compat/media/decoding_service_priv.h
369index 4e80077..2a7544d 100644
370--- a/compat/media/decoding_service_priv.h
371+++ b/compat/media/decoding_service_priv.h
372@@ -130,7 +130,12 @@ protected:
373
374 private:
375 static sp<DecodingService> decoding_service;
376+#if ANDROID_VERSION_MAJOR==5
377+ sp<IGraphicBufferProducer> producer;
378+ sp<IGraphicBufferConsumer> consumer;
379+#else
380 sp<BufferQueue> buffer_queue;
381+#endif
382 sp<IDecodingServiceSession> session;
383 DecodingClientDeathCbHybris client_death_cb;
384 void *client_death_context;
385diff --git a/compat/media/media_codec_list.cpp b/compat/media/media_codec_list.cpp
386index 28a8128..930c4c8 100644
387--- a/compat/media/media_codec_list.cpp
388+++ b/compat/media/media_codec_list.cpp
389@@ -60,13 +60,21 @@ void media_codec_list_get_codec_info_at_id(size_t index)
390 const char *media_codec_list_get_codec_name(size_t index)
391 {
392 REPORT_FUNCTION()
393+#if ANDROID_VERSION_MAJOR==5
394+ return MediaCodecList::getInstance()->getCodecInfo(index)->getCodecName();
395+#else
396 return MediaCodecList::getInstance()->getCodecName(index);
397+#endif
398 }
399
400 bool media_codec_list_is_encoder(size_t index)
401 {
402 REPORT_FUNCTION()
403+#if ANDROID_VERSION_MAJOR==5
404+ return MediaCodecList::getInstance()->getCodecInfo(index)->isEncoder();
405+#else
406 return MediaCodecList::getInstance()->isEncoder(index);
407+#endif
408 }
409
410 size_t media_codec_list_get_num_supported_types(size_t index)
411@@ -74,12 +82,16 @@ size_t media_codec_list_get_num_supported_types(size_t index)
412 REPORT_FUNCTION()
413
414 Vector<AString> types;
415+#if ANDROID_VERSION_MAJOR==5
416+ MediaCodecList::getInstance()->getCodecInfo(index)->getSupportedMimes(&types);
417+#else
418 status_t err = MediaCodecList::getInstance()->getSupportedTypes(index, &types);
419 if (err != OK)
420 {
421 ALOGE("Failed to get the number of supported codec types (err: %d)", err);
422 return 0;
423 }
424+#endif
425 ALOGD("Number of supported codec types: %d", types.size());
426
427 return types.size();
428@@ -90,7 +102,11 @@ size_t media_codec_list_get_nth_supported_type_len(size_t index, size_t n)
429 REPORT_FUNCTION()
430
431 Vector<AString> types;
432+#if ANDROID_VERSION_MAJOR==5
433+ MediaCodecList::getInstance()->getCodecInfo(index)->getSupportedMimes(&types);
434+#else
435 status_t err = MediaCodecList::getInstance()->getSupportedTypes(index, &types);
436+#endif
437
438 return types[n].size();
439 }
440@@ -106,31 +122,48 @@ int media_codec_list_get_nth_supported_type(size_t index, char *type, size_t n)
441 }
442
443 Vector<AString> types;
444+#if ANDROID_VERSION_MAJOR==5
445+ MediaCodecList::getInstance()->getCodecInfo(index)->getSupportedMimes(&types);
446+#else
447 status_t err = MediaCodecList::getInstance()->getSupportedTypes(index, &types);
448+#endif
449 for (size_t i=0; i<types[n].size(); ++i)
450 type[i] = types.itemAt(n).c_str()[i];
451
452+#if ANDROID_VERSION_MAJOR==5
453+ return OK;
454+#else
455 return err;
456+#endif
457 }
458
459 static void media_codec_list_get_num_codec_capabilities(size_t index, const char *type, size_t *num_profile_levels, size_t *num_color_formats)
460 {
461 REPORT_FUNCTION()
462
463+#if ANDROID_VERSION_MAJOR==5
464+ Vector<MediaCodecInfo::ProfileLevel> profile_levels;
465+#else
466 Vector<MediaCodecList::ProfileLevel> profile_levels;
467+#endif
468 Vector<uint32_t> color_formats;
469 ALOGD("index: %d, type: '%s'", index, type);
470-#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
471+#if ANDROID_VERSION_MAJOR==5
472+ MediaCodecList::getInstance()->getCodecInfo(index)->getCapabilitiesFor(type)->getSupportedProfileLevels(&profile_levels);
473+ MediaCodecList::getInstance()->getCodecInfo(index)->getCapabilitiesFor(type)->getSupportedColorFormats(&color_formats);
474+#elif ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
475 status_t err = MediaCodecList::getInstance()->getCodecCapabilities(index, type, &profile_levels, &color_formats);
476 #else
477 uint32_t flags;
478 status_t err = MediaCodecList::getInstance()->getCodecCapabilities(index, type, &profile_levels, &color_formats, &flags);
479 #endif
480+#if ANDROID_VERSION_MAJOR<5
481 if (err != OK)
482 {
483 ALOGE("Failed to get the number of supported codec capabilities (err: %d)", err);
484 return;
485 }
486+#endif
487
488 if (num_profile_levels != NULL)
489 {
490@@ -180,43 +213,63 @@ int media_codec_list_get_nth_codec_profile_level(size_t index, const char *type,
491 return BAD_VALUE;
492 }
493
494+#if ANDROID_VERSION_MAJOR==5
495+ Vector<MediaCodecInfo::ProfileLevel> profile_levels;
496+#else
497 Vector<MediaCodecList::ProfileLevel> profile_levels;
498+#endif
499 Vector<uint32_t> formats;
500-#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
501+#if ANDROID_VERSION_MAJOR==5
502+ MediaCodecList::getInstance()->getCodecInfo(index)->getCapabilitiesFor(type)->getSupportedProfileLevels(&profile_levels);
503+#elif ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
504 status_t err = MediaCodecList::getInstance()->getCodecCapabilities(index, type, &profile_levels, &formats);
505 #else
506 uint32_t flags;
507 status_t err = MediaCodecList::getInstance()->getCodecCapabilities(index, type, &profile_levels, &formats, &flags);
508 #endif
509+#if ANDROID_VERSION_MAJOR<5
510 if (err != OK)
511 {
512 ALOGE("Failed to get the nth codec profile level (err: %d)", err);
513 return 0;
514 }
515+#endif
516
517 pro_level->profile = profile_levels[n].mProfile;
518 pro_level->level = profile_levels[n].mLevel;
519
520+#if ANDROID_VERSION_MAJOR==5
521+ return OK;
522+#else
523 return err;
524+#endif
525 }
526
527 int media_codec_list_get_codec_color_formats(size_t index, const char *type, uint32_t *color_formats)
528 {
529 REPORT_FUNCTION()
530
531+#if ANDROID_VERSION_MAJOR==5
532+ Vector<MediaCodecInfo::ProfileLevel> profile_levels;
533+#else
534 Vector<MediaCodecList::ProfileLevel> profile_levels;
535+#endif
536 Vector<uint32_t> formats;
537-#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
538+#if ANDROID_VERSION_MAJOR==5
539+ MediaCodecList::getInstance()->getCodecInfo(index)->getCapabilitiesFor(type)->getSupportedColorFormats(&formats);
540+#elif ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
541 status_t err = MediaCodecList::getInstance()->getCodecCapabilities(index, type, &profile_levels, &formats);
542 #else
543 uint32_t flags;
544 status_t err = MediaCodecList::getInstance()->getCodecCapabilities(index, type, &profile_levels, &formats, &flags);
545 #endif
546+#if ANDROID_VERSION_MAJOR<5
547 if (err != OK)
548 {
549 ALOGE("Failed to get the number of supported codec types (err: %d)", err);
550 return 0;
551 }
552+#endif
553
554 for (size_t i=0; i<formats.size(); ++i)
555 {
556diff --git a/compat/media/media_compatibility_layer.cpp b/compat/media/media_compatibility_layer.cpp
557index 45922e3..bb86e5c 100644
558--- a/compat/media/media_compatibility_layer.cpp
559+++ b/compat/media/media_compatibility_layer.cpp
560@@ -87,7 +87,11 @@ struct FrameAvailableListener : public android::GLConsumer::FrameAvailableListen
561 }
562
563 // From android::GLConsumer/SurfaceTexture::FrameAvailableListener
564- void onFrameAvailable()
565+#if ANDROID_VERSION_MAJOR==5 && ANDROID_VERSION_MINOR>=1
566+ virtual void onFrameAvailable(const android::BufferItem& item)
567+#else
568+ virtual void onFrameAvailable()
569+#endif
570 {
571 if (set_video_texture_needs_update_cb != NULL)
572 set_video_texture_needs_update_cb(video_texture_needs_update_context);
573@@ -238,7 +242,9 @@ struct MediaPlayerWrapper : public android::MediaPlayer
574 source_fd = -1;
575 }
576
577-#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
578+#if ANDROID_VERSION_MAJOR==5
579+ android::status_t setVideoSurfaceTexture(android::sp<android::IGraphicBufferProducer> bq, const android::sp<android::GLConsumer> &surfaceTexture)
580+#elif ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
581 android::status_t setVideoSurfaceTexture(const android::sp<android::SurfaceTexture> &surfaceTexture)
582 #else
583 android::status_t setVideoSurfaceTexture(android::sp<android::BufferQueue> bq, const android::sp<android::GLConsumer> &surfaceTexture)
584@@ -443,7 +449,13 @@ int android_media_set_data_source(MediaPlayerWrapper *mp, const char* url)
585 String16 src(url);
586 if (src.startsWith(String16("http://")) == true) {
587 ALOGD("HTTP source URL detected");
588+#if 0 // remarked for future debugging - chunsang
589+#if ANDROID_VERSION_MAJOR==5
590+ mp->setDataSource(NULL,url, NULL);
591+#else
592 mp->setDataSource(url, NULL);
593+#endif
594+#endif
595 } else {
596 ALOGD("File source URL detected");
597 int fd = open(url, O_RDONLY);
598@@ -480,6 +492,11 @@ int android_media_set_preview_texture(MediaPlayerWrapper *mp, int texture_id)
599 new android::NativeBufferAlloc()
600 );
601
602+#if ANDROID_VERSION_MAJOR==5
603+ android::sp<IGraphicBufferProducer> producer;
604+ android::sp<IGraphicBufferConsumer> consumer;
605+ BufferQueue::createBufferQueue(&producer, &consumer);
606+#else
607 android::sp<android::BufferQueue> buffer_queue(
608 #if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
609 new android::BufferQueue(false, NULL, native_alloc)
610@@ -487,17 +504,28 @@ int android_media_set_preview_texture(MediaPlayerWrapper *mp, int texture_id)
611 new android::BufferQueue(NULL)
612 #endif
613 );
614+#endif
615
616 static const bool allow_synchronous_mode = true;
617 // Create a new GLConsumer/SurfaceTexture from the texture_id in synchronous mode (don't wait on all data in the buffer)
618-#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
619+#if ANDROID_VERSION_MAJOR==5
620+ mp->setVideoSurfaceTexture(producer, android::sp<android::GLConsumer>(
621+ new android::GLConsumer(
622+#elif ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
623 mp->setVideoSurfaceTexture(android::sp<android::SurfaceTexture>(
624 new android::SurfaceTexture(
625 #else
626 mp->setVideoSurfaceTexture(buffer_queue, android::sp<android::GLConsumer>(
627 new android::GLConsumer(
628 #endif
629-#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
630+#if ANDROID_VERSION_MAJOR==5
631+ consumer,
632+ texture_id,
633+ GL_TEXTURE_EXTERNAL_OES,
634+ true,
635+ false)));
636+
637+#elif ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
638 texture_id,
639 allow_synchronous_mode,
640 GL_TEXTURE_EXTERNAL_OES,
641diff --git a/compat/media/media_recorder_client.cpp b/compat/media/media_recorder_client.cpp
642index 717ea1d..896bec8 100644
643--- a/compat/media/media_recorder_client.cpp
644+++ b/compat/media/media_recorder_client.cpp
645@@ -254,6 +254,18 @@ status_t MediaRecorderClient::stop()
646 return recorder->stop();
647 }
648
649+status_t MediaRecorderClient::pause()
650+{
651+ REPORT_FUNCTION();
652+ Mutex::Autolock lock(recorder_lock);
653+ if (recorder == NULL) {
654+ ALOGE("recorder must not be NULL");
655+ return NO_INIT;
656+ }
657+ return recorder->pause();
658+
659+}
660+
661 status_t MediaRecorderClient::reset()
662 {
663 REPORT_FUNCTION();
664diff --git a/compat/media/media_recorder_client.h b/compat/media/media_recorder_client.h
665index c9e8635..d5c3eb6 100644
666--- a/compat/media/media_recorder_client.h
667+++ b/compat/media/media_recorder_client.h
668@@ -60,6 +60,7 @@ public:
669 virtual status_t getMaxAmplitude(int* max);
670 virtual status_t start();
671 virtual status_t stop();
672+ virtual status_t pause();
673 virtual status_t reset();
674 virtual status_t init();
675 virtual status_t close();
676diff --git a/compat/media/surface_texture_client_hybris.cpp b/compat/media/surface_texture_client_hybris.cpp
677index cef620f..dfd3138 100644
678--- a/compat/media/surface_texture_client_hybris.cpp
679+++ b/compat/media/surface_texture_client_hybris.cpp
680@@ -68,7 +68,15 @@ _SurfaceTextureClientHybris::_SurfaceTextureClientHybris()
681 }
682 #endif
683
684-#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR>=4
685+#if ANDROID_VERSION_MAJOR==5
686+_SurfaceTextureClientHybris::_SurfaceTextureClientHybris(const sp<IGraphicBufferProducer> &st)
687+ : Surface::Surface(st, true),
688+ refcount(1),
689+ ready(false)
690+{
691+ REPORT_FUNCTION()
692+}
693+#elif ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR>=4
694 _SurfaceTextureClientHybris::_SurfaceTextureClientHybris(const sp<BufferQueue> &bq)
695 : Surface::Surface(bq, true),
696 refcount(1),
697@@ -210,8 +218,13 @@ SurfaceTextureClientHybris surface_texture_client_create_by_id(unsigned int text
698 ALOGE("Cannot create new SurfaceTextureClientHybris, texture id must be > 0.");
699 return NULL;
700 }
701+#if ANDROID_VERSION_MAJOR==5
702+ sp<IGraphicBufferProducer> producer;
703+ sp<IGraphicBufferConsumer> consumer;
704+ BufferQueue::createBufferQueue(&producer, &consumer);
705
706-#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
707+ _SurfaceTextureClientHybris *stch(new _SurfaceTextureClientHybris(producer));
708+#elif ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
709 // Use a new native buffer allocator vs the default one, which means it'll use the proper one
710 // that will allow rendering to work with Mir
711 sp<NativeBufferAlloc> native_alloc(new NativeBufferAlloc());
712@@ -229,7 +242,9 @@ SurfaceTextureClientHybris surface_texture_client_create_by_id(unsigned int text
713 stch->surface_texture.clear();
714
715 const bool allow_synchronous_mode = true;
716-#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
717+#if ANDROID_VERSION_MAJOR==5
718+ stch->surface_texture = new GLConsumer(consumer, texture_id, GL_TEXTURE_EXTERNAL_OES, true, true);
719+#elif ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
720 stch->surface_texture = new SurfaceTexture(texture_id, allow_synchronous_mode, GL_TEXTURE_EXTERNAL_OES, true, buffer_queue);
721 set_surface(stch, stch->surface_texture);
722 #else
723diff --git a/compat/media/surface_texture_client_hybris_priv.h b/compat/media/surface_texture_client_hybris_priv.h
724index f59e841..189dca6 100644
725--- a/compat/media/surface_texture_client_hybris_priv.h
726+++ b/compat/media/surface_texture_client_hybris_priv.h
727@@ -89,7 +89,11 @@ class _GLConsumerHybris : public GLConsumer
728 {
729 }
730
731+#if ANDROID_VERSION_MAJOR==5 && ANDROID_VERSION_MINOR>=1
732+ virtual void onFrameAvailable(const android::BufferItem& item)
733+#else
734 virtual void onFrameAvailable()
735+#endif
736 {
737 if (frame_available_cb != NULL)
738 frame_available_cb(glc_wrapper, context);
739diff --git a/compat/surface_flinger/Android.mk b/compat/surface_flinger/Android.mk
740index f3ced66..666a298 100644
741--- a/compat/surface_flinger/Android.mk
742+++ b/compat/surface_flinger/Android.mk
743@@ -1,5 +1,6 @@
744 LOCAL_PATH := $(call my-dir)
745 include $(CLEAR_VARS)
746+include $(LOCAL_PATH)/../Android.common.mk
747
748 HYBRIS_PATH := $(LOCAL_PATH)/../../hybris
749
750diff --git a/compat/surface_flinger/surface_flinger_compatibility_layer.cpp b/compat/surface_flinger/surface_flinger_compatibility_layer.cpp
751index fa1c519..90249e6 100644
752--- a/compat/surface_flinger/surface_flinger_compatibility_layer.cpp
753+++ b/compat/surface_flinger/surface_flinger_compatibility_layer.cpp
754@@ -28,6 +28,9 @@
755 #include <ui/PixelFormat.h>
756 #include <ui/Region.h>
757 #include <ui/Rect.h>
758+#if ANDROID_VERSION_MAJOR==5
759+ #include <hardware/hwcomposer_defs.h>
760+#endif
761
762 #include <cassert>
763 #include <cstdio>
764@@ -80,7 +83,11 @@ void sf_blank(size_t display_id)
765 return;
766 }
767
768+#if ANDROID_VERSION_MAJOR<=4
769 android::SurfaceComposerClient::blankDisplay(display);
770+#elif ANDROID_VERSION_MAJOR==5
771+ android::SurfaceComposerClient::setDisplayPowerMode(display, HWC_POWER_MODE_OFF);
772+#endif
773 }
774
775 void sf_unblank(size_t display_id)
776@@ -98,7 +105,11 @@ void sf_unblank(size_t display_id)
777 return;
778 }
779
780+#if ANDROID_VERSION_MAJOR<=4
781 android::SurfaceComposerClient::unblankDisplay(display);
782+#elif ANDROID_VERSION_MAJOR==5
783+ android::SurfaceComposerClient::setDisplayPowerMode(display, HWC_POWER_MODE_NORMAL);
784+#endif
785 }
786
787 size_t sf_get_display_width(size_t display_id)
788diff --git a/debian/changelog b/debian/changelog
789index a347f90..c14408a 100644
790--- a/debian/changelog
791+++ b/debian/changelog
792@@ -1,3 +1,18 @@
793+libhybris (0.1.0+git20151016+6d424c9-0ubuntu1) vivid; urgency=medium
794+
795+ [ Ricardo Salveti de Araujo ]
796+ * New upstream snapshot:
797+ - Rebasing patches and removing the ones that are already available in
798+ upstream
799+
800+ [ Alex Tu ]
801+ * Fix Build error.
802+
803+ [ Simon Fels ]
804+ * Merge with upstream and rebased chagnes
805+
806+ -- Simon Fels <simon.fels@canonical.com> Fri, 16 Oct 2015 09:14:11 +0200
807+
808 libhybris (0.1.0+git20131207+e452e83-0ubuntu39) vivid; urgency=medium
809
810 * linker: adding dl_iterate_phdr for ARM (required by Android 5 blobs)
811diff --git a/debian/copyright b/debian/copyright
812index 23dd030..e5f5612 100644
813--- a/debian/copyright
814+++ b/debian/copyright
815@@ -10,7 +10,7 @@ Files: compat/ui/* hybris/egl/eglhybris.h hybris/hardware/hardware.c hybris/incl
816 Copyright: 2012-2013 Simon Busch <morphis@gravedo.de>
817 License: Apache 2.0
818
819-Files: hybris/include/hybris/internal/binding.h
820+Files: hybris/include/hybris/common/binding.h
821 Copyright: 2013 Simon Busch <morphis@gravedo.de>
822 2012 Canonical Ltd
823 License: Apache 2.0
824diff --git a/debian/libhybris-dev.install b/debian/libhybris-dev.install
825index 6cb42b5..904c145 100644
826--- a/debian/libhybris-dev.install
827+++ b/debian/libhybris-dev.install
828@@ -3,15 +3,21 @@ usr/lib/*/libhybris-hwcomposerwindow.so
829 usr/lib/*/libsync.so
830 usr/lib/*/libui.so
831 usr/lib/*/libsf.so
832+usr/lib/*/libvibrator.so
833 usr/lib/*/libis.so
834 usr/lib/*/libcamera.so
835 usr/lib/*/libwifi.so
836+usr/lib/*/libnfc_nxp.so
837+usr/lib/*/libvibrator.so
838 usr/lib/*/pkgconfig/hwcomposer-egl.pc
839 usr/lib/*/pkgconfig/hybris-egl-platform.pc
840 usr/lib/*/pkgconfig/libis.pc
841 usr/lib/*/pkgconfig/libcamera.pc
842 usr/lib/*/pkgconfig/libwifi.pc
843+usr/lib/*/pkgconfig/libvibrator.pc
844+usr/lib/*/pkgconfig/libnfc_nxp.pc
845 usr/lib/*/pkgconfig/libsf.pc
846+usr/lib/*/pkgconfig/libvibrator.pc
847 usr/lib/*/pkgconfig/libsync.pc
848 usr/include/hybris/input
849 usr/include/hybris/camera
850diff --git a/debian/libhybris.install.in b/debian/libhybris.install.in
851index d7a3157..8ce2e41 100644
852--- a/debian/libhybris.install.in
853+++ b/debian/libhybris.install.in
854@@ -3,9 +3,12 @@ usr/lib/*/libhybris-hwcomposerwindow.so.*
855 usr/lib/*/libsync.so.*
856 usr/lib/*/libui.so.*
857 usr/lib/*/libsf.so.*
858+usr/lib/*/libvibrator.so.*
859 usr/lib/*/libis.so.*
860 usr/lib/*/libcamera.so.*
861 usr/lib/*/libwifi.so.*
862+usr/lib/*/libnfc_nxp.so.*
863+usr/lib/*/libvibrator.so.*
864 usr/lib/*/libhybris/*.so
865 usr/lib/*/libwayland-egl.so.* #PKGLIBDIR#
866 usr/lib/*/libEGL.so.* #PKGLIBDIR#
867diff --git a/hybris/Makefile.am b/hybris/Makefile.am
868index 735a40c..906140e 100644
869--- a/hybris/Makefile.am
870+++ b/hybris/Makefile.am
871@@ -3,8 +3,11 @@ SUBDIRS = include properties common hardware
872 if HAS_ANDROID_4_2_0
873 SUBDIRS += libsync
874 endif
875+if HAS_ANDROID_5_0_0
876+SUBDIRS += libsync
877+endif
878+SUBDIRS += egl glesv1 glesv2 ui sf input camera vibrator media wifi
879
880-SUBDIRS += egl glesv1 glesv2 ui sf input camera media wifi
881 if HAS_LIBNFC_NXP_HEADERS
882 SUBDIRS += libnfc_nxp libnfc_ndef_nxp
883 endif
884diff --git a/hybris/camera/Makefile.am b/hybris/camera/Makefile.am
885index 14ad97e..63aec2e 100644
886--- a/hybris/camera/Makefile.am
887+++ b/hybris/camera/Makefile.am
888@@ -2,7 +2,7 @@ lib_LTLIBRARIES = \
889 libcamera.la
890
891 libcamera_la_SOURCES = camera.c
892-libcamera_la_CFLAGS = -I$(top_srcdir)/include
893+libcamera_la_CFLAGS = -I$(top_srcdir)/include $(ANDROID_HEADERS_CFLAGS)
894 if WANT_TRACE
895 libcamera_la_CFLAGS += -DDEBUG
896 endif
897diff --git a/hybris/camera/camera.c b/hybris/camera/camera.c
898index ce4046d..41071a1 100644
899--- a/hybris/camera/camera.c
900+++ b/hybris/camera/camera.c
901@@ -17,10 +17,11 @@
902 * Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
903 */
904
905+#include <android-config.h>
906 #include <dlfcn.h>
907 #include <stddef.h>
908
909-#include <hybris/internal/binding.h>
910+#include <hybris/common/binding.h>
911 #include <hybris/camera/camera_compatibility_layer.h>
912 #include <hybris/camera/camera_compatibility_layer_capabilities.h>
913 #include <hybris/surface_flinger/surface_flinger_compatibility_layer.h>
914diff --git a/hybris/common/Makefile.am b/hybris/common/Makefile.am
915index bdb1845..2c795b3 100644
916--- a/hybris/common/Makefile.am
917+++ b/hybris/common/Makefile.am
918@@ -6,11 +6,16 @@ if HAS_ANDROID_4_0_0
919 SUBDIRS = jb
920 libhybris_common_la_LIBADD= jb/libandroid-linker.la
921 else
922+if HAS_ANDROID_5_0_0
923+SUBDIRS = jb
924+libhybris_common_la_LIBADD= jb/libandroid-linker.la
925+else
926 if HAS_ANDROID_2_3_0
927 SUBDIRS = gingerbread
928 libhybris_common_la_LIBADD= gingerbread/libandroid-linker.la
929 else
930-ERROR
931+$(error No Android Version is defined)
932+endif
933 endif
934 endif
935
936@@ -23,6 +28,7 @@ libhybris_common_la_SOURCES = \
937 sysconf.c
938 libhybris_common_la_CFLAGS = \
939 -I$(top_srcdir)/include \
940+ $(ANDROID_HEADERS_CFLAGS) \
941 -I$(top_srcdir)/common
942 if WANT_TRACE
943 libhybris_common_la_CFLAGS += -DDEBUG
944diff --git a/hybris/common/dlfcn.c b/hybris/common/dlfcn.c
945index 80601fd..0ddc41e 100644
946--- a/hybris/common/dlfcn.c
947+++ b/hybris/common/dlfcn.c
948@@ -16,7 +16,7 @@
949 */
950
951 #include <../include/hybris/dlfcn/dlfcn.h>
952-#include <../include/hybris/internal/binding.h>
953+#include <../include/hybris/common/binding.h>
954
955 void *hybris_dlopen(const char *filename, int flag)
956 {
957diff --git a/hybris/common/gingerbread/Makefile.am b/hybris/common/gingerbread/Makefile.am
958index 92f81c5..f265879 100644
959--- a/hybris/common/gingerbread/Makefile.am
960+++ b/hybris/common/gingerbread/Makefile.am
961@@ -16,6 +16,7 @@ libandroid_linker_la_SOURCES = \
962 rt.c
963 libandroid_linker_la_CFLAGS = \
964 -I$(top_srcdir)/include \
965+ $(ANDROID_HEADERS_CFLAGS) \
966 -I$(top_srcdir)/common \
967 -DLINKER_TEXT_BASE=0xB0000100 \
968 -DLINKER_AREA_SIZE=0x01000000 \
969diff --git a/hybris/common/hooks.c b/hybris/common/hooks.c
970index 84f841e..78c9a02 100644
971--- a/hybris/common/hooks.c
972+++ b/hybris/common/hooks.c
973@@ -17,7 +17,7 @@
974 *
975 */
976
977-#include <hybris/internal/floating_point_abi.h>
978+#include <hybris/common/binding.h>
979
980 #include "hooks_shm.h"
981
982@@ -33,15 +33,17 @@
983 #include <strings.h>
984 #include <dlfcn.h>
985 #include <pthread.h>
986+#include <sys/xattr.h>
987+#include <grp.h>
988 #include <signal.h>
989 #include <errno.h>
990 #include <dirent.h>
991 #include <sys/types.h>
992-#include <sys/xattr.h>
993-#include <grp.h>
994+#include <stdarg.h>
995
996 #include <sys/ipc.h>
997 #include <sys/shm.h>
998+#include <fcntl.h>
999
1000 #include <linux/futex.h>
1001 #include <sys/syscall.h>
1002@@ -51,6 +53,8 @@
1003 #include <unistd.h>
1004 #include <syslog.h>
1005 #include <locale.h>
1006+#include <sys/syscall.h>
1007+#include <sys/auxv.h>
1008
1009 #include <hybris/properties/properties.h>
1010
1011@@ -245,6 +249,11 @@ static size_t my_strlen(const char *s)
1012 return strlen(s);
1013 }
1014
1015+static pid_t my_gettid( void )
1016+{
1017+ return syscall( __NR_gettid );
1018+}
1019+
1020 /*
1021 * Main pthread functions
1022 *
1023@@ -559,7 +568,6 @@ static int my_pthread_mutex_lock_timeout_np(pthread_mutex_t *__mutex, unsigned _
1024 *((int *)__mutex) = (int) realmutex;
1025 }
1026
1027- /* TODO: Android uses CLOCK_MONOTONIC here but I am not sure which one to use */
1028 clock_gettime(CLOCK_REALTIME, &tv);
1029 tv.tv_sec += __msecs/1000;
1030 tv.tv_nsec += (__msecs % 1000) * 1000000;
1031@@ -776,7 +784,6 @@ static int my_pthread_cond_timedwait_relative_np(pthread_cond_t *cond,
1032 *((unsigned int *) mutex) = (unsigned int) realmutex;
1033 }
1034
1035- /* TODO: Android uses CLOCK_MONOTONIC here but I am not sure which one to use */
1036 struct timespec tv;
1037 clock_gettime(CLOCK_REALTIME, &tv);
1038 tv.tv_sec += reltime->tv_sec;
1039@@ -1239,39 +1246,77 @@ static int my_setlinebuf(FILE *fp)
1040 return 0;
1041 }
1042
1043-static inline void swap(void **a, void **b)
1044-{
1045- void *tmp = *a;
1046- *a = *b;
1047- *b = tmp;
1048-}
1049+/* "struct dirent" from bionic/libc/include/dirent.h */
1050+struct bionic_dirent {
1051+ uint64_t d_ino;
1052+ int64_t d_off;
1053+ unsigned short d_reclen;
1054+ unsigned char d_type;
1055+ char d_name[256];
1056+};
1057
1058-static int my_getaddrinfo(const char *hostname, const char *servname,
1059- const struct addrinfo *hints, struct addrinfo **res)
1060+static struct bionic_dirent *my_readdir(DIR *dirp)
1061 {
1062- // make a local copy of hints
1063- struct addrinfo *fixed_hints = (struct addrinfo*)malloc(sizeof(struct addrinfo));
1064- memcpy(fixed_hints, hints, sizeof(struct addrinfo));
1065- // fix bionic -> glibc missmatch
1066- swap((void**)&(fixed_hints->ai_canonname), (void**)&(fixed_hints->ai_addr));
1067- // do glibc getaddrinfo
1068- int result = getaddrinfo(hostname, servname, fixed_hints, res);
1069- // release the copy of hints
1070- free(fixed_hints);
1071- // fix bionic <- glibc missmatch
1072- struct addrinfo *it = *res;
1073- while(NULL != it)
1074- {
1075- swap((void**)&(it->ai_canonname), (void**)&(it->ai_addr));
1076- it = it->ai_next;
1077+ /**
1078+ * readdir(3) manpage says:
1079+ * The data returned by readdir() may be overwritten by subsequent calls
1080+ * to readdir() for the same directory stream.
1081+ *
1082+ * XXX: At the moment, for us, the data will be overwritten even by
1083+ * subsequent calls to /different/ directory streams. Eventually fix that
1084+ * (e.g. by storing per-DIR * bionic_dirent structs, and removing them on
1085+ * closedir, requires hooking of all funcs returning/taking DIR *) and
1086+ * handling the additional data attachment there)
1087+ **/
1088+
1089+ static struct bionic_dirent result;
1090+
1091+ struct dirent *real_result = readdir(dirp);
1092+ if (!real_result) {
1093+ return NULL;
1094 }
1095- return result;
1096+
1097+ result.d_ino = real_result->d_ino;
1098+ result.d_off = real_result->d_off;
1099+ result.d_reclen = real_result->d_reclen;
1100+ result.d_type = real_result->d_type;
1101+ memcpy(result.d_name, real_result->d_name, sizeof(result.d_name));
1102+
1103+ // Make sure the string is zero-terminated, even if cut off (which
1104+ // shouldn't happen, as both bionic and glibc have d_name defined
1105+ // as fixed array of 256 chars)
1106+ result.d_name[sizeof(result.d_name)-1] = '\0';
1107+ return &result;
1108 }
1109
1110-static void my_freeaddrinfo(struct addrinfo *__ai)
1111+static int my_readdir_r(DIR *dir, struct bionic_dirent *entry,
1112+ struct bionic_dirent **result)
1113 {
1114- swap((void**)&(__ai->ai_canonname), (void**)&(__ai->ai_addr));
1115- freeaddrinfo(__ai);
1116+ struct dirent entry_r;
1117+ struct dirent *result_r;
1118+
1119+ int res = readdir_r(dir, &entry_r, &result_r);
1120+
1121+ if (res == 0) {
1122+ if (result_r != NULL) {
1123+ *result = entry;
1124+
1125+ entry->d_ino = entry_r.d_ino;
1126+ entry->d_off = entry_r.d_off;
1127+ entry->d_reclen = entry_r.d_reclen;
1128+ entry->d_type = entry_r.d_type;
1129+ memcpy(entry->d_name, entry_r.d_name, sizeof(entry->d_name));
1130+
1131+ // Make sure the string is zero-terminated, even if cut off (which
1132+ // shouldn't happen, as both bionic and glibc have d_name defined
1133+ // as fixed array of 256 chars)
1134+ entry->d_name[sizeof(entry->d_name) - 1] = '\0';
1135+ } else {
1136+ *result = NULL;
1137+ }
1138+ }
1139+
1140+ return res;
1141 }
1142
1143 extern long my_sysconf(int name);
1144@@ -1291,11 +1336,6 @@ static int __my_system_property_read(const void *pi, char *name, char *value)
1145 return property_get(name, value, NULL);
1146 }
1147
1148-static int __my_system_property_get(const char *name, char *value)
1149-{
1150- return property_get(name, value, NULL);
1151-}
1152-
1153 static int __my_system_property_foreach(void (*propfn)(const void *pi, void *cookie), void *cookie)
1154 {
1155 return 0;
1156@@ -1337,10 +1377,71 @@ static const void *__my_system_property_find_nth(unsigned n)
1157 }
1158
1159 extern int __cxa_atexit(void (*)(void*), void*, void*);
1160+extern void __cxa_finalize(void * d);
1161+
1162+struct open_redirect {
1163+ const char *from;
1164+ const char *to;
1165+};
1166+
1167+struct open_redirect open_redirects[] = {
1168+ { "/dev/log/main", "/dev/alog/main" },
1169+ { "/dev/log/radio", "/dev/alog/radio" },
1170+ { "/dev/log/system", "/dev/alog/system" },
1171+ { "/dev/log/events", "/dev/alog/events" },
1172+ { NULL, NULL }
1173+};
1174+
1175+int my_open(const char *pathname, int flags, ...)
1176+{
1177+ va_list ap;
1178+ mode_t mode = 0;
1179+ const char *target_path = pathname;
1180+
1181+ if (pathname != NULL) {
1182+ struct open_redirect *entry = &open_redirects[0];
1183+ while (entry->from != NULL) {
1184+ if (strcmp(pathname, entry->from) == 0) {
1185+ target_path = entry->to;
1186+ break;
1187+ }
1188+ entry++;
1189+ }
1190+ }
1191+
1192+ if (flags & O_CREAT) {
1193+ va_start(ap, flags);
1194+ mode = va_arg(ap, mode_t);
1195+ va_end(ap);
1196+ }
1197+
1198+ return open(target_path, flags, mode);
1199+}
1200+
1201+/**
1202+ * NOTE: Normally we don't have to wrap __system_property_get (libc.so) as it is only used
1203+ * through the property_get (libcutils.so) function. However when property_get is used
1204+ * internally in libcutils.so we don't have any chance to hook our replacement in.
1205+ * Therefore we have to hook __system_property_get too and just replace it with the
1206+ * implementation of our internal property handling
1207+ */
1208+
1209+int my_system_property_get(const char *name, const char *value)
1210+{
1211+ return property_get(name, value, NULL);
1212+}
1213+
1214+static __thread void *tls_hooks[16];
1215+
1216+void *__get_tls_hooks()
1217+{
1218+ return tls_hooks;
1219+}
1220
1221 static struct _hook hooks[] = {
1222 {"property_get", property_get },
1223 {"property_set", property_set },
1224+ {"__system_property_get", my_system_property_get },
1225 {"getenv", getenv },
1226 {"printf", printf },
1227 {"malloc", my_malloc },
1228@@ -1408,6 +1509,9 @@ static struct _hook hooks[] = {
1229 {"opendir", opendir},
1230 {"closedir", closedir},
1231 /* pthread.h */
1232+ {"getauxval", getauxval},
1233+ {"gettid", my_gettid},
1234+ {"getpid", getpid},
1235 {"pthread_atfork", pthread_atfork},
1236 {"pthread_create", my_pthread_create},
1237 {"pthread_kill", pthread_kill},
1238@@ -1541,14 +1645,32 @@ static struct _hook hooks[] = {
1239 {"__errno", __errno_location},
1240 {"__set_errno", my_set_errno},
1241 /* net specifics, to avoid __res_get_state */
1242- {"getaddrinfo", my_getaddrinfo},
1243- {"freeaddrinfo", my_freeaddrinfo},
1244+ {"getaddrinfo", getaddrinfo},
1245 {"gethostbyaddr", gethostbyaddr},
1246 {"gethostbyname", gethostbyname},
1247 {"gethostbyname2", gethostbyname2},
1248 {"gethostent", gethostent},
1249 {"strftime", strftime},
1250 {"sysconf", my_sysconf},
1251+ {"dlopen", android_dlopen},
1252+ {"dlerror", android_dlerror},
1253+ {"dlsym", android_dlsym},
1254+ {"dladdr", android_dladdr},
1255+ {"dlclose", android_dlclose},
1256+ /* dirent.h */
1257+ {"opendir", opendir},
1258+ {"fdopendir", fdopendir},
1259+ {"closedir", closedir},
1260+ {"readdir", my_readdir},
1261+ {"readdir_r", my_readdir_r},
1262+ {"rewinddir", rewinddir},
1263+ {"seekdir", seekdir},
1264+ {"telldir", telldir},
1265+ {"dirfd", dirfd},
1266+ /* fcntl.h */
1267+ {"open", my_open},
1268+ // TODO: scandir, scandirat, alphasort, versionsort
1269+ {"__get_tls_hooks", __get_tls_hooks},
1270 {"sscanf", sscanf},
1271 {"scanf", scanf},
1272 {"vscanf", vscanf},
1273@@ -1569,8 +1691,8 @@ static struct _hook hooks[] = {
1274 /* grp.h */
1275 {"getgrgid", getgrgid},
1276 {"__cxa_atexit", __cxa_atexit},
1277+ {"__cxa_finalize", __cxa_finalize},
1278 {"__system_property_read", __my_system_property_read},
1279- {"__system_property_get", __my_system_property_get},
1280 {"__system_property_set", property_set},
1281 {"__system_property_foreach", __my_system_property_foreach},
1282 {"__system_property_find", __my_system_property_find},
1283diff --git a/hybris/common/ics/Makefile.am b/hybris/common/ics/Makefile.am
1284index bba1b2b..de4bdad 100644
1285--- a/hybris/common/ics/Makefile.am
1286+++ b/hybris/common/ics/Makefile.am
1287@@ -16,6 +16,7 @@ libandroid_linker_la_SOURCES = \
1288 rt.c
1289 libandroid_linker_la_CFLAGS = \
1290 -I$(top_srcdir)/include \
1291+ $(ANDROID_HEADERS_CFLAGS)\
1292 -I$(top_srcdir)/common \
1293 -DLINKER_TEXT_BASE=0xB0000100 \
1294 -DLINKER_AREA_SIZE=0x01000000 \
1295diff --git a/hybris/common/jb/Makefile.am b/hybris/common/jb/Makefile.am
1296index 142bc82..c95ea22 100644
1297--- a/hybris/common/jb/Makefile.am
1298+++ b/hybris/common/jb/Makefile.am
1299@@ -16,6 +16,7 @@ libandroid_linker_la_SOURCES = \
1300 rt.c
1301 libandroid_linker_la_CFLAGS = \
1302 -I$(top_srcdir)/include \
1303+ $(ANDROID_HEADERS_CFLAGS) \
1304 -I$(top_srcdir)/common \
1305 -D_GNU_SOURCE \
1306 -DLINKER_TEXT_BASE=0xB0000100 \
1307diff --git a/hybris/common/jb/dlfcn.c b/hybris/common/jb/dlfcn.c
1308index 96c2478..9e39889 100644
1309--- a/hybris/common/jb/dlfcn.c
1310+++ b/hybris/common/jb/dlfcn.c
1311@@ -180,7 +180,6 @@ _Unwind_Ptr android_dl_unwind_find_exidx(_Unwind_Ptr pc, int *pcount);
1312 // 0123456 78901234 567890 12345678 9012345 6789012345678901
1313 #define ANDROID_LIBDL_STRTAB \
1314 "dlopen\0dlclose\0dlsym\0dlerror\0dladdr\0dl_iterate_phdr\0"
1315-
1316 #elif defined(ANDROID_SH_LINKER)
1317 // 0000000 00011111 111112 22222222 2333333 3333444444444455
1318 // 0123456 78901234 567890 12345678 9012345 6789012345678901
1319@@ -258,7 +257,7 @@ static Elf_Sym libdl_symtab[] = {
1320 * stubbing them out in libdl.
1321 */
1322 static unsigned libdl_buckets[1] = { 1 };
1323-#ifdef ANDROID_ARM_LINKER
1324+#if defined(ANDROID_ARM_LINKER)
1325 static unsigned libdl_chains[8] = { 0, 2, 3, 4, 5, 6, 7, 0 };
1326 #else
1327 static unsigned libdl_chains[7] = { 0, 2, 3, 4, 5, 6, 0 };
1328@@ -271,6 +270,7 @@ soinfo libdl_info = {
1329 strtab: ANDROID_LIBDL_STRTAB,
1330 symtab: libdl_symtab,
1331
1332+ refcount: 1,
1333 nbucket: sizeof(libdl_buckets)/sizeof(unsigned),
1334 nchain: sizeof(libdl_chains)/sizeof(unsigned),
1335 bucket: libdl_buckets,
1336diff --git a/hybris/common/jb/linker.c b/hybris/common/jb/linker.c
1337index 1d723f6..20333db 100644
1338--- a/hybris/common/jb/linker.c
1339+++ b/hybris/common/jb/linker.c
1340@@ -358,7 +358,6 @@ _Unwind_Ptr android_dl_unwind_find_exidx(_Unwind_Ptr pc, int *pcount)
1341 return NULL;
1342 }
1343 #endif
1344-
1345 /* Here, we only have to provide a callback to iterate across all the
1346 * loaded libraries. gcc_eh does the rest. */
1347 int
1348@@ -1340,7 +1339,7 @@ static int reloc_library(soinfo *si, Elf_Rel *rel, unsigned count)
1349 /* We only allow an undefined symbol if this is a weak
1350 reference.. */
1351 s = &symtab[sym];
1352- if (ELF32_ST_BIND(s->st_info) != STB_WEAK) {
1353+ if (ELF32_ST_BIND(s->st_info) != STB_WEAK && strcmp(si->name, "libdsyscalls.so") != 0) {
1354 DL_ERR("%5d cannot locate '%s'...\n", pid, sym_name);
1355 return -1;
1356 }
1357diff --git a/hybris/common/logging.c b/hybris/common/logging.c
1358index 2683136..0c4c79b 100644
1359--- a/hybris/common/logging.c
1360+++ b/hybris/common/logging.c
1361@@ -23,6 +23,7 @@
1362 #include <string.h>
1363 #include <stdio.h>
1364 #include <pthread.h>
1365+#include <time.h>
1366
1367 FILE *hybris_logging_target = NULL;
1368
1369@@ -109,6 +110,17 @@ hybris_get_thread_id()
1370 return (void *)pthread_self();
1371 }
1372
1373+double
1374+hybris_get_thread_time()
1375+{
1376+ struct timespec now;
1377+ if(clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now) == 0) {
1378+ return (double)now.tv_sec + (double)now.tv_nsec / 1000000000.0;
1379+ } else {
1380+ return -1.0;
1381+ }
1382+}
1383+
1384 int
1385 hybris_should_trace(const char *module, const char *tracepoint)
1386 {
1387diff --git a/hybris/common/logging.h b/hybris/common/logging.h
1388index 146eb6e..f4841b9 100644
1389--- a/hybris/common/logging.h
1390+++ b/hybris/common/logging.h
1391@@ -69,6 +69,9 @@ hybris_set_log_level(enum hybris_log_level level);
1392 void *
1393 hybris_get_thread_id();
1394
1395+double
1396+hybris_get_thread_time();
1397+
1398 enum hybris_log_format hybris_logging_format();
1399
1400 int hybris_should_trace(const char *module, const char *tracepoint);
1401@@ -93,13 +96,13 @@ extern FILE *hybris_logging_target;
1402 ##__VA_ARGS__); \
1403 fflush(hybris_logging_target); \
1404 } else if (hybris_logging_format() == HYBRIS_LOG_FORMAT_SYSTRACE) { \
1405- fprintf(hybris_logging_target, "B|%i|%s(%s) %s:%d (%s) " message "\n", \
1406- getpid(), module, __PRETTY_FUNCTION__, __FILE__, __LINE__, \
1407+ fprintf(hybris_logging_target, "B|%i|%.9f|%s(%s) %s:%d (%s) " message "\n", \
1408+ getpid(), hybris_get_thread_time(), module, __PRETTY_FUNCTION__, __FILE__, __LINE__, \
1409 #level + 11 /* + 11 = strip leading "HYBRIS_LOG_" */, \
1410 ##__VA_ARGS__); \
1411 fflush(hybris_logging_target); \
1412- fprintf(hybris_logging_target, "E|%i|%s(%s) %s:%d (%s) " message "\n", \
1413- getpid(), module, __PRETTY_FUNCTION__, __FILE__, __LINE__, \
1414+ fprintf(hybris_logging_target, "E|%i|%.9f|%s(%s) %s:%d (%s) " message "\n", \
1415+ getpid(), hybris_get_thread_time(), module, __PRETTY_FUNCTION__, __FILE__, __LINE__, \
1416 #level + 11 /* + 11 = strip leading "HYBRIS_LOG_" */, \
1417 ##__VA_ARGS__); \
1418 fflush(hybris_logging_target); \
1419@@ -113,19 +116,19 @@ extern FILE *hybris_logging_target;
1420 pthread_mutex_lock(&hybris_logging_mutex); \
1421 if (hybris_logging_format() == HYBRIS_LOG_FORMAT_NORMAL) \
1422 { \
1423- fprintf(hybris_logging_target, "PID: %i Tracepoint-%c/%s::%s" message "\n", \
1424- getpid(), what, tracepoint, module, \
1425+ fprintf(hybris_logging_target, "PID: %i TTIME: %.9f Tracepoint-%c/%s::%s" message "\n", \
1426+ getpid(), hybris_get_thread_time(), what, tracepoint, module, \
1427 ##__VA_ARGS__); \
1428 fflush(hybris_logging_target); \
1429 } else if (hybris_logging_format() == HYBRIS_LOG_FORMAT_SYSTRACE) { \
1430 if (what == 'B') \
1431- fprintf(hybris_logging_target, "B|%i|%s::%s" message "", \
1432- getpid(), tracepoint, module, ##__VA_ARGS__); \
1433+ fprintf(hybris_logging_target, "B|%i|%.9f|%s::%s" message "", \
1434+ getpid(), hybris_get_thread_time(), tracepoint, module, ##__VA_ARGS__); \
1435 else if (what == 'E') \
1436 fprintf(hybris_logging_target, "E"); \
1437 else \
1438- fprintf(hybris_logging_target, "C|%i|%s::%s-%i|" message "", \
1439- getpid(), tracepoint, module, getpid(), ##__VA_ARGS__); \
1440+ fprintf(hybris_logging_target, "C|%i|%.9f|%s::%s-%i|" message "", \
1441+ getpid(), hybris_get_thread_time(), tracepoint, module, getpid(), ##__VA_ARGS__); \
1442 fflush(hybris_logging_target); \
1443 } \
1444 pthread_mutex_unlock(&hybris_logging_mutex); \
1445diff --git a/hybris/configure.ac b/hybris/configure.ac
1446index fef76b9..692d0fc 100644
1447--- a/hybris/configure.ac
1448+++ b/hybris/configure.ac
1449@@ -67,6 +67,11 @@ AC_ARG_ENABLE(wayland,
1450 [wayland="no"])
1451 AM_CONDITIONAL( [WANT_WAYLAND], [test x"$wayland" = x"yes"])
1452
1453+AC_ARG_ENABLE(wayland_serverside_buffers,
1454+ [ --enable-wayland_serverside_buffers Enable serverside buffer allocation for wayland (default=enabled)],
1455+ [wayland_serverside_buffers=$enableval],
1456+ [wayland_serverside_buffers=yes])
1457+AM_CONDITIONAL( [WANT_WL_SERVERSIDE_BUFFERS], [test x"$wayland_serverside_buffers" = x"yes"])
1458
1459 AC_ARG_ENABLE(arch,
1460 [ --enable-arch[=arch] Compile specific CPU target(default=arm)
1461@@ -102,50 +107,76 @@ AC_ARG_WITH(default-hybris-ld-library-path,
1462 [ ])
1463 AC_SUBST(DEFAULT_HYBRIS_LD_LIBRARY_PATH)
1464
1465-
1466-android_headers_path=""
1467 AC_ARG_WITH(android-headers,
1468 [ --with-android-headers=DIR Use android headers available in DIR. See utils/extract-headers.sh ],
1469 [
1470- if [ ! test -e $withval/android-version.h ]; then
1471- echo "Error! missing android-version.h in android header path"
1472- exit 1
1473- fi
1474- rm -f include/android
1475- ln -sf $withval include/android
1476- android_headers_path="$withval"
1477-
1478- # According to http://en.wikipedia.org/wiki/Android_version_history#Version_history_by_API_level
1479- android_headers_major=`grep -E "define ANDROID_VERSION_MAJOR " $android_headers_path/android-version.h | sed "s|^\#define ANDROID_VERSION_MAJOR \(.*\)$|\1|g"`
1480-
1481- android_headers_minor=`grep -E "define ANDROID_VERSION_MINOR " $android_headers_path/android-version.h | sed "s|^\#define ANDROID_VERSION_MINOR \(.*\)$|\1|g"`
1482-
1483- android_headers_patch=`grep -E "define ANDROID_VERSION_PATCH " $android_headers_path/android-version.h | sed "s|^\#define ANDROID_VERSION_PATCH \(.*\)$|\1|g"`
1484-
1485- if [ test "x$android_headers_major" = x ]; then
1486- echo "Error! Was unable to locate define ANDROID_VERSION_MAJOR in $android_headers_path/android-version.h"
1487- fi
1488-
1489- AC_SUBST(ANDROID_VERSION_MAJOR, [$android_headers_major])
1490- AC_SUBST(ANDROID_VERSION_MINOR, [$android_headers_minor])
1491- AC_SUBST(ANDROID_VERSION_PATCH, [$android_headers_patch])
1492-
1493- echo "Android headers version is $android_headers_major.$android_headers_minor.$android_headers_patch"
1494+ AM_CONDITIONAL([HAS_LIBNFC_NXP_HEADERS], [test -f $withval/libnfc-nxp/phLibNfc.h])
1495+ AS_IF([test -f $withval/libnfc-nxp/phLibNfc.h], [ANDROID_HEADERS_CFLAGS="-I$withval -I$withval/libnfc-nxp"],[ANDROID_HEADERS_CFLAGS="-I$withval"])
1496+ AC_SUBST([ANDROID_HEADERS_CFLAGS])
1497 ],
1498- [
1499- echo "Error! need to provide path to Android headers --with-android-headers=DIR. See utils/extract-headers.sh"
1500- exit 1
1501- ]
1502- )
1503+ [ PKG_CHECK_MODULES(ANDROID_HEADERS, android-headers,, exit) ]
1504+)
1505+CPPFLAGS="$CPPFLAGS $ANDROID_HEADERS_CFLAGS"
1506+
1507+AC_CHECK_HEADERS(android-config.h,,AC_MSG_ERROR(required header file is missing))
1508+AC_CHECK_HEADERS(android-version.h,,AC_MSG_ERROR(required header file is missing))
1509+
1510+# AC_AWK_CPP
1511+AC_DEFUN([AC_AWK_CPP],
1512+[AC_LANG_PREPROC_REQUIRE()dnl
1513+AC_REQUIRE([AC_PROG_AWK])dnl
1514+AC_LANG_CONFTEST([AC_LANG_SOURCE([[$2]])])
1515+
1516+ac_awk_cpp_out="`$CPP $CPPFLAGS conftest.$ac_ext|$AWK '$1'`"
1517+AS_IF([test "x$ac_awk_cpp_out" = x], [$4], [$3])
1518+rm -f conftest*
1519+])# AC_AWK_CPP
1520+
1521+
1522+# According to http://en.wikipedia.org/wiki/Android_version_history#Version_history_by_API_level
1523+###########################
1524+AC_AWK_CPP([/has_ANDROID_VERSION_MAJOR/ {print \$2;}],
1525+[
1526+#include <android-version.h>
1527+has_ANDROID_VERSION_MAJOR ANDROID_VERSION_MAJOR
1528+],
1529+[android_headers_major=$ac_awk_cpp_out],
1530+[AC_MSG_ERROR(required 'major' version is missing)])
1531
1532-# Add automake tests for version/API needs here that you need in code, including test .am's
1533
1534+###########################
1535+AC_AWK_CPP([/has_ANDROID_VERSION_MINOR/ {print \$2;}],
1536+[
1537+#include <android-version.h>
1538+has_ANDROID_VERSION_MINOR ANDROID_VERSION_MINOR
1539+],
1540+[android_headers_minor=$ac_awk_cpp_out],
1541+[AC_MSG_ERROR(required 'minor' version is missing)])
1542+
1543+###########################
1544+AC_AWK_CPP([/has_ANDROID_VERSION_PATCH/ {print \$2;}],
1545+[
1546+#include <android-version.h>
1547+has_ANDROID_VERSION_PATCH ANDROID_VERSION_PATCH
1548+],
1549+[android_headers_patch=$ac_awk_cpp_out],
1550+[AC_MSG_ERROR(require 'patch' version is missing)])
1551+
1552+AC_MSG_NOTICE("Android headers version is $android_headers_major.$android_headers_minor.$android_headers_patch.$ac_awk_cpp_out")
1553+###########################
1554+AC_SUBST(ANDROID_VERSION_MAJOR, [$android_headers_major])
1555+AC_SUBST(ANDROID_VERSION_MINOR, [$android_headers_minor])
1556+AC_SUBST(ANDROID_VERSION_PATCH, [$android_headers_patch])
1557+
1558+AC_MSG_NOTICE("Android headers version is $android_headers_major.$android_headers_minor.$android_headers_patch")
1559+
1560+# Add automake tests for version/API needs here that you need in code, including test .am's
1561+AM_CONDITIONAL([HAS_ANDROID_5_0_0], [test $android_headers_major -ge 5 -a $android_headers_minor -ge 0 ])
1562 AM_CONDITIONAL([HAS_ANDROID_4_2_0], [test $android_headers_major -ge 4 -a $android_headers_minor -ge 2 ])
1563 AM_CONDITIONAL([HAS_ANDROID_4_1_0], [test $android_headers_major -ge 4 -a $android_headers_minor -ge 1 ])
1564 AM_CONDITIONAL([HAS_ANDROID_4_0_0], [test $android_headers_major -ge 4 -a $android_headers_minor -ge 0 ])
1565 AM_CONDITIONAL([HAS_ANDROID_2_3_0], [test $android_headers_major -ge 2 -a $android_headers_minor -ge 3 ])
1566
1567-AM_CONDITIONAL([HAS_LIBNFC_NXP_HEADERS], [test -f ${android_headers_path}/libnfc-nxp/phLibNfc.h])
1568
1569 AC_CONFIG_FILES([
1570 Makefile
1571@@ -184,6 +215,8 @@ AC_CONFIG_FILES([
1572 input/libis.pc
1573 camera/Makefile
1574 camera/libcamera.pc
1575+ vibrator/Makefile
1576+ vibrator/libvibrator.pc
1577 media/Makefile
1578 media/libmedia.pc
1579 wifi/Makefile
1580@@ -220,4 +253,3 @@ echo
1581 echo "------------------------------------------------------------------------"
1582 echo
1583 echo "Now type 'make' to compile and 'make install' to install this package."
1584-
1585diff --git a/hybris/egl/Makefile.am b/hybris/egl/Makefile.am
1586index 1837089..de779b9 100644
1587--- a/hybris/egl/Makefile.am
1588+++ b/hybris/egl/Makefile.am
1589@@ -11,7 +11,7 @@ libEGL_la_SOURCES = \
1590 pkgconfigdir = $(libdir)/pkgconfig
1591 pkgconfig_DATA = egl.pc
1592
1593-libEGL_la_CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/include/android -DPKGLIBDIR="\"$(pkglibdir)/\"" -I$(top_srcdir)/common -DDEFAULT_EGL_PLATFORM="\"@DEFAULT_EGL_PLATFORM@\""
1594+libEGL_la_CFLAGS = -I$(top_srcdir)/include $(ANDROID_HEADERS_CFLAGS) -DPKGLIBDIR="\"$(pkglibdir)/\"" -I$(top_srcdir)/common -DDEFAULT_EGL_PLATFORM="\"@DEFAULT_EGL_PLATFORM@\""
1595 if WANT_MESA
1596 libEGL_la_CFLAGS += -DLIBHYBRIS_WANTS_MESA_X11_HEADERS
1597 endif
1598@@ -22,7 +22,7 @@ if WANT_DEBUG
1599 libEGL_la_CFLAGS += -ggdb -O0
1600 endif
1601
1602-libEGL_la_CXXFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/include/android -I$(top_srcdir)/common -DPKGLIBDIR="\"$(pkglibdir)/\""
1603+libEGL_la_CXXFLAGS = -I$(top_srcdir)/include $(ANDROID_HEADERS_CFLAGS) -I$(top_srcdir)/common -DPKGLIBDIR="\"$(pkglibdir)/\""
1604 if WANT_MESA
1605 libEGL_la_CXXFLAGS += -DLIBHYBRIS_WANTS_MESA_X11_HEADERS
1606 endif
1607diff --git a/hybris/egl/egl.c b/hybris/egl/egl.c
1608index 3bd2b25..ffb6d39 100644
1609--- a/hybris/egl/egl.c
1610+++ b/hybris/egl/egl.c
1611@@ -32,14 +32,17 @@
1612 #include <assert.h>
1613
1614
1615-#include <hybris/internal/binding.h>
1616+#include <hybris/common/binding.h>
1617 #include <string.h>
1618
1619-#include <android/system/window.h>
1620+#include <system/window.h>
1621 #include "logging.h"
1622
1623 static void *_libegl = NULL;
1624 static void *_libgles = NULL;
1625+static void *_hybris_libgles1 = NULL;
1626+static void *_hybris_libgles2 = NULL;
1627+static int _egl_context_client_version = 1;
1628
1629 static EGLint (*_eglGetError)(void) = NULL;
1630
1631@@ -122,8 +125,22 @@ static void _init_androidegl()
1632 _libgles = (void *) android_dlopen(getenv("LIBGLESV2") ? getenv("LIBGLESV2") : "libGLESv2.so", RTLD_LAZY);
1633 }
1634
1635-#define EGL_DLSYM(fptr, sym) do { if (_libegl == NULL) { _init_androidegl(); }; if (*(fptr) == NULL) { *(fptr) = (void *) android_dlsym(_libegl, sym); } } while (0)
1636-#define GLESv2_DLSYM(fptr, sym) do { if (_libgles == NULL) { _init_androidegl(); }; if (*(fptr) == NULL) { *(fptr) = (void *) android_dlsym(_libgles, sym); } } while (0)
1637+static void * _android_egl_dlsym(const char *symbol)
1638+{
1639+ if (_libegl == NULL)
1640+ _init_androidegl();
1641+
1642+ return android_dlsym(_libegl, symbol);
1643+}
1644+
1645+struct ws_egl_interface hybris_egl_interface = {
1646+ _android_egl_dlsym,
1647+ egl_helper_has_mapping,
1648+ egl_helper_get_mapping,
1649+};
1650+
1651+#define EGL_DLSYM(fptr, sym) do { if (_libegl == NULL) { _init_androidegl(); }; if (*(fptr) == NULL) { *(fptr) = (void *) android_dlsym(_libegl, sym); } } while (0)
1652+#define GLESv2_DLSYM(fptr, sym) do { if (_libgles == NULL) { _init_androidegl(); }; if (*(fptr) == NULL) { *(fptr) = (void *) android_dlsym(_libgles, sym); } } while (0)
1653
1654 EGLint eglGetError(void)
1655 {
1656@@ -131,40 +148,33 @@ EGLint eglGetError(void)
1657 return (*_eglGetError)();
1658 }
1659
1660-struct _eglDisplayMapping {
1661- EGLNativeDisplayType ndt;
1662- EGLDisplay display;
1663-};
1664-
1665 #define _EGL_MAX_DISPLAYS 100
1666
1667-struct _eglDisplayMapping *_displayMappings[_EGL_MAX_DISPLAYS];
1668+struct _EGLDisplay *_displayMappings[_EGL_MAX_DISPLAYS];
1669
1670-void _addMapping(EGLNativeDisplayType display_id, EGLDisplay display)
1671+void _addMapping(struct _EGLDisplay *display_id)
1672 {
1673 int i;
1674 for (i = 0; i < _EGL_MAX_DISPLAYS; i++)
1675 {
1676 if (_displayMappings[i] == NULL)
1677 {
1678- _displayMappings[i] = (struct _eglDisplayMapping *) malloc(sizeof(struct _eglDisplayMapping));
1679- _displayMappings[i]->ndt = display_id;
1680- _displayMappings[i]->display = display;
1681+ _displayMappings[i] = display_id;
1682 return;
1683 }
1684 }
1685 }
1686
1687-EGLNativeDisplayType _egldisplay2NDT(EGLDisplay display)
1688+struct _EGLDisplay *hybris_egl_display_get_mapping(EGLDisplay display)
1689 {
1690 int i;
1691 for (i = 0; i < _EGL_MAX_DISPLAYS; i++)
1692 {
1693 if (_displayMappings[i])
1694 {
1695- if (_displayMappings[i]->display == display)
1696+ if (_displayMappings[i]->dpy == display)
1697 {
1698- return _displayMappings[i]->ndt;
1699+ return _displayMappings[i];
1700 }
1701
1702 }
1703@@ -177,17 +187,22 @@ EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id)
1704 EGL_DLSYM(&_eglGetDisplay, "eglGetDisplay");
1705 EGLNativeDisplayType real_display;
1706
1707- if (!ws_IsValidDisplay(display_id))
1708- {
1709- return EGL_NO_DISPLAY;
1710- }
1711-
1712 real_display = (*_eglGetDisplay)(EGL_DEFAULT_DISPLAY);
1713 if (real_display == EGL_NO_DISPLAY)
1714 {
1715 return EGL_NO_DISPLAY;
1716 }
1717- _addMapping(display_id, real_display);
1718+
1719+ struct _EGLDisplay *dpy = hybris_egl_display_get_mapping(real_display);
1720+ if (!dpy) {
1721+ dpy = ws_GetDisplay(display_id);
1722+ if (!dpy) {
1723+ return EGL_NO_DISPLAY;
1724+ }
1725+ dpy->dpy = real_display;
1726+ _addMapping(dpy);
1727+ }
1728+
1729 return real_display;
1730 }
1731
1732@@ -200,6 +215,9 @@ EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
1733 EGLBoolean eglTerminate(EGLDisplay dpy)
1734 {
1735 EGL_DLSYM(&_eglTerminate, "eglTerminate");
1736+
1737+ struct _EGLDisplay *display = hybris_egl_display_get_mapping(dpy);
1738+ ws_Terminate(display);
1739 return (*_eglTerminate)(dpy);
1740 }
1741
1742@@ -240,12 +258,18 @@ EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
1743 {
1744 EGL_DLSYM(&_eglCreateWindowSurface, "eglCreateWindowSurface");
1745
1746- win = ws_CreateWindow(win, _egldisplay2NDT(dpy));
1747-
1748+ HYBRIS_TRACE_BEGIN("hybris-egl", "eglCreateWindowSurface", "");
1749+ struct _EGLDisplay *display = hybris_egl_display_get_mapping(dpy);
1750+ win = ws_CreateWindow(win, display);
1751+
1752 assert(((struct ANativeWindowBuffer *) win)->common.magic == ANDROID_NATIVE_WINDOW_MAGIC);
1753
1754+ HYBRIS_TRACE_BEGIN("native-egl", "eglCreateWindowSurface", "");
1755 EGLSurface result = (*_eglCreateWindowSurface)(dpy, config, win, attrib_list);
1756+ HYBRIS_TRACE_END("native-egl", "eglCreateWindowSurface", "");
1757 egl_helper_push_mapping(result, win);
1758+
1759+ HYBRIS_TRACE_END("hybris-egl", "eglCreateWindowSurface", "");
1760 return result;
1761 }
1762
1763@@ -341,8 +365,26 @@ EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1764
1765 EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
1766 {
1767+ EGLBoolean ret;
1768+ EGLSurface surface;
1769+ EGLNativeWindowType win;
1770+ HYBRIS_TRACE_BEGIN("hybris-egl", "eglSwapInterval", "=%d", interval);
1771+
1772+ /* Some egl implementations don't pass through the setSwapInterval
1773+ * call. Since we may support various swap intervals internally, we'll
1774+ * call it anyway and then give the wrapped egl implementation a chance
1775+ * to chage it. */
1776+ EGL_DLSYM(&_eglGetCurrentSurface, "eglGetCurrentSurface");
1777+ surface = (*_eglGetCurrentSurface)(EGL_DRAW);
1778+ if (egl_helper_has_mapping(surface))
1779+ ws_setSwapInterval(dpy, egl_helper_get_mapping(surface), interval);
1780+
1781+ HYBRIS_TRACE_BEGIN("native-egl", "eglSwapInterval", "=%d", interval);
1782 EGL_DLSYM(&_eglSwapInterval, "eglSwapInterval");
1783- return (*_eglSwapInterval)(dpy, interval);
1784+ ret = (*_eglSwapInterval)(dpy, interval);
1785+ HYBRIS_TRACE_END("native-egl", "eglSwapInterval", "");
1786+ HYBRIS_TRACE_END("hybris-egl", "eglSwapInterval", "");
1787+ return ret;
1788 }
1789
1790 EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config,
1791@@ -350,6 +392,15 @@ EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config,
1792 const EGLint *attrib_list)
1793 {
1794 EGL_DLSYM(&_eglCreateContext, "eglCreateContext");
1795+
1796+ EGLint *p = attrib_list;
1797+ while (p != NULL && *p != EGL_NONE) {
1798+ if (*p == EGL_CONTEXT_CLIENT_VERSION) {
1799+ _egl_context_client_version = p[1];
1800+ }
1801+ p += 2;
1802+ }
1803+
1804 return (*_eglCreateContext)(dpy, config, share_context, attrib_list);
1805 }
1806
1807@@ -400,15 +451,33 @@ EGLBoolean eglWaitGL(void)
1808 EGLBoolean eglWaitNative(EGLint engine)
1809 {
1810 EGL_DLSYM(&_eglWaitNative, "eglWaitNative");
1811- return (*_eglWaitNative)(engine);
1812+ return (*_eglWaitNative)(engine);
1813+}
1814+
1815+EGLBoolean _my_eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects)
1816+{
1817+ EGLNativeWindowType win;
1818+ EGLBoolean ret;
1819+ HYBRIS_TRACE_BEGIN("hybris-egl", "eglSwapBuffersWithDamageEXT", "");
1820+ EGL_DLSYM(&_eglSwapBuffers, "eglSwapBuffers");
1821+
1822+ if (egl_helper_has_mapping(surface)) {
1823+ win = egl_helper_get_mapping(surface);
1824+ ws_prepareSwap(dpy, win, rects, n_rects);
1825+ ret = (*_eglSwapBuffers)(dpy, surface);
1826+ ws_finishSwap(dpy, win);
1827+ } else {
1828+ ret = (*_eglSwapBuffers)(dpy, surface);
1829+ }
1830+ HYBRIS_TRACE_END("hybris-egl", "eglSwapBuffersWithDamageEXT", "");
1831+ return ret;
1832 }
1833
1834 EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
1835 {
1836- EGLBoolean ret;
1837+ EGLBoolean ret;
1838 HYBRIS_TRACE_BEGIN("hybris-egl", "eglSwapBuffers", "");
1839- EGL_DLSYM(&_eglSwapBuffers, "eglSwapBuffers");
1840- ret = (*_eglSwapBuffers)(dpy, surface);
1841+ ret = _my_eglSwapBuffersWithDamageEXT(dpy, surface, NULL, 0);
1842 HYBRIS_TRACE_END("hybris-egl", "eglSwapBuffers", "");
1843 return ret;
1844 }
1845@@ -420,6 +489,7 @@ EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface,
1846 return (*_eglCopyBuffers)(dpy, surface, target);
1847 }
1848
1849+
1850 static EGLImageKHR _my_eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
1851 {
1852 EGL_DLSYM(&_eglCreateImageKHR, "eglCreateImageKHR");
1853@@ -429,14 +499,27 @@ static EGLImageKHR _my_eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum
1854 const EGLint *newattrib_list = attrib_list;
1855
1856 ws_passthroughImageKHR(&newctx, &newtarget, &newbuffer, &newattrib_list);
1857- return (*_eglCreateImageKHR)(dpy, newctx, newtarget, newbuffer, newattrib_list);
1858+
1859+ EGLImageKHR eik = (*_eglCreateImageKHR)(dpy, newctx, newtarget, newbuffer, newattrib_list);
1860+
1861+ if (eik == EGL_NO_IMAGE_KHR) {
1862+ return EGL_NO_IMAGE_KHR;
1863+ }
1864+
1865+ struct egl_image *image;
1866+ image = malloc(sizeof *image);
1867+ image->egl_image = eik;
1868+ image->egl_buffer = buffer;
1869+ image->target = target;
1870+
1871+ return (EGLImageKHR)image;
1872 }
1873
1874 static void _my_glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
1875 {
1876 GLESv2_DLSYM(&_glEGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES");
1877- (*_glEGLImageTargetTexture2DOES)(target, image);
1878- return;
1879+ struct egl_image *img = image;
1880+ (*_glEGLImageTargetTexture2DOES)(target, img ? img->egl_image : NULL);
1881 }
1882
1883 __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
1884@@ -445,19 +528,49 @@ __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
1885 if (strcmp(procname, "eglCreateImageKHR") == 0)
1886 {
1887 return _my_eglCreateImageKHR;
1888- }
1889+ }
1890+ else if (strcmp(procname, "eglDestroyImageKHR") == 0)
1891+ {
1892+ return eglDestroyImageKHR;
1893+ }
1894+ else if (strcmp(procname, "eglSwapBuffersWithDamageEXT") == 0)
1895+ {
1896+ return _my_eglSwapBuffersWithDamageEXT;
1897+ }
1898 else if (strcmp(procname, "glEGLImageTargetTexture2DOES") == 0)
1899 {
1900 return _my_glEGLImageTargetTexture2DOES;
1901 }
1902- __eglMustCastToProperFunctionPointerType ret = ws_eglGetProcAddress(procname);
1903+
1904+ __eglMustCastToProperFunctionPointerType ret = NULL;
1905+
1906+ switch (_egl_context_client_version) {
1907+ case 1: // OpenGL ES 1.x API
1908+ if (_hybris_libgles1 == NULL) {
1909+ _hybris_libgles1 = (void *) dlopen(getenv("HYBRIS_LIBGLESV1") ?: "libGLESv1_CM.so.1", RTLD_LAZY);
1910+ }
1911+ ret = _hybris_libgles1 ? dlsym(_hybris_libgles1, procname) : NULL;
1912+ break;
1913+ case 2: // OpenGL ES 2.0 API
1914+ if (_hybris_libgles2 == NULL) {
1915+ _hybris_libgles2 = (void *) dlopen(getenv("HYBRIS_LIBGLESV2") ?: "libGLESv2.so.2", RTLD_LAZY);
1916+ }
1917+ ret = _hybris_libgles2 ? dlsym(_hybris_libgles2, procname) : NULL;
1918+ break;
1919+ case 3: // OpenGL ES 3.x API
1920+ // TODO: Load from libGLESv3.so once we have OpenGL ES 3.0/3.1 support
1921+ break;
1922+ default:
1923+ HYBRIS_WARN("Unknown EGL context client version: %d", _egl_context_client_version);
1924+ break;
1925+ }
1926+
1927+ if (ret == NULL) {
1928+ ret = ws_eglGetProcAddress(procname);
1929+ }
1930
1931 if (ret == NULL) {
1932-#ifdef RTLD_DEFAULT
1933- ret = dlsym(RTLD_DEFAULT, procname);
1934- if (ret == NULL)
1935-#endif
1936- ret = (*_eglGetProcAddress)(procname);
1937+ ret = (*_eglGetProcAddress)(procname);
1938 }
1939
1940 return ret;
1941@@ -466,8 +579,13 @@ __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
1942 EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
1943 {
1944 EGL_DLSYM(&_eglDestroyImageKHR, "eglDestroyImageKHR");
1945- return (*_eglDestroyImageKHR)(dpy, image);
1946+ struct egl_image *img = image;
1947+ EGLBoolean ret = (*_eglDestroyImageKHR)(dpy, img ? img->egl_image : NULL);
1948+ if (ret == EGL_TRUE) {
1949+ free(img);
1950+ return EGL_TRUE;
1951+ }
1952+ return ret;
1953 }
1954
1955-
1956 // vim:ts=4:sw=4:noexpandtab
1957diff --git a/hybris/egl/eglhybris.h b/hybris/egl/eglhybris.h
1958index 2aeed65..b777166 100644
1959--- a/hybris/egl/eglhybris.h
1960+++ b/hybris/egl/eglhybris.h
1961@@ -18,10 +18,10 @@
1962 #ifndef EGL_HYBRIS_H_
1963 #define EGL_HYBRIS_H_
1964
1965-#include <android/hardware/gralloc.h>
1966+#include <hardware/gralloc.h>
1967 /* Needed for ICS window.h */
1968 #include <string.h>
1969-#include <android/system/window.h>
1970+#include <system/window.h>
1971
1972 #ifdef __cplusplus
1973 extern "C" {
1974@@ -31,6 +31,12 @@ int hybris_register_buffer_handle(buffer_handle_t handle);
1975 int hybris_unregister_buffer_handle(buffer_handle_t handle);
1976 void hybris_dump_buffer_to_file(struct ANativeWindowBuffer *buf);
1977
1978+void *hybris_android_egl_dlsym(const char *symbol);
1979+int hybris_egl_has_mapping(EGLSurface surface);
1980+EGLNativeWindowType hybris_egl_get_mapping(EGLSurface surface);
1981+
1982+struct _EGLDisplay *hybris_egl_display_get_mapping(EGLDisplay dpy);
1983+
1984 #ifdef __cplusplus
1985 }
1986 #endif
1987diff --git a/hybris/egl/helper.cpp b/hybris/egl/helper.cpp
1988index 8370ccc..b1c84c2 100644
1989--- a/hybris/egl/helper.cpp
1990+++ b/hybris/egl/helper.cpp
1991@@ -40,6 +40,17 @@ int egl_helper_has_mapping(EGLSurface surface)
1992 return (_surface_window_map.find(surface) != _surface_window_map.end());
1993 }
1994
1995+EGLNativeWindowType egl_helper_get_mapping(EGLSurface surface)
1996+{
1997+ std::map<EGLSurface,EGLNativeWindowType>::iterator it;
1998+ it = _surface_window_map.find(surface);
1999+
2000+ /* Caller must check with egl_helper_has_mapping() before */
2001+ assert(it != _surface_window_map.end());
2002+
2003+ return it->second;
2004+}
2005+
2006 EGLNativeWindowType egl_helper_pop_mapping(EGLSurface surface)
2007 {
2008 std::map<EGLSurface,EGLNativeWindowType>::iterator it;
2009diff --git a/hybris/egl/helper.h b/hybris/egl/helper.h
2010index ee313ab..1b3144b 100644
2011--- a/hybris/egl/helper.h
2012+++ b/hybris/egl/helper.h
2013@@ -36,6 +36,9 @@ void egl_helper_push_mapping(EGLSurface surface, EGLNativeWindowType window);
2014 /* Check if a mapping for a surface exist */
2015 int egl_helper_has_mapping(EGLSurface surface);
2016
2017+/* Return (without removing) the mapping for a surface */
2018+EGLNativeWindowType egl_helper_get_mapping(EGLSurface surface);
2019+
2020 /* Return and remove the mapping for a surface */
2021 EGLNativeWindowType egl_helper_pop_mapping(EGLSurface surface);
2022
2023diff --git a/hybris/egl/platforms/Makefile.am b/hybris/egl/platforms/Makefile.am
2024index 5da4211..4126752 100644
2025--- a/hybris/egl/platforms/Makefile.am
2026+++ b/hybris/egl/platforms/Makefile.am
2027@@ -3,6 +3,9 @@ SUBDIRS = common null fbdev
2028 if HAS_ANDROID_4_2_0
2029 SUBDIRS += hwcomposer
2030 endif
2031+if HAS_ANDROID_5_0_0
2032+SUBDIRS += hwcomposer
2033+endif
2034
2035 if WANT_WAYLAND
2036 SUBDIRS += wayland
2037diff --git a/hybris/egl/platforms/common/Makefile.am b/hybris/egl/platforms/common/Makefile.am
2038index 2be0d75..3c3aa64 100644
2039--- a/hybris/egl/platforms/common/Makefile.am
2040+++ b/hybris/egl/platforms/common/Makefile.am
2041@@ -37,7 +37,7 @@ BUILT_SOURCES = wayland-android-protocol.c \
2042
2043 libwayland_egl_la_SOURCES = wayland-egl.c
2044
2045-libwayland_egl_la_CFLAGS = -I. -I$(top_srcdir)/include -I$(top_srcdir)/include/android $(WAYLAND_CLIENT_CFLAGS) $(WAYLAND_SERVER_CFLAGS)
2046+libwayland_egl_la_CFLAGS = -I. -I$(top_srcdir)/include $(ANDROID_HEADERS_CFLAGS) $(WAYLAND_CLIENT_CFLAGS) $(WAYLAND_SERVER_CFLAGS)
2047 if WANT_TRACE
2048 libwayland_egl_la_CFLAGS += -DDEBUG
2049 endif
2050@@ -45,7 +45,7 @@ if WANT_DEBUG
2051 libwayland_egl_la_CFLAGS += -ggdb -O0
2052 endif
2053
2054-libwayland_egl_la_CXXFLAGS = -I. -I$(top_srcdir)/include -I$(top_srcdir)/include/android $(WAYLAND_CLIENT_CFLAGS) $(WAYLAND_SERVER_CFLAGS)
2055+libwayland_egl_la_CXXFLAGS = -I. -I$(top_srcdir)/include $(ANDROID_HEADERS_CFLAGS) $(WAYLAND_CLIENT_CFLAGS) $(WAYLAND_SERVER_CFLAGS)
2056 if WANT_TRACE
2057 libwayland_egl_la_CXXFLAGS += -DDEBUG
2058 endif
2059@@ -57,9 +57,9 @@ libwayland_egl_la_LDFLAGS = \
2060
2061 endif
2062
2063-libhybris_eglplatformcommon_la_CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/include/android -I$(top_srcdir)/egl -I$(top_srcdir)/common/
2064+libhybris_eglplatformcommon_la_CFLAGS = -I$(top_srcdir)/include $(ANDROID_HEADERS_CFLAGS) -I$(top_srcdir)/egl -I$(top_srcdir)/common/
2065 if WANT_WAYLAND
2066-libhybris_eglplatformcommon_la_CFLAGS += $(WAYLAND_CLIENT_CFLAGS) $(WAYLAND_SERVER_CFLAGS) -I$(top_srcdir)/include/android
2067+libhybris_eglplatformcommon_la_CFLAGS += $(WAYLAND_CLIENT_CFLAGS) $(WAYLAND_SERVER_CFLAGS) $(ANDROID_HEADERS_CFLAGS)
2068 endif
2069
2070 if WANT_MESA
2071@@ -73,13 +73,13 @@ libhybris_eglplatformcommon_la_CFLAGS += -ggdb -O0
2072 endif
2073
2074
2075-libhybris_eglplatformcommon_la_CXXFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/egl -I$(top_srcdir)/include/android -I$(top_srcdir)/common/
2076+libhybris_eglplatformcommon_la_CXXFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/egl $(ANDROID_HEADERS_CFLAGS) -I$(top_srcdir)/common/
2077 if WANT_MESA
2078 libhybris_eglplatformcommon_la_CXXFLAGS += -DLIBHYBRIS_WANTS_MESA_X11_HEADERS
2079 endif
2080
2081 if WANT_WAYLAND
2082-libhybris_eglplatformcommon_la_CXXFLAGS += $(WAYLAND_CLIENT_CFLAGS) $(WAYLAND_SERVER_CFLAGS) -I$(top_srcdir)/include/android
2083+libhybris_eglplatformcommon_la_CXXFLAGS += $(WAYLAND_CLIENT_CFLAGS) $(WAYLAND_SERVER_CFLAGS) $(ANDROID_HEADERS_CFLAGS)
2084 endif
2085
2086 if WANT_TRACE
2087@@ -92,6 +92,15 @@ libhybris_eglplatformcommon_la_LDFLAGS = \
2088 $(top_builddir)/common/libhybris-common.la \
2089 -version-info "1":"0":"0"
2090
2091+if HAS_ANDROID_4_2_0
2092+libhybris_eglplatformcommon_la_LDFLAGS += $(top_builddir)/libsync/libsync.la
2093+endif
2094+
2095+if HAS_ANDROID_5_0_0
2096+libhybris_eglplatformcommon_la_LDFLAGS += $(top_builddir)/libsync/libsync.la
2097+endif
2098+
2099+
2100 eglplatformcommondir = $(includedir)/hybris/eglplatformcommon
2101 eglplatformcommon_HEADERS = \
2102 support.h \
2103diff --git a/hybris/egl/platforms/common/eglplatformcommon.cpp b/hybris/egl/platforms/common/eglplatformcommon.cpp
2104index 4878379..a6c0076 100644
2105--- a/hybris/egl/platforms/common/eglplatformcommon.cpp
2106+++ b/hybris/egl/platforms/common/eglplatformcommon.cpp
2107@@ -1,8 +1,9 @@
2108+#include <android-config.h>
2109 #include <ws.h>
2110 #include <stdlib.h>
2111 #include <dlfcn.h>
2112 #include <string.h>
2113-#include <android/hardware/gralloc.h>
2114+#include <hardware/gralloc.h>
2115 #include <stdio.h>
2116 #include <assert.h>
2117 #include "config.h"
2118@@ -21,15 +22,32 @@
2119
2120 #include "windowbuffer.h"
2121
2122+static struct ws_egl_interface *my_egl_interface;
2123 static gralloc_module_t *my_gralloc = 0;
2124 static alloc_device_t *my_alloc = 0;
2125
2126-extern "C" void eglplatformcommon_init(gralloc_module_t *gralloc, alloc_device_t *allocdevice)
2127+extern "C" void eglplatformcommon_init(struct ws_egl_interface *egl_iface, gralloc_module_t *gralloc, alloc_device_t *allocdevice)
2128 {
2129+ my_egl_interface = egl_iface;
2130 my_gralloc = gralloc;
2131 my_alloc = allocdevice;
2132 }
2133
2134+extern "C" void *hybris_android_egl_dlsym(const char *symbol)
2135+{
2136+ return (*my_egl_interface->android_egl_dlsym)(symbol);
2137+}
2138+
2139+extern "C" int hybris_egl_has_mapping(EGLSurface surface)
2140+{
2141+ return (*my_egl_interface->has_mapping)(surface);
2142+}
2143+
2144+EGLNativeWindowType hybris_egl_get_mapping(EGLSurface surface)
2145+{
2146+ return (*my_egl_interface->get_mapping)(surface);
2147+}
2148+
2149 extern "C" int hybris_register_buffer_handle(buffer_handle_t handle)
2150 {
2151 if (!my_gralloc)
2152@@ -64,6 +82,8 @@ extern "C" void hybris_dump_buffer_to_file(ANativeWindowBuffer *buf)
2153 snprintf(b, 1020, "vaddr.%p.%p.%i.%is%ix%ix%i", buf, vaddr, cnt, buf->width, buf->stride, buf->height, bytes_pp);
2154 cnt++;
2155 int fd = ::open(b, O_WRONLY|O_CREAT, S_IRWXU);
2156+ if(fd < 0)
2157+ return;
2158
2159 ::write(fd, vaddr, buf->stride * buf->height * bytes_pp);
2160 ::close(fd);
2161@@ -75,7 +95,7 @@ extern "C" void hybris_dump_buffer_to_file(ANativeWindowBuffer *buf)
2162 extern "C" EGLBoolean eglplatformcommon_eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
2163 {
2164 assert(my_gralloc != NULL);
2165- server_wlegl_create(display, my_gralloc);
2166+ server_wlegl_create(display, my_gralloc, my_alloc);
2167 return EGL_TRUE;
2168 }
2169
2170@@ -85,7 +105,7 @@ extern "C" EGLBoolean eglplatformcommon_eglUnbindWaylandDisplayWL(EGLDisplay dpy
2171 }
2172
2173 extern "C" EGLBoolean eglplatformcommon_eglQueryWaylandBufferWL(EGLDisplay dpy,
2174- struct wl_buffer *buffer, EGLint attribute, EGLint *value)
2175+ struct wl_resource *buffer, EGLint attribute, EGLint *value)
2176 {
2177 server_wlegl_buffer *buf = server_wlegl_buffer_from(buffer);
2178 ANativeWindowBuffer* anwb = (ANativeWindowBuffer *) buf->buf;
2179@@ -114,8 +134,73 @@ extern "C" EGLBoolean eglplatformcommon_eglQueryWaylandBufferWL(EGLDisplay dpy,
2180 return EGL_FALSE ;
2181 }
2182
2183+// Added as part of EGL_HYBRIS_WL_acquire_native_buffer. Buffers are released
2184+// and decRef'ed using eglHybrisReleaseNativeBuffer
2185+extern "C" EGLBoolean eglplatformcommon_eglHybrisAcquireNativeBufferWL(EGLDisplay dpy, struct wl_resource *wlBuffer, EGLClientBuffer *buffer)
2186+ {
2187+ if (!buffer)
2188+ return EGL_FALSE;
2189+ server_wlegl_buffer *buf = server_wlegl_buffer_from(wlBuffer);
2190+ if (!buf->buf->isAllocated()) {
2191+ // We only return the handles from buffers which are allocated server side. This is because some
2192+ // hardware compositors have problems with client-side allocated buffers.
2193+ buffer = 0;
2194+ return EGL_FALSE;
2195+ }
2196+ ANativeWindowBuffer* anwb = (ANativeWindowBuffer *) buf->buf;
2197+ anwb->common.incRef(&anwb->common);
2198+ *buffer = (EGLClientBuffer *) anwb;
2199+ return EGL_TRUE;
2200+}
2201+
2202 #endif
2203
2204+// Added as part of EGL_HYBRIS_native_buffer2
2205+extern "C" EGLBoolean eglplatformcommon_eglHybrisNativeBufferHandle(EGLDisplay dpy, EGLClientBuffer buffer, void **handle)
2206+{
2207+ if (!buffer || !handle)
2208+ return EGL_FALSE;
2209+ ANativeWindowBuffer *anwb = (ANativeWindowBuffer *) buffer;
2210+ *handle = (void *) anwb->handle;
2211+ return EGL_TRUE;
2212+}
2213+
2214+extern "C" void eglplatformcommon_eglHybrisGetNativeBufferInfo(EGLClientBuffer buffer, int *num_ints, int *num_fds)
2215+{
2216+ RemoteWindowBuffer *buf = static_cast<RemoteWindowBuffer *>((ANativeWindowBuffer *) buffer);
2217+ *num_ints = buf->handle->numInts;
2218+ *num_fds = buf->handle->numFds;
2219+}
2220+
2221+extern "C" void eglplatformcommon_eglHybrisSerializeNativeBuffer(EGLClientBuffer buffer, int *ints, int *fds)
2222+{
2223+ RemoteWindowBuffer *buf = static_cast<RemoteWindowBuffer *>((ANativeWindowBuffer *) buffer);
2224+ memcpy(ints, buf->handle->data + buf->handle->numFds, buf->handle->numInts * sizeof(int));
2225+ memcpy(fds, buf->handle->data, buf->handle->numFds * sizeof(int));
2226+}
2227+
2228+extern "C" EGLBoolean eglplatformcommon_eglHybrisCreateRemoteBuffer(EGLint width, EGLint height, EGLint usage, EGLint format, EGLint stride,
2229+ int num_ints, int *ints, int num_fds, int *fds, EGLClientBuffer *buffer)
2230+{
2231+ assert(my_gralloc != NULL);
2232+
2233+ native_handle_t *native = native_handle_create(num_fds, num_ints);
2234+ memcpy(&native->data[0], fds, num_fds * sizeof(int));
2235+ memcpy(&native->data[num_fds], ints, num_ints * sizeof(int));
2236+
2237+ int ret = my_gralloc->registerBuffer(my_gralloc, (buffer_handle_t)native);
2238+
2239+ if (ret == 0)
2240+ {
2241+ RemoteWindowBuffer *buf = new RemoteWindowBuffer(width, height, stride, format, usage, (buffer_handle_t)native, my_gralloc, my_alloc);
2242+ buf->common.incRef(&buf->common);
2243+ *buffer = (EGLClientBuffer) static_cast<ANativeWindowBuffer *>(buf);
2244+ return EGL_TRUE;
2245+ }
2246+ else
2247+ return EGL_FALSE;
2248+}
2249+
2250 extern "C" EGLBoolean eglplatformcommon_eglHybrisCreateNativeBuffer(EGLint width, EGLint height, EGLint usage, EGLint format, EGLint *stride, EGLClientBuffer *buffer)
2251 {
2252 int ret;
2253@@ -129,8 +214,9 @@ extern "C" EGLBoolean eglplatformcommon_eglHybrisCreateNativeBuffer(EGLint width
2254
2255 if (ret == 0)
2256 {
2257- RemoteWindowBuffer *buf = new RemoteWindowBuffer(width, height, _stride, format, usage, _handle, my_gralloc);
2258+ RemoteWindowBuffer *buf = new RemoteWindowBuffer(width, height, _stride, format, usage, _handle, my_gralloc, my_alloc);
2259 buf->common.incRef(&buf->common);
2260+ buf->setAllocated(true);
2261 *buffer = (EGLClientBuffer) static_cast<ANativeWindowBuffer *>(buf);
2262 *stride = _stride;
2263 return EGL_TRUE;
2264@@ -185,9 +271,9 @@ eglplatformcommon_passthroughImageKHR(EGLContext *ctx, EGLenum *target, EGLClien
2265 static int debugenvchecked = 0;
2266 if (*target == EGL_WAYLAND_BUFFER_WL)
2267 {
2268- server_wlegl_buffer *buf = server_wlegl_buffer_from((struct wl_buffer *)*buffer);
2269- HYBRIS_TRACE_BEGIN("eglplatformcommon", "Wayland_eglImageKHR", "-resource@%i", ((struct wl_buffer *)*buffer)->resource.object.id);
2270- HYBRIS_TRACE_END("eglplatformcommon", "Wayland_eglImageKHR", "-resource@%i", ((struct wl_buffer *)*buffer)->resource.object.id);
2271+ server_wlegl_buffer *buf = server_wlegl_buffer_from((struct wl_resource *)*buffer);
2272+ HYBRIS_TRACE_BEGIN("eglplatformcommon", "Wayland_eglImageKHR", "-resource@%i", wl_resource_get_id((struct wl_resource *)*buffer));
2273+ HYBRIS_TRACE_END("eglplatformcommon", "Wayland_eglImageKHR", "-resource@%i", wl_resource_get_id((struct wl_resource *)*buffer));
2274 if (debugenvchecked == 0)
2275 {
2276 if (getenv("HYBRIS_WAYLAND_KHR_DUMP_BUFFERS") != NULL)
2277@@ -223,6 +309,11 @@ extern "C" __eglMustCastToProperFunctionPointerType eglplatformcommon_eglGetProc
2278 return (__eglMustCastToProperFunctionPointerType)eglplatformcommon_eglQueryWaylandBufferWL;
2279 }
2280 else
2281+ if (strcmp(procname, "eglHybrisAcquireNativeBufferWL") == 0)
2282+ {
2283+ return (__eglMustCastToProperFunctionPointerType) eglplatformcommon_eglHybrisAcquireNativeBufferWL;
2284+ }
2285+ else
2286 #endif
2287 if (strcmp(procname, "eglHybrisCreateNativeBuffer") == 0)
2288 {
2289@@ -243,6 +334,26 @@ extern "C" __eglMustCastToProperFunctionPointerType eglplatformcommon_eglGetProc
2290 {
2291 return (__eglMustCastToProperFunctionPointerType)eglplatformcommon_eglHybrisReleaseNativeBuffer;
2292 }
2293+ else
2294+ if (strcmp(procname, "eglHybrisGetNativeBufferInfo") == 0)
2295+ {
2296+ return (__eglMustCastToProperFunctionPointerType)eglplatformcommon_eglHybrisGetNativeBufferInfo;
2297+ }
2298+ else
2299+ if (strcmp(procname, "eglHybrisSerializeNativeBuffer") == 0)
2300+ {
2301+ return (__eglMustCastToProperFunctionPointerType)eglplatformcommon_eglHybrisSerializeNativeBuffer;
2302+ }
2303+ else
2304+ if (strcmp(procname, "eglHybrisCreateRemoteBuffer") == 0)
2305+ {
2306+ return (__eglMustCastToProperFunctionPointerType)eglplatformcommon_eglHybrisCreateRemoteBuffer;
2307+ }
2308+ else
2309+ if (strcmp(procname, "eglHybrisNativeBufferHandle") == 0)
2310+ {
2311+ return (__eglMustCastToProperFunctionPointerType)eglplatformcommon_eglHybrisNativeBufferHandle;
2312+ }
2313 return NULL;
2314 }
2315
2316@@ -253,8 +364,7 @@ extern "C" const char *eglplatformcommon_eglQueryString(EGLDisplay dpy, EGLint n
2317 {
2318 const char *ret = (*real_eglQueryString)(dpy, name);
2319 static char eglextensionsbuf[512];
2320- assert(ret != NULL);
2321- snprintf(eglextensionsbuf, 510, "%sEGL_HYBRIS_native_buffer %s", ret,
2322+ snprintf(eglextensionsbuf, 510, "%sEGL_HYBRIS_native_buffer2 EGL_HYBRIS_WL_acquire_native_buffer %s", ret ? ret : "",
2323 #ifdef WANT_WAYLAND
2324 "EGL_WL_bind_wayland_display "
2325 #else
2326diff --git a/hybris/egl/platforms/common/eglplatformcommon.h b/hybris/egl/platforms/common/eglplatformcommon.h
2327index 273817f..aec29db 100644
2328--- a/hybris/egl/platforms/common/eglplatformcommon.h
2329+++ b/hybris/egl/platforms/common/eglplatformcommon.h
2330@@ -1,10 +1,10 @@
2331 #ifndef __EGLPLATFORMCOMMON_H
2332 #define __EGLPLATFORMCOMMON_H
2333 #include <string.h>
2334-#include <android/hardware/gralloc.h>
2335+#include <hardware/gralloc.h>
2336 #include <EGL/egl.h>
2337
2338-void eglplatformcommon_init(gralloc_module_t *gralloc, alloc_device_t *allocdevice);
2339+void eglplatformcommon_init(struct ws_egl_interface *egl_iface, gralloc_module_t *gralloc, alloc_device_t *allocdevice);
2340 __eglMustCastToProperFunctionPointerType eglplatformcommon_eglGetProcAddress(const char *procname);
2341 void eglplatformcommon_passthroughImageKHR(EGLContext *ctx, EGLenum *target, EGLClientBuffer *buffer, const EGLint **attrib_list);
2342 const char *eglplatformcommon_eglQueryString(EGLDisplay dpy, EGLint name, const char *(*real_eglQueryString)(EGLDisplay dpy, EGLint name));
2343diff --git a/hybris/egl/platforms/common/hybris_nativebufferext.h b/hybris/egl/platforms/common/hybris_nativebufferext.h
2344index 0724753..1fac17b 100644
2345--- a/hybris/egl/platforms/common/hybris_nativebufferext.h
2346+++ b/hybris/egl/platforms/common/hybris_nativebufferext.h
2347@@ -24,6 +24,12 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLHYBRISLOCKNATIVEBUFFERPROC)(EGLClientBuff
2348 typedef EGLBoolean (EGLAPIENTRYP PFNEGLHYBRISUNLOCKNATIVEBUFFERPROC)(EGLClientBuffer buffer);
2349 typedef EGLBoolean (EGLAPIENTRYP PFNEGLHYBRISRELEASENATIVEBUFFERPROC)(EGLClientBuffer buffer);
2350
2351+typedef EGLBoolean (EGLAPIENTRYP PFNEGLHYBRISGETNATIVEBUFFERINFOPROC)(EGLClientBuffer buffer, int *num_ints, int *num_fds);
2352+typedef EGLBoolean (EGLAPIENTRYP PFNEGLHYBRISSERIALIZENATIVEBUFFERPROC)(EGLClientBuffer buffer, int *ints, int *fds);
2353+
2354+typedef EGLBoolean (EGLAPIENTRYP PFNEGLHYBRISCREATEREMOTEBUFFERPROC)(EGLint width, EGLint height, EGLint usage, EGLint format, EGLint stride,
2355+ int num_ints, int *ints, int num_fds, int *fds, EGLClientBuffer *buffer);
2356+
2357 enum {
2358 /* buffer is never read in software */
2359 HYBRIS_USAGE_SW_READ_NEVER = 0x00000000,
2360diff --git a/hybris/egl/platforms/common/native_handle.c b/hybris/egl/platforms/common/native_handle.c
2361index c219c71..16ca2d6 100644
2362--- a/hybris/egl/platforms/common/native_handle.c
2363+++ b/hybris/egl/platforms/common/native_handle.c
2364@@ -16,13 +16,14 @@
2365
2366 #define LOG_TAG "NativeHandle"
2367
2368+#include <android-config.h>
2369 #include <stdint.h>
2370 #include <errno.h>
2371 #include <string.h>
2372 #include <stdlib.h>
2373 #include <unistd.h>
2374
2375-#include <android/cutils/native_handle.h>
2376+#include <cutils/native_handle.h>
2377
2378 native_handle_t* native_handle_create(int numFds, int numInts)
2379 {
2380diff --git a/hybris/egl/platforms/common/nativewindowbase.cpp b/hybris/egl/platforms/common/nativewindowbase.cpp
2381index f6ec979..c028c35 100644
2382--- a/hybris/egl/platforms/common/nativewindowbase.cpp
2383+++ b/hybris/egl/platforms/common/nativewindowbase.cpp
2384@@ -1,17 +1,25 @@
2385+#include <android-config.h>
2386 #include <string.h>
2387-#include <android/system/window.h>
2388-#include <android/hardware/gralloc.h>
2389+#include <system/window.h>
2390+#include <hardware/gralloc.h>
2391 #include "support.h"
2392 #include <stdarg.h>
2393
2394+#if ANDROID_VERSION_MAJOR>=4 && ANDROID_VERSION_MINOR>=2 || ANDROID_VERSION_MAJOR>=5
2395+extern "C" {
2396+#include <sync/sync.h>
2397+}
2398+#endif
2399+
2400+
2401 #include "nativewindowbase.h"
2402
2403 #include "logging.h"
2404
2405-#include <android/android-version.h>
2406-
2407 #define TRACE(message, ...) HYBRIS_DEBUG_LOG(EGL, message, ##__VA_ARGS__)
2408
2409+
2410+
2411 BaseNativeWindowBuffer::BaseNativeWindowBuffer()
2412 {
2413 TRACE("%p", this);
2414@@ -91,7 +99,7 @@ BaseNativeWindow::BaseNativeWindow()
2415
2416 ANativeWindow::setSwapInterval = _setSwapInterval;
2417
2418-#if ANDROID_VERSION_MAJOR>=4 && ANDROID_VERSION_MINOR>=2
2419+#if ANDROID_VERSION_MAJOR>=4 && ANDROID_VERSION_MINOR>=2 || ANDROID_VERSION_MAJOR>=5
2420 ANativeWindow::lockBuffer_DEPRECATED = &_lockBuffer_DEPRECATED;
2421 ANativeWindow::dequeueBuffer_DEPRECATED = &_dequeueBuffer_DEPRECATED;
2422 ANativeWindow::queueBuffer_DEPRECATED = &_queueBuffer_DEPRECATED;
2423@@ -153,7 +161,17 @@ int BaseNativeWindow::_dequeueBuffer_DEPRECATED(ANativeWindow* window, ANativeWi
2424 BaseNativeWindowBuffer* temp = static_cast<BaseNativeWindowBuffer*>(*buffer);
2425 int fenceFd = -1;
2426 int ret = static_cast<BaseNativeWindow*>(window)->dequeueBuffer(&temp, &fenceFd);
2427+
2428 *buffer = static_cast<ANativeWindowBuffer*>(temp);
2429+
2430+#if ANDROID_VERSION_MAJOR>=4 && ANDROID_VERSION_MINOR>=2 || ANDROID_VERSION_MAJOR>=5
2431+ if (fenceFd >= 0)
2432+ {
2433+ sync_wait(fenceFd, -1);
2434+ close(fenceFd);
2435+ }
2436+#endif
2437+
2438 return ret;
2439 }
2440
2441@@ -239,7 +257,7 @@ const char *BaseNativeWindow::_native_query_operation(int what)
2442 case NATIVE_WINDOW_DEFAULT_WIDTH: return "NATIVE_WINDOW_DEFAULT_WIDTH";
2443 case NATIVE_WINDOW_DEFAULT_HEIGHT: return "NATIVE_WINDOW_DEFAULT_HEIGHT";
2444 case NATIVE_WINDOW_TRANSFORM_HINT: return "NATIVE_WINDOW_TRANSFORM_HINT";
2445-#if ANDROID_VERSION_MAJOR>=4 && ANDROID_VERSION_MINOR>=1
2446+#if ANDROID_VERSION_MAJOR>=4 && ANDROID_VERSION_MINOR>=1 || ANDROID_VERSION_MAJOR>=5
2447 case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: return "NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND";
2448 #endif
2449 default: return "NATIVE_UNKNOWN_QUERY";
2450@@ -353,7 +371,7 @@ int BaseNativeWindow::_perform(struct ANativeWindow* window, int operation, ...
2451 case NATIVE_WINDOW_API_DISCONNECT : // 14, /* private */
2452 TRACE("api disconnect");
2453 break;
2454-#if ANDROID_VERSION_MAJOR>=4 && ANDROID_VERSION_MINOR>=1
2455+#if ANDROID_VERSION_MAJOR>=4 && ANDROID_VERSION_MINOR>=1 || ANDROID_VERSION_MAJOR>=5
2456 case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS : // 15, /* private */
2457 TRACE("set buffers user dimensions");
2458 break;
2459diff --git a/hybris/egl/platforms/common/nativewindowbase.h b/hybris/egl/platforms/common/nativewindowbase.h
2460index fadb123..247575a 100644
2461--- a/hybris/egl/platforms/common/nativewindowbase.h
2462+++ b/hybris/egl/platforms/common/nativewindowbase.h
2463@@ -3,7 +3,7 @@
2464
2465 /* for ICS window.h */
2466 #include <string.h>
2467-#include <android/system/window.h>
2468+#include <system/window.h>
2469 #include <EGL/egl.h>
2470 #include "support.h"
2471 #include <stdarg.h>
2472diff --git a/hybris/egl/platforms/common/server_wlegl.cpp b/hybris/egl/platforms/common/server_wlegl.cpp
2473index c2d3ef8..7db9747 100644
2474--- a/hybris/egl/platforms/common/server_wlegl.cpp
2475+++ b/hybris/egl/platforms/common/server_wlegl.cpp
2476@@ -20,6 +20,7 @@
2477 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2478 */
2479
2480+#include <android-config.h>
2481 #include <cstring>
2482
2483 #include <EGL/egl.h>
2484@@ -39,7 +40,7 @@ extern "C" {
2485 static inline server_wlegl *
2486 server_wlegl_from(struct wl_resource *resource)
2487 {
2488- return reinterpret_cast<server_wlegl *>(resource->data);
2489+ return reinterpret_cast<server_wlegl *>(wl_resource_get_user_data(resource));
2490 }
2491
2492 static void
2493@@ -97,7 +98,7 @@ server_wlegl_create_buffer(struct wl_client *client,
2494 return;
2495 }
2496
2497- buffer = server_wlegl_buffer_create(id, width, height, stride,
2498+ buffer = server_wlegl_buffer_create(client, id, width, height, stride,
2499 format, usage, native, wlegl);
2500 if (!buffer) {
2501 native_handle_close((native_handle_t *)native);
2502@@ -107,13 +108,49 @@ server_wlegl_create_buffer(struct wl_client *client,
2503 "invalid native handle");
2504 return;
2505 }
2506+}
2507+
2508+static void
2509+server_wlegl_get_server_buffer_handle(wl_client *client, wl_resource *res, uint32_t id, int32_t width, int32_t height, int32_t format, int32_t usage)
2510+{
2511+ if (width == 0 || height == 0) {
2512+ wl_resource_post_error(res, 0, "invalid buffer size: %u,%u\n", width, height);
2513+ return;
2514+ }
2515+
2516+ server_wlegl *wlegl = server_wlegl_from(res);
2517+
2518+ wl_resource *resource = wl_resource_create(client, &android_wlegl_server_buffer_handle_interface, wl_resource_get_version(res), id);
2519+
2520+ buffer_handle_t _handle;
2521+ int _stride;
2522+
2523+ usage |= GRALLOC_USAGE_HW_COMPOSER;
2524+
2525+ int ret = wlegl->alloc->alloc(wlegl->alloc, width, height, format, usage, &_handle, &_stride);
2526+ server_wlegl_buffer *buffer = server_wlegl_buffer_create_server(client, width, height, _stride, format, usage, _handle, wlegl);
2527+
2528+ struct wl_array ints;
2529+ int *ints_data;
2530+ wl_array_init(&ints);
2531+ ints_data = (int*) wl_array_add(&ints, _handle->numInts * sizeof(int));
2532+ memcpy(ints_data, _handle->data + _handle->numFds, _handle->numInts * sizeof(int));
2533+
2534+ android_wlegl_server_buffer_handle_send_buffer_ints(resource, &ints);
2535+ wl_array_release(&ints);
2536+
2537+ for (int i = 0; i < _handle->numFds; i++) {
2538+ android_wlegl_server_buffer_handle_send_buffer_fd(resource, _handle->data[i]);
2539+ }
2540
2541- wl_client_add_resource(client, &buffer->base.resource);
2542+ android_wlegl_server_buffer_handle_send_buffer(resource, buffer->resource, format, _stride);
2543+ wl_resource_destroy(resource);
2544 }
2545
2546 static const struct android_wlegl_interface server_wlegl_impl = {
2547 server_wlegl_create_handle,
2548 server_wlegl_create_buffer,
2549+ server_wlegl_get_server_buffer_handle,
2550 };
2551
2552 static void
2553@@ -123,12 +160,12 @@ server_wlegl_bind(struct wl_client *client, void *data,
2554 server_wlegl *wlegl = reinterpret_cast<server_wlegl *>(data);
2555 struct wl_resource *resource;
2556
2557- resource = wl_client_add_object(client, &android_wlegl_interface,
2558- &server_wlegl_impl, id, wlegl);
2559+ resource = wl_resource_create(client, &android_wlegl_interface, version, id);
2560+ wl_resource_set_implementation(resource, &server_wlegl_impl, wlegl, 0);
2561 }
2562
2563 server_wlegl *
2564-server_wlegl_create(struct wl_display *display, gralloc_module_t *gralloc)
2565+server_wlegl_create(struct wl_display *display, gralloc_module_t *gralloc, alloc_device_t *alloc)
2566 {
2567 struct server_wlegl *wlegl;
2568 int ret;
2569@@ -136,10 +173,10 @@ server_wlegl_create(struct wl_display *display, gralloc_module_t *gralloc)
2570 wlegl = new server_wlegl;
2571
2572 wlegl->display = display;
2573- wlegl->global = wl_display_add_global(display,
2574- &android_wlegl_interface,
2575+ wlegl->global = wl_global_create(display, &android_wlegl_interface, 2,
2576 wlegl, server_wlegl_bind);
2577 wlegl->gralloc = (const gralloc_module_t *)gralloc;
2578+ wlegl->alloc = alloc;
2579
2580 return wlegl;
2581 }
2582diff --git a/hybris/egl/platforms/common/server_wlegl.h b/hybris/egl/platforms/common/server_wlegl.h
2583index 4a26218..c5ae73e 100644
2584--- a/hybris/egl/platforms/common/server_wlegl.h
2585+++ b/hybris/egl/platforms/common/server_wlegl.h
2586@@ -37,14 +37,9 @@ struct wl_buffer;
2587 struct server_wlegl;
2588
2589 server_wlegl *
2590-server_wlegl_create(struct wl_display *wldpy, gralloc_module_t *gralloc);
2591+server_wlegl_create(struct wl_display *wldpy, gralloc_module_t *gralloc, alloc_device_t *alloc);
2592
2593 void
2594 server_wlegl_destroy(server_wlegl *wlegl);
2595
2596-EGLImageKHR
2597-egl_create_image_wl(EGLDisplay egldisplay,
2598- struct wl_buffer *user_buffer,
2599- const EGLint *attrib_list);
2600-
2601 #endif /* SERVER_WLEGL_H */
2602diff --git a/hybris/egl/platforms/common/server_wlegl_buffer.cpp b/hybris/egl/platforms/common/server_wlegl_buffer.cpp
2603index dd8e08d..4767f6b 100644
2604--- a/hybris/egl/platforms/common/server_wlegl_buffer.cpp
2605+++ b/hybris/egl/platforms/common/server_wlegl_buffer.cpp
2606@@ -20,6 +20,7 @@
2607 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2608 */
2609
2610+#include <android-config.h>
2611 #include <cstring>
2612 #include <cassert>
2613
2614@@ -37,27 +38,22 @@ static const struct wl_buffer_interface server_wlegl_buffer_impl = {
2615 };
2616
2617 server_wlegl_buffer *
2618-server_wlegl_buffer_from(struct wl_buffer *buffer)
2619+server_wlegl_buffer_from(struct wl_resource *buffer)
2620 {
2621- if (buffer->resource.object.implementation !=
2622- (void (**)(void)) &server_wlegl_buffer_impl)
2623- return NULL;
2624-
2625- return container_of(buffer, server_wlegl_buffer, base);
2626+ return static_cast<server_wlegl_buffer *>(wl_resource_get_user_data(buffer));
2627 }
2628
2629 static void
2630 server_wlegl_buffer_dtor(struct wl_resource *resource)
2631 {
2632- struct wl_buffer *base =
2633- reinterpret_cast<struct wl_buffer*>(resource->data);
2634- server_wlegl_buffer *buffer = server_wlegl_buffer_from(base);
2635+ server_wlegl_buffer *buffer = server_wlegl_buffer_from(resource);
2636 buffer->buf->common.decRef(&buffer->buf->common);
2637 delete buffer;
2638 }
2639
2640 server_wlegl_buffer *
2641-server_wlegl_buffer_create(uint32_t id,
2642+server_wlegl_buffer_create(wl_client *client,
2643+ uint32_t id,
2644 int32_t width,
2645 int32_t height,
2646 int32_t stride,
2647@@ -69,29 +65,42 @@ server_wlegl_buffer_create(uint32_t id,
2648 server_wlegl_buffer *buffer = new server_wlegl_buffer;
2649 int ret;
2650
2651- memset(buffer, 0, sizeof(*buffer));
2652-
2653 buffer->wlegl = wlegl;
2654-
2655- buffer->base.resource.object.id = id;
2656- buffer->base.resource.object.interface = &wl_buffer_interface;
2657- buffer->base.resource.object.implementation =
2658- (void (**)(void)) &server_wlegl_buffer_impl;
2659-
2660- buffer->base.resource.data = &buffer->base;
2661- buffer->base.resource.destroy = server_wlegl_buffer_dtor;
2662-
2663- buffer->base.width = width;
2664- buffer->base.height = height;
2665+ buffer->resource = wl_resource_create(client, &wl_buffer_interface, 1, id);
2666+ wl_resource_set_implementation(buffer->resource, &server_wlegl_buffer_impl, buffer, server_wlegl_buffer_dtor);
2667
2668 ret = wlegl->gralloc->registerBuffer(wlegl->gralloc, handle);
2669 if (ret) {
2670 delete buffer;
2671 return NULL;
2672 }
2673-
2674+
2675+ buffer->buf = new RemoteWindowBuffer(
2676+ width, height, stride, format, usage, handle, wlegl->gralloc, NULL);
2677+ buffer->buf->common.incRef(&buffer->buf->common);
2678+ return buffer;
2679+}
2680+
2681+server_wlegl_buffer *
2682+server_wlegl_buffer_create_server(wl_client *client,
2683+ int32_t width,
2684+ int32_t height,
2685+ int32_t stride,
2686+ int32_t format,
2687+ int32_t usage,
2688+ buffer_handle_t handle,
2689+ server_wlegl *wlegl)
2690+{
2691+ server_wlegl_buffer *buffer = new server_wlegl_buffer;
2692+ int ret;
2693+
2694+ buffer->wlegl = wlegl;
2695+ buffer->resource = wl_resource_create(client, &wl_buffer_interface, 1, 0);
2696+ wl_resource_set_implementation(buffer->resource, &server_wlegl_buffer_impl, buffer, server_wlegl_buffer_dtor);
2697+
2698 buffer->buf = new RemoteWindowBuffer(
2699- width, height, stride, format, usage, handle, wlegl->gralloc);
2700+ width, height, stride, format, usage, handle, wlegl->gralloc, wlegl->alloc);
2701+ buffer->buf->setAllocated(true);
2702 buffer->buf->common.incRef(&buffer->buf->common);
2703 return buffer;
2704 }
2705diff --git a/hybris/egl/platforms/common/server_wlegl_buffer.h b/hybris/egl/platforms/common/server_wlegl_buffer.h
2706index 67b42e4..9e86719 100644
2707--- a/hybris/egl/platforms/common/server_wlegl_buffer.h
2708+++ b/hybris/egl/platforms/common/server_wlegl_buffer.h
2709@@ -33,18 +33,23 @@
2710 struct server_wlegl;
2711
2712 struct server_wlegl_buffer {
2713- struct wl_buffer base;
2714+ struct wl_resource *resource;
2715 server_wlegl *wlegl;
2716
2717 RemoteWindowBuffer *buf;
2718 };
2719
2720 server_wlegl_buffer *
2721-server_wlegl_buffer_create(uint32_t id, int32_t width, int32_t height,
2722+server_wlegl_buffer_create(wl_client *client, uint32_t id, int32_t width, int32_t height,
2723 int32_t stride, int32_t format, int32_t usage,
2724 buffer_handle_t handle, server_wlegl *wlegl);
2725
2726 server_wlegl_buffer *
2727-server_wlegl_buffer_from(struct wl_buffer *);
2728+server_wlegl_buffer_create_server(wl_client *client, int32_t width, int32_t height,
2729+ int32_t stride, int32_t format, int32_t usage,
2730+ buffer_handle_t handle, server_wlegl *wlegl);
2731+
2732+server_wlegl_buffer *
2733+server_wlegl_buffer_from(struct wl_resource *);
2734
2735 #endif /* SERVER_WLEGL_BUFFER_H */
2736diff --git a/hybris/egl/platforms/common/server_wlegl_handle.cpp b/hybris/egl/platforms/common/server_wlegl_handle.cpp
2737index fcac8f3..04ad085 100644
2738--- a/hybris/egl/platforms/common/server_wlegl_handle.cpp
2739+++ b/hybris/egl/platforms/common/server_wlegl_handle.cpp
2740@@ -20,6 +20,7 @@
2741 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2742 */
2743
2744+#include <android-config.h>
2745 #include <stdint.h>
2746 #include <cstring>
2747 #include <unistd.h>
2748diff --git a/hybris/egl/platforms/common/server_wlegl_private.h b/hybris/egl/platforms/common/server_wlegl_private.h
2749index 0e19f0c..b0a1397 100644
2750--- a/hybris/egl/platforms/common/server_wlegl_private.h
2751+++ b/hybris/egl/platforms/common/server_wlegl_private.h
2752@@ -34,6 +34,7 @@ struct server_wlegl {
2753 struct wl_global *global;
2754
2755 const gralloc_module_t *gralloc;
2756+ alloc_device_t *alloc;
2757 };
2758
2759 #endif /* SERVER_WLEGL_PRIVATE_H */
2760diff --git a/hybris/egl/platforms/common/wayland-android-client-protocol.h b/hybris/egl/platforms/common/wayland-android-client-protocol.h
2761deleted file mode 100644
2762index 822eb7b..0000000
2763--- a/hybris/egl/platforms/common/wayland-android-client-protocol.h
2764+++ /dev/null
2765@@ -1,149 +0,0 @@
2766-/*
2767- * Copyright © 2012 Collabora, Ltd.
2768- *
2769- * Permission to use, copy, modify, distribute, and sell this
2770- * software and its documentation for any purpose is hereby granted
2771- * without fee, provided that the above copyright notice appear in
2772- * all copies and that both that copyright notice and this permission
2773- * notice appear in supporting documentation, and that the name of
2774- * the copyright holders not be used in advertising or publicity
2775- * pertaining to distribution of the software without specific,
2776- * written prior permission. The copyright holders make no
2777- * representations about the suitability of this software for any
2778- * purpose. It is provided "as is" without express or implied
2779- * warranty.
2780- *
2781- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
2782- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
2783- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
2784- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2785- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
2786- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
2787- * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
2788- * THIS SOFTWARE.
2789- */
2790-
2791-#ifndef ANDROID_CLIENT_PROTOCOL_H
2792-#define ANDROID_CLIENT_PROTOCOL_H
2793-
2794-#ifdef __cplusplus
2795-extern "C" {
2796-#endif
2797-
2798-#include <stdint.h>
2799-#include <stddef.h>
2800-#include "wayland-client.h"
2801-
2802-struct wl_client;
2803-struct wl_resource;
2804-
2805-struct android_wlegl;
2806-struct android_wlegl_handle;
2807-
2808-extern const struct wl_interface android_wlegl_interface;
2809-extern const struct wl_interface android_wlegl_handle_interface;
2810-
2811-#ifndef ANDROID_WLEGL_ERROR_ENUM
2812-#define ANDROID_WLEGL_ERROR_ENUM
2813-enum android_wlegl_error {
2814- ANDROID_WLEGL_ERROR_BAD_HANDLE = 0,
2815- ANDROID_WLEGL_ERROR_BAD_VALUE = 1,
2816-};
2817-#endif /* ANDROID_WLEGL_ERROR_ENUM */
2818-
2819-#define ANDROID_WLEGL_CREATE_HANDLE 0
2820-#define ANDROID_WLEGL_CREATE_BUFFER 1
2821-
2822-static inline void
2823-android_wlegl_set_user_data(struct android_wlegl *android_wlegl, void *user_data)
2824-{
2825- wl_proxy_set_user_data((struct wl_proxy *) android_wlegl, user_data);
2826-}
2827-
2828-static inline void *
2829-android_wlegl_get_user_data(struct android_wlegl *android_wlegl)
2830-{
2831- return wl_proxy_get_user_data((struct wl_proxy *) android_wlegl);
2832-}
2833-
2834-static inline void
2835-android_wlegl_destroy(struct android_wlegl *android_wlegl)
2836-{
2837- wl_proxy_destroy((struct wl_proxy *) android_wlegl);
2838-}
2839-
2840-static inline struct android_wlegl_handle *
2841-android_wlegl_create_handle(struct android_wlegl *android_wlegl, int32_t num_fds, struct wl_array *ints)
2842-{
2843- struct wl_proxy *id;
2844-
2845- id = wl_proxy_create((struct wl_proxy *) android_wlegl,
2846- &android_wlegl_handle_interface);
2847- if (!id)
2848- return NULL;
2849-
2850- wl_proxy_marshal((struct wl_proxy *) android_wlegl,
2851- ANDROID_WLEGL_CREATE_HANDLE, id, num_fds, ints);
2852-
2853- return (struct android_wlegl_handle *) id;
2854-}
2855-
2856-static inline struct wl_buffer *
2857-android_wlegl_create_buffer(struct android_wlegl *android_wlegl, int32_t width, int32_t height, int32_t stride, int32_t format, int32_t usage, struct android_wlegl_handle *native_handle)
2858-{
2859- struct wl_proxy *id;
2860-
2861- id = wl_proxy_create((struct wl_proxy *) android_wlegl,
2862- &wl_buffer_interface);
2863- if (!id)
2864- return NULL;
2865-
2866- wl_proxy_marshal((struct wl_proxy *) android_wlegl,
2867- ANDROID_WLEGL_CREATE_BUFFER, id, width, height, stride, format, usage, native_handle);
2868-
2869- return (struct wl_buffer *) id;
2870-}
2871-
2872-#ifndef ANDROID_WLEGL_HANDLE_ERROR_ENUM
2873-#define ANDROID_WLEGL_HANDLE_ERROR_ENUM
2874-enum android_wlegl_handle_error {
2875- ANDROID_WLEGL_HANDLE_ERROR_TOO_MANY_FDS = 0,
2876-};
2877-#endif /* ANDROID_WLEGL_HANDLE_ERROR_ENUM */
2878-
2879-#define ANDROID_WLEGL_HANDLE_ADD_FD 0
2880-#define ANDROID_WLEGL_HANDLE_DESTROY 1
2881-
2882-static inline void
2883-android_wlegl_handle_set_user_data(struct android_wlegl_handle *android_wlegl_handle, void *user_data)
2884-{
2885- wl_proxy_set_user_data((struct wl_proxy *) android_wlegl_handle, user_data);
2886-}
2887-
2888-static inline void *
2889-android_wlegl_handle_get_user_data(struct android_wlegl_handle *android_wlegl_handle)
2890-{
2891- return wl_proxy_get_user_data((struct wl_proxy *) android_wlegl_handle);
2892-}
2893-
2894-static inline void
2895-android_wlegl_handle_add_fd(struct android_wlegl_handle *android_wlegl_handle, int32_t fd)
2896-{
2897- wl_proxy_marshal((struct wl_proxy *) android_wlegl_handle,
2898- ANDROID_WLEGL_HANDLE_ADD_FD, fd);
2899-}
2900-
2901-static inline void
2902-android_wlegl_handle_destroy(struct android_wlegl_handle *android_wlegl_handle)
2903-{
2904- wl_proxy_marshal((struct wl_proxy *) android_wlegl_handle,
2905- ANDROID_WLEGL_HANDLE_DESTROY);
2906-
2907- wl_proxy_destroy((struct wl_proxy *) android_wlegl_handle);
2908-}
2909-
2910-#ifdef __cplusplus
2911-}
2912-#endif
2913-
2914-#endif
2915diff --git a/hybris/egl/platforms/common/wayland-android-protocol.c b/hybris/egl/platforms/common/wayland-android-protocol.c
2916deleted file mode 100644
2917index f4903e2..0000000
2918--- a/hybris/egl/platforms/common/wayland-android-protocol.c
2919+++ /dev/null
2920@@ -1,69 +0,0 @@
2921-/*
2922- * Copyright © 2012 Collabora, Ltd.
2923- *
2924- * Permission to use, copy, modify, distribute, and sell this
2925- * software and its documentation for any purpose is hereby granted
2926- * without fee, provided that the above copyright notice appear in
2927- * all copies and that both that copyright notice and this permission
2928- * notice appear in supporting documentation, and that the name of
2929- * the copyright holders not be used in advertising or publicity
2930- * pertaining to distribution of the software without specific,
2931- * written prior permission. The copyright holders make no
2932- * representations about the suitability of this software for any
2933- * purpose. It is provided "as is" without express or implied
2934- * warranty.
2935- *
2936- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
2937- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
2938- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
2939- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2940- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
2941- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
2942- * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
2943- * THIS SOFTWARE.
2944- */
2945-
2946-#include <stdlib.h>
2947-#include <stdint.h>
2948-#include "wayland-util.h"
2949-
2950-extern const struct wl_interface android_wlegl_handle_interface;
2951-extern const struct wl_interface wl_buffer_interface;
2952-extern const struct wl_interface android_wlegl_handle_interface;
2953-
2954-static const struct wl_interface *types[] = {
2955- NULL,
2956- &android_wlegl_handle_interface,
2957- NULL,
2958- NULL,
2959- &wl_buffer_interface,
2960- NULL,
2961- NULL,
2962- NULL,
2963- NULL,
2964- NULL,
2965- &android_wlegl_handle_interface,
2966-};
2967-
2968-static const struct wl_message android_wlegl_requests[] = {
2969- { "create_handle", "nia", types + 1 },
2970- { "create_buffer", "niiiiio", types + 4 },
2971-};
2972-
2973-WL_EXPORT const struct wl_interface android_wlegl_interface = {
2974- "android_wlegl", 1,
2975- 2, android_wlegl_requests,
2976- 0, NULL,
2977-};
2978-
2979-static const struct wl_message android_wlegl_handle_requests[] = {
2980- { "add_fd", "h", types + 0 },
2981- { "destroy", "", types + 0 },
2982-};
2983-
2984-WL_EXPORT const struct wl_interface android_wlegl_handle_interface = {
2985- "android_wlegl_handle", 1,
2986- 2, android_wlegl_handle_requests,
2987- 0, NULL,
2988-};
2989-
2990diff --git a/hybris/egl/platforms/common/wayland-android-server-protocol.h b/hybris/egl/platforms/common/wayland-android-server-protocol.h
2991deleted file mode 100644
2992index 78f77c9..0000000
2993--- a/hybris/egl/platforms/common/wayland-android-server-protocol.h
2994+++ /dev/null
2995@@ -1,142 +0,0 @@
2996-/*
2997- * Copyright © 2012 Collabora, Ltd.
2998- *
2999- * Permission to use, copy, modify, distribute, and sell this
3000- * software and its documentation for any purpose is hereby granted
3001- * without fee, provided that the above copyright notice appear in
3002- * all copies and that both that copyright notice and this permission
3003- * notice appear in supporting documentation, and that the name of
3004- * the copyright holders not be used in advertising or publicity
3005- * pertaining to distribution of the software without specific,
3006- * written prior permission. The copyright holders make no
3007- * representations about the suitability of this software for any
3008- * purpose. It is provided "as is" without express or implied
3009- * warranty.
3010- *
3011- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
3012- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
3013- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
3014- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3015- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
3016- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
3017- * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
3018- * THIS SOFTWARE.
3019- */
3020-
3021-#ifndef ANDROID_SERVER_PROTOCOL_H
3022-#define ANDROID_SERVER_PROTOCOL_H
3023-
3024-#ifdef __cplusplus
3025-extern "C" {
3026-#endif
3027-
3028-#include <stdint.h>
3029-#include <stddef.h>
3030-#include "wayland-util.h"
3031-
3032-struct wl_client;
3033-struct wl_resource;
3034-
3035-struct android_wlegl;
3036-struct android_wlegl_handle;
3037-
3038-extern const struct wl_interface android_wlegl_interface;
3039-extern const struct wl_interface android_wlegl_handle_interface;
3040-
3041-#ifndef ANDROID_WLEGL_ERROR_ENUM
3042-#define ANDROID_WLEGL_ERROR_ENUM
3043-enum android_wlegl_error {
3044- ANDROID_WLEGL_ERROR_BAD_HANDLE = 0,
3045- ANDROID_WLEGL_ERROR_BAD_VALUE = 1,
3046-};
3047-#endif /* ANDROID_WLEGL_ERROR_ENUM */
3048-
3049-/**
3050- * android_wlegl - Android EGL graphics buffer support
3051- * @create_handle: Create an Android native_handle_t object
3052- * @create_buffer: Create a wl_buffer from the native handle
3053- *
3054- * Interface used in the Android wrapper libEGL to share graphics buffers
3055- * between the server and the client.
3056- */
3057-struct android_wlegl_interface {
3058- /**
3059- * create_handle - Create an Android native_handle_t object
3060- * @id: (none)
3061- * @num_fds: (none)
3062- * @ints: an array of int32_t
3063- *
3064- * This creator method initialises the native_handle_t object
3065- * with everything except the file descriptors, which have to be
3066- * submitted separately.
3067- */
3068- void (*create_handle)(struct wl_client *client,
3069- struct wl_resource *resource,
3070- uint32_t id,
3071- int32_t num_fds,
3072- struct wl_array *ints);
3073- /**
3074- * create_buffer - Create a wl_buffer from the native handle
3075- * @id: (none)
3076- * @width: (none)
3077- * @height: (none)
3078- * @stride: (none)
3079- * @format: (none)
3080- * @usage: (none)
3081- * @native_handle: (none)
3082- *
3083- * Pass the Android native_handle_t to the server and attach it
3084- * to the new wl_buffer object.
3085- *
3086- * The android_wlegl_handle object must be destroyed immediately
3087- * after this request.
3088- */
3089- void (*create_buffer)(struct wl_client *client,
3090- struct wl_resource *resource,
3091- uint32_t id,
3092- int32_t width,
3093- int32_t height,
3094- int32_t stride,
3095- int32_t format,
3096- int32_t usage,
3097- struct wl_resource *native_handle);
3098-};
3099-
3100-#ifndef ANDROID_WLEGL_HANDLE_ERROR_ENUM
3101-#define ANDROID_WLEGL_HANDLE_ERROR_ENUM
3102-enum android_wlegl_handle_error {
3103- ANDROID_WLEGL_HANDLE_ERROR_TOO_MANY_FDS = 0,
3104-};
3105-#endif /* ANDROID_WLEGL_HANDLE_ERROR_ENUM */
3106-
3107-/**
3108- * android_wlegl_handle - An Android native_handle_t object
3109- * @add_fd: (none)
3110- * @destroy: (none)
3111- *
3112- * The Android native_handle_t is a semi-opaque object, that contains an
3113- * EGL implementation specific number of int32 values and file descriptors.
3114- *
3115- * We cannot send a variable size array of file descriptors over the
3116- * Wayland protocol, so we send them one by one.
3117- */
3118-struct android_wlegl_handle_interface {
3119- /**
3120- * add_fd - (none)
3121- * @fd: (none)
3122- */
3123- void (*add_fd)(struct wl_client *client,
3124- struct wl_resource *resource,
3125- int32_t fd);
3126- /**
3127- * destroy - (none)
3128- */
3129- void (*destroy)(struct wl_client *client,
3130- struct wl_resource *resource);
3131-};
3132-
3133-#ifdef __cplusplus
3134-}
3135-#endif
3136-
3137-#endif
3138diff --git a/hybris/egl/platforms/common/wayland-android.xml b/hybris/egl/platforms/common/wayland-android.xml
3139index 647a8ca..24ef780 100644
3140--- a/hybris/egl/platforms/common/wayland-android.xml
3141+++ b/hybris/egl/platforms/common/wayland-android.xml
3142@@ -26,7 +26,7 @@
3143 THIS SOFTWARE.
3144 </copyright>
3145
3146- <interface name="android_wlegl" version="1">
3147+ <interface name="android_wlegl" version="2">
3148 <description summary="Android EGL graphics buffer support">
3149 Interface used in the Android wrapper libEGL to share
3150 graphics buffers between the server and the client.
3151@@ -67,6 +67,15 @@
3152 <arg name="native_handle" type="object" interface="android_wlegl_handle" />
3153 </request>
3154
3155+
3156+ <request name="get_server_buffer_handle" since="2">
3157+ <arg name="id" type="new_id" interface="android_wlegl_server_buffer_handle"/>
3158+ <arg name="width" type="int"/>
3159+ <arg name="height" type="int"/>
3160+ <arg name="format" type="int"/>
3161+ <arg name="usage" type="int"/>
3162+ </request>
3163+
3164 </interface>
3165
3166 <interface name="android_wlegl_handle" version="1">
3167@@ -91,4 +100,28 @@
3168
3169 </interface>
3170
3171+
3172+ <interface name="android_wlegl_server_buffer_handle" version="1">
3173+ <description summary="a server allocated buffer">
3174+ On creation a server_side_buffer object will immediately send
3175+ the "buffer_fd" and "buffer_ints" events needed by the client to
3176+ reference the gralloc buffer, followed by the "buffer" event carrying
3177+ the wl_buffer object.
3178+ </description>
3179+ <event name="buffer_fd">
3180+ <arg name="fd" type="fd"/>
3181+ </event>
3182+ <event name="buffer_ints">
3183+ <arg name="ints" type="array"/>
3184+ </event>
3185+ <event name="buffer">
3186+ <description summary="the wl_buffer">
3187+ This event will be sent after the ints and all the fds have been sent
3188+ </description>
3189+ <arg name="buffer" type="new_id" interface="wl_buffer"/>
3190+ <arg name="format" type="int"/>
3191+ <arg name="stride" type="int"/>
3192+ </event>
3193+ </interface>
3194+
3195 </protocol>
3196diff --git a/hybris/egl/platforms/common/wayland-egl-priv.h b/hybris/egl/platforms/common/wayland-egl-priv.h
3197index 9fc3c80..8c2d10d 100644
3198--- a/hybris/egl/platforms/common/wayland-egl-priv.h
3199+++ b/hybris/egl/platforms/common/wayland-egl-priv.h
3200@@ -27,6 +27,7 @@ struct wl_egl_window {
3201
3202 void *nativewindow;
3203 void (*resize_callback)(struct wl_egl_window *, void *);
3204+ void (*free_callback)(struct wl_egl_window *, void *);
3205 };
3206
3207 #ifdef __cplusplus
3208diff --git a/hybris/egl/platforms/common/wayland-egl.c b/hybris/egl/platforms/common/wayland-egl.c
3209index 38a48fe..0fab487 100644
3210--- a/hybris/egl/platforms/common/wayland-egl.c
3211+++ b/hybris/egl/platforms/common/wayland-egl.c
3212@@ -1,3 +1,4 @@
3213+#include <android-config.h>
3214 #include <stdlib.h>
3215
3216 #include <wayland-client.h>
3217@@ -30,6 +31,7 @@ wl_egl_window_create(struct wl_surface *surface,
3218
3219 egl_window->surface = surface;
3220 egl_window->resize_callback = NULL;
3221+ egl_window->free_callback = NULL;
3222 wl_egl_window_resize(egl_window, width, height, 0, 0);
3223 egl_window->attached_width = 0;
3224 egl_window->attached_height = 0;
3225@@ -42,6 +44,8 @@ wl_egl_window_create(struct wl_surface *surface,
3226 WL_EGL_EXPORT void
3227 wl_egl_window_destroy(struct wl_egl_window *egl_window)
3228 {
3229+ if (egl_window->free_callback)
3230+ egl_window->free_callback(egl_window, NULL);
3231 free(egl_window);
3232 }
3233
3234diff --git a/hybris/egl/platforms/common/windowbuffer.cpp b/hybris/egl/platforms/common/windowbuffer.cpp
3235index b75bc17..c7ed412 100644
3236--- a/hybris/egl/platforms/common/windowbuffer.cpp
3237+++ b/hybris/egl/platforms/common/windowbuffer.cpp
3238@@ -20,13 +20,18 @@
3239 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3240 */
3241
3242+#include <android-config.h>
3243 #include <cstring>
3244 #include <cassert>
3245 #include "windowbuffer.h"
3246
3247 RemoteWindowBuffer::~RemoteWindowBuffer()
3248 {
3249+ if (!m_allocated) {
3250 this->m_gralloc->unregisterBuffer(this->m_gralloc, this->handle);
3251 native_handle_close(this->handle);
3252 native_handle_delete(const_cast<native_handle_t*>(this->handle));
3253+ } else if (this->m_alloc) {
3254+ this->m_alloc->free((alloc_device_t *)this->m_alloc, this->handle);
3255+ }
3256 }
3257diff --git a/hybris/egl/platforms/common/windowbuffer.h b/hybris/egl/platforms/common/windowbuffer.h
3258index 5f5628c..7a59821 100644
3259--- a/hybris/egl/platforms/common/windowbuffer.h
3260+++ b/hybris/egl/platforms/common/windowbuffer.h
3261@@ -38,7 +38,8 @@ class RemoteWindowBuffer : public BaseNativeWindowBuffer
3262 unsigned int format,
3263 unsigned int usage,
3264 buffer_handle_t handle,
3265- const gralloc_module_t *gralloc
3266+ const gralloc_module_t *gralloc,
3267+ const alloc_device_t *alloc = NULL
3268 ) {
3269 // Base members
3270 ANativeWindowBuffer::width = width;
3271@@ -48,9 +49,17 @@ class RemoteWindowBuffer : public BaseNativeWindowBuffer
3272 ANativeWindowBuffer::stride = stride;
3273 ANativeWindowBuffer::handle = handle;
3274 this->m_gralloc = gralloc;
3275+ this->m_alloc = alloc;
3276+ this->m_allocated = false;
3277 };
3278 ~RemoteWindowBuffer();
3279+
3280+ void setAllocated(bool allocated) { m_allocated = allocated; }
3281+ bool isAllocated() const { return m_allocated; }
3282+
3283 private:
3284 const gralloc_module_t *m_gralloc;
3285+ const alloc_device_t *m_alloc;
3286+ bool m_allocated;
3287 };
3288 #endif /* WINDOWBUFFER_H */
3289diff --git a/hybris/egl/platforms/fbdev/Makefile.am b/hybris/egl/platforms/fbdev/Makefile.am
3290index 327ba1b..2312cc9 100644
3291--- a/hybris/egl/platforms/fbdev/Makefile.am
3292+++ b/hybris/egl/platforms/fbdev/Makefile.am
3293@@ -9,7 +9,7 @@ eglplatform_fbdev_la_CXXFLAGS = \
3294 -I$(top_srcdir)/common \
3295 -I$(top_srcdir)/egl \
3296 -I$(top_srcdir)/egl/platforms/common \
3297- -I$(top_srcdir)/include/android
3298+ $(ANDROID_HEADERS_CFLAGS)
3299
3300 if WANT_TRACE
3301 eglplatform_fbdev_la_CXXFLAGS += -DDEBUG
3302diff --git a/hybris/egl/platforms/fbdev/eglplatform_fbdev.cpp b/hybris/egl/platforms/fbdev/eglplatform_fbdev.cpp
3303index 8557f7e..d8228a9 100644
3304--- a/hybris/egl/platforms/fbdev/eglplatform_fbdev.cpp
3305+++ b/hybris/egl/platforms/fbdev/eglplatform_fbdev.cpp
3306@@ -1,3 +1,4 @@
3307+#include <android-config.h>
3308 #include <ws.h>
3309 #include "fbdev_window.h"
3310 #include <malloc.h>
3311@@ -13,48 +14,58 @@ extern "C" {
3312
3313 #include "logging.h"
3314
3315-static int inited = 0;
3316 static gralloc_module_t *gralloc = 0;
3317 static framebuffer_device_t *framebuffer = 0;
3318 static alloc_device_t *alloc = 0;
3319 static FbDevNativeWindow *_nativewindow = NULL;
3320
3321-extern "C" int fbdevws_IsValidDisplay(EGLNativeDisplayType display)
3322+extern "C" void fbdevws_init_module(struct ws_egl_interface *egl_iface)
3323 {
3324- if (__sync_fetch_and_add(&inited,1)==0)
3325- {
3326- int err;
3327- err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **) &gralloc);
3328- if (gralloc==NULL) {
3329- fprintf(stderr, "failed to get gralloc module: (%s)\n",strerror(-err));
3330- assert(0);
3331- }
3332-
3333- err = framebuffer_open((hw_module_t *) gralloc, &framebuffer);
3334- if (err) {
3335- fprintf(stderr, "ERROR: failed to open framebuffer: (%s)\n",strerror(-err));
3336- assert(0);
3337- }
3338- TRACE("** framebuffer_open: status=(%s) format=x%x", strerror(-err), framebuffer->format);
3339-
3340- err = gralloc_open((const hw_module_t *) gralloc, &alloc);
3341- if (err) {
3342- fprintf(stderr, "ERROR: failed to open gralloc: (%s)\n",strerror(-err));
3343- assert(0);
3344- }
3345- TRACE("** gralloc_open %p status=%s", gralloc, strerror(-err));
3346- eglplatformcommon_init(gralloc, alloc);
3347+ int err;
3348+ err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **) &gralloc);
3349+ if (gralloc==NULL) {
3350+ fprintf(stderr, "failed to get gralloc module: (%s)\n",strerror(-err));
3351+ assert(0);
3352 }
3353
3354- return display == EGL_DEFAULT_DISPLAY;
3355+ err = framebuffer_open((hw_module_t *) gralloc, &framebuffer);
3356+ if (err) {
3357+ fprintf(stderr, "ERROR: failed to open framebuffer: (%s)\n",strerror(-err));
3358+ assert(0);
3359+ }
3360+ TRACE("** framebuffer_open: status=(%s) format=x%x", strerror(-err), framebuffer->format);
3361+
3362+ err = gralloc_open((const hw_module_t *) gralloc, &alloc);
3363+ if (err) {
3364+ fprintf(stderr, "ERROR: failed to open gralloc: (%s)\n",strerror(-err));
3365+ assert(0);
3366+ }
3367+ TRACE("** gralloc_open %p status=%s", gralloc, strerror(-err));
3368+ eglplatformcommon_init(egl_iface, gralloc, alloc);
3369+}
3370+
3371+extern "C" _EGLDisplay *fbdevws_GetDisplay(EGLNativeDisplayType display)
3372+{
3373+ assert (gralloc != NULL);
3374+
3375+ _EGLDisplay *dpy = 0;
3376+ if (display == EGL_DEFAULT_DISPLAY) {
3377+ dpy = new _EGLDisplay;
3378+ }
3379+ return dpy;
3380+}
3381+
3382+extern "C" void fbdevws_Terminate(_EGLDisplay *dpy)
3383+{
3384+ delete dpy;
3385 }
3386
3387-extern "C" EGLNativeWindowType fbdevws_CreateWindow(EGLNativeWindowType win, EGLNativeDisplayType display)
3388+extern "C" EGLNativeWindowType fbdevws_CreateWindow(EGLNativeWindowType win, _EGLDisplay *display)
3389 {
3390- assert (inited >= 1);
3391+ assert (gralloc != NULL);
3392 assert (_nativewindow == NULL);
3393
3394- _nativewindow = new FbDevNativeWindow(gralloc, alloc, framebuffer);
3395+ _nativewindow = new FbDevNativeWindow(alloc, framebuffer);
3396 _nativewindow->common.incRef(&_nativewindow->common);
3397 return (EGLNativeWindowType) static_cast<struct ANativeWindow *>(_nativewindow);
3398 }
3399@@ -79,13 +90,24 @@ extern "C" void fbdevws_passthroughImageKHR(EGLContext *ctx, EGLenum *target, EG
3400 eglplatformcommon_passthroughImageKHR(ctx, target, buffer, attrib_list);
3401 }
3402
3403+extern "C" void fbdevws_setSwapInterval(EGLDisplay dpy, EGLNativeWindowType win, EGLint interval)
3404+{
3405+ FbDevNativeWindow *window = static_cast<FbDevNativeWindow *>((struct ANativeWindow *)win);
3406+ window->setSwapInterval(interval);
3407+}
3408+
3409 struct ws_module ws_module_info = {
3410- fbdevws_IsValidDisplay,
3411+ fbdevws_init_module,
3412+ fbdevws_GetDisplay,
3413+ fbdevws_Terminate,
3414 fbdevws_CreateWindow,
3415 fbdevws_DestroyWindow,
3416 fbdevws_eglGetProcAddress,
3417 fbdevws_passthroughImageKHR,
3418- eglplatformcommon_eglQueryString
3419+ eglplatformcommon_eglQueryString,
3420+ NULL,
3421+ NULL,
3422+ fbdevws_setSwapInterval,
3423 };
3424
3425 // vim:ts=4:sw=4:noexpandtab
3426diff --git a/hybris/egl/platforms/fbdev/fbdev_window.cpp b/hybris/egl/platforms/fbdev/fbdev_window.cpp
3427index 40ffcf3..f5f7680 100644
3428--- a/hybris/egl/platforms/fbdev/fbdev_window.cpp
3429+++ b/hybris/egl/platforms/fbdev/fbdev_window.cpp
3430@@ -14,6 +14,7 @@
3431 * limitations under the License.
3432 */
3433
3434+#include <android-config.h>
3435 #include "fbdev_window.h"
3436 #include "logging.h"
3437
3438@@ -22,8 +23,6 @@
3439 #include <pthread.h>
3440 #include <stdio.h>
3441
3442-#include <android/android-version.h>
3443-
3444 #define FRAMEBUFFER_PARTITIONS 2
3445
3446 static pthread_cond_t _cond = PTHREAD_COND_INITIALIZER;
3447@@ -65,16 +64,17 @@ FbDevNativeWindowBuffer::~FbDevNativeWindowBuffer()
3448
3449
3450 ////////////////////////////////////////////////////////////////////////////////
3451-FbDevNativeWindow::FbDevNativeWindow(gralloc_module_t* gralloc,
3452- alloc_device_t* alloc,
3453+FbDevNativeWindow::FbDevNativeWindow( alloc_device_t* alloc,
3454 framebuffer_device_t* fbDev)
3455 {
3456 m_alloc = alloc;
3457 m_fbDev = fbDev;
3458 m_bufFormat = m_fbDev->format;
3459 m_usage = GRALLOC_USAGE_HW_FB;
3460+ m_bufferCount = 0;
3461+ m_allocateBuffers = true;
3462
3463-#if ANDROID_VERSION_MAJOR>=4 && ANDROID_VERSION_MINOR>=2
3464+#if ANDROID_VERSION_MAJOR>=4 && ANDROID_VERSION_MINOR>=2 || ANDROID_VERSION_MAJOR>=5
3465 if (m_fbDev->numFramebuffers>0)
3466 setBufferCount(m_fbDev->numFramebuffers);
3467 else
3468@@ -151,6 +151,9 @@ int FbDevNativeWindow::dequeueBuffer(BaseNativeWindowBuffer** buffer, int *fence
3469
3470 pthread_mutex_lock(&_mutex);
3471
3472+ if (m_allocateBuffers)
3473+ reallocateBuffers();
3474+
3475 HYBRIS_TRACE_BEGIN("fbdev-platform", "dequeueBuffer-wait", "");
3476 #if defined(DEBUG)
3477
3478@@ -453,12 +456,9 @@ unsigned int FbDevNativeWindow::transformHint() const
3479 */
3480 int FbDevNativeWindow::setUsage(int usage)
3481 {
3482- int need_realloc = (m_usage != usage);
3483- TRACE("usage=x%x realloc=%d", usage, need_realloc);
3484+ m_allocateBuffers = (m_usage != usage);
3485+ TRACE("usage=x%x m_allocateBuffers=%d", usage, m_allocateBuffers);
3486 m_usage = usage;
3487- if (need_realloc)
3488- this->setBufferCount(m_bufList.size());
3489-
3490 return NO_ERROR;
3491 }
3492
3493@@ -471,11 +471,9 @@ int FbDevNativeWindow::setUsage(int usage)
3494 */
3495 int FbDevNativeWindow::setBuffersFormat(int format)
3496 {
3497- int need_realloc = (format != m_bufFormat);
3498- TRACE("format=x%x realloc=%d", format, need_realloc);
3499+ m_allocateBuffers |= (format != m_bufFormat);
3500+ TRACE("format=x%x m_allocateBuffers=%d", format, m_allocateBuffers);
3501 m_bufFormat = format;
3502- if (need_realloc)
3503- this->setBufferCount(m_bufList.size());
3504 return NO_ERROR;
3505 }
3506
3507@@ -487,12 +485,18 @@ int FbDevNativeWindow::setBuffersFormat(int format)
3508 int FbDevNativeWindow::setBufferCount(int cnt)
3509 {
3510 TRACE("cnt=%d", cnt);
3511- int err=NO_ERROR;
3512- pthread_mutex_lock(&_mutex);
3513+ if (m_bufferCount != cnt) {
3514+ m_bufferCount = cnt;
3515+ m_allocateBuffers = true;
3516+ }
3517+ return NO_ERROR;
3518+}
3519
3520+void FbDevNativeWindow::reallocateBuffers()
3521+{
3522 destroyBuffers();
3523
3524- for(unsigned int i = 0; i < cnt; i++)
3525+ for(unsigned int i = 0; i < m_bufferCount; i++)
3526 {
3527 FbDevNativeWindowBuffer *fbnb = new FbDevNativeWindowBuffer(m_alloc,
3528 m_fbDev->width, m_fbDev->height, m_fbDev->format,
3529@@ -507,16 +511,15 @@ int FbDevNativeWindow::setBufferCount(int cnt)
3530 if (fbnb->status)
3531 {
3532 fbnb->common.decRef(&fbnb->common);
3533- fprintf(stderr,"WARNING: %s: allocated only %d buffers out of %d\n", __PRETTY_FUNCTION__, m_freeBufs, cnt);
3534+ fprintf(stderr,"WARNING: %s: allocated only %d buffers out of %d\n", __PRETTY_FUNCTION__, m_freeBufs, m_bufferCount);
3535 break;
3536 }
3537
3538 m_freeBufs++;
3539 m_bufList.push_back(fbnb);
3540 }
3541- pthread_mutex_unlock(&_mutex);
3542
3543- return err;
3544+ m_allocateBuffers = false;
3545 }
3546
3547 /*
3548diff --git a/hybris/egl/platforms/fbdev/fbdev_window.h b/hybris/egl/platforms/fbdev/fbdev_window.h
3549index 435ad8b..fa651bd 100644
3550--- a/hybris/egl/platforms/fbdev/fbdev_window.h
3551+++ b/hybris/egl/platforms/fbdev/fbdev_window.h
3552@@ -19,7 +19,7 @@
3553
3554 #include "nativewindowbase.h"
3555 #include <linux/fb.h>
3556-#include <android/hardware/gralloc.h>
3557+#include <hardware/gralloc.h>
3558
3559 #include <list>
3560
3561@@ -44,13 +44,13 @@ protected:
3562
3563 class FbDevNativeWindow : public BaseNativeWindow {
3564 public:
3565- FbDevNativeWindow(gralloc_module_t* gralloc, alloc_device_t* alloc,
3566+ FbDevNativeWindow(alloc_device_t* alloc,
3567 framebuffer_device_t* fbDev);
3568 ~FbDevNativeWindow();
3569
3570-protected:
3571 // overloads from BaseNativeWindow
3572 virtual int setSwapInterval(int interval);
3573+protected:
3574
3575 virtual int dequeueBuffer(BaseNativeWindowBuffer** buffer, int* fenceFd);
3576 virtual int queueBuffer(BaseNativeWindowBuffer* buffer, int fenceFd);
3577@@ -73,13 +73,17 @@ protected:
3578
3579 private:
3580 void destroyBuffers();
3581+ void reallocateBuffers();
3582
3583 private:
3584 framebuffer_device_t* m_fbDev;
3585 alloc_device_t* m_alloc;
3586 unsigned int m_usage;
3587 unsigned int m_bufFormat;
3588+ unsigned int m_bufferCount;
3589 int m_freeBufs;
3590+ bool m_allocateBuffers;
3591+
3592 std::list<FbDevNativeWindowBuffer*> m_bufList;
3593 FbDevNativeWindowBuffer* m_frontBuf;
3594 };
3595diff --git a/hybris/egl/platforms/hwcomposer/Makefile.am b/hybris/egl/platforms/hwcomposer/Makefile.am
3596index ec429ee..7df979c 100644
3597--- a/hybris/egl/platforms/hwcomposer/Makefile.am
3598+++ b/hybris/egl/platforms/hwcomposer/Makefile.am
3599@@ -15,7 +15,7 @@ libhybris_hwcomposerwindow_la_CXXFLAGS = \
3600 -I$(top_srcdir)/common \
3601 -I$(top_srcdir)/egl \
3602 -I$(top_srcdir)/egl/platforms/common \
3603- -I$(top_srcdir)/include/android
3604+ $(ANDROID_HEADERS_CFLAGS)
3605
3606 if WANT_TRACE
3607 libhybris_hwcomposerwindow_la_CXXFLAGS += -DDEBUG
3608@@ -32,7 +32,9 @@ libhybris_hwcomposerwindow_la_LDFLAGS = \
3609 if HAS_ANDROID_4_2_0
3610 libhybris_hwcomposerwindow_la_LDFLAGS += $(top_builddir)/libsync/libsync.la
3611 endif
3612-
3613+if HAS_ANDROID_5_0_0
3614+libhybris_hwcomposerwindow_la_LDFLAGS += $(top_builddir)/libsync/libsync.la
3615+endif
3616 pkglib_LTLIBRARIES = eglplatform_hwcomposer.la
3617
3618 eglplatform_hwcomposer_la_SOURCES = \
3619@@ -43,7 +45,7 @@ eglplatform_hwcomposer_la_CXXFLAGS = \
3620 -I$(top_srcdir)/common \
3621 -I$(top_srcdir)/egl \
3622 -I$(top_srcdir)/egl/platforms/common \
3623- -I$(top_srcdir)/include/android
3624+ $(ANDROID_HEADERS_CFLAGS)
3625
3626 if WANT_TRACE
3627 eglplatform_hwcomposer_la_CXXFLAGS += -DDEBUG
3628diff --git a/hybris/egl/platforms/hwcomposer/eglplatform_hwcomposer.cpp b/hybris/egl/platforms/hwcomposer/eglplatform_hwcomposer.cpp
3629index 4385b6b..da24ae6 100644
3630--- a/hybris/egl/platforms/hwcomposer/eglplatform_hwcomposer.cpp
3631+++ b/hybris/egl/platforms/hwcomposer/eglplatform_hwcomposer.cpp
3632@@ -1,3 +1,4 @@
3633+#include <android-config.h>
3634 #include <ws.h>
3635 #include "hwcomposer_window.h"
3636 #include <malloc.h>
3637@@ -13,37 +14,46 @@ extern "C" {
3638
3639 #include "logging.h"
3640
3641-static int inited = 0;
3642 static gralloc_module_t *gralloc = 0;
3643 static alloc_device_t *alloc = 0;
3644 static HWComposerNativeWindow *_nativewindow = NULL;
3645
3646-extern "C" int hwcomposerws_IsValidDisplay(EGLNativeDisplayType display)
3647+extern "C" void hwcomposerws_init_module(struct ws_egl_interface *egl_iface)
3648 {
3649- if (__sync_fetch_and_add(&inited,1)==0)
3650- {
3651- int err;
3652- err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **) &gralloc);
3653- if (gralloc==NULL) {
3654- fprintf(stderr, "failed to get gralloc module: (%s)\n",strerror(-err));
3655- assert(0);
3656- }
3657+ int err;
3658+ err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **) &gralloc);
3659+ if (gralloc==NULL) {
3660+ fprintf(stderr, "failed to get gralloc module: (%s)\n",strerror(-err));
3661+ assert(0);
3662+ }
3663
3664- err = gralloc_open((const hw_module_t *) gralloc, &alloc);
3665- if (err) {
3666- fprintf(stderr, "ERROR: failed to open gralloc: (%s)\n",strerror(-err));
3667- assert(0);
3668- }
3669- TRACE("** gralloc_open %p status=%s", gralloc, strerror(-err));
3670- eglplatformcommon_init(gralloc, alloc);
3671+ err = gralloc_open((const hw_module_t *) gralloc, &alloc);
3672+ if (err) {
3673+ fprintf(stderr, "ERROR: failed to open gralloc: (%s)\n",strerror(-err));
3674+ assert(0);
3675 }
3676+ TRACE("** gralloc_open %p status=%s", gralloc, strerror(-err));
3677+ eglplatformcommon_init(egl_iface, gralloc, alloc);
3678+}
3679
3680- return display == EGL_DEFAULT_DISPLAY;
3681+extern "C" _EGLDisplay *hwcomposerws_GetDisplay(EGLNativeDisplayType display)
3682+{
3683+ assert (gralloc != NULL);
3684+ _EGLDisplay *dpy = 0;
3685+ if (display == EGL_DEFAULT_DISPLAY) {
3686+ dpy = new _EGLDisplay;
3687+ }
3688+ return dpy;
3689+}
3690+
3691+extern "C" void hwcomposerws_Terminate(_EGLDisplay *dpy)
3692+{
3693+ delete dpy;
3694 }
3695
3696-extern "C" EGLNativeWindowType hwcomposerws_CreateWindow(EGLNativeWindowType win, EGLNativeDisplayType display)
3697+extern "C" EGLNativeWindowType hwcomposerws_CreateWindow(EGLNativeWindowType win, _EGLDisplay *display)
3698 {
3699- assert (inited >= 1);
3700+ assert (gralloc != NULL);
3701 assert (_nativewindow == NULL);
3702
3703 HWComposerNativeWindow *window = static_cast<HWComposerNativeWindow *>((ANativeWindow *) win);
3704@@ -74,7 +84,9 @@ extern "C" void hwcomposerws_passthroughImageKHR(EGLContext *ctx, EGLenum *targe
3705 }
3706
3707 struct ws_module ws_module_info = {
3708- hwcomposerws_IsValidDisplay,
3709+ hwcomposerws_init_module,
3710+ hwcomposerws_GetDisplay,
3711+ hwcomposerws_Terminate,
3712 hwcomposerws_CreateWindow,
3713 hwcomposerws_DestroyWindow,
3714 hwcomposerws_eglGetProcAddress,
3715diff --git a/hybris/egl/platforms/hwcomposer/hwcomposer_window.cpp b/hybris/egl/platforms/hwcomposer/hwcomposer_window.cpp
3716index 0ea4068..18056dc 100644
3717--- a/hybris/egl/platforms/hwcomposer/hwcomposer_window.cpp
3718+++ b/hybris/egl/platforms/hwcomposer/hwcomposer_window.cpp
3719@@ -14,6 +14,7 @@
3720 * limitations under the License.
3721 */
3722
3723+#include <android-config.h>
3724 #include "hwcomposer_window.h"
3725 #include "logging.h"
3726
3727@@ -23,10 +24,8 @@
3728 #include <stdio.h>
3729 #include <unistd.h>
3730
3731-#include <android/android-version.h>
3732-
3733 extern "C" {
3734-#include <android/sync/sync.h>
3735+#include <sync/sync.h>
3736 };
3737
3738 static pthread_cond_t _cond = PTHREAD_COND_INITIALIZER;
3739@@ -76,7 +75,7 @@ HWComposerNativeWindow::HWComposerNativeWindow(unsigned int width, unsigned int
3740 m_width = width;
3741 m_height = height;
3742 m_bufFormat = format;
3743- m_usage = GRALLOC_USAGE_HW_COMPOSER;
3744+ m_usage = GRALLOC_USAGE_HW_COMPOSER|GRALLOC_USAGE_HW_FB;
3745 m_frontBuf = NULL;
3746 }
3747
3748@@ -163,44 +162,33 @@ int HWComposerNativeWindow::dequeueBuffer(BaseNativeWindowBuffer** buffer, int *
3749 }
3750 #endif
3751
3752-
3753- while (m_freeBufs==0)
3754- {
3755- pthread_cond_wait(&_cond, &_mutex);
3756- }
3757-
3758- while (1)
3759+ std::list<HWComposerNativeWindowBuffer*>::iterator it = m_bufList.begin();
3760+ for (; it != m_bufList.end(); ++it)
3761 {
3762- std::list<HWComposerNativeWindowBuffer*>::iterator it = m_bufList.begin();
3763- for (; it != m_bufList.end(); ++it)
3764- {
3765- if (*it==m_frontBuf)
3766- continue;
3767- if ((*it)->busy==0)
3768- {
3769- TRACE("Found a free non-front buffer");
3770- break;
3771- }
3772- }
3773- if (it == m_bufList.end())
3774- {
3775- // have to wait once again
3776- pthread_cond_wait(&_cond, &_mutex);
3777+ if (*it==m_frontBuf)
3778 continue;
3779+ if ((*it)->busy==0)
3780+ {
3781+ TRACE("Found a free non-front buffer");
3782+ break;
3783 }
3784-
3785+ }
3786+ if (it == m_bufList.end())
3787+ {
3788+ fbnb = m_frontBuf;
3789+ }
3790+ else
3791+ {
3792 fbnb = *it;
3793- break;
3794 }
3795 HYBRIS_TRACE_END("hwcomposer-platform", "dequeueBuffer-wait", "");
3796
3797 assert(fbnb!=NULL);
3798 fbnb->busy = 1;
3799- m_freeBufs--;
3800
3801 *buffer = fbnb;
3802- *fenceFd = -1;
3803-
3804+ *fenceFd = dup(fbnb->fenceFd);
3805+ close(fbnb->fenceFd);
3806 TRACE("%lu DONE --> %p", pthread_self(), fbnb);
3807 pthread_mutex_unlock(&_mutex);
3808 HYBRIS_TRACE_END("hwcomposer-platform", "dequeueBuffer", "");
3809@@ -233,67 +221,29 @@ int HWComposerNativeWindow::queueBuffer(BaseNativeWindowBuffer* buffer, int fenc
3810 HWComposerNativeWindowBuffer* fbnb = (HWComposerNativeWindowBuffer*) buffer;
3811
3812 HYBRIS_TRACE_BEGIN("hwcomposer-platform", "queueBuffer", "-%p", fbnb);
3813- fbnb->fenceFd = fenceFd;
3814-
3815+
3816 pthread_mutex_lock(&_mutex);
3817-
3818- /* Front buffer hasn't yet been picked up for posting */
3819- while (m_frontBuf && m_frontBuf->busy >= 2)
3820- {
3821- pthread_cond_wait(&_cond, &_mutex);
3822- }
3823-
3824- assert(fbnb->busy==1);
3825- fbnb->busy = 2;
3826 m_frontBuf = fbnb;
3827- m_freeBufs++;
3828-
3829- sync_wait(fenceFd, -1);
3830- ::close(fenceFd);
3831-
3832- pthread_cond_signal(&_cond);
3833-
3834- TRACE("%lu %p %p",pthread_self(), m_frontBuf, fbnb);
3835+ fbnb->fenceFd = fenceFd;
3836+ this->present(fbnb);
3837+ fbnb->busy = 0;
3838 pthread_mutex_unlock(&_mutex);
3839+
3840+ // After this, we expect fenceFd to be equal to the release fd
3841+ TRACE("%lu %p %p",pthread_self(), m_frontBuf, fbnb);
3842 HYBRIS_TRACE_END("hwcomposer-platform", "queueBuffer", "-%p", fbnb);
3843
3844 return 0;
3845 }
3846
3847-void HWComposerNativeWindow::lockFrontBuffer(HWComposerNativeWindowBuffer **buffer)
3848+int HWComposerNativeWindow::getFenceBufferFd(HWComposerNativeWindowBuffer *buffer)
3849 {
3850- TRACE("");
3851- HWComposerNativeWindowBuffer *buf;
3852- pthread_mutex_lock(&_mutex);
3853-
3854- while (!m_frontBuf)
3855- {
3856- pthread_cond_wait(&_cond, &_mutex);
3857- }
3858-
3859- assert(m_frontBuf->busy == 2);
3860-
3861- m_frontBuf->busy = 3;
3862- buf = m_frontBuf;
3863- pthread_mutex_unlock(&_mutex);
3864-
3865- *buffer = buf;
3866- return;
3867-
3868+ return buffer->fenceFd;
3869 }
3870
3871-void HWComposerNativeWindow::unlockFrontBuffer(HWComposerNativeWindowBuffer *buffer)
3872+void HWComposerNativeWindow::setFenceBufferFd(HWComposerNativeWindowBuffer *buffer, int fd)
3873 {
3874- TRACE("");
3875- pthread_mutex_lock(&_mutex);
3876-
3877- assert(buffer == m_frontBuf);
3878- m_frontBuf->busy = 0;
3879-
3880- pthread_cond_signal(&_cond);
3881- pthread_mutex_unlock(&_mutex);
3882-
3883- return;
3884+ buffer->fenceFd = fd;
3885 }
3886
3887 /*
3888@@ -330,11 +280,7 @@ int HWComposerNativeWindow::cancelBuffer(BaseNativeWindowBuffer* buffer, int fen
3889
3890 fbnb->busy=0;
3891
3892- m_freeBufs++;
3893-
3894- pthread_cond_signal(&_cond);
3895- pthread_mutex_unlock(&_mutex);
3896-
3897+ pthread_mutex_unlock(&_mutex);
3898 return 0;
3899 }
3900
3901@@ -494,7 +440,7 @@ int HWComposerNativeWindow::setBufferCount(int cnt)
3902 {
3903 HWComposerNativeWindowBuffer *fbnb = new HWComposerNativeWindowBuffer(m_alloc,
3904 m_width, m_height, m_bufFormat,
3905- m_usage|GRALLOC_USAGE_HW_COMPOSER);
3906+ m_usage|GRALLOC_USAGE_HW_COMPOSER|GRALLOC_USAGE_HW_FB);
3907
3908 fbnb->common.incRef(&fbnb->common);
3909
3910diff --git a/hybris/egl/platforms/hwcomposer/hwcomposer_window.h b/hybris/egl/platforms/hwcomposer/hwcomposer_window.h
3911index 3eb5335..0fd237b 100644
3912--- a/hybris/egl/platforms/hwcomposer/hwcomposer_window.h
3913+++ b/hybris/egl/platforms/hwcomposer/hwcomposer_window.h
3914@@ -19,7 +19,7 @@
3915
3916 #include "nativewindowbase.h"
3917 #include <linux/fb.h>
3918-#include <android/hardware/gralloc.h>
3919+#include <hardware/gralloc.h>
3920
3921 #include <list>
3922
3923@@ -50,9 +50,8 @@ public:
3924 void setup(gralloc_module_t* gralloc, alloc_device_t* alloc);
3925
3926
3927- void lockFrontBuffer(HWComposerNativeWindowBuffer **buffer);
3928- void unlockFrontBuffer(HWComposerNativeWindowBuffer *buffer);
3929-
3930+ int getFenceBufferFd(HWComposerNativeWindowBuffer *buffer);
3931+ void setFenceBufferFd(HWComposerNativeWindowBuffer *buffer, int fd);
3932 protected:
3933 // overloads from BaseNativeWindow
3934 virtual int setSwapInterval(int interval);
3935@@ -75,7 +74,7 @@ protected:
3936 virtual int setBuffersFormat(int format);
3937 virtual int setBuffersDimensions(int width, int height);
3938 virtual int setBufferCount(int cnt);
3939-
3940+ virtual void present(HWComposerNativeWindowBuffer *buffer) = 0;
3941 private:
3942 void destroyBuffers();
3943
3944diff --git a/hybris/egl/platforms/null/Makefile.am b/hybris/egl/platforms/null/Makefile.am
3945index 94ae895..e648a63 100644
3946--- a/hybris/egl/platforms/null/Makefile.am
3947+++ b/hybris/egl/platforms/null/Makefile.am
3948@@ -2,8 +2,25 @@ pkglib_LTLIBRARIES = eglplatform_null.la
3949
3950
3951 eglplatform_null_la_SOURCES = eglplatform_null.c
3952-eglplatform_null_la_CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/egl
3953+eglplatform_null_la_CFLAGS = \
3954+ -I$(top_srcdir)/include \
3955+ -I$(top_srcdir)/common \
3956+ -I$(top_srcdir)/include \
3957+ -I$(top_srcdir)/egl \
3958+ -I$(top_srcdir)/egl/platforms/common \
3959+ $(ANDROID_HEADERS_CFLAGS) \
3960+ $(WAYLAND_SERVER_CFLAGS)
3961
3962-eglplatform_null_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
3963+eglplatform_null_la_LDFLAGS = \
3964+ -avoid-version -module -shared -export-dynamic \
3965+ $(top_builddir)/egl/platforms/common/libhybris-eglplatformcommon.la \
3966+ $(top_builddir)/hardware/libhardware.la \
3967+ $(WAYLAND_SERVER_LIBS)
3968
3969+if WANT_DEBUG
3970+eglplatform_null_la_CFLAGS += -I$(top_srcdir)/common -ggdb -O0
3971+endif
3972
3973+if WANT_TRACE
3974+eglplatform_null_la_CFLAGS += -DDEBUG
3975+endif
3976diff --git a/hybris/egl/platforms/null/eglplatform_null.c b/hybris/egl/platforms/null/eglplatform_null.c
3977index 5663a51..379afe7 100644
3978--- a/hybris/egl/platforms/null/eglplatform_null.c
3979+++ b/hybris/egl/platforms/null/eglplatform_null.c
3980@@ -1,13 +1,19 @@
3981+#include <android-config.h>
3982 #include <ws.h>
3983 #include <dlfcn.h>
3984 #include <stdlib.h>
3985
3986-#include <hybris/internal/binding.h>
3987+#include <hybris/common/binding.h>
3988+#include <eglplatformcommon.h>
3989+#include "logging.h"
3990
3991 static void * (*_androidCreateDisplaySurface)();
3992
3993 static void *_libui = NULL;
3994
3995+static gralloc_module_t *gralloc = 0;
3996+static alloc_device_t *alloc = 0;
3997+
3998 static void _init_androidui()
3999 {
4000 _libui = (void *) android_dlopen("/system/lib/libui.so", RTLD_LAZY);
4001@@ -22,13 +28,27 @@ static EGLNativeWindowType android_createDisplaySurface()
4002 }
4003
4004
4005+static void nullws_init_module(struct ws_egl_interface *egl_iface)
4006+{
4007+ int err;
4008+ hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **) &gralloc);
4009+ err = gralloc_open((const hw_module_t *) gralloc, &alloc);
4010+ TRACE("++ %lu wayland: got gralloc %p err:%s", pthread_self(), gralloc, strerror(-err));
4011+ eglplatformcommon_init(egl_iface, gralloc, alloc);
4012
4013-static int nullws_IsValidDisplay(EGLNativeDisplayType display)
4014+}
4015+
4016+static struct _EGLDisplay *nullws_GetDisplay(EGLNativeDisplayType display)
4017 {
4018- return 1;
4019+ return malloc(sizeof(struct _EGLDisplay));
4020 }
4021
4022-static EGLNativeWindowType nullws_CreateWindow(EGLNativeWindowType win, EGLNativeDisplayType display)
4023+static void nullws_Terminate(struct _EGLDisplay *dpy)
4024+{
4025+ free(dpy);
4026+}
4027+
4028+static EGLNativeWindowType nullws_CreateWindow(EGLNativeWindowType win, struct _EGLDisplay *display)
4029 {
4030 if (win == 0)
4031 {
4032@@ -43,27 +63,14 @@ static void nullws_DestroyWindow(EGLNativeWindowType win)
4033 // TODO: Cleanup?
4034 }
4035
4036-static __eglMustCastToProperFunctionPointerType nullws_eglGetProcAddress(const char *procname)
4037-{
4038- return NULL;
4039-}
4040-
4041-static void nullws_passthroughImageKHR(EGLContext *ctx, EGLenum *target, EGLClientBuffer *buffer, const EGLint **attrib_list)
4042-{
4043-}
4044-
4045-const char *nullws_eglQueryString(EGLDisplay dpy, EGLint name, const char *(*real_eglQueryString)(EGLDisplay dpy, EGLint name))
4046-{
4047- return (*real_eglQueryString)(dpy, name);
4048-}
4049-
4050-
4051 struct ws_module ws_module_info = {
4052- nullws_IsValidDisplay,
4053+ nullws_init_module,
4054+ nullws_GetDisplay,
4055+ nullws_Terminate,
4056 nullws_CreateWindow,
4057 nullws_DestroyWindow,
4058- nullws_eglGetProcAddress,
4059- nullws_passthroughImageKHR,
4060- nullws_eglQueryString
4061+ eglplatformcommon_eglGetProcAddress,
4062+ eglplatformcommon_passthroughImageKHR,
4063+ eglplatformcommon_eglQueryString
4064 };
4065
4066diff --git a/hybris/egl/platforms/wayland/Makefile.am b/hybris/egl/platforms/wayland/Makefile.am
4067index 62cecfc..8a5e9c6 100644
4068--- a/hybris/egl/platforms/wayland/Makefile.am
4069+++ b/hybris/egl/platforms/wayland/Makefile.am
4070@@ -6,7 +6,7 @@ eglplatform_wayland_la_CXXFLAGS = \
4071 -I$(top_srcdir)/include \
4072 -I$(top_srcdir)/egl \
4073 -I$(top_srcdir)/egl/platforms/common \
4074- -I$(top_srcdir)/include/android \
4075+ $(ANDROID_HEADERS_CFLAGS) \
4076 $(WAYLAND_CLIENT_CFLAGS)
4077
4078 if WANT_DEBUG
4079@@ -21,6 +21,10 @@ if WANT_DEBUG
4080 eglplatform_wayland_la_CXXFLAGS += -ggdb -O0
4081 endif
4082
4083+if !WANT_WL_SERVERSIDE_BUFFERS
4084+eglplatform_wayland_la_CXXFLAGS += -DHYBRIS_NO_SERVER_SIDE_BUFFERS
4085+endif
4086+
4087
4088
4089 eglplatform_wayland_la_LDFLAGS = \
4090@@ -28,7 +32,11 @@ eglplatform_wayland_la_LDFLAGS = \
4091 $(top_builddir)/egl/platforms/common/libhybris-eglplatformcommon.la \
4092 $(top_builddir)/hardware/libhardware.la \
4093 $(WAYLAND_CLIENT_LIBS)
4094-
4095 if HAS_ANDROID_4_2_0
4096 eglplatform_wayland_la_LDFLAGS += $(top_builddir)/libsync/libsync.la
4097 endif
4098+
4099+if HAS_ANDROID_5_0_0
4100+eglplatform_wayland_la_LDFLAGS += $(top_builddir)/libsync/libsync.la
4101+endif
4102+
4103diff --git a/hybris/egl/platforms/wayland/eglplatform_wayland.cpp b/hybris/egl/platforms/wayland/eglplatform_wayland.cpp
4104index c7b08e3..a71487f 100644
4105--- a/hybris/egl/platforms/wayland/eglplatform_wayland.cpp
4106+++ b/hybris/egl/platforms/wayland/eglplatform_wayland.cpp
4107@@ -16,25 +16,31 @@
4108 ** License version 2.1 as published by the Free Software Foundation
4109 ** and appearing in the file license.lgpl included in the packaging
4110 ** of this file.
4111- **
4112+ **
4113 ** This library is distributed in the hope that it will be useful,
4114 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
4115 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4116 ** Lesser General Public License for more details.
4117- **
4118+ **
4119 ****************************************************************************************/
4120
4121+#include <android-config.h>
4122 #include <ws.h>
4123 #include <malloc.h>
4124 #include <assert.h>
4125 #include <fcntl.h>
4126 #include <stdio.h>
4127+#include <stdlib.h>
4128 #include <sys/stat.h>
4129 #include <unistd.h>
4130 #include <assert.h>
4131+#include <stdlib.h>
4132 extern "C" {
4133 #include <eglplatformcommon.h>
4134 };
4135+#include <eglhybris.h>
4136+
4137+#include <EGL/eglext.h>
4138
4139 extern "C" {
4140 #include <wayland-client.h>
4141@@ -44,28 +50,146 @@ extern "C" {
4142 #include "wayland_window.h"
4143 #include "logging.h"
4144 #include "wayland-egl-priv.h"
4145+#include "server_wlegl_buffer.h"
4146+#include "wayland-android-client-protocol.h"
4147
4148-static int inited = 0;
4149 static gralloc_module_t *gralloc = 0;
4150 static alloc_device_t *alloc = 0;
4151
4152-extern "C" int waylandws_IsValidDisplay(EGLNativeDisplayType display)
4153+
4154+static const char * (*_eglQueryString)(EGLDisplay dpy, EGLint name) = NULL;
4155+static __eglMustCastToProperFunctionPointerType (*_eglGetProcAddress)(const char *procname) = NULL;
4156+static EGLSyncKHR (*_eglCreateSyncKHR)(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) = NULL;
4157+static EGLBoolean (*_eglDestroySyncKHR)(EGLDisplay dpy, EGLSyncKHR sync) = NULL;
4158+static EGLint (*_eglClientWaitSyncKHR)(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) = NULL;
4159+
4160+struct WaylandDisplay {
4161+ _EGLDisplay base;
4162+
4163+ wl_display *wl_dpy;
4164+ wl_event_queue *queue;
4165+ wl_registry *registry;
4166+ android_wlegl *wlegl;
4167+};
4168+
4169+extern "C" void waylandws_init_module(struct ws_egl_interface *egl_iface)
4170 {
4171 int err;
4172- if ( __sync_fetch_and_add(&inited,1)==0)
4173- {
4174- hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **) &gralloc);
4175- err = gralloc_open((const hw_module_t *) gralloc, &alloc);
4176- TRACE("++ %lu wayland: got gralloc %p err:%s", pthread_self(), gralloc, strerror(-err));
4177- eglplatformcommon_init(gralloc, alloc);
4178+ hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **) &gralloc);
4179+ err = gralloc_open((const hw_module_t *) gralloc, &alloc);
4180+ TRACE("++ %lu wayland: got gralloc %p err:%s", pthread_self(), gralloc, strerror(-err));
4181+ eglplatformcommon_init(egl_iface, gralloc, alloc);
4182+}
4183+
4184+static void _init_egl_funcs(EGLDisplay display)
4185+{
4186+ if (_eglQueryString != NULL)
4187+ return;
4188+
4189+ _eglQueryString = (const char * (*)(void*, int))
4190+ hybris_android_egl_dlsym("eglQueryString");
4191+ assert(_eglQueryString);
4192+ _eglGetProcAddress = (__eglMustCastToProperFunctionPointerType (*)(const char *))
4193+ hybris_android_egl_dlsym("eglGetProcAddress");
4194+ assert(_eglGetProcAddress);
4195+
4196+ const char *extensions = (*_eglQueryString)(display, EGL_EXTENSIONS);
4197+
4198+ if (strstr(extensions, "EGL_KHR_fence_sync")) {
4199+ _eglCreateSyncKHR = (PFNEGLCREATESYNCKHRPROC)
4200+ (*_eglGetProcAddress)("eglCreateSyncKHR");
4201+ assert(_eglCreateSyncKHR);
4202+ _eglDestroySyncKHR = (PFNEGLDESTROYSYNCKHRPROC)
4203+ (*_eglGetProcAddress)("eglDestroySyncKHR");
4204+ assert(_eglDestroySyncKHR);
4205+ _eglClientWaitSyncKHR = (PFNEGLCLIENTWAITSYNCKHRPROC)
4206+ (*_eglGetProcAddress)("eglClientWaitSyncKHR");
4207+ assert(_eglClientWaitSyncKHR);
4208 }
4209+}
4210
4211- return 1;
4212+static void registry_handle_global(void *data, wl_registry *registry, uint32_t name, const char *interface, uint32_t version)
4213+{
4214+ WaylandDisplay *dpy = (WaylandDisplay *)data;
4215+
4216+ if (strcmp(interface, "android_wlegl") == 0) {
4217+ dpy->wlegl = static_cast<struct android_wlegl *>(wl_registry_bind(registry, name, &android_wlegl_interface, std::min(2u, version)));
4218+ }
4219+}
4220+
4221+static const wl_registry_listener registry_listener = {
4222+ registry_handle_global
4223+};
4224+
4225+static void callback_done(void *data, wl_callback *cb, uint32_t d)
4226+{
4227+ WaylandDisplay *dpy = (WaylandDisplay *)data;
4228+
4229+ wl_callback_destroy(cb);
4230+ if (!dpy->wlegl) {
4231+ fprintf(stderr, "Fatal: the server doesn't advertise the android_wlegl global!");
4232+ abort();
4233+ }
4234 }
4235
4236-extern "C" EGLNativeWindowType waylandws_CreateWindow(EGLNativeWindowType win, EGLNativeDisplayType display)
4237+static const wl_callback_listener callback_listener = {
4238+ callback_done
4239+};
4240+
4241+extern "C" _EGLDisplay *waylandws_GetDisplay(EGLNativeDisplayType display)
4242+{
4243+ WaylandDisplay *wdpy = new WaylandDisplay;
4244+ wdpy->wl_dpy = (wl_display *)display;
4245+ wdpy->wlegl = NULL;
4246+ wdpy->queue = wl_display_create_queue(wdpy->wl_dpy);
4247+ wdpy->registry = wl_display_get_registry(wdpy->wl_dpy);
4248+ wl_proxy_set_queue((wl_proxy *) wdpy->registry, wdpy->queue);
4249+ wl_registry_add_listener(wdpy->registry, &registry_listener, wdpy);
4250+
4251+ wl_callback *cb = wl_display_sync(wdpy->wl_dpy);
4252+ wl_proxy_set_queue((wl_proxy *) cb, wdpy->queue);
4253+ wl_callback_add_listener(cb, &callback_listener, wdpy);
4254+
4255+ return &wdpy->base;
4256+}
4257+
4258+extern "C" void waylandws_Terminate(_EGLDisplay *dpy)
4259 {
4260- WaylandNativeWindow *window = new WaylandNativeWindow((struct wl_egl_window *) win, (struct wl_display *) display, gralloc, alloc);
4261+ WaylandDisplay *wdpy = (WaylandDisplay *)dpy;
4262+ int ret = 0;
4263+ // We still have the sync callback on flight, wait for it to arrive
4264+ while (ret == 0 && !wdpy->wlegl) {
4265+ ret = wl_display_dispatch_queue(wdpy->wl_dpy, wdpy->queue);
4266+ }
4267+ assert(ret >= 0);
4268+ android_wlegl_destroy(wdpy->wlegl);
4269+ wl_registry_destroy(wdpy->registry);
4270+ wl_event_queue_destroy(wdpy->queue);
4271+ delete wdpy;
4272+}
4273+
4274+extern "C" EGLNativeWindowType waylandws_CreateWindow(EGLNativeWindowType win, _EGLDisplay *display)
4275+{
4276+ struct wl_egl_window *wl_window = (struct wl_egl_window*) win;
4277+ struct wl_display *wl_display = (struct wl_display*) display;
4278+
4279+ if (wl_window == 0 || wl_display == 0) {
4280+ HYBRIS_ERROR("Running with EGL_PLATFORM=wayland without setup wayland environment is not possible");
4281+ HYBRIS_ERROR("If you want to run a standlone EGL client do it like this:");
4282+ HYBRIS_ERROR(" $ export EGL_PLATFORM=null");
4283+ HYBRIS_ERROR(" $ test_glevs2");
4284+ abort();
4285+ }
4286+
4287+ WaylandDisplay *wdpy = (WaylandDisplay *)display;
4288+
4289+ int ret = 0;
4290+ while (ret == 0 && !wdpy->wlegl) {
4291+ ret = wl_display_dispatch_queue(wdpy->wl_dpy, wdpy->queue);
4292+ }
4293+ assert(ret >= 0);
4294+
4295+ WaylandNativeWindow *window = new WaylandNativeWindow((struct wl_egl_window *) win, wdpy->wl_dpy, wdpy->wlegl, alloc, gralloc);
4296 window->common.incRef(&window->common);
4297 return (EGLNativeWindowType) static_cast<struct ANativeWindow *>(window);
4298 }
4299@@ -83,12 +207,37 @@ extern "C" int waylandws_post(EGLNativeWindowType win, void *buffer)
4300 return ((WaylandNativeWindow *) eglwin->nativewindow)->postBuffer((ANativeWindowBuffer *) buffer);
4301 }
4302
4303-extern "C" __eglMustCastToProperFunctionPointerType waylandws_eglGetProcAddress(const char *procname)
4304+extern "C" wl_buffer *waylandws_createWlBuffer(EGLDisplay dpy, EGLImageKHR image)
4305+{
4306+ egl_image *img = reinterpret_cast<egl_image *>(image);
4307+ if (!img) {
4308+ // The spec says we should send a EGL_BAD_PARAMETER error here, but we don't have the
4309+ // means, as of now.
4310+ return NULL;
4311+ }
4312+ if (img->target == EGL_WAYLAND_BUFFER_WL) {
4313+ WaylandDisplay *wdpy = (WaylandDisplay *)hybris_egl_display_get_mapping(dpy);
4314+ server_wlegl_buffer *buf = server_wlegl_buffer_from((wl_resource *)img->egl_buffer);
4315+ WaylandNativeWindowBuffer wnb(buf->buf);
4316+ // The buffer will be managed by the app, so pass NULL as the queue so that
4317+ // it will be assigned to the default queue
4318+ wnb.wlbuffer_from_native_handle(wdpy->wlegl, wdpy->wl_dpy, NULL);
4319+ return wnb.wlbuffer;
4320+ }
4321+ // EGL_BAD_MATCH
4322+ return NULL;
4323+}
4324+
4325+extern "C" __eglMustCastToProperFunctionPointerType waylandws_eglGetProcAddress(const char *procname)
4326 {
4327 if (strcmp(procname, "eglHybrisWaylandPostBuffer") == 0)
4328 {
4329 return (__eglMustCastToProperFunctionPointerType) waylandws_post;
4330 }
4331+ else if (strcmp(procname, "eglCreateWaylandBufferFromImageWL") == 0)
4332+ {
4333+ return (__eglMustCastToProperFunctionPointerType) waylandws_createWlBuffer;
4334+ }
4335 else
4336 return eglplatformcommon_eglGetProcAddress(procname);
4337 }
4338@@ -98,13 +247,56 @@ extern "C" void waylandws_passthroughImageKHR(EGLContext *ctx, EGLenum *target,
4339 eglplatformcommon_passthroughImageKHR(ctx, target, buffer, attrib_list);
4340 }
4341
4342+extern "C" const char *waylandws_eglQueryString(EGLDisplay dpy, EGLint name, const char *(*real_eglQueryString)(EGLDisplay dpy, EGLint name))
4343+{
4344+ const char *ret = eglplatformcommon_eglQueryString(dpy, name, real_eglQueryString);
4345+ if (ret && name == EGL_EXTENSIONS)
4346+ {
4347+ static char eglextensionsbuf[512];
4348+ snprintf(eglextensionsbuf, 510, "%s %s", ret,
4349+ "EGL_EXT_swap_buffers_with_damage EGL_WL_create_wayland_buffer_from_image"
4350+ );
4351+ ret = eglextensionsbuf;
4352+ }
4353+ return ret;
4354+}
4355+
4356+extern "C" void waylandws_prepareSwap(EGLDisplay dpy, EGLNativeWindowType win, EGLint *damage_rects, EGLint damage_n_rects)
4357+{
4358+ WaylandNativeWindow *window = static_cast<WaylandNativeWindow *>((struct ANativeWindow *)win);
4359+ window->prepareSwap(damage_rects, damage_n_rects);
4360+}
4361+
4362+extern "C" void waylandws_finishSwap(EGLDisplay dpy, EGLNativeWindowType win)
4363+{
4364+ _init_egl_funcs(dpy);
4365+ WaylandNativeWindow *window = static_cast<WaylandNativeWindow *>((struct ANativeWindow *)win);
4366+ if (_eglCreateSyncKHR) {
4367+ EGLSyncKHR sync = (*_eglCreateSyncKHR)(dpy, EGL_SYNC_FENCE_KHR, NULL);
4368+ (*_eglClientWaitSyncKHR)(dpy, sync, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, EGL_FOREVER_KHR);
4369+ (*_eglDestroySyncKHR)(dpy, sync);
4370+ }
4371+ window->finishSwap();
4372+}
4373+
4374+extern "C" void waylandws_setSwapInterval(EGLDisplay dpy, EGLNativeWindowType win, EGLint interval)
4375+{
4376+ WaylandNativeWindow *window = static_cast<WaylandNativeWindow *>((struct ANativeWindow *)win);
4377+ window->setSwapInterval(interval);
4378+}
4379+
4380 struct ws_module ws_module_info = {
4381- waylandws_IsValidDisplay,
4382+ waylandws_init_module,
4383+ waylandws_GetDisplay,
4384+ waylandws_Terminate,
4385 waylandws_CreateWindow,
4386 waylandws_DestroyWindow,
4387 waylandws_eglGetProcAddress,
4388 waylandws_passthroughImageKHR,
4389- eglplatformcommon_eglQueryString
4390+ waylandws_eglQueryString,
4391+ waylandws_prepareSwap,
4392+ waylandws_finishSwap,
4393+ waylandws_setSwapInterval,
4394 };
4395
4396
4397diff --git a/hybris/egl/platforms/wayland/wayland_window.cpp b/hybris/egl/platforms/wayland/wayland_window.cpp
4398index 2b13bf9..271df57 100644
4399--- a/hybris/egl/platforms/wayland/wayland_window.cpp
4400+++ b/hybris/egl/platforms/wayland/wayland_window.cpp
4401@@ -25,6 +25,7 @@
4402 ****************************************************************************************/
4403
4404
4405+#include <android-config.h>
4406 #include "wayland_window.h"
4407 #include "wayland-egl-priv.h"
4408 #include <assert.h>
4409@@ -32,18 +33,29 @@
4410 #include <errno.h>
4411
4412 #include "logging.h"
4413-#include <android/android-version.h>
4414 #include <eglhybris.h>
4415
4416-#if ANDROID_VERSION_MAJOR>=4 && ANDROID_VERSION_MINOR>=2
4417+#if ANDROID_VERSION_MAJOR>=4 && ANDROID_VERSION_MINOR>=2 || ANDROID_VERSION_MAJOR>=5
4418 extern "C" {
4419-#include <android/sync/sync.h>
4420+#include <sync/sync.h>
4421 }
4422 #endif
4423
4424+static void
4425+buffer_create_sync_callback(void *data, struct wl_callback *callback, uint32_t serial)
4426+{
4427+ struct wl_callback **created_callback = static_cast<struct wl_callback **>(data);
4428+
4429+ *created_callback = NULL;
4430+ wl_callback_destroy(callback);
4431+}
4432
4433+static const struct wl_callback_listener buffer_create_sync_listener = {
4434+ buffer_create_sync_callback
4435+};
4436
4437-void WaylandNativeWindowBuffer::wlbuffer_from_native_handle(struct android_wlegl *android_wlegl)
4438+void WaylandNativeWindowBuffer::wlbuffer_from_native_handle(struct android_wlegl *android_wlegl,
4439+ struct wl_display *display, struct wl_event_queue *queue)
4440 {
4441 struct wl_array ints;
4442 int *ints_data;
4443@@ -64,16 +76,32 @@ void WaylandNativeWindowBuffer::wlbuffer_from_native_handle(struct android_wlegl
4444 wlbuffer = android_wlegl_create_buffer(android_wlegl,
4445 width, height, stride,
4446 format, usage, wlegl_handle);
4447+ wl_proxy_set_queue((struct wl_proxy *) wlbuffer, queue);
4448
4449 android_wlegl_handle_destroy(wlegl_handle);
4450+
4451+ creation_callback = wl_display_sync(display);
4452+ wl_callback_add_listener(creation_callback, &buffer_create_sync_listener, &creation_callback);
4453+ wl_proxy_set_queue((struct wl_proxy *)creation_callback, queue);
4454+}
4455+
4456+void WaylandNativeWindow::resize(unsigned int width, unsigned int height)
4457+{
4458+ lock();
4459+ this->m_defaultWidth = width;
4460+ this->m_defaultHeight = height;
4461+ unlock();
4462 }
4463
4464 void WaylandNativeWindow::resize_callback(struct wl_egl_window *egl_window, void *)
4465 {
4466 TRACE("%dx%d",egl_window->width,egl_window->height);
4467- native_window_set_buffers_dimensions(
4468- (WaylandNativeWindow*)egl_window->nativewindow,
4469- egl_window->width,egl_window->height);
4470+ ((WaylandNativeWindow *) egl_window->nativewindow)->resize(egl_window->width, egl_window->height);
4471+}
4472+
4473+void WaylandNativeWindow::free_callback(struct wl_egl_window *egl_window, void *)
4474+{
4475+ ((WaylandNativeWindow*)(egl_window->nativewindow))->m_window = 0;
4476 }
4477
4478 void WaylandNativeWindow::lock()
4479@@ -86,23 +114,7 @@ void WaylandNativeWindow::unlock()
4480 pthread_mutex_unlock(&this->mutex);
4481 }
4482
4483- void
4484-WaylandNativeWindow::registry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
4485- const char *interface, uint32_t version)
4486-{
4487- WaylandNativeWindow *nw = static_cast<WaylandNativeWindow *>(data);
4488-
4489- if (strcmp(interface, "android_wlegl") == 0) {
4490- nw->m_android_wlegl = static_cast<struct android_wlegl *>(wl_registry_bind(registry, name, &android_wlegl_interface, 1));
4491- }
4492-}
4493-
4494-static const struct wl_registry_listener registry_listener = {
4495- WaylandNativeWindow::registry_handle_global
4496-};
4497-
4498-
4499- void
4500+void
4501 WaylandNativeWindow::sync_callback(void *data, struct wl_callback *callback, uint32_t serial)
4502 {
4503 int *done = static_cast<int *>(data);
4504@@ -115,7 +127,7 @@ static const struct wl_callback_listener sync_listener = {
4505 WaylandNativeWindow::sync_callback
4506 };
4507
4508- int
4509+int
4510 WaylandNativeWindow::wayland_roundtrip(WaylandNativeWindow *display)
4511 {
4512 struct wl_callback *callback;
4513@@ -125,7 +137,7 @@ WaylandNativeWindow::wayland_roundtrip(WaylandNativeWindow *display)
4514 callback = wl_display_sync(display->m_display);
4515 wl_callback_add_listener(callback, &sync_listener, &done);
4516 wl_proxy_set_queue((struct wl_proxy *) callback, display->wl_queue);
4517- while (ret == 0 && !done)
4518+ while (ret >= 0 && !done)
4519 ret = wl_display_dispatch_queue(display->m_display, display->wl_queue);
4520
4521 return ret;
4522@@ -147,7 +159,7 @@ static void check_fatal_error(struct wl_display *display)
4523 abort();
4524 }
4525
4526- static void
4527+static void
4528 wayland_frame_callback(void *data, struct wl_callback *callback, uint32_t time)
4529 {
4530 WaylandNativeWindow *surface = static_cast<WaylandNativeWindow *>(data);
4531@@ -159,7 +171,8 @@ static const struct wl_callback_listener frame_listener = {
4532 wayland_frame_callback
4533 };
4534
4535-WaylandNativeWindow::WaylandNativeWindow(struct wl_egl_window *window, struct wl_display *display, const gralloc_module_t* gralloc, alloc_device_t* alloc_device)
4536+WaylandNativeWindow::WaylandNativeWindow(struct wl_egl_window *window, struct wl_display *display, android_wlegl *wlegl, alloc_device_t* alloc_device, gralloc_module_t *gralloc)
4537+ : m_android_wlegl(wlegl)
4538 {
4539 int wayland_ok;
4540
4541@@ -172,25 +185,27 @@ WaylandNativeWindow::WaylandNativeWindow(struct wl_egl_window *window, struct wl
4542 this->m_defaultWidth = window->width;
4543 this->m_defaultHeight = window->height;
4544 this->m_window->resize_callback = resize_callback;
4545- this->m_format = 1;
4546- this->wl_queue = wl_display_create_queue(display);
4547+ this->m_window->free_callback = free_callback;
4548 this->frame_callback = NULL;
4549- this->registry = wl_display_get_registry(display);
4550- wl_proxy_set_queue((struct wl_proxy *) this->registry,
4551- this->wl_queue);
4552- wl_registry_add_listener(this->registry, &registry_listener, this);
4553+ this->wl_queue = wl_display_create_queue(display);
4554+ this->m_format = 1;
4555
4556- wayland_ok = wayland_roundtrip(this);
4557- assert(wayland_ok >= 0);
4558- assert(this->m_android_wlegl != NULL);
4559+ const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
4560+ const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
4561+ // This is the default as per the EGL documentation
4562+ this->m_swap_interval = 1;
4563
4564- this->m_gralloc = gralloc;
4565 this->m_alloc = alloc_device;
4566+ m_gralloc = gralloc;
4567
4568 m_usage=GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
4569 pthread_mutex_init(&mutex, NULL);
4570 pthread_cond_init(&cond, NULL);
4571+ m_queueReads = 0;
4572 m_freeBufs = 0;
4573+ m_damage_rects = NULL;
4574+ m_damage_n_rects = 0;
4575+ m_lastBuffer = 0;
4576 setBufferCount(3);
4577 HYBRIS_TRACE_END("wayland-platform", "create_window", "");
4578 }
4579@@ -198,19 +213,15 @@ WaylandNativeWindow::WaylandNativeWindow(struct wl_egl_window *window, struct wl
4580 WaylandNativeWindow::~WaylandNativeWindow()
4581 {
4582 std::list<WaylandNativeWindowBuffer *>::iterator it = m_bufList.begin();
4583- for (; it != m_bufList.end(); it++)
4584- {
4585- WaylandNativeWindowBuffer* buf=*it;
4586- if (buf->wlbuffer)
4587- wl_buffer_destroy(buf->wlbuffer);
4588- buf->wlbuffer = NULL;
4589- buf->common.decRef(&buf->common);
4590- }
4591+ destroyBuffers();
4592 if (frame_callback)
4593 wl_callback_destroy(frame_callback);
4594- wl_registry_destroy(registry);
4595 wl_event_queue_destroy(wl_queue);
4596- android_wlegl_destroy(m_android_wlegl);
4597+ if (m_window) {
4598+ m_window->nativewindow = NULL;
4599+ m_window->resize_callback = NULL;
4600+ m_window->free_callback = NULL;
4601+ }
4602 }
4603
4604 void WaylandNativeWindow::frame() {
4605@@ -221,10 +232,23 @@ void WaylandNativeWindow::frame() {
4606 HYBRIS_TRACE_END("wayland-platform", "frame_event", "");
4607 }
4608
4609-
4610 // overloads from BaseNativeWindow
4611 int WaylandNativeWindow::setSwapInterval(int interval) {
4612 TRACE("interval:%i", interval);
4613+
4614+ if (interval < 0)
4615+ interval = 0;
4616+ if (interval > 1)
4617+ interval = 1;
4618+
4619+ HYBRIS_TRACE_BEGIN("wayland-platform", "swap_interval", "=%d", interval);
4620+
4621+ lock();
4622+ m_swap_interval = interval;
4623+ unlock();
4624+
4625+ HYBRIS_TRACE_END("wayland-platform", "swap_interval", "");
4626+
4627 return 0;
4628 }
4629
4630@@ -241,7 +265,6 @@ static struct wl_buffer_listener wl_buffer_listener = {
4631
4632 void WaylandNativeWindow::releaseBuffer(struct wl_buffer *buffer)
4633 {
4634- lock();
4635 std::list<WaylandNativeWindowBuffer *>::iterator it = posted.begin();
4636
4637 for (; it != posted.end(); it++)
4638@@ -256,7 +279,6 @@ void WaylandNativeWindow::releaseBuffer(struct wl_buffer *buffer)
4639 posted.erase(it);
4640 TRACE("released posted buffer: %p", buffer);
4641 pwnb->busy = 0;
4642- pthread_cond_signal(&cond);
4643 unlock();
4644 return;
4645 }
4646@@ -288,15 +310,13 @@ void WaylandNativeWindow::releaseBuffer(struct wl_buffer *buffer)
4647 ++m_freeBufs;
4648 HYBRIS_TRACE_COUNTER("wayland-platform", "m_freeBufs", "%i", m_freeBufs);
4649 for (it = m_bufList.begin(); it != m_bufList.end(); it++)
4650- {
4651+ {
4652 (*it)->youngest = 0;
4653 }
4654- wnb->youngest = 1;
4655+ wnb->youngest = 1;
4656
4657
4658- pthread_cond_signal(&cond);
4659 HYBRIS_TRACE_END("wayland-platform", "releaseBuffer", "-%p", wnb);
4660- unlock();
4661 }
4662
4663
4664@@ -307,15 +327,17 @@ int WaylandNativeWindow::dequeueBuffer(BaseNativeWindowBuffer **buffer, int *fen
4665 TRACE("%p", buffer);
4666
4667 lock();
4668+ readQueue(false);
4669+
4670 HYBRIS_TRACE_BEGIN("wayland-platform", "dequeueBuffer_wait_for_buffer", "");
4671
4672 HYBRIS_TRACE_COUNTER("wayland-platform", "m_freeBufs", "%i", m_freeBufs);
4673
4674 while (m_freeBufs==0) {
4675 HYBRIS_TRACE_COUNTER("wayland-platform", "m_freeBufs", "%i", m_freeBufs);
4676-
4677- pthread_cond_wait(&cond,&mutex);
4678+ readQueue(true);
4679 }
4680+
4681 std::list<WaylandNativeWindowBuffer *>::iterator it = m_bufList.begin();
4682 for (; it != m_bufList.end(); it++)
4683 {
4684@@ -333,7 +355,7 @@ int WaylandNativeWindow::dequeueBuffer(BaseNativeWindowBuffer **buffer, int *fen
4685 it = m_bufList.begin();
4686 for (; it != m_bufList.end() && (*it)->busy; it++)
4687 {}
4688-
4689+
4690 }
4691 if (it==m_bufList.end()) {
4692 unlock();
4693@@ -362,6 +384,7 @@ int WaylandNativeWindow::dequeueBuffer(BaseNativeWindowBuffer **buffer, int *fen
4694
4695 wnb->busy = 1;
4696 *buffer = wnb;
4697+ queue.push_back(wnb);
4698 --m_freeBufs;
4699
4700 HYBRIS_TRACE_COUNTER("wayland-platform", "m_freeBufs", "%i", m_freeBufs);
4701@@ -408,26 +431,16 @@ int WaylandNativeWindow::postBuffer(ANativeWindowBuffer* buffer)
4702
4703 lock();
4704 wnb->busy = 1;
4705- unlock();
4706- /* XXX locking/something is a bit fishy here */
4707- while (this->frame_callback && ret != -1) {
4708- ret = wl_display_dispatch_queue(m_display, this->wl_queue);
4709- }
4710+ ret = readQueue(false);
4711
4712 if (ret < 0) {
4713- TRACE("wl_display_dispatch_queue returned an error:%i", ret);
4714- check_fatal_error(m_display);
4715+ unlock();
4716 return ret;
4717 }
4718
4719- lock();
4720- this->frame_callback = wl_surface_frame(m_window->surface);
4721- wl_callback_add_listener(this->frame_callback, &frame_listener, this);
4722- wl_proxy_set_queue((struct wl_proxy *) this->frame_callback, this->wl_queue);
4723-
4724 if (wnb->wlbuffer == NULL)
4725 {
4726- wnb->wlbuffer_from_native_handle(m_android_wlegl);
4727+ wnb->wlbuffer_from_native_handle(m_android_wlegl, m_display, wl_queue);
4728 TRACE("%p add listener with %p inside", wnb, wnb->wlbuffer);
4729 wl_buffer_add_listener(wnb->wlbuffer, &wl_buffer_listener, this);
4730 wl_proxy_set_queue((struct wl_proxy *) wnb->wlbuffer, this->wl_queue);
4731@@ -437,43 +450,125 @@ int WaylandNativeWindow::postBuffer(ANativeWindowBuffer* buffer)
4732 wl_surface_attach(m_window->surface, wnb->wlbuffer, 0, 0);
4733 wl_surface_damage(m_window->surface, 0, 0, wnb->width, wnb->height);
4734 wl_surface_commit(m_window->surface);
4735- //--m_freeBufs;
4736- //pthread_cond_signal(&cond);
4737+ wl_display_flush(m_display);
4738+
4739 posted.push_back(wnb);
4740 unlock();
4741
4742 return NO_ERROR;
4743 }
4744
4745-static int debugenvchecked = 0;
4746-
4747-int WaylandNativeWindow::queueBuffer(BaseNativeWindowBuffer* buffer, int fenceFd)
4748+int WaylandNativeWindow::readQueue(bool block)
4749 {
4750- WaylandNativeWindowBuffer *wnb = (WaylandNativeWindowBuffer*) buffer;
4751 int ret = 0;
4752
4753- HYBRIS_TRACE_BEGIN("wayland-platform", "queueBuffer", "-%p", wnb);
4754+ if (++m_queueReads == 1) {
4755+ if (block) {
4756+ ret = wl_display_dispatch_queue(m_display, wl_queue);
4757+ } else {
4758+ ret = wl_display_dispatch_queue_pending(m_display, wl_queue);
4759+ }
4760+
4761+ // all threads waiting on the false branch will wake and return now, so we
4762+ // can safely set m_queueReads to 0 here instead of relying on every thread
4763+ // to decrement it. This prevents a race condition when a thread enters readQueue()
4764+ // before the one in this thread returns.
4765+ // The new thread would go in the false branch, and there would be no thread in the
4766+ // true branch, blocking the new thread and any other that will call readQueue in
4767+ // the future.
4768+ m_queueReads = 0;
4769+
4770+ pthread_cond_broadcast(&cond);
4771+
4772+ if (ret < 0) {
4773+ TRACE("wl_display_dispatch_queue returned an error");
4774+ check_fatal_error(m_display);
4775+ return ret;
4776+ }
4777+ } else if (block) {
4778+ while (m_queueReads > 0) {
4779+ pthread_cond_wait(&cond, &mutex);
4780+ }
4781+ }
4782+
4783+ return ret;
4784+}
4785+
4786+void WaylandNativeWindow::prepareSwap(EGLint *damage_rects, EGLint damage_n_rects)
4787+{
4788 lock();
4789- wnb->busy = 1;
4790+ m_damage_rects = damage_rects;
4791+ m_damage_n_rects = damage_n_rects;
4792 unlock();
4793- /* XXX locking/something is a bit fishy here */
4794- HYBRIS_TRACE_BEGIN("wayland-platform", "queueBuffer_wait_for_frame_callback", "-%p", wnb);
4795+}
4796
4797- while (this->frame_callback && ret != -1) {
4798- ret = wl_display_dispatch_queue(m_display, this->wl_queue);
4799- }
4800+void WaylandNativeWindow::finishSwap()
4801+{
4802+ int ret = 0;
4803+ lock();
4804
4805+ WaylandNativeWindowBuffer *wnb = queue.front();
4806+ if (!wnb) {
4807+ wnb = m_lastBuffer;
4808+ } else {
4809+ queue.pop_front();
4810+ }
4811+ assert(wnb);
4812+ m_lastBuffer = wnb;
4813+ wnb->busy = 1;
4814
4815+ ret = readQueue(false);
4816+ if (this->frame_callback) {
4817+ do {
4818+ ret = readQueue(true);
4819+ } while (this->frame_callback && ret != -1);
4820+ }
4821 if (ret < 0) {
4822- TRACE("wl_display_dispatch_queue returned an error");
4823 HYBRIS_TRACE_END("wayland-platform", "queueBuffer_wait_for_frame_callback", "-%p", wnb);
4824- check_fatal_error(m_display);
4825- return ret;
4826+ return;
4827+ }
4828+
4829+ if (wnb->wlbuffer == NULL)
4830+ {
4831+ wnb->init(m_android_wlegl, m_display, wl_queue);
4832+ TRACE("%p add listener with %p inside", wnb, wnb->wlbuffer);
4833+ wl_buffer_add_listener(wnb->wlbuffer, &wl_buffer_listener, this);
4834+ wl_proxy_set_queue((struct wl_proxy *) wnb->wlbuffer, this->wl_queue);
4835+ }
4836+
4837+ if (m_swap_interval > 0) {
4838+ this->frame_callback = wl_surface_frame(m_window->surface);
4839+ wl_callback_add_listener(this->frame_callback, &frame_listener, this);
4840+ wl_proxy_set_queue((struct wl_proxy *) this->frame_callback, this->wl_queue);
4841 }
4842
4843- HYBRIS_TRACE_END("wayland-platform", "queueBuffer_wait_for_frame_callback", "-%p", wnb);
4844+ wl_surface_attach(m_window->surface, wnb->wlbuffer, 0, 0);
4845+ wl_surface_damage(m_window->surface, 0, 0, wnb->width, wnb->height);
4846+ wl_surface_commit(m_window->surface);
4847+ // Some compositors, namely Weston, queue buffer release events instead
4848+ // of sending them immediately. If a frame event is used, this should
4849+ // not be a problem. Without a frame event, we need to send a sync
4850+ // request to ensure that they get flushed.
4851+ wl_callback_destroy(wl_display_sync(m_display));
4852+ wl_display_flush(m_display);
4853+ fronted.push_back(wnb);
4854+
4855+ m_window->attached_width = wnb->width;
4856+ m_window->attached_height = wnb->height;
4857+
4858+ m_damage_rects = NULL;
4859+ m_damage_n_rects = 0;
4860+ unlock();
4861+}
4862
4863+static int debugenvchecked = 0;
4864
4865+int WaylandNativeWindow::queueBuffer(BaseNativeWindowBuffer* buffer, int fenceFd)
4866+{
4867+ WaylandNativeWindowBuffer *wnb = (WaylandNativeWindowBuffer*) buffer;
4868+ int ret = 0;
4869+
4870+ HYBRIS_TRACE_BEGIN("wayland-platform", "queueBuffer", "-%p", wnb);
4871 lock();
4872
4873 if (debugenvchecked == 0)
4874@@ -491,59 +586,17 @@ int WaylandNativeWindow::queueBuffer(BaseNativeWindowBuffer* buffer, int fenceFd
4875
4876 }
4877
4878-#if ANDROID_VERSION_MAJOR>=4 && ANDROID_VERSION_MINOR>=2
4879+#if ANDROID_VERSION_MAJOR>=4 && ANDROID_VERSION_MINOR>=2 || ANDROID_VERSION_MAJOR>=5
4880 HYBRIS_TRACE_BEGIN("wayland-platform", "queueBuffer_waiting_for_fence", "-%p", wnb);
4881- sync_wait(fenceFd, -1);
4882- close(fenceFd);
4883- HYBRIS_TRACE_END("wayland-platform", "queueBuffer_waiting_for_fence", "-%p", wnb);
4884-#endif
4885-
4886- this->frame_callback = wl_surface_frame(m_window->surface);
4887- wl_callback_add_listener(this->frame_callback, &frame_listener, this);
4888- wl_proxy_set_queue((struct wl_proxy *) this->frame_callback, this->wl_queue);
4889-
4890- if (wnb->wlbuffer == NULL)
4891+ if (fenceFd >= 0)
4892 {
4893- wnb->wlbuffer_from_native_handle(m_android_wlegl);
4894- TRACE("%p add listener with %p inside", wnb, wnb->wlbuffer);
4895- wl_buffer_add_listener(wnb->wlbuffer, &wl_buffer_listener, this);
4896- wl_proxy_set_queue((struct wl_proxy *) wnb->wlbuffer, this->wl_queue);
4897+ sync_wait(fenceFd, -1);
4898+ close(fenceFd);
4899 }
4900- TRACE("%p DAMAGE AREA: %dx%d", wnb, wnb->width, wnb->height);
4901- HYBRIS_TRACE_BEGIN("wayland-platform", "queueBuffer_attachdamagecommit", "-resource@%i", wl_proxy_get_id((struct wl_proxy *) wnb->wlbuffer));
4902-
4903- wl_surface_attach(m_window->surface, wnb->wlbuffer, 0, 0);
4904- wl_surface_damage(m_window->surface, 0, 0, wnb->width, wnb->height);
4905- wl_surface_commit(m_window->surface);
4906- wl_display_flush(m_display);
4907- HYBRIS_TRACE_END("wayland-platform", "queueBuffer_attachdamagecommit", "-resource@%i", wl_proxy_get_id((struct wl_proxy *) wnb->wlbuffer));
4908+ HYBRIS_TRACE_END("wayland-platform", "queueBuffer_waiting_for_fence", "-%p", wnb);
4909+#endif
4910
4911- //--m_freeBufs;
4912- //pthread_cond_signal(&cond);
4913- fronted.push_back(wnb);
4914 HYBRIS_TRACE_COUNTER("wayland-platform", "fronted.size", "%i", fronted.size());
4915-
4916- if (fronted.size() == m_bufList.size())
4917- {
4918- HYBRIS_TRACE_BEGIN("wayland-platform", "queueBuffer_wait_for_nonfronted_buffer", "-%p", wnb);
4919-
4920- /* We have fronted all our buffers, let's wait for one of them to be free */
4921- do {
4922- unlock();
4923- ret = wl_display_dispatch_queue(m_display, this->wl_queue);
4924- lock();
4925- if (ret == -1)
4926- {
4927- check_fatal_error(m_display);
4928- break;
4929- }
4930- HYBRIS_TRACE_COUNTER("wayland-platform", "fronted.size", "%i", fronted.size());
4931-
4932- if (fronted.size() != m_bufList.size())
4933- break;
4934- } while (1);
4935- HYBRIS_TRACE_END("wayland-platform", "queueBuffer_wait_for_nonfronted_buffer", "-%p", wnb);
4936- }
4937 HYBRIS_TRACE_END("wayland-platform", "queueBuffer", "-%p", wnb);
4938 unlock();
4939
4940@@ -575,10 +628,17 @@ int WaylandNativeWindow::cancelBuffer(BaseNativeWindowBuffer* buffer, int fenceF
4941 }
4942 wnb->youngest = 1;
4943
4944- pthread_cond_signal(&cond);
4945+ if (m_queueReads != 0) {
4946+ // Some thread is waiting on wl_display_dispatch_queue(), possibly waiting for a wl_buffer.release
4947+ // event. Since we have now cancelled a buffer push an artificial event so that the dispatch returns
4948+ // and the thread can notice the cancelled buffer. This means there is a delay of one roundtrip,
4949+ // but I don't see other solution except having one dedicated thread for calling wl_display_dispatch_queue().
4950+ wl_callback_destroy(wl_display_sync(m_display));
4951+ }
4952
4953 HYBRIS_TRACE_END("wayland-platform", "cancelBuffer", "-%p", wnb);
4954 unlock();
4955+
4956 return 0;
4957 }
4958
4959@@ -614,7 +674,7 @@ unsigned int WaylandNativeWindow::queueLength() const {
4960
4961 unsigned int WaylandNativeWindow::type() const {
4962 TRACE("");
4963-#if ANDROID_VERSION_MAJOR>=4 && ANDROID_VERSION_MINOR>=3
4964+#if ANDROID_VERSION_MAJOR>=4 && ANDROID_VERSION_MINOR>=3 || ANDROID_VERSION_MAJOR>=5
4965 /* https://android.googlesource.com/platform/system/core/+/bcfa910611b42018db580b3459101c564f802552%5E!/ */
4966 return NATIVE_WINDOW_SURFACE;
4967 #else
4968@@ -644,6 +704,16 @@ void WaylandNativeWindow::destroyBuffer(WaylandNativeWindowBuffer* wnb)
4969 TRACE("wnb:%p", wnb);
4970
4971 assert(wnb != NULL);
4972+
4973+ int ret = 0;
4974+ while (ret != -1 && wnb->creation_callback)
4975+ ret = wl_display_dispatch_queue(m_display, wl_queue);
4976+
4977+ if (wnb->creation_callback) {
4978+ wl_callback_destroy(wnb->creation_callback);
4979+ wnb->creation_callback = NULL;
4980+ }
4981+
4982 if (wnb->wlbuffer)
4983 wl_buffer_destroy(wnb->wlbuffer);
4984 wnb->wlbuffer = NULL;
4985@@ -659,6 +729,7 @@ void WaylandNativeWindow::destroyBuffers()
4986 for (; it!=m_bufList.end(); ++it)
4987 {
4988 destroyBuffer(*it);
4989+ it = m_bufList.erase(it);
4990 }
4991 m_bufList.clear();
4992 m_freeBufs = 0;
4993@@ -666,9 +737,15 @@ void WaylandNativeWindow::destroyBuffers()
4994
4995 WaylandNativeWindowBuffer *WaylandNativeWindow::addBuffer() {
4996
4997- WaylandNativeWindowBuffer *wnb = new WaylandNativeWindowBuffer(m_alloc, m_width, m_height, m_format, m_usage);
4998+ WaylandNativeWindowBuffer *wnb;
4999+
5000+#ifndef HYBRIS_NO_SERVER_SIDE_BUFFERS
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches