~sergiusens/libhybris/autotests

« back to all changes in this revision

Viewing changes to hybris/egl/platforms/wayland/wayland_window.cpp

  • Committer: Package Import Robot
  • Author(s): Ricardo Salveti de Araujo
  • Date: 2013-06-04 07:33:11 UTC
  • Revision ID: package-import@ubuntu.com-20130604073311-20ldi2hm1axkvjl1
Tags: upstream-0.1.0+git20130601+dfb2e26
ImportĀ upstreamĀ versionĀ 0.1.0+git20130601+dfb2e26

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************************
 
2
 **
 
3
 ** Copyright (C) 2013 Jolla Ltd.
 
4
 ** Contact: Carsten Munk <carsten.munk@jollamobile.com>
 
5
 ** All rights reserved.
 
6
 **
 
7
 ** This file is part of Wayland enablement for libhybris
 
8
 **
 
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
 
12
 ** of this file.
 
13
 **
 
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
 
18
 ** of this file.
 
19
 ** 
 
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.
 
24
 ** 
 
25
 ****************************************************************************************/
 
26
 
 
27
 
 
28
#include "wayland_window.h"
 
29
#include "wayland-egl-priv.h"
 
30
#include <assert.h>
 
31
 
 
32
void WaylandNativeWindow::lock()
 
33
{
 
34
        pthread_mutex_lock(&this->mutex);       
 
35
}
 
36
 
 
37
void WaylandNativeWindow::unlock()
 
38
{
 
39
        pthread_mutex_unlock(&this->mutex);
 
40
}
 
41
 
 
42
void
 
43
WaylandNativeWindow::registry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
 
44
                       const char *interface, uint32_t version)
 
45
{
 
46
   WaylandNativeWindow *nw = static_cast<WaylandNativeWindow *>(data);
 
47
 
 
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));
 
50
   }
 
51
}
 
52
 
 
53
static const struct wl_registry_listener registry_listener = {
 
54
       WaylandNativeWindow::registry_handle_global
 
55
};
 
56
 
 
57
 
 
58
void
 
59
WaylandNativeWindow::sync_callback(void *data, struct wl_callback *callback, uint32_t serial)
 
60
{
 
61
   int *done = static_cast<int *>(data);
 
62
 
 
63
   *done = 1;
 
64
   wl_callback_destroy(callback);
 
65
}
 
66
 
 
67
static const struct wl_callback_listener sync_listener = {
 
68
   WaylandNativeWindow::sync_callback
 
69
};
 
70
 
 
71
int
 
72
WaylandNativeWindow::wayland_roundtrip(WaylandNativeWindow *display)
 
73
{
 
74
   struct wl_callback *callback;
 
75
   int done = 0, ret = 0;
 
76
   wl_display_dispatch_queue_pending(display->m_display, display->wl_queue);
 
77
 
 
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);
 
83
 
 
84
   return ret;
 
85
}
 
86
 
 
87
static void
 
88
wayland_frame_callback(void *data, struct wl_callback *callback, uint32_t time)
 
89
{
 
90
   WaylandNativeWindow *surface = static_cast<WaylandNativeWindow *>(data);
 
91
   surface->frame();
 
92
   wl_callback_destroy(callback);
 
93
}
 
94
 
 
95
static const struct wl_callback_listener frame_listener = {
 
96
   wayland_frame_callback
 
97
};
 
98
 
 
99
 
 
100
WaylandNativeWindow::WaylandNativeWindow(struct wl_egl_window *window, struct wl_display *display, const gralloc_module_t* gralloc, alloc_device_t* alloc_device)
 
101
{
 
102
        int i;
 
103
 
 
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;
 
110
        this->m_format = 1;
 
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,
 
115
                      this->wl_queue);
 
116
        wl_registry_add_listener(this->registry, &registry_listener, this);
 
117
 
 
118
        assert(wayland_roundtrip(this) >= 0);
 
119
        assert(this->m_android_wlegl != NULL);
 
120
        
 
121
        this->m_gralloc = gralloc;
 
122
        this->m_alloc = alloc_device;
 
123
        
 
124
        m_usage=GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
 
125
        pthread_mutex_init(&mutex, NULL);
 
126
 
 
127
        TRACE("WaylandNativeWindow created in %p", pthread_self());
 
128
}
 
129
 
 
130
WaylandNativeWindow::~WaylandNativeWindow()
 
131
{
 
132
//      FIXME: 
 
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);
 
137
//      delete buf;
 
138
        
 
139
}
 
140
 
 
141
buffer_handle_t WaylandNativeWindowBuffer::getHandle()
 
142
{
 
143
  return handle;
 
144
}
 
145
 
 
146
void WaylandNativeWindow::frame() {
 
147
        this->frame_callback = NULL;
 
148
}
 
149
 
 
150
 
 
151
// overloads from BaseNativeWindow
 
152
int WaylandNativeWindow::setSwapInterval(int interval) {
 
153
    TRACE("");
 
154
    return 0;
 
155
}
 
156
 
 
157
static void
 
158
wl_buffer_release(void *data, struct wl_buffer *buffer)
 
159
{
 
160
   WaylandNativeWindow *win = static_cast<WaylandNativeWindow *>(data);
 
161
   win->releaseBuffer(buffer);
 
162
}
 
163
 
 
164
static struct wl_buffer_listener wl_buffer_listener = {
 
165
   wl_buffer_release
 
166
};
 
167
 
 
168
void WaylandNativeWindow::releaseBuffer(struct wl_buffer *buffer)
 
169
{
 
170
        lock();
 
171
        std::list<WaylandNativeWindowBuffer *>::iterator it = fronted.begin();
 
172
 
 
173
        for (; it != fronted.end(); it++)
 
174
        {
 
175
                if ((*it)->wlbuffer == buffer)
 
176
                        break;
 
177
        }
 
178
        assert(it != fronted.end());
 
179
        WaylandNativeWindowBuffer *buf = *it;
 
180
        fronted.erase(it);
 
181
        
 
182
        for (it = buffers.begin(); it != buffers.end(); it++)
 
183
        {
 
184
                if ((*it) == buf)
 
185
                        break;
 
186
        }
 
187
        assert(it != buffers.end());
 
188
        TRACE("Release buffer %p", buffer);
 
189
        buf->busy = 0;
 
190
        unlock();
 
191
}
 
192
 
 
193
 
 
194
int WaylandNativeWindow::dequeueBuffer(BaseNativeWindowBuffer **buffer, int *fenceFd){
 
195
    WaylandNativeWindowBuffer *backbuf;
 
196
 
 
197
    while (1)
 
198
    {
 
199
            lock();
 
200
            std::list<WaylandNativeWindowBuffer *>::iterator it = buffers.begin();
 
201
            for (; it != buffers.end(); it++)
 
202
                if ((*it)->busy == 0)
 
203
                        break;
 
204
            if (it != buffers.end())
 
205
            {
 
206
                backbuf = *it; 
 
207
                break;
 
208
            }
 
209
            unlock();
 
210
    }
 
211
    backbuf->busy = 1; 
 
212
    *buffer = backbuf;
 
213
    unlock();
 
214
    return NO_ERROR;
 
215
}
 
216
 
 
217
int WaylandNativeWindow::lockBuffer(BaseNativeWindowBuffer* buffer){
 
218
    TRACE("===================");
 
219
    return NO_ERROR;
 
220
}
 
221
 
 
222
int WaylandNativeWindow::queueBuffer(BaseNativeWindowBuffer* buffer, int fenceFd){
 
223
    WaylandNativeWindowBuffer *backbuf = (WaylandNativeWindowBuffer *) buffer;
 
224
    int ret = 0;
 
225
    lock();
 
226
    backbuf->busy = 2;
 
227
    unlock();
 
228
    while (this->frame_callback && ret != -1)
 
229
        ret = wl_display_dispatch_queue(m_display, this->wl_queue);
 
230
    
 
231
    if (ret < 0)
 
232
        return ret;
 
233
 
 
234
    lock();
 
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);
 
238
 
 
239
    if (backbuf->wlbuffer == NULL)      
 
240
    {
 
241
            struct wl_array ints;
 
242
            int *ints_data;
 
243
            struct android_wlegl_handle *wlegl_handle;
 
244
            buffer_handle_t handle;
 
245
                
 
246
            handle = backbuf->handle;
 
247
 
 
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]);
 
255
            }
 
256
 
 
257
            backbuf->wlbuffer = android_wlegl_create_buffer(m_android_wlegl,
 
258
                        backbuf->width, backbuf->height, backbuf->stride,
 
259
                        backbuf->format, backbuf->usage, wlegl_handle);
 
260
 
 
261
            android_wlegl_handle_destroy(wlegl_handle);
 
262
            backbuf->common.incRef(&backbuf->common);
 
263
 
 
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,
 
267
                                this->wl_queue);
 
268
    }
 
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);   
 
273
 
 
274
    unlock();
 
275
    return NO_ERROR;
 
276
}
 
277
 
 
278
int WaylandNativeWindow::cancelBuffer(BaseNativeWindowBuffer* buffer, int fenceFd){
 
279
    TRACE("");
 
280
    return 0;
 
281
}
 
282
 
 
283
unsigned int WaylandNativeWindow::width() const {
 
284
    TRACE("value: %i", m_width);
 
285
    return m_width;
 
286
}
 
287
 
 
288
unsigned int WaylandNativeWindow::height() const {
 
289
    TRACE("value: %i", m_height);
 
290
    return m_height;
 
291
}
 
292
 
 
293
unsigned int WaylandNativeWindow::format() const {
 
294
    TRACE("value: %i", m_format);
 
295
    return m_format;
 
296
}
 
297
 
 
298
unsigned int WaylandNativeWindow::defaultWidth() const {
 
299
    TRACE("value: %i", m_defaultWidth);
 
300
    return m_defaultWidth;
 
301
}
 
302
 
 
303
unsigned int WaylandNativeWindow::defaultHeight() const {
 
304
    TRACE("value: %i", m_defaultHeight);
 
305
    return m_defaultHeight;
 
306
}
 
307
 
 
308
unsigned int WaylandNativeWindow::queueLength() const {
 
309
    TRACE("");
 
310
    return 1;
 
311
}
 
312
 
 
313
unsigned int WaylandNativeWindow::type() const {
 
314
    TRACE("");
 
315
    return NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT;
 
316
}
 
317
 
 
318
unsigned int WaylandNativeWindow::transformHint() const {
 
319
    TRACE("");
 
320
    return 0;
 
321
}
 
322
 
 
323
int WaylandNativeWindow::setBuffersFormat(int format) {
 
324
    TRACE("format %i", format);
 
325
    m_format = format;
 
326
    return NO_ERROR;
 
327
}
 
328
 
 
329
int WaylandNativeWindow::setBufferCount(int cnt) {
 
330
    int i;
 
331
    for (int i = 0; i < cnt; i++)
 
332
    {
 
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,
 
336
                        backbuf->usage,
 
337
                        &backbuf->handle,
 
338
                        &backbuf->stride);
 
339
        assert(err == 0);
 
340
        buffers.push_back(backbuf);     
 
341
    }
 
342
 
 
343
    return NO_ERROR;
 
344
}
 
345
 
 
346
 
 
347
 
 
348
 
 
349
int WaylandNativeWindow::setBuffersDimensions(int width, int height) {
 
350
    TRACE("size %ix%i", width, height);
 
351
    return NO_ERROR;
 
352
}
 
353
 
 
354
int WaylandNativeWindow::setUsage(int usage) {
 
355
    TRACE("");
 
356
    m_usage = usage | GRALLOC_USAGE_HW_TEXTURE;
 
357
    return NO_ERROR;
 
358
}