Ejemplo n.º 1
0
static EGLBoolean
dri2_x11_get_sync_values(_EGLDisplay *display, _EGLSurface *surface,
                         EGLuint64KHR *ust, EGLuint64KHR *msc,
                         EGLuint64KHR *sbc)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(display);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surface);
   xcb_dri2_get_msc_cookie_t cookie;
   xcb_dri2_get_msc_reply_t *reply;

   cookie = xcb_dri2_get_msc(dri2_dpy->conn, dri2_surf->drawable);
   reply = xcb_dri2_get_msc_reply(dri2_dpy->conn, cookie, NULL);

   if (!reply) {
      _eglError(EGL_BAD_ACCESS, __func__);
      return EGL_FALSE;
   }

   *ust = ((EGLuint64KHR) reply->ust_hi << 32) | reply->ust_lo;
   *msc = ((EGLuint64KHR) reply->msc_hi << 32) | reply->msc_lo;
   *sbc = ((EGLuint64KHR) reply->sbc_hi << 32) | reply->sbc_lo;
   free(reply);

   return EGL_TRUE;
}
static EGLBoolean
droid_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
{
   struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv);
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
   _EGLContext *ctx;

   if (dri2_surf->base.Type != EGL_WINDOW_BIT)
      return EGL_TRUE;

   if (dri2_drv->glFlush) {
      ctx = _eglGetCurrentContext();
      if (ctx && ctx->DrawSurface == &dri2_surf->base)
         dri2_drv->glFlush();
   }

   (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);

   if (dri2_surf->buffer)
      droid_window_enqueue_buffer(dri2_surf);

   (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);

   return EGL_TRUE;
}
Ejemplo n.º 3
0
static EGLBoolean
dri2_drm_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
   int i;

   if (dri2_dpy->swrast) {
      (*dri2_dpy->core->swapBuffers)(dri2_surf->dri_drawable);
   } else {
      if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
         if (dri2_surf->current)
            _eglError(EGL_BAD_SURFACE, "dri2_swap_buffers");
         for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++)
            if (dri2_surf->color_buffers[i].age > 0)
               dri2_surf->color_buffers[i].age++;
         dri2_surf->current = dri2_surf->back;
         dri2_surf->current->age = 1;
         dri2_surf->back = NULL;
      }

      (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
      (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
   }

   return EGL_TRUE;
}
static EGLBoolean
dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
   int i;

   if (!_eglPutSurface(surf))
      return EGL_TRUE;

   (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable);

   for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
      if (dri2_surf->color_buffers[i].bo)
	 gbm_bo_destroy(dri2_surf->color_buffers[i].bo);
   }

   for (i = 0; i < __DRI_BUFFER_COUNT; i++) {
      if (dri2_surf->dri_buffers[i])
         dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
                                       dri2_surf->dri_buffers[i]);
   }

   free(surf);

   return EGL_TRUE;
}
Ejemplo n.º 5
0
static EGLBoolean
droid_query_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
                    EGLint attribute, EGLint *value)
{
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
   switch (attribute) {
      case EGL_WIDTH:
         if (dri2_surf->base.Type == EGL_WINDOW_BIT && dri2_surf->window) {
            dri2_surf->window->query(dri2_surf->window,
                                     NATIVE_WINDOW_DEFAULT_WIDTH, value);
            return EGL_TRUE;
         }
         break;
      case EGL_HEIGHT:
         if (dri2_surf->base.Type == EGL_WINDOW_BIT && dri2_surf->window) {
            dri2_surf->window->query(dri2_surf->window,
                                     NATIVE_WINDOW_DEFAULT_HEIGHT, value);
            return EGL_TRUE;
         }
         break;
      default:
         break;
   }
   return _eglQuerySurface(drv, dpy, surf, attribute, value);
}
Ejemplo n.º 6
0
static EGLBoolean
dri2_copy_region(_EGLDriver *drv, _EGLDisplay *disp,
		 _EGLSurface *draw, xcb_xfixes_region_t region)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
   enum xcb_dri2_attachment_t render_attachment;
   xcb_dri2_copy_region_cookie_t cookie;

   /* No-op for a pixmap or pbuffer surface */
   if (draw->Type == EGL_PIXMAP_BIT || draw->Type == EGL_PBUFFER_BIT)
      return EGL_TRUE;

   if (dri2_dpy->flush)
      (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);

   if (dri2_surf->have_fake_front)
      render_attachment = XCB_DRI2_ATTACHMENT_BUFFER_FAKE_FRONT_LEFT;
   else
      render_attachment = XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT;

   cookie = xcb_dri2_copy_region_unchecked(dri2_dpy->conn,
					   dri2_surf->drawable,
					   region,
					   XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT,
					   render_attachment);
   free(xcb_dri2_copy_region_reply(dri2_dpy->conn, cookie, NULL));

   return EGL_TRUE;
}
Ejemplo n.º 7
0
static EGLBoolean
dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);

   (void) drv;

   if (!_eglPutSurface(surf))
      return EGL_TRUE;

   (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable);
   
   if (dri2_dpy->dri2) {
      xcb_dri2_destroy_drawable (dri2_dpy->conn, dri2_surf->drawable);
   } else {
      assert(dri2_dpy->swrast);
      swrastDestroyDrawable(dri2_dpy, dri2_surf);
   }

   if (surf->Type == EGL_PBUFFER_BIT)
      xcb_free_pixmap (dri2_dpy->conn, dri2_surf->drawable);

   free(surf);

   return EGL_TRUE;
}
Ejemplo n.º 8
0
/**
 * Called via eglDestroySurface(), drv->API.DestroySurface().
 */
static EGLBoolean
dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
   int i;

   (void) drv;

   if (!_eglPutSurface(surf))
      return EGL_TRUE;

   (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable);

   for (i = 0; i < WL_BUFFER_COUNT; ++i)
      if (dri2_surf->wl_drm_buffer[i])
         wl_buffer_destroy(dri2_surf->wl_drm_buffer[i]);

   for (i = 0; i < __DRI_BUFFER_COUNT; ++i)
      if (dri2_surf->dri_buffers[i] && !(i == __DRI_BUFFER_FRONT_LEFT &&
          dri2_surf->base.Type == EGL_PIXMAP_BIT))
         dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
                                       dri2_surf->dri_buffers[i]);

   if (dri2_surf->third_buffer) {
      dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
                                    dri2_surf->third_buffer);
   }

   free(surf);

   return EGL_TRUE;
}
Ejemplo n.º 9
0
static EGLBoolean
dri2_swap_buffers_region(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw,
			 EGLint numRects, const EGLint *rects)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
   EGLBoolean ret;
   xcb_xfixes_region_t region;
   xcb_rectangle_t rectangles[16];
   int i;

   if (numRects > (int)ARRAY_SIZE(rectangles))
      return dri2_copy_region(drv, disp, draw, dri2_surf->region);

   for (i = 0; i < numRects; i++) {
      rectangles[i].x = rects[i * 4];
      rectangles[i].y = dri2_surf->base.Height - rects[i * 4 + 1] - rects[i * 4 + 3];
      rectangles[i].width = rects[i * 4 + 2];
      rectangles[i].height = rects[i * 4 + 3];
   }

   region = xcb_generate_id(dri2_dpy->conn);
   xcb_xfixes_create_region(dri2_dpy->conn, region, numRects, rectangles);
   ret = dri2_copy_region(drv, disp, draw, region);
   xcb_xfixes_destroy_region(dri2_dpy->conn, region);

   return ret;
}
Ejemplo n.º 10
0
static EGLBoolean
dri2_copy_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
		  EGLNativePixmapType native_target)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
   xcb_gcontext_t gc;
   xcb_pixmap_t target = (uintptr_t )native_target;

   (void) drv;

   (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);

   gc = xcb_generate_id(dri2_dpy->conn);
   xcb_create_gc(dri2_dpy->conn, gc, target, 0, NULL);
   xcb_copy_area(dri2_dpy->conn,
		  dri2_surf->drawable,
		  target,
		  gc,
		  0, 0,
		  0, 0,
		  dri2_surf->base.Width,
		  dri2_surf->base.Height);
   xcb_free_gc(dri2_dpy->conn, gc);

   return EGL_TRUE;
}
Ejemplo n.º 11
0
static EGLBoolean
dri2_drm_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
   unsigned i;

   if (dri2_dpy->swrast) {
      (*dri2_dpy->core->swapBuffers)(dri2_surf->dri_drawable);
   } else {
      if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
         if (dri2_surf->current)
            _eglError(EGL_BAD_SURFACE, "dri2_swap_buffers");
         for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++)
            if (dri2_surf->color_buffers[i].age > 0)
               dri2_surf->color_buffers[i].age++;

         /* Make sure we have a back buffer in case we're swapping without
          * ever rendering. */
         if (get_back_bo(dri2_surf) < 0) {
            _eglError(EGL_BAD_ALLOC, "dri2_swap_buffers");
            return EGL_FALSE;
         }

         dri2_surf->current = dri2_surf->back;
         dri2_surf->current->age = 1;
         dri2_surf->back = NULL;
      }

      dri2_flush_drawable_for_swapbuffers(disp, draw);
      (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
   }

   return EGL_TRUE;
}
Ejemplo n.º 12
0
static EGLImageKHR
dri2_get_fb_image(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw, EGLint type)
{
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);

   return (type == EGL_DRM_BUFFER_FRONT) ? dri2_surf->khr_front:dri2_surf->khr_back;
}
Ejemplo n.º 13
0
static EGLBoolean
dri2_x11_swap_interval(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
                       EGLint interval)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);

   if (dri2_dpy->swap_available)
      xcb_dri2_swap_interval(dri2_dpy->conn, dri2_surf->drawable, interval);

   return EGL_TRUE;
}
Ejemplo n.º 14
0
static int64_t
dri2_swap_buffers_msc(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw,
                      int64_t msc, int64_t divisor, int64_t remainder)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
   uint32_t msc_hi = msc >> 32;
   uint32_t msc_lo = msc & 0xffffffff;
   uint32_t divisor_hi = divisor >> 32;
   uint32_t divisor_lo = divisor & 0xffffffff;
   uint32_t remainder_hi = remainder >> 32;
   uint32_t remainder_lo = remainder & 0xffffffff;
   xcb_dri2_swap_buffers_cookie_t cookie;
   xcb_dri2_swap_buffers_reply_t *reply;
   int64_t swap_count = -1;

   /* No-op for a pixmap or pbuffer surface */
   if (draw->Type == EGL_PIXMAP_BIT || draw->Type == EGL_PBUFFER_BIT)
      return 0;

   if (draw->SwapBehavior == EGL_BUFFER_PRESERVED || !dri2_dpy->swap_available)
      return dri2_copy_region(drv, disp, draw, dri2_surf->region) ? 0 : -1;

   if (dri2_dpy->flush)
      (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);

   cookie = xcb_dri2_swap_buffers_unchecked(dri2_dpy->conn, dri2_surf->drawable,
                  msc_hi, msc_lo, divisor_hi, divisor_lo, remainder_hi, remainder_lo);

   reply = xcb_dri2_swap_buffers_reply(dri2_dpy->conn, cookie, NULL);

   if (reply) {
      swap_count = (((int64_t)reply->swap_hi) << 32) | reply->swap_lo;
      free(reply);
   }

   /* Since we aren't watching for the server's invalidate events like we're
    * supposed to (due to XCB providing no mechanism for filtering the events
    * the way xlib does), and SwapBuffers is a common cause of invalidate
    * events, just shove one down to the driver, even though we haven't told
    * the driver that we're the kind of loader that provides reliable
    * invalidate events.  This causes the driver to request buffers again at
    * its next draw, so that we get the correct buffers if a pageflip
    * happened.  The driver should still be using the viewport hack to catch
    * window resizes.
    */
   if (dri2_dpy->flush &&
       dri2_dpy->flush->base.version >= 3 && dri2_dpy->flush->invalidate)
      (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);

   return swap_count;
}
Ejemplo n.º 15
0
static EGLint
dri2_drm_query_buffer_age(_EGLDriver *drv,
                          _EGLDisplay *disp, _EGLSurface *surface)
{
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surface);

   if (get_back_bo(dri2_surf) < 0) {
      _eglError(EGL_BAD_ALLOC, "dri2_query_buffer_age");
      return 0;
   }

   return dri2_surf->back->age;
}
Ejemplo n.º 16
0
static EGLBoolean
dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);

   if (dri2_dpy->dri2) {
      return dri2_swap_buffers_msc(drv, disp, draw, 0, 0, 0) != -1;
   } else {
      assert(dri2_dpy->swrast);

      dri2_dpy->core->swapBuffers(dri2_surf->dri_drawable);
      return EGL_TRUE;
   }
}
Ejemplo n.º 17
0
static EGLBoolean
surfaceless_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);

   if (!_eglPutSurface(surf))
      return EGL_TRUE;

   surfaceless_free_images(dri2_surf);

   (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable);

   free(dri2_surf);
   return EGL_TRUE;
}
Ejemplo n.º 18
0
static EGLBoolean
dri2_x11_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);

   if (!dri2_dpy->flush) {
      dri2_dpy->core->swapBuffers(dri2_surf->dri_drawable);
      return EGL_TRUE;
   }

   if (dri2_x11_swap_buffers_msc(drv, disp, draw, 0, 0, 0) == -1) {
      /* Swap failed with a window drawable. */
      return _eglError(EGL_BAD_NATIVE_WINDOW, __func__);
   }
   return EGL_TRUE;
}
Ejemplo n.º 19
0
static EGLBoolean
dri2_swap_interval(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, EGLint interval)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);

   if (interval > surf->Config->MaxSwapInterval)
      interval = surf->Config->MaxSwapInterval;
   else if (interval < surf->Config->MinSwapInterval)
      interval = surf->Config->MinSwapInterval;

   if (interval != surf->SwapInterval && dri2_dpy->swap_available)
      xcb_dri2_swap_interval(dri2_dpy->conn, dri2_surf->drawable, interval);

   surf->SwapInterval = interval;

   return EGL_TRUE;
}
static EGLBoolean
dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);

   if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
      if (dri2_surf->current)
	 _eglError(EGL_BAD_SURFACE, "dri2_swap_buffers");
      dri2_surf->current = dri2_surf->back;
      dri2_surf->back = NULL;
   }

   (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
   (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);

   return EGL_TRUE;
}
Ejemplo n.º 21
0
static EGLBoolean
droid_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);

   if (dri2_surf->base.Type != EGL_WINDOW_BIT)
      return EGL_TRUE;

   dri2_flush_drawable_for_swapbuffers(disp, draw);

   if (dri2_surf->buffer)
      droid_window_enqueue_buffer(disp, dri2_surf);

   (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);

   return EGL_TRUE;
}
Ejemplo n.º 22
0
static EGLBoolean
dri2_copy_region(_EGLDriver *drv, _EGLDisplay *disp,
		 _EGLSurface *draw, xcb_xfixes_region_t region)
{
   struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv);
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
   _EGLContext *ctx;
   enum xcb_dri2_attachment_t render_attachment;
   xcb_dri2_copy_region_cookie_t cookie;

   if (dri2_drv->glFlush) {
      ctx = _eglGetCurrentContext();
      if (ctx && ctx->DrawSurface == &dri2_surf->base)
         dri2_drv->glFlush();
   }

   (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);

#if 0
   /* FIXME: Add support for dri swapbuffers, that'll give us swap
    * interval and page flipping (at least for fullscreen windows) as
    * well as the page flip event.  Unless surface->SwapBehavior is
    * EGL_BUFFER_PRESERVED. */
#if __DRI2_FLUSH_VERSION >= 2
   if (pdraw->psc->f)
      (*pdraw->psc->f->flushInvalidate)(pdraw->driDrawable);
#endif
#endif

   if (dri2_surf->have_fake_front)
      render_attachment = XCB_DRI2_ATTACHMENT_BUFFER_FAKE_FRONT_LEFT;
   else
      render_attachment = XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT;

   cookie = xcb_dri2_copy_region_unchecked(dri2_dpy->conn,
					   dri2_surf->drawable,
					   region,
					   XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT,
					   render_attachment);
   free(xcb_dri2_copy_region_reply(dri2_dpy->conn, cookie, NULL));

   return EGL_TRUE;
}
Ejemplo n.º 23
0
static EGLBoolean
dri2_x11_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);

   if (dri2_dpy->dri2) {
      if (dri2_x11_swap_buffers_msc(drv, disp, draw, 0, 0, 0) != -1) {
          return EGL_TRUE;
      }
      /* Swap failed with a window drawable. */
      _eglError(EGL_BAD_NATIVE_WINDOW, __FUNCTION__);
      return EGL_FALSE;
   } else {
      assert(dri2_dpy->swrast);

      dri2_dpy->core->swapBuffers(dri2_surf->dri_drawable);
      return EGL_TRUE;
   }
}
Ejemplo n.º 24
0
static EGLBoolean
droid_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);

   droid_free_local_buffers(dri2_surf);

   if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
      if (dri2_surf->buffer)
         droid_window_cancel_buffer(disp, dri2_surf);

      dri2_surf->window->common.decRef(&dri2_surf->window->common);
   }

   (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable);

   free(dri2_surf);

   return EGL_TRUE;
}
Ejemplo n.º 25
0
static int64_t
dri2_swap_buffers_msc(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw,
                      int64_t msc, int64_t divisor, int64_t remainder)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
   uint32_t msc_hi = msc >> 32;
   uint32_t msc_lo = msc & 0xffffffff;
   uint32_t divisor_hi = divisor >> 32;
   uint32_t divisor_lo = divisor & 0xffffffff;
   uint32_t remainder_hi = remainder >> 32;
   uint32_t remainder_lo = remainder & 0xffffffff;
   xcb_dri2_swap_buffers_cookie_t cookie;
   xcb_dri2_swap_buffers_reply_t *reply;
   int64_t swap_count = -1;

   /* No-op for a pixmap or pbuffer surface */
   if (draw->Type == EGL_PIXMAP_BIT || draw->Type == EGL_PBUFFER_BIT)
      return 0;

   if (draw->SwapBehavior == EGL_BUFFER_PRESERVED || !dri2_dpy->swap_available)
      return dri2_copy_region(drv, disp, draw, dri2_surf->region) ? 0 : -1;

   if (dri2_dpy->flush)
      (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);

   cookie = xcb_dri2_swap_buffers_unchecked(dri2_dpy->conn, dri2_surf->drawable,
                  msc_hi, msc_lo, divisor_hi, divisor_lo, remainder_hi, remainder_lo);

   reply = xcb_dri2_swap_buffers_reply(dri2_dpy->conn, cookie, NULL);

   if (reply) {
      swap_count = (((int64_t)reply->swap_hi) << 32) | reply->swap_lo;
      free(reply);
   }

   return swap_count;
}
Ejemplo n.º 26
0
/**
 * Function utilizes swrastGetDrawableInfo to get surface
 * geometry from x server and calls default query surface
 * implementation that returns the updated values.
 *
 * In case of errors we still return values that we currently
 * have.
 */
static EGLBoolean
dri2_query_surface(_EGLDriver *drv, _EGLDisplay *disp,
                   _EGLSurface *surf, EGLint attribute,
                   EGLint *value)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
   int x, y, w, h;

   __DRIdrawable *drawable = dri2_dpy->vtbl->get_dri_drawable(surf);

   switch (attribute) {
   case EGL_WIDTH:
   case EGL_HEIGHT:
      if (x11_get_drawable_info(drawable, &x, &y, &w, &h, dri2_surf)) {
         surf->Width = w;
         surf->Height = h;
      }
      break;
   default:
      break;
   }
   return _eglQuerySurface(drv, disp, surf, attribute, value);
}
Ejemplo n.º 27
0
/**
 * Called via eglSwapBuffers(), drv->API.SwapBuffers().
 */
static EGLBoolean
dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
   struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv);
   struct wl_callback *callback;

   if (dri2_surf->block_swap_buffers) {
      wl_display_flush(dri2_dpy->wl_dpy);
      while (dri2_surf->block_swap_buffers)
         wl_display_iterate(dri2_dpy->wl_dpy, WL_DISPLAY_READABLE);
   }

   dri2_surf->block_swap_buffers = EGL_TRUE;
   callback = wl_surface_frame(dri2_surf->wl_win->surface);
   wl_callback_add_listener(callback, &frame_listener, dri2_surf);

   if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
      pointer_swap(
	    (const void **) &dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT],
	    (const void **) &dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]);

      dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT]->attachment = 
	 __DRI_BUFFER_FRONT_LEFT;
      dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]->attachment = 
	 __DRI_BUFFER_BACK_LEFT;

      swap_wl_buffers(dri2_surf, WL_BUFFER_FRONT, WL_BUFFER_BACK);

      if (!dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT])
	 dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT] =
	    wayland_create_buffer(dri2_surf,
		  dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT]);

      wl_buffer_damage(dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT], 0, 0,
		       dri2_surf->base.Width, dri2_surf->base.Height);
      wl_surface_attach(dri2_surf->wl_win->surface,
	    dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT],
	    dri2_surf->dx, dri2_surf->dy);
      dri2_surf->wl_buffer_lock[WL_BUFFER_FRONT] = 1;

      dri2_surf->wl_win->attached_width  = dri2_surf->base.Width;
      dri2_surf->wl_win->attached_height = dri2_surf->base.Height;
      /* reset resize growing parameters */
      dri2_surf->dx = 0;
      dri2_surf->dy = 0;

      wl_surface_damage(dri2_surf->wl_win->surface, 0, 0,
	    dri2_surf->base.Width, dri2_surf->base.Height);
   }

   _EGLContext *ctx;
   if (dri2_drv->glFlush) {
      ctx = _eglGetCurrentContext();
      if (ctx && ctx->DrawSurface == &dri2_surf->base)
         dri2_drv->glFlush();
   }

   (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
   (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);

   return EGL_TRUE;
}
Ejemplo n.º 28
0
static EGLBoolean
dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
   __DRIbuffer buffer;
   static bitmap_t bm;

   int i;

   if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
      if (dri2_surf->current)
        _eglError(EGL_BAD_SURFACE, "dri2_swap_buffers");
      for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++)
         if (dri2_surf->color_buffers[i].age > 0)
            dri2_surf->color_buffers[i].age++;

#if 0

      if ( (dri2_surf->back != NULL) &&
           (dri2_surf->back->bo != NULL))
      {
        struct gbm_dri_bo *bo;
        bo = (struct gbm_dri_bo *)dri2_surf->back->bo;

        if(bm.width == 0)
        {
//            printf("%s bo: %p handle: %d width: %d height: %d pitch %d format %x\n",
//                __FUNCTION__, bo, bo->base.base.handle.s32, bo->base.base.width,
 //                             bo->base.base.height, (int)bo->base.base.stride,
//                              bo->base.base.format);

            bm.width      = bo->base.base.width;
            bm.height     = bo->base.base.height;
            bm.pitch      = (int)bo->base.base.stride;
            bm.max_width  = bo->base.base.width;
            bm.max_height = bo->base.base.height;
            bm.flags      = HW_TEX_BLIT;

            if( blit_bitmap_from_handle(&bm, bo->base.base.handle.s32))
            {
                printf("sna_bitmap_from_handle failed\n");
            }
        }
        if( bm.handle != 0)
        {
//           printf("%s bo: %p handle: %d width: %d height: %d pitch %d format %x\n",
//                __FUNCTION__, bo, bo->base.base.handle.s32, bo->base.base.width,
//                              bo->base.base.height, (int)bo->base.base.stride,
//                              bo->base.base.format);

            blit_set_bo_handle(&bm, bo->base.base.handle.s32);
            blit_blit_tex(&bm, 0, 0, 5, 20, bm.width, bm.height, 0, 0);
        }
      }
#endif

      dri2_surf->current = dri2_surf->back;
      dri2_surf->current->age = 1;
      dri2_surf->back = NULL;
   }

   (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
   (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);

   return EGL_TRUE;
}