示例#1
0
QT_BEGIN_NAMESPACE

#ifndef DRM_CAP_CURSOR_WIDTH
#define DRM_CAP_CURSOR_WIDTH 0x8
#endif

#ifndef DRM_CAP_CURSOR_HEIGHT
#define DRM_CAP_CURSOR_HEIGHT 0x9
#endif

QKmsCursor::QKmsCursor(QKmsScreen *screen)
    : m_screen(screen),
      m_graphicsBufferManager(screen->device()->gbmDevice()),
      m_cursorImage(new QPlatformCursorImage(0, 0, 0, 0, 0, 0)),
      m_moved(false),
      m_cursorSize(64, 64)
{
    uint64_t value = 0;
    if (!drmGetCap(m_screen->device()->fd(), DRM_CAP_CURSOR_WIDTH, &value))
        m_cursorSize.setWidth(value);
    if (!drmGetCap(m_screen->device()->fd(), DRM_CAP_CURSOR_HEIGHT, &value))
        m_cursorSize.setHeight(value);

    m_cursorBufferObject = gbm_bo_create(m_graphicsBufferManager, m_cursorSize.width(), m_cursorSize.height(),
                                         GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE);
}
示例#2
0
static int
get_back_bo(struct dri2_egl_surface *dri2_surf)
{
   struct dri2_egl_display *dri2_dpy =
      dri2_egl_display(dri2_surf->base.Resource.Display);
   struct gbm_dri_surface *surf = dri2_surf->gbm_surf;
   int i;

   if (dri2_surf->back == NULL) {
      for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
	 if (!dri2_surf->color_buffers[i].locked) {
	    dri2_surf->back = &dri2_surf->color_buffers[i];
	    break;
	 }
      }
   }

   if (dri2_surf->back == NULL)
      return -1;
   if (dri2_surf->back->bo == NULL)
      dri2_surf->back->bo = gbm_bo_create(&dri2_dpy->gbm_dri->base.base,
					  surf->base.width, surf->base.height,
					  surf->base.format, surf->base.flags);
   if (dri2_surf->back->bo == NULL)
      return -1;

   return 0;
}
示例#3
0
std::shared_ptr<mc::Buffer> mgg::GBMBufferAllocator::alloc_buffer(
    mc::BufferProperties const& buffer_properties)
{
    uint32_t bo_flags{0};

    /* Create the GBM buffer object */
    if (buffer_properties.usage == mc::BufferUsage::software)
        bo_flags |= GBM_BO_USE_WRITE;
    else
        bo_flags |= GBM_BO_USE_RENDERING;

    gbm_bo *bo_raw = gbm_bo_create(
                         platform->gbm.device,
                         buffer_properties.size.width.as_uint32_t(),
                         buffer_properties.size.height.as_uint32_t(),
                         mgg::mir_format_to_gbm_format(buffer_properties.format),
                         bo_flags);

    if (!bo_raw)
        BOOST_THROW_EXCEPTION(std::runtime_error("Failed to create GBM buffer object"));

    std::shared_ptr<gbm_bo> bo{bo_raw, GBMBODeleter()};

    std::unique_ptr<EGLImageBufferTextureBinder> texture_binder{
        new EGLImageBufferTextureBinder{bo, egl_extensions}};

    /* Create the GBMBuffer */
    std::shared_ptr<mc::Buffer> buffer{new GBMBuffer{bo, std::move(texture_binder)}};

    (*buffer_initializer)(*buffer);

    return buffer;
}
示例#4
0
QT_BEGIN_NAMESPACE

QKmsCursor::QKmsCursor(QKmsScreen *screen)
    : m_screen(screen),
      m_graphicsBufferManager(screen->device()->gbmDevice()),
      m_moved(false)
{
    gbm_bo *bo = gbm_bo_create(m_graphicsBufferManager, 64, 64,
                               GBM_BO_FORMAT_ARGB8888,
                               GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_RENDERING);

    m_eglImage = eglCreateImageKHR(m_screen->device()->eglDisplay(), 0, EGL_NATIVE_PIXMAP_KHR,
                                   bo, 0);
    gbm_bo_destroy(bo);
    m_cursorImage = new QPlatformCursorImage(0, 0, 0, 0, 0, 0);
}
示例#5
0
static int
get_back_bo(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer)
{
   struct dri2_egl_display *dri2_dpy =
      dri2_egl_display(dri2_surf->base.Resource.Display);
   struct gbm_dri_bo *bo;
   struct gbm_dri_surface *surf = dri2_surf->gbm_surf;
   int i, name, pitch;

   if (dri2_surf->back == NULL)
   {
      for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++)
      {
        if(dri2_surf->color_buffers[i].locked)
        {
            dri2_surf->color_buffers[i].locked = 0;
            continue;
        }
        dri2_surf->back = &dri2_surf->color_buffers[i];
      }
   }

    if (dri2_surf->back == NULL)
        return -1;
    if (dri2_surf->back->bo == NULL)
        dri2_surf->back->bo = gbm_bo_create(&dri2_dpy->gbm_dri->base.base,
					  surf->base.width, surf->base.height,
					  surf->base.format, surf->base.flags);
    if (dri2_surf->back->bo == NULL)
        return -1;

    bo = (struct gbm_dri_bo *) dri2_surf->back->bo;

    dri2_dpy->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_NAME, &name);
    dri2_dpy->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_STRIDE, &pitch);

    buffer->attachment = __DRI_BUFFER_BACK_LEFT;
    buffer->name = name;
    buffer->pitch = pitch;
    buffer->cpp = 4;
    buffer->flags = 0;

    dri2_surf->back->locked = 1;

    return 0;
}
示例#6
0
static int
get_swrast_front_bo(struct dri2_egl_surface *dri2_surf)
{
   struct dri2_egl_display *dri2_dpy =
      dri2_egl_display(dri2_surf->base.Resource.Display);
   struct gbm_dri_surface *surf = dri2_surf->gbm_surf;

   if (dri2_surf->current == NULL) {
      assert(!dri2_surf->color_buffers[0].locked);
      dri2_surf->current = &dri2_surf->color_buffers[0];
   }

   if (dri2_surf->current->bo == NULL)
      dri2_surf->current->bo = gbm_bo_create(&dri2_dpy->gbm_dri->base.base,
                                             surf->base.width, surf->base.height,
                                             surf->base.format, surf->base.flags);
   if (dri2_surf->current->bo == NULL)
      return -1;

   return 0;
}
示例#7
0
static PixmapPtr
xwl_glamor_create_pixmap(ScreenPtr screen,
                         int width, int height, int depth, unsigned int hint)
{
    struct xwl_screen *xwl_screen = xwl_screen_get(screen);
    struct gbm_bo *bo;

    if (width > 0 && height > 0 && depth >= 15 &&
        (hint == 0 ||
         hint == CREATE_PIXMAP_USAGE_BACKING_PIXMAP ||
         hint == CREATE_PIXMAP_USAGE_SHARED)) {
        bo = gbm_bo_create(xwl_screen->gbm, width, height,
                           gbm_format_for_depth(depth),
                           GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);

        if (bo)
            return xwl_glamor_create_pixmap_for_bo(screen, bo, depth);
    }

    return glamor_create_pixmap(screen, width, height, depth, hint);
}
示例#8
0
unsigned int
glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h)
{
    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
    struct glamor_egl_screen_private *glamor_egl;
    EGLImageKHR image;
    GLuint texture;

#ifdef GLAMOR_HAS_GBM
    struct gbm_bo *bo;
    EGLNativePixmapType native_pixmap;

    glamor_egl = glamor_egl_get_screen_private(scrn);
    bo = gbm_bo_create(glamor_egl->gbm, w, h, GBM_FORMAT_ARGB8888,
                       GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT);
    if (!bo)
        return 0;

    /* If the following assignment raises an error or a warning
     * then that means EGLNativePixmapType is not struct gbm_bo *
     * on your platform: This code won't work and you should not
     * compile with dri3 support enabled */
    native_pixmap = bo;

    image = eglCreateImageKHR(glamor_egl->display,
                              EGL_NO_CONTEXT,
                              EGL_NATIVE_PIXMAP_KHR,
                              native_pixmap, NULL);
    gbm_bo_destroy(bo);
    if (image == EGL_NO_IMAGE_KHR)
        return 0;
    glamor_create_texture_from_image(glamor_egl, image, &texture);
    eglDestroyImageKHR(glamor_egl->display, image);

    return texture;
#else
    return 0;                   /* this path should never happen */
#endif
}
示例#9
0
QOpenWFDOutputBuffer::QOpenWFDOutputBuffer(const QSize &size, QOpenWFDPort *port)
    : mPort(port)
    , mAvailable(true)
{
    qDebug() << "creating output buffer for size" << size;
    glGenRenderbuffers(1,&mRbo);
    glBindRenderbuffer(GL_RENDERBUFFER, mRbo);

    mGbm_buffer = gbm_bo_create(port->device()->gbmDevice(),
                  size.width(),
                  size.height(),
                  GBM_BO_FORMAT_XRGB8888,
                  GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);

    mEglImage = port->device()->eglCreateImage(port->device()->eglDisplay(),0, EGL_NATIVE_PIXMAP_KHR, mGbm_buffer, 0);

    port->device()->glEglImageTargetRenderBufferStorage(GL_RENDERBUFFER,mEglImage);

    mWfdSource = wfdCreateSourceFromImage(port->device()->handle(),port->pipeline(),mEglImage,WFD_NONE);
    if (mWfdSource == WFD_INVALID_HANDLE) {
        qWarning("failed to create wfdSource from image");
    }
}
/* Calculate appropriate pitch for a pixmap and allocate a BO that can hold it.
 */
struct amdgpu_buffer *amdgpu_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width,
					      int height, int depth, int usage_hint,
					      int bitsPerPixel, int *new_pitch)
{
	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
	struct amdgpu_buffer *pixmap_buffer;

	if (info->gbm) {
		uint32_t bo_use = GBM_BO_USE_RENDERING;
		uint32_t gbm_format;

		switch (depth) {
#ifdef GBM_FORMAT_R8
		case 8:
			gbm_format = GBM_FORMAT_R8;
			break;
#endif
		case 16:
			gbm_format = GBM_FORMAT_RGB565;
			break;
		case 32:
			gbm_format = GBM_FORMAT_ARGB8888;
			break;
		case 24:
			if (bitsPerPixel == 32) {
				gbm_format = GBM_FORMAT_XRGB8888;
				break;
			}
			/* fall through */
		default:
			ErrorF("%s: Unsupported depth/bpp %d/%d\n", __func__,
			       depth, bitsPerPixel);
			return NULL;
		}

		pixmap_buffer = (struct amdgpu_buffer *)calloc(1, sizeof(struct amdgpu_buffer));
		if (!pixmap_buffer) {
			return NULL;
		}
		pixmap_buffer->ref_count = 1;

		if ( bitsPerPixel == pScrn->bitsPerPixel)
			bo_use |= GBM_BO_USE_SCANOUT;

#ifdef CREATE_PIXMAP_USAGE_SHARED
		if (usage_hint == CREATE_PIXMAP_USAGE_SHARED) {
			/* XXX: Need to tell GBM to disable tiling in this case */
		}
#endif

		if (usage_hint & AMDGPU_CREATE_PIXMAP_LINEAR) {
			bo_use |= GBM_BO_USE_LINEAR;
		}

		pixmap_buffer->bo.gbm = gbm_bo_create(info->gbm, width, height,
						      gbm_format,
						      bo_use);
		if (!pixmap_buffer->bo.gbm) {
			free(pixmap_buffer);
			return NULL;
		}

		pixmap_buffer->flags |= AMDGPU_BO_FLAGS_GBM;

		if (new_pitch)
			*new_pitch = gbm_bo_get_stride(pixmap_buffer->bo.gbm);
	} else {
		AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
		unsigned cpp = (bitsPerPixel + 7) / 8;
		unsigned pitch = cpp *
			AMDGPU_ALIGN(width, drmmode_get_pitch_align(pScrn, cpp));

		pixmap_buffer = amdgpu_bo_open(pAMDGPUEnt->pDev, pitch * height,
					       4096, AMDGPU_GEM_DOMAIN_VRAM);

		if (new_pitch)
			*new_pitch = pitch;
	}

	return pixmap_buffer;
}
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;
}
示例#12
0
bool DisplayOzone::Buffer::resize(int32_t width, int32_t height)
{
    if (mWidth == width && mHeight == height)
    {
        return true;
    }

    reset();

    if (width <= 0 || height <= 0)
    {
        return true;
    }

    mBO = gbm_bo_create(mDisplay->mGBM, width, height, mGBMFormat, mUseFlags);
    if (!mBO)
    {
        return false;
    }

    mDMABuf = gbm_bo_get_fd(mBO);
    if (mDMABuf < 0)
    {
        return false;
    }

    // clang-format off
    const EGLint attr[] =
    {
        EGL_WIDTH, width,
        EGL_HEIGHT, height,
        EGL_LINUX_DRM_FOURCC_EXT, UnsignedToSigned(mDRMFormat),
        EGL_DMA_BUF_PLANE0_FD_EXT, mDMABuf,
        EGL_DMA_BUF_PLANE0_PITCH_EXT, UnsignedToSigned(gbm_bo_get_stride(mBO)),
        EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,
        EGL_NONE,
    };
    // clang-format on

    mImage = mDisplay->mEGL->createImageKHR(EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, nullptr, attr);
    if (mImage == EGL_NO_IMAGE_KHR)
    {
        return false;
    }

    FunctionsGL *gl    = mDisplay->mFunctionsGL;
    StateManagerGL *sm = mDisplay->getRenderer()->getStateManager();

    gl->genRenderbuffers(1, &mColorBuffer);
    sm->bindRenderbuffer(GL_RENDERBUFFER, mColorBuffer);
    gl->eglImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, mImage);

    sm->bindFramebuffer(GL_FRAMEBUFFER, mGLFB);
    gl->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER,
                                mColorBuffer);

    if (mDepthBits || mStencilBits)
    {
        gl->genRenderbuffers(1, &mDSBuffer);
        sm->bindRenderbuffer(GL_RENDERBUFFER, mDSBuffer);
        gl->renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height);
    }

    if (mDepthBits)
    {
        gl->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
                                    mDSBuffer);
    }

    if (mStencilBits)
    {
        gl->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
                                    mDSBuffer);
    }

    mWidth  = width;
    mHeight = height;
    return true;
}
示例#13
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;
}
示例#14
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());
}
示例#15
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;
  }