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) }; }
struct wl_buffer * xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap) { struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen); struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap); int prime_fd; if (xwl_pixmap->buffer) return xwl_pixmap->buffer; prime_fd = gbm_bo_get_fd(xwl_pixmap->bo); if (prime_fd == -1) return NULL; xwl_pixmap->buffer = wl_drm_create_prime_buffer(xwl_screen->drm, prime_fd, pixmap->drawable.width, pixmap->drawable.height, drm_format_for_depth(pixmap->drawable.depth), 0, gbm_bo_get_stride(xwl_pixmap->bo), 0, 0, 0, 0); close(prime_fd); return xwl_pixmap->buffer; }
static int xwl_dri3_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, CARD16 *stride, CARD32 *size) { struct xwl_pixmap *xwl_pixmap; xwl_pixmap = xwl_pixmap_get(pixmap); *stride = gbm_bo_get_stride(xwl_pixmap->bo); *size = pixmap->drawable.width * *stride; return gbm_bo_get_fd(xwl_pixmap->bo); }
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; }
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; }