Ejemplo n.º 1
0
struct SDrmFbWrapper *PVRShellInitOS::DrmFbGetFromBo(struct gbm_bo *bo)
{
	struct SDrmFbWrapper *fb = (struct SDrmFbWrapper *)gbm_bo_get_user_data(bo);
	uint32_t width, height, stride, handle;
	int ret;

	if (fb)
	{
		return fb;
	}

	fb = new struct SDrmFbWrapper;
	fb->psGbmBo = bo;
	fb->i32Fd = m_i32DrmFile;

	width = gbm_bo_get_width(bo);
	height = gbm_bo_get_height(bo);
	stride = gbm_bo_get_stride(bo);
	handle = gbm_bo_get_handle(bo).u32;

	ret = drmModeAddFB(m_i32DrmFile, width, height, 24, 32, stride, handle, &fb->ui32FbId);

	if (ret) 
	{
		delete fb;
		return NULL;
	}

	gbm_bo_set_user_data(bo, fb, pfnCallbackDrmFbDestroy);
	return fb;
}
Ejemplo n.º 2
0
QEglFSKmsGbmScreen::FrameBuffer *QEglFSKmsGbmScreen::framebufferForBufferObject(gbm_bo *bo)
{
    {
        FrameBuffer *fb = static_cast<FrameBuffer *>(gbm_bo_get_user_data(bo));
        if (fb)
            return fb;
    }

    uint32_t width = gbm_bo_get_width(bo);
    uint32_t height = gbm_bo_get_height(bo);
    uint32_t stride = gbm_bo_get_stride(bo);
    uint32_t handle = gbm_bo_get_handle(bo).u32;

    QScopedPointer<FrameBuffer> fb(new FrameBuffer);

    int ret = drmModeAddFB(device()->fd(), width, height, 24, 32,
                           stride, handle, &fb->fb);

    if (ret) {
        qWarning("Failed to create KMS FB!");
        return Q_NULLPTR;
    }

    gbm_bo_set_user_data(bo, fb.data(), bufferDestroyedHandler);
    return fb.take();
}
Ejemplo n.º 3
0
static struct drm_fb *drm_fb_get_from_bo(struct gbm_bo *bo)
{
   struct drm_fb *fb = (struct drm_fb*)gbm_bo_get_user_data(bo);
   if (fb)
      return fb;

   fb = (struct drm_fb*)calloc(1, sizeof(*fb));
   fb->bo = bo;

   unsigned width  = gbm_bo_get_width(bo);
   unsigned height = gbm_bo_get_height(bo);
   unsigned stride = gbm_bo_get_stride(bo);
   unsigned handle = gbm_bo_get_handle(bo).u32;

   RARCH_LOG("[KMS/EGL]: New FB: %ux%u (stride: %u).\n", width, height, stride);

   int ret = drmModeAddFB(g_drm_fd, width, height, 24, 32, stride, handle, &fb->fb_id);
   if (ret < 0)
   {
      RARCH_ERR("[KMS/EGL]: Failed to create FB: %s\n", strerror(errno));
      free(fb);
      return NULL;
   }

   gbm_bo_set_user_data(bo, fb, drm_fb_destroy_callback);
   return fb;
}
Ejemplo n.º 4
0
NativeStateDRM::DRMFBState*
NativeStateDRM::fb_get_from_bo(gbm_bo* bo)
{
    DRMFBState* fb = reinterpret_cast<DRMFBState*>(gbm_bo_get_user_data(bo));
    if (fb) {
        return fb;
    }

    unsigned int width = gbm_bo_get_width(bo);
    unsigned int height = gbm_bo_get_height(bo);
    unsigned int stride = gbm_bo_get_stride(bo);
    unsigned int handle = gbm_bo_get_handle(bo).u32;
    unsigned int fb_id(0);
    int status = drmModeAddFB(fd_, width, height, 24, 32, stride, handle, &fb_id);
    if (status < 0) {
        Log::error("Failed to create FB: %d\n", status);
        return 0;
    }

    fb = new DRMFBState();
    fb->fd = fd_;
    fb->bo = bo;
    fb->fb_id = fb_id;

    gbm_bo_set_user_data(bo, fb, fb_destroy_callback);
    return fb;
}
Ejemplo n.º 5
0
RenderingBackend::BufferExport RenderingBackendGBM::Surface::lockFrontBuffer()
{
    struct gbm_bo* bo = gbm_surface_lock_front_buffer(m_surface);
    assert(bo);

    uint32_t handle = gbm_bo_get_handle(bo).u32;
#ifndef NDEBUG
    auto result =
#endif
        m_lockedBuffers.insert({ handle, bo });
    assert(result.second);

    auto* data = static_cast<BufferDataGBM*>(gbm_bo_get_user_data(bo));
    if (data) {
        std::pair<uint32_t, uint32_t> storedSize{ data->width, data->height };
        if (m_size == storedSize)
            return RenderingBackend::BufferExport{ -1, reinterpret_cast<const uint8_t*>(data), sizeof(BufferDataGBM) };

        delete data;
    }

    data = new BufferDataGBM{ handle, m_size.first, m_size.second, gbm_bo_get_stride(bo), gbm_bo_get_format(bo), BufferDataGBM::magicValue };
    gbm_bo_set_user_data(bo, data, &destroyBOData);

    return RenderingBackend::BufferExport{ gbm_bo_get_fd(bo), reinterpret_cast<const uint8_t*>(data), sizeof(BufferDataGBM) };
}
Ejemplo n.º 6
0
static struct drm_fb * drm_fb_get_from_bo(struct gbm_bo *bo)
{
        struct drm_fb *fb = (drm_fb*)gbm_bo_get_user_data(bo);
        uint32_t width, height, stride, handle;
        int ret;

        if (fb)
                return fb;

        fb = (drm_fb*)calloc(1, sizeof *fb);
        fb->bo = bo;

        width = gbm_bo_get_width(bo);
        height = gbm_bo_get_height(bo);
        stride = gbm_bo_get_stride(bo);
        handle = gbm_bo_get_handle(bo).u32;

        ret = drmModeAddFB(drm.fd, width, height, 24, 32, stride, handle, &fb->fb_id);
        if (ret) {
                printf("failed to create fb: %s\n", strerror(errno));
                free(fb);
                return NULL;
        }

        gbm_bo_set_user_data(bo, fb, drm_fb_destroy_callback);

        return fb;
}
Ejemplo n.º 7
0
void
glamor_get_name_from_bo(int gbm_fd, struct gbm_bo *bo, int *name)
{
    union gbm_bo_handle handle;

    handle = gbm_bo_get_handle(bo);
    if (!glamor_get_flink_name(gbm_fd, handle.u32, name))
        *name = -1;
}
Ejemplo n.º 8
0
int
glamor_get_fd_from_bo(int gbm_fd, struct gbm_bo *bo, int *fd)
{
    union gbm_bo_handle handle;
    struct drm_prime_handle args;

    handle = gbm_bo_get_handle(bo);
    args.handle = handle.u32;
    args.flags = DRM_CLOEXEC;
    if (ioctl(gbm_fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args))
        return FALSE;
    *fd = args.fd;
    return TRUE;
}
Ejemplo n.º 9
0
static void
swap(struct gbm_winsys *winsys)
{
        struct gbm_dev *dev = winsys->dev;
        struct gbm_context *context = winsys->context;
        struct gbm_bo *bo;
        uint32_t handle, stride;
        uint32_t width, height;
        uint32_t fb_id;

        eglSwapBuffers(context->edpy, context->egl_surface);

        bo = gbm_surface_lock_front_buffer(context->gbm_surface);
        width = gbm_bo_get_width(bo);
        height = gbm_bo_get_height(bo);
        stride = gbm_bo_get_stride(bo);
        handle = gbm_bo_get_handle(bo).u32;

        if (drmModeAddFB(dev->fd,
                         width, height,
                         24, /* depth */
                         32, /* bpp */
                         stride,
                         handle,
                         &fb_id)) {
                fprintf(stderr,
                        "Failed to create new back buffer handle: %m\n");
        } else {
                if (dev->saved_crtc == NULL &&
                    set_initial_crtc(dev, fb_id))
                        return;

                if (drmModePageFlip(dev->fd,
                                    dev->crtc,
                                    fb_id,
                                    DRM_MODE_PAGE_FLIP_EVENT,
                                    dev)) {
                        fprintf(stderr, "Failed to page flip: %m\n");
                        return;
                }

                dev->pending_swap = 1;

                wait_swap(dev);

                free_current_bo(context);
                context->current_bo = bo;
                context->current_fb_id = fb_id;
        }
}
Ejemplo n.º 10
0
drm_fb * CDRMUtils::DrmFbGetFromBo(struct gbm_bo *bo)
{
  {
    struct drm_fb *fb = static_cast<drm_fb *>(gbm_bo_get_user_data(bo));
    if(fb)
    {
      return fb;
    }
  }

  struct drm_fb *fb = new drm_fb;
  fb->bo = bo;

  uint32_t width,
           height,
           handles[4] = {0},
           strides[4] = {0},
           offsets[4] = {0};

  width = gbm_bo_get_width(bo);
  height = gbm_bo_get_height(bo);

  handles[0] = gbm_bo_get_handle(bo).u32;
  strides[0] = gbm_bo_get_stride(bo);
  memset(offsets, 0, 16);

  auto ret = drmModeAddFB2(m_fd,
                           width,
                           height,
                           m_primary_plane->format,
                           handles,
                           strides,
                           offsets,
                           &fb->fb_id,
                           0);

  if(ret)
  {
    delete (fb);
    CLog::Log(LOGDEBUG, "CDRMUtils::%s - failed to add framebuffer", __FUNCTION__);
    return nullptr;
  }

  gbm_bo_set_user_data(bo, fb, DrmFbDestroyCallback);

  return fb;
}
Ejemplo n.º 11
0
void mgm::RealKMSOutput::set_cursor(gbm_bo* buffer)
{
    if (current_crtc)
    {
        if (auto result = drmModeSetCursor(
                drm_fd,
                current_crtc->crtc_id,
                gbm_bo_get_handle(buffer).u32,
                gbm_bo_get_width(buffer),
                gbm_bo_get_height(buffer)))
        {
            fatal_error("drmModeSetCursor failed (returned %d)", result);
        }

        has_cursor_ = true;
    }
}
Ejemplo n.º 12
0
void QKmsScreen::performPageFlip()
{
    if (!m_next_bo)
        return;

    uint32_t width = gbm_bo_get_width(m_next_bo);
    uint32_t height = gbm_bo_get_height(m_next_bo);
    uint32_t stride = gbm_bo_get_stride(m_next_bo);
    uint32_t handle = gbm_bo_get_handle(m_next_bo).u32;

    uint32_t fb_id;
    int ret = drmModeAddFB(m_device->fd(), width, height, 24, 32,
                           stride, handle, &fb_id);
    if (ret) {
        qFatal("kms: Failed to create fb: fd %d, w %d, h %d, stride %d, handle %d, ret %d",
               m_device->fd(), width, height, stride, handle, ret);
    }

    if (!m_modeSet) {
        //Set the Mode of the screen.
        int ret = drmModeSetCrtc(m_device->fd(), m_crtcId, fb_id,
                0, 0, &m_connectorId, 1, &m_mode);
        if (ret)
            qFatal("failed to set mode");
        m_modeSet = true;

        // Initialize cursor

        static int hideCursor = qgetenv("QT_QPA_KMS_HIDECURSOR").toInt();
        if (!hideCursor) {
            QCursor cursor(Qt::ArrowCursor);
            m_cursor->changeCursor(&cursor, 0);
        }
    }

    int pageFlipStatus = drmModePageFlip(m_device->fd(), m_crtcId,
                                         fb_id,
                                         DRM_MODE_PAGE_FLIP_EVENT, this);
    if (pageFlipStatus)
    {
        qWarning("Pageflip status: %d", pageFlipStatus);
        gbm_surface_release_buffer(m_gbmSurface, m_next_bo);
        m_next_bo = 0;
    }
}
Ejemplo n.º 13
0
static void update_framebuffer_from_bo(
    const struct MPGLContext *ctx, struct gbm_bo *bo)
{
    struct priv *p = ctx->priv;
    p->fb.bo = bo;
    p->fb.fd = p->kms->fd;
    p->fb.width = gbm_bo_get_width(bo);
    p->fb.height = gbm_bo_get_height(bo);
    int stride = gbm_bo_get_stride(bo);
    int handle = gbm_bo_get_handle(bo).u32;

    int ret = drmModeAddFB(p->kms->fd, p->fb.width, p->fb.height,
                           24, 32, stride, handle, &p->fb.id);
    if (ret) {
        MP_ERR(ctx->vo, "Failed to create framebuffer: %s\n", mp_strerror(errno));
    }
    gbm_bo_set_user_data(bo, &p->fb, framebuffer_destroy_callback);
}
int amdgpu_bo_map(ScrnInfoPtr pScrn, struct amdgpu_buffer *bo)
{
	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
	int ret = 0;

	if (info->use_glamor)
		return 0;

	if (bo->flags & AMDGPU_BO_FLAGS_GBM) {
		uint32_t handle, stride, height;
		union drm_amdgpu_gem_mmap args;
		int fd;
		void *ptr;

		handle = gbm_bo_get_handle(bo->bo.gbm).u32;
		stride = gbm_bo_get_stride(bo->bo.gbm);
		height = gbm_bo_get_height(bo->bo.gbm);
		fd = info->dri2.drm_fd;

		memset(&args, 0, sizeof(union drm_amdgpu_gem_mmap));
		args.in.handle = handle;

		ret = drmCommandWriteRead(fd, DRM_AMDGPU_GEM_MMAP,
					&args, sizeof(args));
		if (ret) {
			ErrorF("Failed to get the mmap offset\n");
			return ret;
		}

		ptr = mmap(NULL, stride * height,
			PROT_READ | PROT_WRITE, MAP_SHARED,
			fd, args.out.addr_ptr);

		if (ptr == NULL) {
			ErrorF("Failed to mmap the bo\n");
			return -1;
		}

		bo->cpu_ptr = ptr;
	} else
		ret = amdgpu_bo_cpu_map(bo->bo.amdgpu, &bo->cpu_ptr);

	return ret;
}
Ejemplo n.º 15
0
uint32_t DisplayOzone::Buffer::getDRMFB()
{
    if (!mHasDRMFB)
    {
        int fd              = gbm_device_get_fd(mDisplay->mGBM);
        uint32_t handles[4] = {gbm_bo_get_handle(mBO).u32};
        uint32_t pitches[4] = {gbm_bo_get_stride(mBO)};
        uint32_t offsets[4] = {0};
        if (drmModeAddFB2(fd, mWidth, mHeight, mDRMFormatFB, handles, pitches, offsets, &mDRMFB, 0))
        {
            std::cerr << "drmModeAddFB2 failed" << std::endl;
        }
        else
        {
            mHasDRMFB = true;
        }
    }

    return mDRMFB;
}
Ejemplo n.º 16
0
int main(int argc, char *argv[])
{
   EGLDisplay dpy;
   EGLContext ctx;
   EGLSurface surface;
   EGLConfig config;
   EGLint major, minor, n;
   const char *ver;
   uint32_t handle, stride;
   struct kms kms;
   int ret, fd;
   struct gbm_device *gbm;
   struct gbm_bo *bo;
   drmModeCrtcPtr saved_crtc;
   struct gbm_surface *gs;

   fd = open(device_name, O_RDWR);
   if (fd < 0) {
      /* Probably permissions error */
      fprintf(stderr, "couldn't open %s, skipping\n", device_name);
      return -1;
   }

   gbm = gbm_create_device(fd);
   if (gbm == NULL) {
      fprintf(stderr, "couldn't create gbm device\n");
      ret = -1;
      goto close_fd;
   }

   dpy = eglGetDisplay(gbm);
   if (dpy == EGL_NO_DISPLAY) {
      fprintf(stderr, "eglGetDisplay() failed\n");
      ret = -1;
      goto destroy_gbm_device;
   }
	
   if (!eglInitialize(dpy, &major, &minor)) {
      printf("eglInitialize() failed\n");
      ret = -1;
      goto egl_terminate;
   }

   ver = eglQueryString(dpy, EGL_VERSION);
   printf("EGL_VERSION = %s\n", ver);

   if (!setup_kms(fd, &kms)) {
      ret = -1;
      goto egl_terminate;
   }

   eglBindAPI(EGL_OPENGL_API);

   if (!eglChooseConfig(dpy, attribs, &config, 1, &n) || n != 1) {
      fprintf(stderr, "failed to choose argb config\n");
      goto egl_terminate;
   }
   
   ctx = eglCreateContext(dpy, config, EGL_NO_CONTEXT, NULL);
   if (ctx == NULL) {
      fprintf(stderr, "failed to create context\n");
      ret = -1;
      goto egl_terminate;
   }

   gs = gbm_surface_create(gbm, kms.mode.hdisplay, kms.mode.vdisplay,
			   GBM_BO_FORMAT_XRGB8888,
			   GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
   surface = eglCreateWindowSurface(dpy, config, gs, NULL);

   if (!eglMakeCurrent(dpy, surface, surface, ctx)) {
      fprintf(stderr, "failed to make context current\n");
      ret = -1;
      goto destroy_context;
   }

   render_stuff(kms.mode.hdisplay, kms.mode.vdisplay);

   eglSwapBuffers(dpy, surface);

   bo = gbm_surface_lock_front_buffer(gs);
   handle = gbm_bo_get_handle(bo).u32;
   stride = gbm_bo_get_stride(bo);

   printf("handle=%d, stride=%d\n", handle, stride);

   ret = drmModeAddFB(fd,
		      kms.mode.hdisplay, kms.mode.vdisplay,
		      24, 32, stride, handle, &kms.fb_id);
   if (ret) {
      fprintf(stderr, "failed to create fb\n");
      goto rm_fb;
   }

   saved_crtc = drmModeGetCrtc(fd, kms.encoder->crtc_id);
   if (saved_crtc == NULL)
      goto rm_fb;

   ret = drmModeSetCrtc(fd, kms.encoder->crtc_id, kms.fb_id, 0, 0,
			&kms.connector->connector_id, 1, &kms.mode);
   if (ret) {
      fprintf(stderr, "failed to set mode: %m\n");
      goto free_saved_crtc;
   }

   getchar();

   ret = drmModeSetCrtc(fd, saved_crtc->crtc_id, saved_crtc->buffer_id,
                        saved_crtc->x, saved_crtc->y,
                        &kms.connector->connector_id, 1, &saved_crtc->mode);
   if (ret) {
      fprintf(stderr, "failed to restore crtc: %m\n");
   }

free_saved_crtc:
   drmModeFreeCrtc(saved_crtc);
rm_fb:
   drmModeRmFB(fd, kms.fb_id);
   eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
destroy_context:
   eglDestroyContext(dpy, ctx);
egl_terminate:
   eglTerminate(dpy);
destroy_gbm_device:
   gbm_device_destroy(gbm);
close_fd:
   close(fd);

   return ret;
}
Ejemplo n.º 17
0
static void
_cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen)
{
  CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
  CoglDisplayEGL *egl_display = context->display->winsys;
  CoglDisplayKMS *kms_display = egl_display->platform;
  CoglRenderer *renderer = context->display->renderer;
  CoglRendererEGL *egl_renderer = renderer->winsys;
  CoglRendererKMS *kms_renderer = egl_renderer->platform;
  CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
  CoglOnscreenKMS *kms_onscreen = egl_onscreen->platform;
  uint32_t handle, stride;
  CoglFlipKMS *flip;
  GList *l;

  /* If we already have a pending swap then block until it completes */
  while (kms_onscreen->next_fb_id != 0)
    handle_drm_event (kms_renderer);

  /* First chain-up. This will call eglSwapBuffers */
  parent_vtable->onscreen_swap_buffers (onscreen);

  /* Now we need to set the CRTC to whatever is the front buffer */
  kms_onscreen->next_bo = gbm_surface_lock_front_buffer (kms_onscreen->surface);

#if (COGL_VERSION_ENCODE (COGL_GBM_MAJOR, COGL_GBM_MINOR, COGL_GBM_MICRO) >= \
     COGL_VERSION_ENCODE (8, 1, 0))
  stride = gbm_bo_get_stride (kms_onscreen->next_bo);
#else
  stride = gbm_bo_get_pitch (kms_onscreen->next_bo);
#endif
  handle = gbm_bo_get_handle (kms_onscreen->next_bo).u32;

  if (drmModeAddFB (kms_renderer->fd,
                    kms_display->width,
                    kms_display->height,
                    24, /* depth */
                    32, /* bpp */
                    stride,
                    handle,
                    &kms_onscreen->next_fb_id))
    {
      g_warning ("Failed to create new back buffer handle: %m");
      gbm_surface_release_buffer (kms_onscreen->surface,
                                  kms_onscreen->next_bo);
      kms_onscreen->next_bo = NULL;
      kms_onscreen->next_fb_id = 0;
      return;
    }

  /* If this is the first framebuffer to be presented then we now setup the
   * crtc modes... */
  if (kms_display->pending_set_crtc)
    {
      setup_crtc_modes (context->display, kms_onscreen->next_fb_id);
      kms_display->pending_set_crtc = FALSE;
    }

  flip = g_slice_new0 (CoglFlipKMS);
  flip->onscreen = onscreen;

  for (l = kms_display->outputs; l; l = l->next)
    {
      CoglOutputKMS *output = l->data;

      if (drmModePageFlip (kms_renderer->fd,
                           output->encoder->crtc_id,
                           kms_onscreen->next_fb_id,
                           DRM_MODE_PAGE_FLIP_EVENT,
                           flip))
        {
          g_warning ("Failed to flip: %m");
          continue;
        }

      flip->pending++;
    }

  if (flip->pending == 0)
    {
      drmModeRmFB (kms_renderer->fd, kms_onscreen->next_fb_id);
      gbm_surface_release_buffer (kms_onscreen->surface,
                                  kms_onscreen->next_bo);
      kms_onscreen->next_bo = NULL;
      kms_onscreen->next_fb_id = 0;
      g_slice_free (CoglFlipKMS, flip);
      flip = NULL;
    }
  else
    {
      /* Ensure the onscreen remains valid while it has any pending flips... */
      cogl_object_ref (flip->onscreen);
    }
}
Ejemplo n.º 18
0
static DFBResult
mesaAllocateBuffer( CoreSurfacePool       *pool,
                    void                  *pool_data,
                    void                  *pool_local,
                    CoreSurfaceBuffer     *buffer,
                    CoreSurfaceAllocation *allocation,
                    void                  *alloc_data )
{
     int                 ret;
     CoreSurface        *surface;
     MesaPoolData       *data  = pool_data;
     MesaPoolLocalData  *local = pool_local;
     MesaAllocationData *alloc = alloc_data;
     MesaData           *mesa;

     (void)data;
     (void)local;

     D_DEBUG_AT( Mesa_Surfaces, "%s( %p )\n", __FUNCTION__, buffer );

     D_MAGIC_ASSERT( pool, CoreSurfacePool );
     D_MAGIC_ASSERT( data, MesaPoolData );
     D_MAGIC_ASSERT( local, MesaPoolLocalData );
     D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );

     mesa = local->mesa;
     D_ASSERT( mesa != NULL );

     surface = buffer->surface;
     D_MAGIC_ASSERT( surface, CoreSurface );

     EGLContext context = eglGetCurrentContext();

     eglMakeCurrent( mesa->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, mesa->ctx );


     GLint texture, fbo, rbo;

     glGetIntegerv( GL_TEXTURE_BINDING_2D, &texture );
     glGetIntegerv( GL_FRAMEBUFFER_BINDING, &fbo );
     glGetIntegerv( GL_RENDERBUFFER_BINDING, &rbo );

     alloc->bo = gbm_bo_create( mesa->gbm, surface->config.size.w, surface->config.size.h, GBM_BO_FORMAT_ARGB8888,
                                                                            GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING );
     alloc->handle = gbm_bo_get_handle( alloc->bo ).u32;
     alloc->pitch  = gbm_bo_get_stride( alloc->bo );

     alloc->image  = eglCreateImageKHR( mesa->dpy, NULL, EGL_NATIVE_PIXMAP_KHR, alloc->bo, NULL );

     alloc->size = alloc->pitch * surface->config.size.h;

     D_DEBUG_AT( Mesa_Surfaces, "  -> pitch %d, size %d\n", alloc->pitch, alloc->size );

     allocation->size = alloc->size;


     /*
      * Color Render Buffer
      */
     glGenRenderbuffers( 1, &alloc->color_rb );

     glBindRenderbuffer( GL_RENDERBUFFER, alloc->color_rb );

     glEGLImageTargetRenderbufferStorageOES( GL_RENDERBUFFER, alloc->image );


     /*
      * Framebuffer
      */
     glGenFramebuffers( 1, &alloc->fbo );

     glBindFramebuffer( GL_FRAMEBUFFER, alloc->fbo );

     glFramebufferRenderbuffer( GL_FRAMEBUFFER,
                                GL_COLOR_ATTACHMENT0,
                                GL_RENDERBUFFER,
                                alloc->color_rb );

     if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
          D_ERROR( "DirectFB/Mesa: Framebuffer not complete\n" );
     }


     /*
      * Texture
      */
     glGenTextures( 1, &alloc->texture );

     glBindTexture( GL_TEXTURE_2D, alloc->texture );

     glEGLImageTargetTexture2DOES( GL_TEXTURE_2D, alloc->image );


     /*
      * Restore
      */
     glBindRenderbuffer( GL_RENDERBUFFER, rbo );
     glBindFramebuffer( GL_FRAMEBUFFER, fbo );
     glBindTexture( GL_TEXTURE_2D, texture );

     eglMakeCurrent( mesa->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, context );


     /*
      * Mode Framebuffer
      */
     ret = drmModeAddFB( local->mesa->fd,
                         surface->config.size.w, surface->config.size.h,
                         24, 32, alloc->pitch, alloc->handle, &alloc->fb_id );
     if (ret) {
          D_ERROR( "DirectFB/Mesa: drmModeAddFB() failed!\n" );
//          return DFB_FAILURE;
     }


     D_MAGIC_SET( alloc, MesaAllocationData );

     return DFB_OK;
}
Ejemplo n.º 19
0
uint32_t
update_buffer_nativesurface(struct ivi_share_nativesurface *p_nativesurface)
{
    if (NULL == p_nativesurface || NULL == p_nativesurface->surface) {
        return IVI_SHAREBUFFER_NOT_AVAILABLE;
    }

    struct drm_backend *backend =
        (struct drm_backend*)p_nativesurface->surface->compositor->backend;
    if (NULL == backend) {
        return IVI_SHAREBUFFER_NOT_AVAILABLE;
    }

    struct weston_buffer *buffer = p_nativesurface->surface->buffer_ref.buffer;
    if (!buffer) {
        return IVI_SHAREBUFFER_NOT_AVAILABLE;
    }

    struct gbm_bo *bo = gbm_bo_import(backend->gbm, GBM_BO_IMPORT_WL_BUFFER,
                                      buffer->legacy_buffer, GBM_BO_USE_SCANOUT);
    if (!bo) {
        weston_log("failed to import gbm_bo\n");
        return IVI_SHAREBUFFER_INVALID;
    }

    struct drm_gem_flink flink = {0};
    flink.handle = gbm_bo_get_handle(bo).u32;
    if (drmIoctl(gbm_device_get_fd(backend->gbm), DRM_IOCTL_GEM_FLINK, &flink) != 0) {
        weston_log("gem_flink: returned non-zero failed\n");
        gbm_bo_destroy(bo);
        return IVI_SHAREBUFFER_INVALID;
    }

    uint32_t name   = flink.name;
    uint32_t width  = gbm_bo_get_width(bo);
    uint32_t height = gbm_bo_get_height(bo);
    uint32_t stride = gbm_bo_get_stride(bo);
    uint32_t format = IVI_SHARE_SURFACE_FORMAT_ARGB8888;
    uint32_t ret    = IVI_SHAREBUFFER_STABLE;

    if (name != p_nativesurface->name) {
        ret |= IVI_SHAREBUFFER_DAMAGE;
    }
    if (width != p_nativesurface->width) {
        ret |= IVI_SHAREBUFFER_CONFIGURE;
    }
    if (height != p_nativesurface->height) {
        ret |= IVI_SHAREBUFFER_CONFIGURE;
    }
    if (stride != p_nativesurface->stride) {
        ret |= IVI_SHAREBUFFER_CONFIGURE;
    }

    p_nativesurface->name   = name;
    p_nativesurface->width  = width;
    p_nativesurface->height = height;
    p_nativesurface->stride = stride;
    p_nativesurface->format = format;

    gbm_bo_destroy(bo);

    return ret;
}
Ejemplo n.º 20
0
static gboolean
_cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
                            GError **error)
{
  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
  CoglContext *context = framebuffer->context;
  CoglDisplay *display = context->display;
  CoglDisplayEGL *egl_display = display->winsys;
  CoglDisplayKMS *kms_display = egl_display->platform;
  CoglRenderer *renderer = display->renderer;
  CoglRendererEGL *egl_renderer = renderer->winsys;
  CoglRendererKMS *kms_renderer = egl_renderer->platform;
  CoglOnscreenEGL *egl_onscreen;
  CoglOnscreenKMS *kms_onscreen;
  int i;

  _COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context, FALSE);

  onscreen->winsys = g_slice_new0 (CoglOnscreenEGL);
  egl_onscreen = onscreen->winsys;

  kms_onscreen = g_slice_new0 (CoglOnscreenKMS);
  egl_onscreen->platform = kms_onscreen;

  context->glGenRenderbuffers (2, kms_onscreen->color_rb);

  for (i = 0; i < 2; i++)
    {
      uint32_t handle, stride;

      kms_onscreen->bo[i] =
        gbm_bo_create (kms_renderer->gbm,
                       kms_display->mode.hdisplay, kms_display->mode.vdisplay,
                       GBM_BO_FORMAT_XRGB8888,
                       GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
      if (!kms_onscreen->bo[i])
        {
          g_set_error (error, COGL_WINSYS_ERROR,
                       COGL_WINSYS_ERROR_CREATE_CONTEXT,
                       "Failed to allocate buffer");
          return FALSE;
        }

      kms_onscreen->image[i] =
        _cogl_egl_create_image (context,
                                EGL_NATIVE_PIXMAP_KHR,
                                kms_onscreen->bo[i],
                                NULL);

      if (kms_onscreen->image[i] == EGL_NO_IMAGE_KHR)
        {
          g_set_error (error, COGL_WINSYS_ERROR,
                       COGL_WINSYS_ERROR_CREATE_CONTEXT,
                       "Failed to create EGL image");
          return FALSE;
        }

      context->glBindRenderbuffer (GL_RENDERBUFFER_EXT,
                                   kms_onscreen->color_rb[i]);
      context->glEGLImageTargetRenderbufferStorage (GL_RENDERBUFFER,
                                                    kms_onscreen->image[i]);
      context->glBindRenderbuffer (GL_RENDERBUFFER_EXT, 0);

      handle = gbm_bo_get_handle (kms_onscreen->bo[i]).u32;
      stride = gbm_bo_get_pitch (kms_onscreen->bo[i]);

      if (drmModeAddFB (kms_renderer->fd,
                        kms_display->mode.hdisplay,
                        kms_display->mode.vdisplay,
                        24, 32,
                        stride,
                        handle,
                        &kms_onscreen->fb_id[i]) != 0)
        {
          g_set_error (error, COGL_WINSYS_ERROR,
                       COGL_WINSYS_ERROR_CREATE_CONTEXT,
                       "Failed to create framebuffer from buffer");
          return FALSE;
        }
    }

  context->glGenFramebuffers (1, &kms_onscreen->fb);
  context->glBindFramebuffer (GL_FRAMEBUFFER_EXT, kms_onscreen->fb);

  context->glGenRenderbuffers (1, &kms_onscreen->depth_rb);
  context->glBindRenderbuffer (GL_RENDERBUFFER_EXT, kms_onscreen->depth_rb);
  context->glRenderbufferStorage (GL_RENDERBUFFER_EXT,
                                  GL_DEPTH_COMPONENT16,
                                  kms_display->mode.hdisplay,
                                  kms_display->mode.vdisplay);
  context->glBindRenderbuffer (GL_RENDERBUFFER_EXT, 0);

  context->glFramebufferRenderbuffer (GL_FRAMEBUFFER_EXT,
                                      GL_DEPTH_ATTACHMENT_EXT,
                                      GL_RENDERBUFFER_EXT,
                                      kms_onscreen->depth_rb);

  kms_onscreen->current_frame = 0;
  _cogl_winsys_onscreen_swap_buffers (onscreen);

  _cogl_framebuffer_winsys_update_size (framebuffer,
                                        kms_display->width,
                                        kms_display->height);

  return TRUE;
}
Ejemplo n.º 21
0
  bool CreateFramebuffer(int width, int height, Framebuffer& framebuffer) {
    framebuffer.bo = gbm_bo_create(gbm_, width, height, GBM_FORMAT_XRGB8888,
                                   GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
    if (!framebuffer.bo) {
      fprintf(stderr, "failed to create a gbm buffer.\n");
      return false;
    }

    framebuffer.fd = gbm_bo_get_fd(framebuffer.bo);
    if (framebuffer.fd < 0) {
      fprintf(stderr, "failed to get fb for bo: %d", framebuffer.fd);
      return false;
    }

    uint32_t handle = gbm_bo_get_handle(framebuffer.bo).u32;
    uint32_t stride = gbm_bo_get_stride(framebuffer.bo);
    uint32_t offset = 0;
    drmModeAddFB2(drm_->GetFD(), width, height, GBM_FORMAT_XRGB8888, &handle,
                  &stride, &offset, &framebuffer.fb_id, 0);
    if (!framebuffer.fb_id) {
      fprintf(stderr, "failed to create framebuffer from buffer object.\n");
      return false;
    }

    const EGLint khr_image_attrs[] = {EGL_DMA_BUF_PLANE0_FD_EXT,
                                      framebuffer.fd,
                                      EGL_WIDTH,
                                      width,
                                      EGL_HEIGHT,
                                      height,
                                      EGL_LINUX_DRM_FOURCC_EXT,
                                      GBM_FORMAT_XRGB8888,
                                      EGL_DMA_BUF_PLANE0_PITCH_EXT,
                                      static_cast<const int>(stride),
                                      EGL_DMA_BUF_PLANE0_OFFSET_EXT,
                                      static_cast<const int>(offset),
                                      EGL_NONE};

    framebuffer.image =
        egl_.CreateImageKHR(egl_.display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT,
                            nullptr /* no client buffer */, khr_image_attrs);
    if (framebuffer.image == EGL_NO_IMAGE_KHR) {
      fprintf(stderr, "failed to make image from buffer object: %s\n",
              EglGetError());
      return false;
    }

    glGenTextures(1, &framebuffer.gl_tex);
    glBindTexture(GL_TEXTURE_2D, framebuffer.gl_tex);
    egl_.EGLImageTargetTexture2DOES(GL_TEXTURE_2D, framebuffer.image);
    glBindTexture(GL_TEXTURE_2D, 0);

    glGenFramebuffers(1, &framebuffer.gl_fb);
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.gl_fb);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                           framebuffer.gl_tex, 0);

    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
      fprintf(stderr,
              "failed framebuffer check for created target buffer: %x\n",
              glCheckFramebufferStatus(GL_FRAMEBUFFER));
      glDeleteFramebuffers(1, &framebuffer.gl_fb);
      glDeleteTextures(1, &framebuffer.gl_tex);
      return false;
    }

    return true;
  }
Ejemplo n.º 22
0
void QKmsBufferManager::setupBuffersForMode(const drmModeModeInfo &mode, int numBuffers)
{
    eglMakeCurrent(m_screen->device()->eglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, m_screen->device()->eglContext());
    m_screen->bindFramebuffer();


    if (m_frameBufferObject) {
        clearBuffers();
    } else {
        //Setup Framebuffer Object
        glGenFramebuffers(1, &m_frameBufferObject);
        glBindFramebuffer(GL_FRAMEBUFFER, m_frameBufferObject);
    }

    //Setup shared Depth/Stencil buffer
    glGenRenderbuffers(1, &m_depthAndStencilBufferObject);
    glBindRenderbuffer(GL_RENDERBUFFER, m_depthAndStencilBufferObject);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES,
                          mode.hdisplay, mode.vdisplay);

    //Setup "numBuffer" many rendering targets
    for (int i = 0; i < numBuffers; i++) {
        QKmsFramebuffer *buffer = new QKmsFramebuffer();

        glGenRenderbuffers(1, &buffer->renderBuffer);
        glBindRenderbuffer(GL_RENDERBUFFER, buffer->renderBuffer);

        buffer->graphicsBufferObject = gbm_bo_create(m_screen->device()->gbmDevice(),
                                                     mode.hdisplay, mode.vdisplay,
                                                     GBM_BO_FORMAT_XRGB8888,
                                                     GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
        buffer->eglImage = eglCreateImageKHR(m_screen->device()->eglDisplay(), 0, EGL_NATIVE_PIXMAP_KHR,
                                             buffer->graphicsBufferObject, 0);
        glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, buffer->eglImage);

        quint32 stride = gbm_bo_get_pitch(buffer->graphicsBufferObject);
        quint32 handle = gbm_bo_get_handle(buffer->graphicsBufferObject).u32;

        int status = drmModeAddFB(m_screen->device()->fd(), mode.hdisplay, mode.vdisplay,
                                  32, 32, stride, handle, &buffer->framebufferId);
        //Todo: IF this returns true, then this is one less buffer that we use
        //Not so fatal, but not handled at the moment.
        if (status)
            qFatal("failed to add framebuffer");
        m_framebuffers.append(buffer);
    }
    //Attach the Depth and Stencil buffer
    glFramebufferRenderbuffer(GL_FRAMEBUFFER,
                              GL_DEPTH_ATTACHMENT,
                              GL_RENDERBUFFER,
                              m_depthAndStencilBufferObject);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER,
                              GL_STENCIL_ATTACHMENT,
                              GL_RENDERBUFFER,
                              m_depthAndStencilBufferObject);
    //Attach  renderbuffer as Color Attachment.
    glFramebufferRenderbuffer(GL_FRAMEBUFFER,
                              GL_COLOR_ATTACHMENT0,
                              GL_RENDERBUFFER,
                              this->renderTargetBuffer());
}
Ejemplo n.º 23
0
int main(int argc, char *argv[])
{
	EGLDisplay dpy;
	EGLContext ctx;
	EGLConfig config;
	EGLSurface surface;
	EGLint major, minor, n;
	const char *ver;
	uint32_t handle, stride;
	int ret, fd, frames = 0;
	struct gbm_device *gbm;
	drmModeCrtcPtr saved_crtc;
	time_t start, end;
	char *data;
	char j;
	int i;
	int once;
	once = 0;

	signal (SIGINT, quit_handler);

	fd = open(device_name, O_RDWR);
	if (fd < 0) {
		/* Probably permissions error */
		fprintf(stderr, "couldn't open %s, skipping\n", device_name);
		return -1;
	}

	gbm = gbm_create_device(fd);
	if (gbm == NULL) {
		fprintf(stderr, "couldn't create gbm device\n");
		ret = -1;
		goto close_fd;
	}

	dpy = eglGetDisplay(gbm);
	if (dpy == EGL_NO_DISPLAY) {
		fprintf(stderr, "eglGetDisplay() failed\n");
		ret = -1;
		goto destroy_gbm_device;
	}

	if (!eglInitialize(dpy, &major, &minor)) {
		printf("eglInitialize() failed\n");
		ret = -1;
		goto egl_terminate;
	}

	ver = eglQueryString(dpy, EGL_VERSION);
	printf("EGL_VERSION = %s\n", ver);

	if (!setup_kms(fd, &kms)) {
		ret = -1;
		goto egl_terminate;
	}

	eglBindAPI(EGL_OPENGL_API);

	if (!eglChooseConfig(dpy, attribs, &config, 1, &n) || n != 1) {
		fprintf(stderr, "failed to choose argb config\n");
		goto egl_terminate;
	}

	ctx = eglCreateContext(dpy, config, EGL_NO_CONTEXT, NULL);
	if (ctx == NULL) {
		fprintf(stderr, "failed to create context\n");
		ret = -1;
		goto egl_terminate;
	}

	gs = gbm_surface_create(gbm, kms.mode.hdisplay, kms.mode.vdisplay,
		GBM_BO_FORMAT_XRGB8888,
		GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
	if (gs == NULL) {
		fprintf(stderr, "unable to create gbm surface\n");
		ret = -1;
		goto egl_terminate;
	}


	surface = eglCreateWindowSurface(dpy, config, gs, NULL);
	if (surface == EGL_NO_SURFACE) {
		fprintf(stderr, "failed to create surface\n");
		ret = -1;
		goto destroy_gbm_surface;
	}

	if (!eglMakeCurrent(dpy, surface, surface, ctx)) {
		fprintf(stderr, "failed to make context current\n");
		ret = -1;
		goto destroy_surface;
	}

	saved_crtc = drmModeGetCrtc(fd, kms.crtc_id);
	if (saved_crtc == NULL)
	{
		fprintf(stderr, "no valid graphic configuration active (VT ?)\n");
	}
	time(&start);
	do {

		drmEventContext evctx;
		fd_set rfds;

		render_stuff(kms.mode.hdisplay, kms.mode.vdisplay);
		eglSwapBuffers(dpy, surface);
		
		if (!gbm_surface_has_free_buffers(gs))
			fprintf(stderr, "out of free buffers\n");

		next_bo = gbm_surface_lock_front_buffer(gs);
		if (!next_bo)
			fprintf(stderr, "failed to lock front buffer: %m\n");

		handle = gbm_bo_get_handle(next_bo).u32;
		stride = gbm_bo_get_stride(next_bo);
		
		ret = drmModeAddFB(fd,
				 kms.mode.hdisplay, kms.mode.vdisplay,
				 24, 32, stride, handle, &next_fb_id);
		if (ret) {
			fprintf(stderr, "failed to create fb\n");
			goto out;
		}
		  
		/* make sure to setup crtc once (fix for broken drivers) */
		if(once == 0){
			once = 1;
			drmModeSetCrtc(fd, kms.crtc_id, next_fb_id,
				0, 0,
				&kms.connector->connector_id, 1, &kms.mode);
		}
		
		ret = drmModePageFlip(fd, kms.crtc_id,
					next_fb_id,
					DRM_MODE_PAGE_FLIP_EVENT, 0);
		if (ret) {
			fprintf(stderr, "failed to page flip: %m\n");
			goto out;
		}

		FD_ZERO(&rfds);
		FD_SET(fd, &rfds);

		while (select(fd + 1, &rfds, NULL, NULL, NULL) == -1)
			NULL;

		memset(&evctx, 0, sizeof evctx);
		evctx.version = DRM_EVENT_CONTEXT_VERSION;
		evctx.page_flip_handler = page_flip_handler;

		drmHandleEvent(fd, &evctx);

		frames++;
	} while (!quit);
	time(&end);

	printf("Frames per second: %.2lf\n", frames / difftime(end, start));

out:
	if(saved_crtc){
		drmModeSetCrtc(fd, saved_crtc->crtc_id, saved_crtc->buffer_id,
			saved_crtc->x, saved_crtc->y,
			&kms.connector->connector_id, 1, &saved_crtc->mode);
		}
	drmModeFreeCrtc(saved_crtc);
	if (current_fb_id)
		drmModeRmFB(fd, current_fb_id);
	if (next_fb_id)
		drmModeRmFB(fd, next_fb_id);
	eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
destroy_context:
	eglDestroyContext(dpy, ctx);
destroy_surface:
	eglDestroySurface(dpy, surface);
destroy_gbm_surface:
	gbm_surface_destroy(gs);
egl_terminate:
	eglTerminate(dpy);
destroy_gbm_device:
	gbm_device_destroy(gbm);
close_fd:
	close(fd);

	return ret;
}