Changeset View
Changeset View
Standalone View
Standalone View
source/blender/windowmanager/intern/wm_draw.c
| Show First 20 Lines • Show All 294 Lines • ▼ Show 20 Lines | |||||
| static void wm_draw_region_buffer_free(ARegion *ar) | static void wm_draw_region_buffer_free(ARegion *ar) | ||||
| { | { | ||||
| if (ar->draw_buffer) { | if (ar->draw_buffer) { | ||||
| for (int view = 0; view < 2; view++) { | for (int view = 0; view < 2; view++) { | ||||
| if (ar->draw_buffer->offscreen[view]) { | if (ar->draw_buffer->offscreen[view]) { | ||||
| GPU_offscreen_free(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]); | |||||
| } | } | ||||
| if (ar->draw_buffer->viewport) { | |||||
| GPU_viewport_free(ar->draw_buffer->viewport); | |||||
| } | } | ||||
| MEM_freeN(ar->draw_buffer); | MEM_freeN(ar->draw_buffer); | ||||
| ar->draw_buffer = NULL; | ar->draw_buffer = NULL; | ||||
| } | } | ||||
| } | } | ||||
| static void wm_draw_offscreen_texture_parameters(GPUOffScreen *offscreen) | static void wm_draw_offscreen_texture_parameters(GPUOffScreen *offscreen) | ||||
| Show All 32 Lines | if (ar->draw_buffer) { | ||||
| } | } | ||||
| } | } | ||||
| if (!ar->draw_buffer) { | if (!ar->draw_buffer) { | ||||
| if (use_viewport) { | if (use_viewport) { | ||||
| /* Allocate viewport which includes an offscreen buffer with depth | /* Allocate viewport which includes an offscreen buffer with depth | ||||
| * multisample, etc. */ | * multisample, etc. */ | ||||
| ar->draw_buffer = MEM_callocN(sizeof(wmDrawBuffer), "wmDrawBuffer"); | ar->draw_buffer = MEM_callocN(sizeof(wmDrawBuffer), "wmDrawBuffer"); | ||||
| ar->draw_buffer->viewport[0] = GPU_viewport_create(); | ar->draw_buffer->viewport = GPU_viewport_create(stereo); | ||||
| ar->draw_buffer->viewport[1] = (stereo) ? GPU_viewport_create() : NULL; | |||||
| } | } | ||||
| else { | else { | ||||
| /* Allocate offscreen buffer if it does not exist. This one has no | /* Allocate offscreen buffer if it does not exist. This one has no | ||||
| * depth or multisample buffers. 3D view creates own buffers with | * depth or multisample buffers. 3D view creates own buffers with | ||||
| * the data it needs. */ | * the data it needs. */ | ||||
| GPUOffScreen *offscreen = GPU_offscreen_create(ar->winx, ar->winy, 0, false, false, NULL); | GPUOffScreen *offscreen = GPU_offscreen_create(ar->winx, ar->winy, 0, false, false, NULL); | ||||
| if (!offscreen) { | if (!offscreen) { | ||||
| return; | return; | ||||
| Show All 24 Lines | |||||
| } | } | ||||
| static void wm_draw_region_bind(ARegion *ar, int view) | static void wm_draw_region_bind(ARegion *ar, int view) | ||||
| { | { | ||||
| if (!ar->draw_buffer) { | if (!ar->draw_buffer) { | ||||
| return; | return; | ||||
| } | } | ||||
| if (ar->draw_buffer->viewport[view]) { | if (ar->draw_buffer->viewport) { | ||||
| GPU_viewport_bind(ar->draw_buffer->viewport[view], &ar->winrct); | GPU_viewport_bind(ar->draw_buffer->viewport, view, &ar->winrct); | ||||
| } | } | ||||
| else { | else { | ||||
| GPU_offscreen_bind(ar->draw_buffer->offscreen[view], false); | GPU_offscreen_bind(ar->draw_buffer->offscreen[view], false); | ||||
| /* For now scissor is expected by region drawing, we could disable it | /* For now scissor is expected by region drawing, we could disable it | ||||
| * and do the enable/disable in the specific cases that setup scissor. */ | * and do the enable/disable in the specific cases that setup scissor. */ | ||||
| glEnable(GL_SCISSOR_TEST); | glEnable(GL_SCISSOR_TEST); | ||||
| glScissor(0, 0, ar->winx, ar->winy); | glScissor(0, 0, ar->winx, ar->winy); | ||||
| } | } | ||||
| ar->draw_buffer->bound_view = view; | ar->draw_buffer->bound_view = view; | ||||
| } | } | ||||
| static void wm_draw_region_unbind(ARegion *ar, int view) | static void wm_draw_region_unbind(ARegion *ar, int view) | ||||
| { | { | ||||
| if (!ar->draw_buffer) { | if (!ar->draw_buffer) { | ||||
| return; | return; | ||||
| } | } | ||||
| ar->draw_buffer->bound_view = -1; | ar->draw_buffer->bound_view = -1; | ||||
| if (ar->draw_buffer->viewport[view]) { | if (ar->draw_buffer->viewport) { | ||||
| GPU_viewport_unbind(ar->draw_buffer->viewport[view]); | GPU_viewport_unbind(ar->draw_buffer->viewport); | ||||
| } | } | ||||
| else { | else { | ||||
| glDisable(GL_SCISSOR_TEST); | glDisable(GL_SCISSOR_TEST); | ||||
| GPU_offscreen_unbind(ar->draw_buffer->offscreen[view], false); | GPU_offscreen_unbind(ar->draw_buffer->offscreen[view], false); | ||||
| } | } | ||||
| } | } | ||||
| static void wm_draw_region_blit(ARegion *ar, int view) | static void wm_draw_region_blit(ARegion *ar, int view) | ||||
| { | { | ||||
| if (!ar->draw_buffer) { | if (!ar->draw_buffer) { | ||||
| return; | return; | ||||
| } | } | ||||
| if (view == -1) { | if (view == -1) { | ||||
| /* Non-stereo drawing. */ | /* Non-stereo drawing. */ | ||||
| view = 0; | view = 0; | ||||
| } | } | ||||
| else if (view > 0) { | else if (view > 0) { | ||||
| if (ar->draw_buffer->viewport[view] == NULL && ar->draw_buffer->offscreen[view] == NULL) { | if (ar->draw_buffer->viewport == NULL && ar->draw_buffer->offscreen[view] == NULL) { | ||||
| /* Region does not need stereo or failed to allocate stereo buffers. */ | /* Region does not need stereo or failed to allocate stereo buffers. */ | ||||
| view = 0; | view = 0; | ||||
| } | } | ||||
| } | } | ||||
| if (ar->draw_buffer->viewport[view]) { | if (ar->draw_buffer->viewport) { | ||||
| GPU_viewport_draw_to_screen(ar->draw_buffer->viewport[view], &ar->winrct); | GPU_viewport_framebuffer_update_view(ar->draw_buffer->viewport, view); | ||||
| GPU_viewport_draw_to_screen(ar->draw_buffer->viewport, &ar->winrct); | |||||
| } | } | ||||
| else { | else { | ||||
| GPU_offscreen_draw_to_screen( | GPU_offscreen_draw_to_screen( | ||||
| ar->draw_buffer->offscreen[view], ar->winrct.xmin, ar->winrct.ymin); | ar->draw_buffer->offscreen[view], ar->winrct.xmin, ar->winrct.ymin); | ||||
| } | } | ||||
| } | } | ||||
| GPUTexture *wm_draw_region_texture(ARegion *ar, int view) | GPUTexture *wm_draw_region_texture(ARegion *ar, int view) | ||||
| { | { | ||||
| if (!ar->draw_buffer) { | if (!ar->draw_buffer) { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| if (ar->draw_buffer->viewport[view]) { | GPUViewport *viewport = ar->draw_buffer->viewport; | ||||
| return GPU_viewport_color_texture(ar->draw_buffer->viewport[view]); | if (viewport) { | ||||
| return GPU_viewport_color_texture(viewport, view); | |||||
| } | } | ||||
| else { | else { | ||||
| return GPU_offscreen_color_texture(ar->draw_buffer->offscreen[view]); | return GPU_offscreen_color_texture(ar->draw_buffer->offscreen[view]); | ||||
| } | } | ||||
| } | } | ||||
| void wm_draw_region_blend(ARegion *ar, int view, bool blend) | void wm_draw_region_blend(ARegion *ar, int view, bool blend) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | void wm_draw_region_blend(ARegion *ar, int view, bool blend) | ||||
| glBindTexture(GL_TEXTURE_2D, 0); | glBindTexture(GL_TEXTURE_2D, 0); | ||||
| if (blend) { | if (blend) { | ||||
| glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||||
| GPU_blend(false); | GPU_blend(false); | ||||
| } | } | ||||
| } | } | ||||
| GPUViewport *WM_draw_region_get_viewport(ARegion *ar, int view) | GPUViewport *WM_draw_region_get_viewport(ARegion *ar, int view) | ||||
fclem: The only part where the view is really required is `DRW_notify_view_update`.
This is the only… | |||||
| { | { | ||||
| if (!ar->draw_buffer) { | if (!ar->draw_buffer) { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| return ar->draw_buffer->viewport[view]; | GPUViewport *viewport = ar->draw_buffer->viewport; | ||||
| GPU_viewport_framebuffer_update_view(viewport, view); | |||||
| return viewport; | |||||
| } | } | ||||
| GPUViewport *WM_draw_region_get_bound_viewport(ARegion *ar) | GPUViewport *WM_draw_region_get_bound_viewport(ARegion *ar) | ||||
Done Inline ActionsThis can be removed and replaced by wm_region_use_viewport. fclem: This can be removed and replaced by wm_region_use_viewport. | |||||
Done Inline ActionsNot sure, wouldn't that fail in DRW_draw_render_loop_ex? if (WM_draw_region_get_bound_viewport(region)) {
/* Don't unbind the framebuffer yet in this case and let
* GPU_viewport_unbind do it, so that we can still do further
* drawing of action zones on top. */
}jbakker: Not sure, wouldn't that fail in DRW_draw_render_loop_ex?
```
if… | |||||
Done Inline ActionsIn this instance it only checks if we are rendering of this areas or for offscreen or for window display. Anyways that's a bit of a bad level call even. We should take this decision from a DRW state not from the area state. Leave it as is for now. fclem: In this instance it only checks if we are rendering of this areas or for offscreen or for… | |||||
| { | { | ||||
| if (!ar->draw_buffer || ar->draw_buffer->bound_view == -1) { | if (!ar->draw_buffer || ar->draw_buffer->bound_view == -1) { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| GPUViewport *viewport = ar->draw_buffer->viewport; | |||||
| int view = ar->draw_buffer->bound_view; | int view = ar->draw_buffer->bound_view; | ||||
| return ar->draw_buffer->viewport[view]; | GPU_viewport_framebuffer_update_view(viewport, view); | ||||
| return viewport; | |||||
| } | } | ||||
| static void wm_draw_window_offscreen(bContext *C, wmWindow *win, bool stereo) | static void wm_draw_window_offscreen(bContext *C, wmWindow *win, bool stereo) | ||||
| { | { | ||||
| Main *bmain = CTX_data_main(C); | Main *bmain = CTX_data_main(C); | ||||
| wmWindowManager *wm = CTX_wm_manager(C); | wmWindowManager *wm = CTX_wm_manager(C); | ||||
| bScreen *screen = WM_window_get_active_screen(win); | bScreen *screen = WM_window_get_active_screen(win); | ||||
| ▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { | ||||
| wm_draw_region_bind(ar, view); | wm_draw_region_bind(ar, view); | ||||
| ED_region_do_draw(C, ar); | ED_region_do_draw(C, ar); | ||||
| wm_draw_region_unbind(ar, view); | wm_draw_region_unbind(ar, view); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| wm_draw_region_buffer_create(ar, false, use_viewport); | wm_draw_region_buffer_create(ar, false, use_viewport); | ||||
| wm_draw_region_bind(ar, 0); | wm_draw_region_bind(ar, 0); | ||||
Done Inline ActionsSo if I understand correctly, you are mixing the stereo views here and saving the result in the first view. fclem: So if I understand correctly, you are mixing the stereo views here and saving the result in the… | |||||
Done Inline ActionsYes as pixels do not move we don't need additional textures for the merging. The color management process is then also straight forward. I will add a Comment to the GPU_viewport_stereo_composite function. jbakker: Yes as pixels do not move we don't need additional textures for the merging. The color… | |||||
| ED_region_do_draw(C, ar); | ED_region_do_draw(C, ar); | ||||
| wm_draw_region_unbind(ar, 0); | wm_draw_region_unbind(ar, 0); | ||||
| } | } | ||||
| ar->do_draw = false; | ar->do_draw = false; | ||||
| CTX_wm_region_set(C, NULL); | CTX_wm_region_set(C, NULL); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
| #if 0 | #if 0 | ||||
| glClearColor(0, 0, 0, 0); | glClearColor(0, 0, 0, 0); | ||||
| glClear(GL_COLOR_BUFFER_BIT); | glClear(GL_COLOR_BUFFER_BIT); | ||||
| #endif | #endif | ||||
| /* Blit non-overlapping area regions. */ | /* Blit non-overlapping area regions. */ | ||||
| ED_screen_areas_iter(win, screen, sa) | ED_screen_areas_iter(win, screen, sa) | ||||
| { | { | ||||
| for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { | for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { | ||||
| if (ar->visible && ar->overlap == false) { | if (ar->visible && ar->overlap == false) { | ||||
| if (view == -1 && ar->draw_buffer && ar->draw_buffer->stereo) { | if (view == -1 && ar->draw_buffer && ar->draw_buffer->stereo) { | ||||
| /* Stereo drawing from textures. */ | /* Stereo drawing from textures. */ | ||||
| if (win->stereo3d_format->display_mode == S3D_DISPLAY_ANAGLYPH) { | if (win->stereo3d_format->display_mode == S3D_DISPLAY_ANAGLYPH) { | ||||
| wm_stereo3d_draw_anaglyph(win, ar); | wm_stereo3d_draw_anaglyph(win, ar); | ||||
| } | } | ||||
| else { | else { | ||||
| wm_stereo3d_draw_interlace(win, ar); | wm_stereo3d_draw_interlace(win, ar); | ||||
Done Inline Actionsremove branch if there is nothing different in both branches fclem: remove branch if there is nothing different in both branches | |||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* Blit from offscreen buffer. */ | /* Blit from offscreen buffer. */ | ||||
| wm_draw_region_blit(ar, view); | wm_draw_region_blit(ar, view); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 317 Lines • Show Last 20 Lines | |||||
The only part where the view is really required is DRW_notify_view_update.
This is the only time I found GPU_viewport_framebuffer_view_set is required. Can we workaround this by having a function call for this only in DRW_notify_view_update?