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); }
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; }
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; }
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); }
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; }
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; }
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); }
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 }
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; }
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; }
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; }
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()); }
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; }