1
/****************************************************************************************
3
** Copyright (C) 2013 Jolla Ltd.
4
** Contact: Carsten Munk <carsten.munk@jollamobile.com>
5
** All rights reserved.
7
** This file is part of Wayland enablement for libhybris
9
** You may use this file under the terms of the GNU Lesser General
10
** Public License version 2.1 as published by the Free Software Foundation
11
** and appearing in the file license.lgpl included in the packaging
14
** This library is free software; you can redistribute it and/or
15
** modify it under the terms of the GNU Lesser General Public
16
** License version 2.1 as published by the Free Software Foundation
17
** and appearing in the file license.lgpl included in the packaging
20
** This library is distributed in the hope that it will be useful,
21
** but WITHOUT ANY WARRANTY; without even the implied warranty of
22
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23
** Lesser General Public License for more details.
25
****************************************************************************************/
28
#include "wayland_window.h"
29
#include "wayland-egl-priv.h"
32
void WaylandNativeWindow::lock()
34
pthread_mutex_lock(&this->mutex);
37
void WaylandNativeWindow::unlock()
39
pthread_mutex_unlock(&this->mutex);
43
WaylandNativeWindow::registry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
44
const char *interface, uint32_t version)
46
WaylandNativeWindow *nw = static_cast<WaylandNativeWindow *>(data);
48
if (strcmp(interface, "android_wlegl") == 0) {
49
nw->m_android_wlegl = static_cast<struct android_wlegl *>(wl_registry_bind(registry, name, &android_wlegl_interface, 1));
53
static const struct wl_registry_listener registry_listener = {
54
WaylandNativeWindow::registry_handle_global
59
WaylandNativeWindow::sync_callback(void *data, struct wl_callback *callback, uint32_t serial)
61
int *done = static_cast<int *>(data);
64
wl_callback_destroy(callback);
67
static const struct wl_callback_listener sync_listener = {
68
WaylandNativeWindow::sync_callback
72
WaylandNativeWindow::wayland_roundtrip(WaylandNativeWindow *display)
74
struct wl_callback *callback;
75
int done = 0, ret = 0;
76
wl_display_dispatch_queue_pending(display->m_display, display->wl_queue);
78
callback = wl_display_sync(display->m_display);
79
wl_callback_add_listener(callback, &sync_listener, &done);
80
wl_proxy_set_queue((struct wl_proxy *) callback, display->wl_queue);
81
while (ret == 0 && !done)
82
ret = wl_display_dispatch_queue(display->m_display, display->wl_queue);
88
wayland_frame_callback(void *data, struct wl_callback *callback, uint32_t time)
90
WaylandNativeWindow *surface = static_cast<WaylandNativeWindow *>(data);
92
wl_callback_destroy(callback);
95
static const struct wl_callback_listener frame_listener = {
96
wayland_frame_callback
100
WaylandNativeWindow::WaylandNativeWindow(struct wl_egl_window *window, struct wl_display *display, const gralloc_module_t* gralloc, alloc_device_t* alloc_device)
104
this->m_window = window;
105
this->m_display = display;
106
this->m_width = window->width;
107
this->m_height = window->height;
108
this->m_defaultWidth = window->width;
109
this->m_defaultHeight = window->height;
111
this->wl_queue = wl_display_create_queue(display);
112
this->frame_callback = NULL;
113
this->registry = wl_display_get_registry(display);
114
wl_proxy_set_queue((struct wl_proxy *) this->registry,
116
wl_registry_add_listener(this->registry, ®istry_listener, this);
118
assert(wayland_roundtrip(this) >= 0);
119
assert(this->m_android_wlegl != NULL);
121
this->m_gralloc = gralloc;
122
this->m_alloc = alloc_device;
124
m_usage=GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
125
pthread_mutex_init(&mutex, NULL);
127
TRACE("WaylandNativeWindow created in %p", pthread_self());
130
WaylandNativeWindow::~WaylandNativeWindow()
133
// We should destroy/free buffers upon deletion
134
// wl_buffer_destroy(buf->wlbuffer);
135
// buf->wlbuffer = NULL;
136
// assert(this->m_alloc->free(this->m_alloc, buf->getHandle()) == 0);
141
buffer_handle_t WaylandNativeWindowBuffer::getHandle()
146
void WaylandNativeWindow::frame() {
147
this->frame_callback = NULL;
151
// overloads from BaseNativeWindow
152
int WaylandNativeWindow::setSwapInterval(int interval) {
158
wl_buffer_release(void *data, struct wl_buffer *buffer)
160
WaylandNativeWindow *win = static_cast<WaylandNativeWindow *>(data);
161
win->releaseBuffer(buffer);
164
static struct wl_buffer_listener wl_buffer_listener = {
168
void WaylandNativeWindow::releaseBuffer(struct wl_buffer *buffer)
171
std::list<WaylandNativeWindowBuffer *>::iterator it = fronted.begin();
173
for (; it != fronted.end(); it++)
175
if ((*it)->wlbuffer == buffer)
178
assert(it != fronted.end());
179
WaylandNativeWindowBuffer *buf = *it;
182
for (it = buffers.begin(); it != buffers.end(); it++)
187
assert(it != buffers.end());
188
TRACE("Release buffer %p", buffer);
194
int WaylandNativeWindow::dequeueBuffer(BaseNativeWindowBuffer **buffer, int *fenceFd){
195
WaylandNativeWindowBuffer *backbuf;
200
std::list<WaylandNativeWindowBuffer *>::iterator it = buffers.begin();
201
for (; it != buffers.end(); it++)
202
if ((*it)->busy == 0)
204
if (it != buffers.end())
217
int WaylandNativeWindow::lockBuffer(BaseNativeWindowBuffer* buffer){
218
TRACE("===================");
222
int WaylandNativeWindow::queueBuffer(BaseNativeWindowBuffer* buffer, int fenceFd){
223
WaylandNativeWindowBuffer *backbuf = (WaylandNativeWindowBuffer *) buffer;
228
while (this->frame_callback && ret != -1)
229
ret = wl_display_dispatch_queue(m_display, this->wl_queue);
235
this->frame_callback = wl_surface_frame(m_window->surface);
236
wl_callback_add_listener(this->frame_callback, &frame_listener, this);
237
wl_proxy_set_queue((struct wl_proxy *) this->frame_callback, this->wl_queue);
239
if (backbuf->wlbuffer == NULL)
241
struct wl_array ints;
243
struct android_wlegl_handle *wlegl_handle;
244
buffer_handle_t handle;
246
handle = backbuf->handle;
248
wl_array_init(&ints);
249
ints_data = (int*) wl_array_add(&ints, handle->numInts*sizeof(int));
250
memcpy(ints_data, handle->data + handle->numFds, handle->numInts*sizeof(int));
251
wlegl_handle = android_wlegl_create_handle(m_android_wlegl, handle->numFds, &ints);
252
wl_array_release(&ints);
253
for (int i = 0; i < handle->numFds; i++) {
254
android_wlegl_handle_add_fd(wlegl_handle, handle->data[i]);
257
backbuf->wlbuffer = android_wlegl_create_buffer(m_android_wlegl,
258
backbuf->width, backbuf->height, backbuf->stride,
259
backbuf->format, backbuf->usage, wlegl_handle);
261
android_wlegl_handle_destroy(wlegl_handle);
262
backbuf->common.incRef(&backbuf->common);
264
TRACE("Add listener for %p with %p inside", backbuf, backbuf->wlbuffer);
265
wl_buffer_add_listener(backbuf->wlbuffer, &wl_buffer_listener, this);
266
wl_proxy_set_queue((struct wl_proxy *) backbuf->wlbuffer,
269
wl_surface_attach(m_window->surface, backbuf->wlbuffer, 0, 0);
270
wl_surface_damage(m_window->surface, 0, 0, backbuf->width, backbuf->height);
271
wl_surface_commit(m_window->surface);
272
fronted.push_back(backbuf);
278
int WaylandNativeWindow::cancelBuffer(BaseNativeWindowBuffer* buffer, int fenceFd){
283
unsigned int WaylandNativeWindow::width() const {
284
TRACE("value: %i", m_width);
288
unsigned int WaylandNativeWindow::height() const {
289
TRACE("value: %i", m_height);
293
unsigned int WaylandNativeWindow::format() const {
294
TRACE("value: %i", m_format);
298
unsigned int WaylandNativeWindow::defaultWidth() const {
299
TRACE("value: %i", m_defaultWidth);
300
return m_defaultWidth;
303
unsigned int WaylandNativeWindow::defaultHeight() const {
304
TRACE("value: %i", m_defaultHeight);
305
return m_defaultHeight;
308
unsigned int WaylandNativeWindow::queueLength() const {
313
unsigned int WaylandNativeWindow::type() const {
315
return NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT;
318
unsigned int WaylandNativeWindow::transformHint() const {
323
int WaylandNativeWindow::setBuffersFormat(int format) {
324
TRACE("format %i", format);
329
int WaylandNativeWindow::setBufferCount(int cnt) {
331
for (int i = 0; i < cnt; i++)
333
WaylandNativeWindowBuffer *backbuf = new WaylandNativeWindowBuffer(m_width, m_height, m_format, m_usage);
334
int err = m_alloc->alloc(m_alloc,
335
backbuf->width ? backbuf->width : 1, backbuf->height ? backbuf->height : 1, backbuf->format,
340
buffers.push_back(backbuf);
349
int WaylandNativeWindow::setBuffersDimensions(int width, int height) {
350
TRACE("size %ix%i", width, height);
354
int WaylandNativeWindow::setUsage(int usage) {
356
m_usage = usage | GRALLOC_USAGE_HW_TEXTURE;