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