static void BPyGPUOffScreen__tp_dealloc(BPyGPUOffScreen *self) { if (self->ofs) { GPU_offscreen_free(self->ofs); } Py_TYPE(self)->tp_free((PyObject *)self); }
static void screen_opengl_render_end(bContext *C, OGLRender *oglrender) { Main *bmain = CTX_data_main(C); Scene *scene = oglrender->scene; if (oglrender->mh) { if (BKE_imtype_is_movie(scene->r.im_format.imtype)) oglrender->mh->end_movie(); } if (oglrender->timer) { /* exec will not have a timer */ scene->r.cfra = oglrender->cfrao; BKE_scene_update_for_newframe(bmain, scene, screen_opengl_layers(oglrender)); WM_event_remove_timer(oglrender->wm, oglrender->win, oglrender->timer); } WM_cursor_modal_restore(oglrender->win); WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene); U.obcenter_dia = oglrender->obcenter_dia_back; GPU_offscreen_free(oglrender->ofs); oglrender->scene->customdata_mask_modal = 0; CTX_wm_area_set(C, oglrender->prevsa); CTX_wm_region_set(C, oglrender->prevar); MEM_freeN(oglrender); }
/* Transform buffer from role to scene linear space using GLSL OCIO conversion * * See IMB_colormanagement_setup_transform_from_role_glsl description for * some more details * * NOTE: this only works for RGBA buffers! */ int glaBufferTransformFromRole_glsl(float *buffer, int width, int height, int role) { GPUOffScreen *ofs; char err_out[256]; rcti display_rect; ofs = GPU_offscreen_create(width, height, err_out); if (!ofs) return FALSE; GPU_offscreen_bind(ofs); if (!IMB_colormanagement_setup_transform_from_role_glsl(role, TRUE)) { GPU_offscreen_unbind(ofs); GPU_offscreen_free(ofs); return FALSE; } BLI_rcti_init(&display_rect, 0, width, 0, height); glMatrixMode(GL_PROJECTION); glPushMatrix(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glaDefine2DArea(&display_rect); glaDrawPixelsTex(0, 0, width, height, GL_RGBA, GL_FLOAT, GL_NEAREST, buffer); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); GPU_offscreen_read_pixels(ofs, GL_FLOAT, buffer); IMB_colormanagement_finish_glsl_transform(); /* unbind */ GPU_offscreen_unbind(ofs); GPU_offscreen_free(ofs); return TRUE; }
static PyObject *bpygpu_offscreen_free(BPyGPUOffScreen *self) { BPY_GPU_OFFSCREEN_CHECK_OBJ(self); GPU_offscreen_free(self->ofs); self->ofs = NULL; Py_RETURN_NONE; }
static void wm_draw_region_buffer_create(ARegion *ar, bool stereo, bool use_viewport) { if (ar->draw_buffer) { if (ar->draw_buffer->stereo != stereo) { /* Free draw buffer on stereo changes. */ wm_draw_region_buffer_free(ar); } else { /* Free offscreen buffer on size changes. Viewport auto resizes. */ GPUOffScreen *offscreen = ar->draw_buffer->offscreen[0]; if (offscreen && (GPU_offscreen_width(offscreen) != ar->winx || GPU_offscreen_height(offscreen) != ar->winy)) { wm_draw_region_buffer_free(ar); } } } if (!ar->draw_buffer) { if (use_viewport) { /* Allocate viewport which includes an offscreen buffer with depth * multisample, etc. */ ar->draw_buffer = MEM_callocN(sizeof(wmDrawBuffer), "wmDrawBuffer"); ar->draw_buffer->viewport[0] = GPU_viewport_create(); ar->draw_buffer->viewport[1] = (stereo) ? GPU_viewport_create() : NULL; } else { /* Allocate offscreen buffer if it does not exist. This one has no * depth or multisample buffers. 3D view creates own buffers with * the data it needs. */ GPUOffScreen *offscreen = GPU_offscreen_create(ar->winx, ar->winy, 0, false, false, NULL); if (!offscreen) { return; } wm_draw_offscreen_texture_parameters(offscreen); GPUOffScreen *offscreen_right = NULL; if (stereo) { offscreen_right = GPU_offscreen_create(ar->winx, ar->winy, 0, false, false, NULL); if (!offscreen_right) { GPU_offscreen_free(offscreen); return; } wm_draw_offscreen_texture_parameters(offscreen_right); } ar->draw_buffer = MEM_callocN(sizeof(wmDrawBuffer), "wmDrawBuffer"); ar->draw_buffer->offscreen[0] = offscreen; ar->draw_buffer->offscreen[1] = offscreen_right; } ar->draw_buffer->bound_view = -1; ar->draw_buffer->stereo = stereo; } }
GPUOffScreen *GPU_offscreen_create(int *width, int *height, char err_out[256]) { GPUOffScreen *ofs; ofs= MEM_callocN(sizeof(GPUOffScreen), "GPUOffScreen"); ofs->fb = GPU_framebuffer_create(); if(!ofs->fb) { GPU_offscreen_free(ofs); return NULL; } ofs->depth = GPU_texture_create_depth(*width, *height, err_out); if(!ofs->depth) { GPU_offscreen_free(ofs); return NULL; } if(*width!=ofs->depth->w || *height!=ofs->depth->h) { *width= ofs->depth->w; *height= ofs->depth->h; printf("Offscreen size differs from given size!\n"); } if(!GPU_framebuffer_texture_attach(ofs->fb, ofs->depth, err_out)) { GPU_offscreen_free(ofs); return NULL; } ofs->color = GPU_texture_create_2D(*width, *height, NULL, err_out); if(!ofs->color) { GPU_offscreen_free(ofs); return NULL; } if(!GPU_framebuffer_texture_attach(ofs->fb, ofs->color, err_out)) { GPU_offscreen_free(ofs); return NULL; } GPU_framebuffer_restore(); return ofs; }
GPUOffScreen *GPU_offscreen_create(int width, int height, char err_out[256]) { GPUOffScreen *ofs; ofs= MEM_callocN(sizeof(GPUOffScreen), "GPUOffScreen"); ofs->w= width; ofs->h= height; ofs->fb = GPU_framebuffer_create(); if (!ofs->fb) { GPU_offscreen_free(ofs); return NULL; } ofs->depth = GPU_texture_create_depth(width, height, err_out); if (!ofs->depth) { GPU_offscreen_free(ofs); return NULL; } if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->depth, err_out)) { GPU_offscreen_free(ofs); return NULL; } ofs->color = GPU_texture_create_2D(width, height, NULL, err_out); if (!ofs->color) { GPU_offscreen_free(ofs); return NULL; } if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->color, err_out)) { GPU_offscreen_free(ofs); return NULL; } GPU_framebuffer_restore(); return ofs; }
GPUOffScreen *GPU_offscreen_create(int width, int height, int samples, char err_out[256]) { GPUOffScreen *ofs; ofs = MEM_callocN(sizeof(GPUOffScreen), "GPUOffScreen"); ofs->fb = GPU_framebuffer_create(); if (!ofs->fb) { GPU_offscreen_free(ofs); return NULL; } if (samples) { if (!GLEW_EXT_framebuffer_multisample || !GLEW_ARB_texture_multisample || /* Only needed for GPU_offscreen_read_pixels. * We could add an arg if we intend to use multi-sample * offscreen buffers w/o reading their pixels */ !GLEW_EXT_framebuffer_blit || /* This is required when blitting from a multi-sampled buffers, * even though we're not scaling. */ !GLEW_EXT_framebuffer_multisample_blit_scaled) { samples = 0; } } ofs->depth = GPU_texture_create_depth_multisample(width, height, samples, err_out); if (!ofs->depth) { GPU_offscreen_free(ofs); return NULL; } if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->depth, 0, err_out)) { GPU_offscreen_free(ofs); return NULL; } ofs->color = GPU_texture_create_2D_multisample(width, height, NULL, GPU_HDR_NONE, samples, err_out); if (!ofs->color) { GPU_offscreen_free(ofs); return NULL; } if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->color, 0, err_out)) { GPU_offscreen_free(ofs); return NULL; } /* check validity at the very end! */ if (!GPU_framebuffer_check_valid(ofs->fb, err_out)) { GPU_offscreen_free(ofs); return NULL; } GPU_framebuffer_restore(); return ofs; }
static void wm_draw_region_buffer_free(ARegion *ar) { if (ar->draw_buffer) { for (int view = 0; view < 2; view++) { if (ar->draw_buffer->offscreen[view]) { GPU_offscreen_free(ar->draw_buffer->offscreen[view]); } if (ar->draw_buffer->viewport[view]) { GPU_viewport_free(ar->draw_buffer->viewport[view]); } } MEM_freeN(ar->draw_buffer); ar->draw_buffer = NULL; } }
static void screen_opengl_render_end(bContext *C, OGLRender *oglrender) { Main *bmain = CTX_data_main(C); Scene *scene = oglrender->scene; size_t i; if (oglrender->mh) { if (BKE_imtype_is_movie(scene->r.im_format.imtype)) { for (i = 0; i < oglrender->totvideos; i++) { oglrender->mh->end_movie(oglrender->movie_ctx_arr[i]); oglrender->mh->context_free(oglrender->movie_ctx_arr[i]); } } if (oglrender->movie_ctx_arr) { MEM_freeN(oglrender->movie_ctx_arr); } } if (oglrender->timer) { /* exec will not have a timer */ scene->r.cfra = oglrender->cfrao; BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, screen_opengl_layers(oglrender)); WM_event_remove_timer(oglrender->wm, oglrender->win, oglrender->timer); } WM_cursor_modal_restore(oglrender->win); WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene); if (oglrender->fx) GPU_fx_compositor_destroy(oglrender->fx); GPU_offscreen_free(oglrender->ofs); oglrender->scene->customdata_mask_modal = 0; CTX_wm_area_set(C, oglrender->prevsa); CTX_wm_region_set(C, oglrender->prevar); MEM_freeN(oglrender); }
static void screen_opengl_render_end(bContext *C, OGLRender *oglrender) { Main *bmain = CTX_data_main(C); Scene *scene = oglrender->scene; int i; if (oglrender->is_animation) { BLI_task_pool_work_and_wait(oglrender->task_pool); BLI_task_pool_free(oglrender->task_pool); /* Depending on various things we might or might not use global scheduler. */ if (oglrender->task_scheduler != NULL) { BLI_task_scheduler_free(oglrender->task_scheduler); } BLI_spin_end(&oglrender->reports_lock); } BLI_mutex_end(&oglrender->task_mutex); BLI_condition_end(&oglrender->task_condition); #ifdef DEBUG_TIME printf("Total render time: %f\n", PIL_check_seconds_timer() - oglrender->time_start); #endif if (oglrender->mh) { if (BKE_imtype_is_movie(scene->r.im_format.imtype)) { for (i = 0; i < oglrender->totvideos; i++) { oglrender->mh->end_movie(oglrender->movie_ctx_arr[i]); oglrender->mh->context_free(oglrender->movie_ctx_arr[i]); } } if (oglrender->movie_ctx_arr) { MEM_freeN(oglrender->movie_ctx_arr); } } if (oglrender->timer) { /* exec will not have a timer */ scene->r.cfra = oglrender->cfrao; BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, screen_opengl_layers(oglrender)); WM_event_remove_timer(oglrender->wm, oglrender->win, oglrender->timer); } WM_cursor_modal_restore(oglrender->win); WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene); if (oglrender->fx) GPU_fx_compositor_destroy(oglrender->fx); GPU_offscreen_free(oglrender->ofs); if (oglrender->is_sequencer) { MEM_freeN(oglrender->seq_data.ibufs_arr); } oglrender->scene->customdata_mask_modal = 0; CTX_wm_area_set(C, oglrender->prevsa); CTX_wm_region_set(C, oglrender->prevar); MEM_freeN(oglrender); }