コード例 #1
0
QDri2Context::QDri2Context(QXcbWindow *window)
    : d_ptr(new QDri2ContextPrivate(window))
{
    Q_D(QDri2Context);

    static const EGLint contextAttribs[] = {
            EGL_CONTEXT_CLIENT_VERSION, 2,
            EGL_NONE
    };

    eglBindAPI(EGL_OPENGL_ES_API);

    EGLContext shareContext = EGL_NO_CONTEXT;
    if (window->widget()->platformWindowFormat().sharedGLContext()) {
        QDri2Context *context = static_cast<QDri2Context *>(window->widget()->platformWindowFormat().sharedGLContext());
        shareContext = context->d_func()->eglContext;
    }
    d->eglContext = eglCreateContext(EGL_DISPLAY_FROM_XCB(d->qXcbWindow), NULL,
                                               shareContext, contextAttribs);

    if (d->eglContext == EGL_NO_CONTEXT) {
        qDebug() << "No eglContext!" << eglGetError();
    }

    EGLBoolean makeCurrentSuccess = eglMakeCurrent(EGL_DISPLAY_FROM_XCB(d->qXcbWindow),EGL_NO_SURFACE,EGL_NO_SURFACE,d->eglContext);
    if (!makeCurrentSuccess) {
        qDebug() << "eglMakeCurrent failed!" << eglGetError();
    }

    xcb_dri2_create_drawable (d->xcbConnection(), d->xcbWindow());

    glGenFramebuffers(1,&d->fbo);
    glBindFramebuffer(GL_FRAMEBUFFER,d->fbo);
    glActiveTexture(GL_TEXTURE0);

    glGenRenderbuffers(1, &d->rbo);
    glBindRenderbuffer(GL_RENDERBUFFER, d->rbo);

    glGenRenderbuffers(1,&d->depth);
    glBindRenderbuffer(GL_RENDERBUFFER, d->depth);

    resize(d->qXcbWindow->widget()->geometry().size());

    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, d->rbo);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERER,d->depth);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERER,d->depth);

    //restore the old current context
    const QPlatformGLContext *currentContext = QPlatformGLContext::currentContext();
    if (currentContext)
        const_cast<QPlatformGLContext*>(currentContext)->makeCurrent();
}
コード例 #2
0
ファイル: cairo-xcb-surface.c プロジェクト: ghub/NVprSDK
static cairo_surface_t *
_xcb_drm_create_surface_for_drawable (cairo_xcb_connection_t *connection,
				      cairo_xcb_screen_t *screen,
				      xcb_drawable_t drawable,
				      pixman_format_code_t pixman_format,
				      int width, int height)
{
    uint32_t attachments[] = { XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT };
    xcb_dri2_get_buffers_reply_t *buffers;
    xcb_dri2_dri2_buffer_t *buffer;
    cairo_surface_t *surface;

    if (! _cairo_drm_size_is_valid (screen->device, width, height))
	return NULL;

    xcb_dri2_create_drawable (connection->xcb_connection,
			      drawable);

    buffers = xcb_dri2_get_buffers_reply (connection->xcb_connection,
					  xcb_dri2_get_buffers (connection->xcb_connection,
								drawable, 1,
								ARRAY_LENGTH (attachments),
								attachments),
					  0);
    if (buffers == NULL) {
	xcb_dri2_destroy_drawable (connection->xcb_connection,
				   drawable);
	return NULL;
    }

    /* If the drawable is a window, we expect to receive an extra fake front,
     * which would involve copying on each flush - contrary to the user
     * expectations. But that is likely to be preferable to mixing drm/xcb
     * operations.
     */
    buffer = xcb_dri2_get_buffers_buffers (buffers);
    if (buffers->count == 1 && buffer[0].attachment == XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT) {
	assert (buffer[0].cpp == PIXMAN_FORMAT_BPP (pixman_format) / 8);
	surface = cairo_drm_surface_create_for_name (screen->device,
						     buffer[0].name,
						     _cairo_format_from_pixman_format (pixman_format),
						     width, height,
						     buffer[0].pitch);
    } else {
	xcb_dri2_destroy_drawable (connection->xcb_connection,
				   drawable);
	surface = NULL;
    }
    free (buffers);

    return surface;
}
コード例 #3
0
ファイル: vl_winsys_dri.c プロジェクト: Distrotech/Mesa
static void
vl_dri2_set_drawable(struct vl_dri_screen *scrn, Drawable drawable)
{
   assert(scrn);
   assert(drawable);

   if (scrn->drawable == drawable)
      return;

   vl_dri2_destroy_drawable(scrn);

   xcb_dri2_create_drawable(scrn->conn, drawable);
   scrn->current_buffer = false;
   vl_compositor_reset_dirty_area(&scrn->dirty_areas[0]);
   vl_compositor_reset_dirty_area(&scrn->dirty_areas[1]);
   scrn->drawable = drawable;
}
コード例 #4
0
ファイル: platform_x11.c プロジェクト: DirectFB/mesa
static _EGLImage *
dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
			     EGLClientBuffer buffer, const EGLint *attr_list)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_image *dri2_img;
   unsigned int attachments[1];
   xcb_drawable_t drawable;
   xcb_dri2_get_buffers_cookie_t buffers_cookie;
   xcb_dri2_get_buffers_reply_t *buffers_reply;
   xcb_dri2_dri2_buffer_t *buffers;
   xcb_get_geometry_cookie_t geometry_cookie;
   xcb_get_geometry_reply_t *geometry_reply;
   xcb_generic_error_t *error;
   int stride, format;

   (void) ctx;

   drawable = (xcb_drawable_t) (uintptr_t) buffer;
   xcb_dri2_create_drawable (dri2_dpy->conn, drawable);
   attachments[0] = XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT;
   buffers_cookie =
      xcb_dri2_get_buffers_unchecked (dri2_dpy->conn,
				      drawable, 1, 1, attachments);
   geometry_cookie = xcb_get_geometry (dri2_dpy->conn, drawable);
   buffers_reply = xcb_dri2_get_buffers_reply (dri2_dpy->conn,
					       buffers_cookie, NULL);
   buffers = xcb_dri2_get_buffers_buffers (buffers_reply);
   if (buffers == NULL) {
      return NULL;
   }

   geometry_reply = xcb_get_geometry_reply (dri2_dpy->conn,
					    geometry_cookie, &error);
   if (geometry_reply == NULL || error != NULL) {
      _eglError(EGL_BAD_ALLOC, "xcb_get_geometry");
      free(error);
      free(buffers_reply);
      return NULL;
   }

   switch (geometry_reply->depth) {
   case 16:
      format = __DRI_IMAGE_FORMAT_RGB565;
      break;
   case 24:
      format = __DRI_IMAGE_FORMAT_XRGB8888;
      break;
   case 32:
      format = __DRI_IMAGE_FORMAT_ARGB8888;
      break;
   default:
      _eglError(EGL_BAD_PARAMETER,
		"dri2_create_image_khr: unsupported pixmap depth");
      free(buffers_reply);
      free(geometry_reply);
      return NULL;
   }

   dri2_img = malloc(sizeof *dri2_img);
   if (!dri2_img) {
      free(buffers_reply);
      free(geometry_reply);
      _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr");
      return EGL_NO_IMAGE_KHR;
   }

   if (!_eglInitImage(&dri2_img->base, disp)) {
      free(buffers_reply);
      free(geometry_reply);
      free(dri2_img);
      return EGL_NO_IMAGE_KHR;
   }

   stride = buffers[0].pitch / buffers[0].cpp;
   dri2_img->dri_image =
      dri2_dpy->image->createImageFromName(dri2_dpy->dri_screen,
					   buffers_reply->width,
					   buffers_reply->height,
					   format,
					   buffers[0].name,
					   stride,
					   dri2_img);

   free(buffers_reply);
   free(geometry_reply);

   return &dri2_img->base;
}
コード例 #5
0
ファイル: platform_x11.c プロジェクト: DirectFB/mesa
/**
 * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
 */
static _EGLSurface *
dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
		    _EGLConfig *conf, EGLNativeWindowType native_window,
		    const EGLint *attrib_list)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
   struct dri2_egl_surface *dri2_surf;
   xcb_get_geometry_cookie_t cookie;
   xcb_get_geometry_reply_t *reply;
   xcb_screen_iterator_t s;
   xcb_generic_error_t *error;
   xcb_drawable_t window = (uintptr_t )native_window;

   (void) drv;

   dri2_surf = malloc(sizeof *dri2_surf);
   if (!dri2_surf) {
      _eglError(EGL_BAD_ALLOC, "dri2_create_surface");
      return NULL;
   }
   
   if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list))
      goto cleanup_surf;

   dri2_surf->region = XCB_NONE;
   if (type == EGL_PBUFFER_BIT) {
      dri2_surf->drawable = xcb_generate_id(dri2_dpy->conn);
      s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn));
      xcb_create_pixmap(dri2_dpy->conn, conf->BufferSize,
			dri2_surf->drawable, s.data->root,
			dri2_surf->base.Width, dri2_surf->base.Height);
   } else {
      dri2_surf->drawable = window;
   }

   if (dri2_dpy->dri2) {
      dri2_surf->dri_drawable = 
	 (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen,
					       type == EGL_WINDOW_BIT ?
					       dri2_conf->dri_double_config : 
					       dri2_conf->dri_single_config,
					       dri2_surf);
   } else {
      assert(dri2_dpy->swrast);
      dri2_surf->dri_drawable = 
	 (*dri2_dpy->swrast->createNewDrawable) (dri2_dpy->dri_screen,
						 dri2_conf->dri_double_config,
						 dri2_surf);
   }

   if (dri2_surf->dri_drawable == NULL) {
      _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable");
      goto cleanup_pixmap;
   }
   
   if (dri2_dpy->dri2) {
      xcb_dri2_create_drawable (dri2_dpy->conn, dri2_surf->drawable);
   } else {
      swrastCreateDrawable(dri2_dpy, dri2_surf, _eglGetConfigKey(conf, EGL_BUFFER_SIZE));
   }

   if (type != EGL_PBUFFER_BIT) {
      cookie = xcb_get_geometry (dri2_dpy->conn, dri2_surf->drawable);
      reply = xcb_get_geometry_reply (dri2_dpy->conn, cookie, &error);
      if (reply == NULL || error != NULL) {
	 _eglError(EGL_BAD_ALLOC, "xcb_get_geometry");
	 free(error);
	 goto cleanup_dri_drawable;
      }

      dri2_surf->base.Width = reply->width;
      dri2_surf->base.Height = reply->height;
      free(reply);
   }

   /* we always copy the back buffer to front */
   dri2_surf->base.PostSubBufferSupportedNV = EGL_TRUE;

   return &dri2_surf->base;

 cleanup_dri_drawable:
   dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable);
 cleanup_pixmap:
   if (type == EGL_PBUFFER_BIT)
      xcb_free_pixmap(dri2_dpy->conn, dri2_surf->drawable);
 cleanup_surf:
   free(dri2_surf);

   return NULL;
}