Changeset View
Changeset View
Standalone View
Standalone View
source/blender/windowmanager/xr/intern/wm_xr_session.c
| Show First 20 Lines • Show All 532 Lines • ▼ Show 20 Lines | |||||
| * \brief Call Ghost-XR to draw a frame | * \brief Call Ghost-XR to draw a frame | ||||
| * | * | ||||
| * Draw callback for the XR-session surface. It's expected to be called on each main loop | * Draw callback for the XR-session surface. It's expected to be called on each main loop | ||||
| * iteration and tells Ghost-XR to submit a new frame by drawing its views. Note that for drawing | * iteration and tells Ghost-XR to submit a new frame by drawing its views. Note that for drawing | ||||
| * each view, #wm_xr_draw_view() will be called through Ghost-XR (see GHOST_XrDrawViewFunc()). | * each view, #wm_xr_draw_view() will be called through Ghost-XR (see GHOST_XrDrawViewFunc()). | ||||
| */ | */ | ||||
| static void wm_xr_session_surface_draw(bContext *C) | static void wm_xr_session_surface_draw(bContext *C) | ||||
| { | { | ||||
| wmXrSurfaceData *surface_data = g_xr_surface->customdata; | |||||
| wmWindowManager *wm = CTX_wm_manager(C); | wmWindowManager *wm = CTX_wm_manager(C); | ||||
| Main *bmain = CTX_data_main(C); | Main *bmain = CTX_data_main(C); | ||||
| wmXrDrawData draw_data; | wmXrDrawData draw_data; | ||||
| if (!GHOST_XrSessionIsRunning(wm->xr.runtime->context)) { | if (!GHOST_XrSessionIsRunning(wm->xr.runtime->context)) { | ||||
| return; | return; | ||||
| } | } | ||||
| Scene *scene; | Scene *scene; | ||||
| Depsgraph *depsgraph; | Depsgraph *depsgraph; | ||||
| wm_xr_session_scene_and_evaluated_depsgraph_get(bmain, wm, &scene, &depsgraph); | wm_xr_session_scene_and_evaluated_depsgraph_get(bmain, wm, &scene, &depsgraph); | ||||
| wm_xr_session_draw_data_populate(&wm->xr, scene, depsgraph, &draw_data); | wm_xr_session_draw_data_populate(&wm->xr, scene, depsgraph, &draw_data); | ||||
| GHOST_XrSessionDrawViews(wm->xr.runtime->context, &draw_data); | GHOST_XrSessionDrawViews(wm->xr.runtime->context, &draw_data); | ||||
| GPU_offscreen_unbind(surface_data->offscreen, false); | GPU_framebuffer_restore(); | ||||
| } | } | ||||
| bool wm_xr_session_surface_offscreen_ensure(wmXrSurfaceData *surface_data, | bool wm_xr_session_surface_offscreen_ensure(wmXrSurfaceData *surface_data, | ||||
| const GHOST_XrDrawViewInfo *draw_view) | const GHOST_XrDrawViewInfo *draw_view) | ||||
| { | { | ||||
| const bool size_changed = surface_data->offscreen && | wmXrViewportPair *vp = NULL; | ||||
| (GPU_offscreen_width(surface_data->offscreen) != draw_view->width) && | if (draw_view->view_idx >= BLI_listbase_count(&surface_data->viewports)) { | ||||
| (GPU_offscreen_height(surface_data->offscreen) != draw_view->height); | vp = MEM_callocN(sizeof(*vp), __func__); | ||||
| BLI_addtail(&surface_data->viewports, vp); | |||||
| } | |||||
| else { | |||||
| vp = BLI_findlink(&surface_data->viewports, draw_view->view_idx); | |||||
| } | |||||
| BLI_assert(vp); | |||||
| GPUOffScreen *offscreen = vp->offscreen; | |||||
| GPUViewport *viewport = vp->viewport; | |||||
| const bool size_changed = offscreen && (GPU_offscreen_width(offscreen) != draw_view->width) && | |||||
| (GPU_offscreen_height(offscreen) != draw_view->height); | |||||
| char err_out[256] = "unknown"; | char err_out[256] = "unknown"; | ||||
| bool failure = false; | bool failure = false; | ||||
| if (surface_data->offscreen) { | if (offscreen) { | ||||
| BLI_assert(surface_data->viewport); | BLI_assert(viewport); | ||||
| if (!size_changed) { | if (!size_changed) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| GPU_viewport_free(surface_data->viewport); | GPU_viewport_free(viewport); | ||||
| GPU_offscreen_free(surface_data->offscreen); | GPU_offscreen_free(offscreen); | ||||
| } | } | ||||
| if (!(surface_data->offscreen = GPU_offscreen_create( | offscreen = vp->offscreen = GPU_offscreen_create( | ||||
| draw_view->width, draw_view->height, true, false, err_out))) { | draw_view->width, draw_view->height, true, false, err_out); | ||||
| if (offscreen) { | |||||
| viewport = vp->viewport = GPU_viewport_create(); | |||||
| if (!viewport) { | |||||
| GPU_offscreen_free(offscreen); | |||||
| offscreen = vp->offscreen = NULL; | |||||
| failure = true; | failure = true; | ||||
| } | } | ||||
| if (failure) { | |||||
| /* Pass. */ | |||||
| } | } | ||||
| else if (!(surface_data->viewport = GPU_viewport_create())) { | else { | ||||
| GPU_offscreen_free(surface_data->offscreen); | |||||
| failure = true; | failure = true; | ||||
| } | } | ||||
| if (failure) { | if (failure) { | ||||
| CLOG_ERROR(&LOG, "Failed to get buffer, %s\n", err_out); | CLOG_ERROR(&LOG, "Failed to get buffer, %s\n", err_out); | ||||
| return false; | return false; | ||||
| } | } | ||||
| return true; | return true; | ||||
| } | } | ||||
| static void wm_xr_session_surface_free_data(wmSurface *surface) | static void wm_xr_session_surface_free_data(wmSurface *surface) | ||||
| { | { | ||||
| wmXrSurfaceData *data = surface->customdata; | wmXrSurfaceData *data = surface->customdata; | ||||
| ListBase *lb = &data->viewports; | |||||
| wmXrViewportPair *vp; | |||||
| if (data->viewport) { | while (vp = BLI_pophead(lb)) { | ||||
| GPU_viewport_free(data->viewport); | if (vp->viewport) { | ||||
| GPU_viewport_free(vp->viewport); | |||||
| } | |||||
| if (vp->offscreen) { | |||||
| GPU_offscreen_free(vp->offscreen); | |||||
| } | } | ||||
| if (data->offscreen) { | BLI_freelinkN(lb, vp); | ||||
| GPU_offscreen_free(data->offscreen); | |||||
| } | } | ||||
| MEM_freeN(surface->customdata); | MEM_freeN(surface->customdata); | ||||
| g_xr_surface = NULL; | g_xr_surface = NULL; | ||||
| } | } | ||||
| static wmSurface *wm_xr_session_surface_create(void) | static wmSurface *wm_xr_session_surface_create(void) | ||||
| ▲ Show 20 Lines • Show All 51 Lines • Show Last 20 Lines | |||||