Exemple #1
0
int WaylandNativeWindow::readQueue(bool block)
{
    int ret = 0;

    if (++m_queueReads == 1) {
        if (block) {
            ret = wl_display_dispatch_queue(m_display, wl_queue);
        } else {
            ret = wl_display_dispatch_queue_pending(m_display, wl_queue);
        }

        // all threads waiting on the false branch will wake and return now, so we
        // can safely set m_queueReads to 0 here instead of relying on every thread
        // to decrement it. This prevents a race condition when a thread enters readQueue()
        // before the one in this thread returns.
        // The new thread would go in the false branch, and there would be no thread in the
        // true branch, blocking the new thread and any other that will call readQueue in
        // the future.
        m_queueReads = 0;

        pthread_cond_broadcast(&cond);

        if (ret < 0) {
            TRACE("wl_display_dispatch_queue returned an error");
            check_fatal_error(m_display);
            return ret;
        }
    } else if (block) {
        while (m_queueReads > 0) {
            pthread_cond_wait(&cond, &mutex);
        }
    }

    return ret;
}
extern "C" EGLNativeWindowType waylandws_CreateWindow(EGLNativeWindowType win, _EGLDisplay *display)
{
	struct wl_egl_window *wl_window = (struct wl_egl_window*) win;
	struct wl_display *wl_display = (struct wl_display*) display;

	if (wl_window == 0 || wl_display == 0) {
		HYBRIS_ERROR("Running with EGL_PLATFORM=wayland without setup wayland environment is not possible");
		HYBRIS_ERROR("If you want to run a standlone EGL client do it like this:");
		HYBRIS_ERROR(" $ export EGL_PLATFORM=null");
		HYBRIS_ERROR(" $ test_glevs2");
		abort();
	}

	WaylandDisplay *wdpy = (WaylandDisplay *)display;

	int ret = 0;
	while (ret == 0 && !wdpy->wlegl) {
		ret = wl_display_dispatch_queue(wdpy->wl_dpy, wdpy->queue);
	}
	assert(ret >= 0);

	WaylandNativeWindow *window = new WaylandNativeWindow((struct wl_egl_window *) win, wdpy->wl_dpy, wdpy->wlegl, alloc, gralloc);
	window->common.incRef(&window->common);
	return (EGLNativeWindowType) static_cast<struct ANativeWindow *>(window);
}
void QWaylandDisplay::blockingReadEvents()
{
    int ret = wl_display_dispatch_queue(mDisplay, mEventQueue);
    if (ret < 0) {
        qWarning("The wayland connection broke (error %d). Did the wayland compositor die?", errno);
        exit(1);
    }
}
Exemple #4
0
int WaylandNativeWindow::queueBuffer(BaseNativeWindowBuffer* buffer, int fenceFd){
    WaylandNativeWindowBuffer *backbuf = (WaylandNativeWindowBuffer *) buffer;
    int ret = 0;
    lock();
    backbuf->busy = 2;
    unlock();
    while (this->frame_callback && ret != -1)
     	ret = wl_display_dispatch_queue(m_display, this->wl_queue);
    
    if (ret < 0)
	return ret;

    lock();
    this->frame_callback = wl_surface_frame(m_window->surface);
    wl_callback_add_listener(this->frame_callback, &frame_listener, this);
    wl_proxy_set_queue((struct wl_proxy *) this->frame_callback, this->wl_queue);

    if (backbuf->wlbuffer == NULL)	
    {
	    struct wl_array ints;
	    int *ints_data;
	    struct android_wlegl_handle *wlegl_handle;
	    buffer_handle_t handle;
		
	    handle = backbuf->handle;

	    wl_array_init(&ints);
	    ints_data = (int*) wl_array_add(&ints, handle->numInts*sizeof(int));
	    memcpy(ints_data, handle->data + handle->numFds, handle->numInts*sizeof(int));
	    wlegl_handle = android_wlegl_create_handle(m_android_wlegl, handle->numFds, &ints);
	    wl_array_release(&ints);
	    for (int i = 0; i < handle->numFds; i++) {
		android_wlegl_handle_add_fd(wlegl_handle, handle->data[i]);
	    }

	    backbuf->wlbuffer = android_wlegl_create_buffer(m_android_wlegl,
			backbuf->width, backbuf->height, backbuf->stride,
			backbuf->format, backbuf->usage, wlegl_handle);

	    android_wlegl_handle_destroy(wlegl_handle);
	    backbuf->common.incRef(&backbuf->common);

	    TRACE("Add listener for %p with %p inside", backbuf, backbuf->wlbuffer);
	    wl_buffer_add_listener(backbuf->wlbuffer, &wl_buffer_listener, this);
	    wl_proxy_set_queue((struct wl_proxy *) backbuf->wlbuffer,
				this->wl_queue);
    }
    wl_surface_attach(m_window->surface, backbuf->wlbuffer, 0, 0); 
    wl_surface_damage(m_window->surface, 0, 0, backbuf->width, backbuf->height);
    wl_surface_commit(m_window->surface);
    fronted.push_back(backbuf);   
 
    unlock();
    return NO_ERROR;
}
int wayland_roundtrip(struct wl_egl_display *display)
{
    struct wl_callback *callback;
    int done = 0, ret = 0;
    wl_display_dispatch_queue_pending(display->display, display->queue);

    callback = wl_display_sync(display->display);
    wl_callback_add_listener(callback, &roundtrip_listener, &done);
    wl_proxy_set_queue((struct wl_proxy *)callback, display->queue);
    while (ret == 0 && !done)
        ret = wl_display_dispatch_queue(display->display, display->queue);

    return ret;
}
extern "C" void waylandws_Terminate(_EGLDisplay *dpy)
{
	WaylandDisplay *wdpy = (WaylandDisplay *)dpy;
	int ret = 0;
	// We still have the sync callback on flight, wait for it to arrive
	while (ret == 0 && !wdpy->wlegl) {
		ret = wl_display_dispatch_queue(wdpy->wl_dpy, wdpy->queue);
	}
	assert(ret >= 0);
	android_wlegl_destroy(wdpy->wlegl);
	wl_registry_destroy(wdpy->registry);
	wl_event_queue_destroy(wdpy->queue);
	delete wdpy;
}
    int
WaylandNativeWindow::wayland_roundtrip(WaylandNativeWindow *display)
{
    struct wl_callback *callback;
    int done = 0, ret = 0;
    wl_display_dispatch_queue_pending(display->m_display, display->wl_queue);

    callback = wl_display_sync(display->m_display);
    wl_callback_add_listener(callback, &sync_listener, &done);
    wl_proxy_set_queue((struct wl_proxy *) callback, display->wl_queue);
    while (ret == 0 && !done)
        ret = wl_display_dispatch_queue(display->m_display, display->wl_queue);

    return ret;
}
int
wayland_roundtrip(struct wayland_display *display)
{
   struct wl_callback *callback;
   int done = 0, ret = 0;

   callback = wl_display_sync(display->dpy);
   wl_callback_add_listener(callback, &sync_listener, &done);
   wl_proxy_set_queue((struct wl_proxy *) callback, display->queue);
   while (ret != -1 && !done)
      ret = wl_display_dispatch_queue(display->dpy, display->queue);

   if (!done)
      wl_callback_destroy(callback);

   return ret;
}
static boolean
wayland_surface_swap_buffers(struct native_surface *nsurf)
{
   struct wayland_surface *surface = wayland_surface(nsurf);
   struct wayland_display *display = surface->display;
   int ret = 0;

   while (surface->frame_callback && ret != -1)
      ret = wl_display_dispatch_queue(display->dpy, display->queue);
   if (ret == -1)
      return EGL_FALSE;

   surface->frame_callback = wl_surface_frame(surface->win->surface);
   wl_callback_add_listener(surface->frame_callback, &frame_listener, surface);
   wl_proxy_set_queue((struct wl_proxy *) surface->frame_callback,
                      display->queue);

   if (surface->type == WL_WINDOW_SURFACE) {
      resource_surface_swap_buffers(surface->rsurf,
                                    NATIVE_ATTACHMENT_FRONT_LEFT,
                                    NATIVE_ATTACHMENT_BACK_LEFT, FALSE);

      wayland_buffers_swap(surface->buffer, WL_BUFFER_FRONT, WL_BUFFER_BACK);

      if (surface->buffer[WL_BUFFER_FRONT] == NULL)
         surface->buffer[WL_BUFFER_FRONT] =
            display->create_buffer(display, surface,
                                   NATIVE_ATTACHMENT_FRONT_LEFT);

      wl_surface_attach(surface->win->surface, surface->buffer[WL_BUFFER_FRONT],
                        surface->dx, surface->dy);

      resource_surface_get_size(surface->rsurf,
                                (uint *) &surface->win->attached_width,
                                (uint *) &surface->win->attached_height);
      surface->dx = 0;
      surface->dy = 0;
   }

   surface->sequence_number++;
   wayland_event_handler->invalid_surface(&display->base,
                                          &surface->base,
                                          surface->sequence_number);

   return TRUE;
}
Exemple #10
0
static gint
gst_wl_display_roundtrip (GstWlDisplay * self)
{
  struct wl_callback *callback;
  gint ret = 0;
  gboolean done = FALSE;

  g_return_val_if_fail (self != NULL, -1);

  /* We don't own the display, process only our queue */
  callback = wl_display_sync (self->display);
  wl_callback_add_listener (callback, &sync_listener, &done);
  wl_proxy_set_queue ((struct wl_proxy *) callback, self->queue);
  while (ret != -1 && !done)
    ret = wl_display_dispatch_queue (self->display, self->queue);
  wl_callback_destroy (callback);

  return ret;
}
void WaylandNativeWindow::destroyBuffer(WaylandNativeWindowBuffer* wnb)
{
    TRACE("wnb:%p", wnb);

    assert(wnb != NULL);

    int ret = 0;
    while (ret != -1 && wnb->creation_callback)
        ret = wl_display_dispatch_queue(m_display, wl_queue);

    if (wnb->creation_callback) {
        wl_callback_destroy(wnb->creation_callback);
        wnb->creation_callback = NULL;
    }

    if (wnb->wlbuffer)
        wl_buffer_destroy(wnb->wlbuffer);
    wnb->wlbuffer = NULL;
    wnb->common.decRef(&wnb->common);
    m_freeBufs--;
}
Exemple #12
0
/* Test that when receiving the first of two synchronization
 * callback events, destroying the second one doesn't cause any
 * errors even if the delete_id event is handled out of order. */
static int
client_test_multiple_queues(void)
{
	struct wl_event_queue *queue;
	struct wl_callback *callback1;
	struct multiple_queues_state state;
	int ret = 0;

	state.display = wl_display_connect(SOCKET_NAME);
	client_assert(state.display);

	/* Make the current thread the display thread. This is because
	 * wl_display_dispatch_queue() will only read the display fd if
	 * the main display thread has been set. */
	wl_display_dispatch_pending(state.display);

	queue = wl_display_create_queue(state.display);
	client_assert(queue);

	state.done = false;
	callback1 = wl_display_sync(state.display);
	wl_callback_add_listener(callback1, &sync_listener, &state);
	wl_proxy_set_queue((struct wl_proxy *) callback1, queue);

	state.callback2 = wl_display_sync(state.display);
	wl_callback_add_listener(state.callback2, &sync_listener, NULL);
	wl_proxy_set_queue((struct wl_proxy *) state.callback2, queue);

	wl_display_flush(state.display);

	while (!state.done && !ret)
		ret = wl_display_dispatch_queue(state.display, queue);

	wl_display_disconnect(state.display);

	return ret == -1 ? -1 : 0;
}
Exemple #13
0
	int DispatchQueue(struct wl_event_queue *queue){
		return wl_display_dispatch_queue(cobj, queue);
	}
/* Swap the contents of a drawable to the screen */
static WSEGLError wseglSwapDrawable
    (WSEGLDrawableHandle _drawable, unsigned long data)
{
    struct wl_egl_window *drawable = (struct wl_egl_window *) _drawable;
    struct wl_callback *callback;

    if (drawable->numFlipBuffers)
    {
//        wsegl_info("PRESENT FLIP");
        PVR2DPresentFlip(drawable->display->context, drawable->flipChain, drawable->backBuffers[drawable->currentBackBuffer], 0);
    }
    else if (drawable->display->display)
    { 
        //wsegl_info("wseglSwapDrawable for wayland, %d %p", drawable->currentBackBuffer, drawable->drmbuffers[drawable->currentBackBuffer]);

        int ret = 0;
        while (drawable->display->frame_callback && ret != -1)
            ret = wl_display_dispatch_queue(drawable->display->display, drawable->display->queue);

        drawable->display->frame_callback = wl_surface_frame(drawable->surface);
        wl_callback_add_listener(drawable->display->frame_callback, &frame_listener, drawable);
        wl_proxy_set_queue((struct wl_proxy *)drawable->display->frame_callback, drawable->display->queue);

        if (!drawable->drmbuffers[drawable->currentBackBuffer])
        {
            int32_t handle;
            struct wl_resource *wlbuf;

            handle = drawable->exporthandles[drawable->currentBackBuffer];
            wlbuf = sgx_wlegl_create_buffer(drawable->display->sgx_wlegl,
                        drawable->width, drawable->height, drawable->strideBytes,
                        drawable->format, handle);
            drawable->drmbuffers[drawable->currentBackBuffer] = wlbuf;
            wsegl_info("sgx_wlegl_create_buffer for %d", drawable->currentBackBuffer);

            wsegl_info("Add listener for %p with %p (buf %d) inside", drawable, wlbuf, drawable->currentBackBuffer);

            // TODO: listen for release

            wl_proxy_set_queue((struct wl_proxy *)wlbuf, drawable->display->queue);
        }

        struct wl_resource *wlbuf = drawable->drmbuffers[drawable->currentBackBuffer];
        wl_surface_attach(drawable->surface, wlbuf, 0, 0); 
        wl_surface_damage(drawable->surface, 0, 0, drawable->width, drawable->height);
        wl_surface_commit(drawable->surface);
    }
    else
    {
       PVR2DBLTINFO blit;

       memset(&blit, 0, sizeof(blit));
    
       blit.CopyCode = PVR2DROPcopy;
       blit.BlitFlags = PVR2D_BLIT_DISABLE_ALL;
       blit.pSrcMemInfo = drawable->backBuffers[drawable->currentBackBuffer];
       blit.SrcStride = drawable->strideBytes;
       blit.SrcX = 0;
       blit.SrcY = 0;
       blit.SizeX = drawable->width;
       blit.SizeY = drawable->height;
       blit.SrcFormat = wsegl2pvr2dformat(drawable->format);

       blit.pDstMemInfo = drawable->frontBufferPVRMEM;
       blit.DstStride = drawable->strideBytes; 
       blit.DstX = 0;
       blit.DstY = 0;
       blit.DSizeX = drawable->width;
       blit.DSizeY = drawable->height;
       blit.DstFormat = wsegl2pvr2dformat(drawable->format);
       PVR2DBlt(drawable->display->context, &blit); 
       PVR2DQueryBlitsComplete
          (drawable->display->context, drawable->frontBufferPVRMEM, 1);                      
       assert (drawable->display->fd >= 0);


       struct omapfb_update_window update_window;
         
       update_window.x = update_window.out_x = 0;
       update_window.y = update_window.out_y = 0;
       update_window.width = update_window.out_width = drawable->width;
       update_window.height = update_window.out_height = drawable->height;
       update_window.format = 0;

       assert(ioctl(drawable->display->fd, OMAPFB_UPDATE_WINDOW, &update_window) == 0);
    }
    
    drawable->currentBackBuffer   
      = (drawable->currentBackBuffer + 1) % WAYLANDWSEGL_MAX_BACK_BUFFERS;

    return WSEGL_SUCCESS;
}
Exemple #15
0
/** Process incoming events
 *
 * \param display The display context object
 * \return The number of dispatched events on success or -1 on failure
 *
 * Dispatch the display's main event queue.
 *
 * If the main event queue is empty, this function blocks until there are
 * events to be read from the display fd. Events are read and queued on
 * the appropriate event queues. Finally, events on the main event queue
 * are dispatched.
 *
 * \note It is not possible to check if there are events on the main queue
 * or not. For dispatching main queue events without blocking, see \ref
 * wl_display_dispatch_pending().
 *
 * \note Calling this will release the display file descriptor if this
 * thread acquired it using wl_display_acquire_fd().
 *
 * \sa wl_display_dispatch_pending(), wl_display_dispatch_queue()
 *
 * \memberof wl_display
 */
WL_EXPORT int
wl_display_dispatch(struct wl_display *display)
{
	return wl_display_dispatch_queue(display, &display->queue);
}
int WaylandNativeWindow::queueBuffer(BaseNativeWindowBuffer* buffer, int fenceFd)
{
    WaylandNativeWindowBuffer *wnb = (WaylandNativeWindowBuffer*) buffer;
    int ret = 0;

    HYBRIS_TRACE_BEGIN("wayland-platform", "queueBuffer", "-%p", wnb);
    lock();
    wnb->busy = 1;
    unlock();
    /* XXX locking/something is a bit fishy here */
    HYBRIS_TRACE_BEGIN("wayland-platform", "queueBuffer_wait_for_frame_callback", "-%p", wnb);

    while (this->frame_callback && ret != -1) {
        ret = wl_display_dispatch_queue(m_display, this->wl_queue);
    }


    if (ret < 0) {
        TRACE("wl_display_dispatch_queue returned an error");
        HYBRIS_TRACE_END("wayland-platform", "queueBuffer_wait_for_frame_callback", "-%p", wnb);
        check_fatal_error(m_display);
        return ret;
    }

    HYBRIS_TRACE_END("wayland-platform", "queueBuffer_wait_for_frame_callback", "-%p", wnb);


    lock();

    if (debugenvchecked == 0)
    {
        if (getenv("HYBRIS_WAYLAND_DUMP_BUFFERS") != NULL)
            debugenvchecked = 2;
        else
            debugenvchecked = 1;
    }
    if (debugenvchecked == 2)
    {
        HYBRIS_TRACE_BEGIN("wayland-platform", "queueBuffer_dumping_buffer", "-%p", wnb);
        hybris_dump_buffer_to_file(wnb->getNativeBuffer());
        HYBRIS_TRACE_END("wayland-platform", "queueBuffer_dumping_buffer", "-%p", wnb);

    }

#if ANDROID_VERSION_MAJOR>=4 && ANDROID_VERSION_MINOR>=2
    HYBRIS_TRACE_BEGIN("wayland-platform", "queueBuffer_waiting_for_fence", "-%p", wnb);
    sync_wait(fenceFd, -1);
    close(fenceFd);
    HYBRIS_TRACE_END("wayland-platform", "queueBuffer_waiting_for_fence", "-%p", wnb);
#endif

    this->frame_callback = wl_surface_frame(m_window->surface);
    wl_callback_add_listener(this->frame_callback, &frame_listener, this);
    wl_proxy_set_queue((struct wl_proxy *) this->frame_callback, this->wl_queue);

    if (wnb->wlbuffer == NULL)
    {
        wnb->wlbuffer_from_native_handle(m_android_wlegl);
        TRACE("%p add listener with %p inside", wnb, wnb->wlbuffer);
        wl_buffer_add_listener(wnb->wlbuffer, &wl_buffer_listener, this);
        wl_proxy_set_queue((struct wl_proxy *) wnb->wlbuffer, this->wl_queue);
    }
    TRACE("%p DAMAGE AREA: %dx%d", wnb, wnb->width, wnb->height);
    HYBRIS_TRACE_BEGIN("wayland-platform", "queueBuffer_attachdamagecommit", "-resource@%i", wl_proxy_get_id((struct wl_proxy *) wnb->wlbuffer));

    wl_surface_attach(m_window->surface, wnb->wlbuffer, 0, 0);
    wl_surface_damage(m_window->surface, 0, 0, wnb->width, wnb->height);
    wl_surface_commit(m_window->surface);
    wl_display_flush(m_display);
    HYBRIS_TRACE_END("wayland-platform", "queueBuffer_attachdamagecommit", "-resource@%i", wl_proxy_get_id((struct wl_proxy *) wnb->wlbuffer));

    //--m_freeBufs;
    //pthread_cond_signal(&cond);
    fronted.push_back(wnb);
    HYBRIS_TRACE_COUNTER("wayland-platform", "fronted.size", "%i", fronted.size());

    if (fronted.size() == m_bufList.size())
    {
        HYBRIS_TRACE_BEGIN("wayland-platform", "queueBuffer_wait_for_nonfronted_buffer", "-%p", wnb);

        /* We have fronted all our buffers, let's wait for one of them to be free */
        do {
            unlock();
            ret = wl_display_dispatch_queue(m_display, this->wl_queue);
            lock();
            if (ret == -1)
            {
                check_fatal_error(m_display);
                break;
            }
            HYBRIS_TRACE_COUNTER("wayland-platform", "fronted.size", "%i", fronted.size());

            if (fronted.size() != m_bufList.size())
                break;
        } while (1);
        HYBRIS_TRACE_END("wayland-platform", "queueBuffer_wait_for_nonfronted_buffer", "-%p", wnb);
    }
    HYBRIS_TRACE_END("wayland-platform", "queueBuffer", "-%p", wnb);
    unlock();

    return NO_ERROR;
}
int WaylandNativeWindow::postBuffer(ANativeWindowBuffer* buffer)
{
    TRACE("");
    WaylandNativeWindowBuffer *wnb = NULL;

    lock();
    std::list<WaylandNativeWindowBuffer *>::iterator it = post_registered.begin();
    for (; it != post_registered.end(); it++)
    {
        if ((*it)->other == buffer)
        {
            wnb = (*it);
            break;
        }
    }
    unlock();
    if (!wnb)
    {
        wnb = new WaylandNativeWindowBuffer(buffer);

        wnb->common.incRef(&wnb->common);
        buffer->common.incRef(&buffer->common);
    }

    int ret = 0;

    lock();
    wnb->busy = 1;
    unlock();
    /* XXX locking/something is a bit fishy here */
    while (this->frame_callback && ret != -1) {
        ret = wl_display_dispatch_queue(m_display, this->wl_queue);
    }

    if (ret < 0) {
        TRACE("wl_display_dispatch_queue returned an error:%i", ret);
        check_fatal_error(m_display);
        return ret;
    }

    lock();
    this->frame_callback = wl_surface_frame(m_window->surface);
    wl_callback_add_listener(this->frame_callback, &frame_listener, this);
    wl_proxy_set_queue((struct wl_proxy *) this->frame_callback, this->wl_queue);

    if (wnb->wlbuffer == NULL)
    {
        wnb->wlbuffer_from_native_handle(m_android_wlegl);
        TRACE("%p add listener with %p inside", wnb, wnb->wlbuffer);
        wl_buffer_add_listener(wnb->wlbuffer, &wl_buffer_listener, this);
        wl_proxy_set_queue((struct wl_proxy *) wnb->wlbuffer, this->wl_queue);
        post_registered.push_back(wnb);
    }
    TRACE("%p DAMAGE AREA: %dx%d", wnb, wnb->width, wnb->height);
    wl_surface_attach(m_window->surface, wnb->wlbuffer, 0, 0);
    wl_surface_damage(m_window->surface, 0, 0, wnb->width, wnb->height);
    wl_surface_commit(m_window->surface);
    //--m_freeBufs;
    //pthread_cond_signal(&cond);
    posted.push_back(wnb);
    unlock();

    return NO_ERROR;
}