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