Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py2
-rw-r--r--source/blender/blenkernel/BKE_screen.h2
-rw-r--r--source/blender/blenkernel/intern/screen.c1
-rw-r--r--source/blender/blenloader/intern/readfile.c7
-rw-r--r--source/blender/draw/DRW_engine.h4
-rw-r--r--source/blender/draw/intern/draw_manager.c159
-rw-r--r--source/blender/editors/include/ED_screen.h2
-rw-r--r--source/blender/editors/interface/interface_draw.c55
-rw-r--r--source/blender/editors/interface/interface_region_popup.c8
-rw-r--r--source/blender/editors/interface/resources.c4
-rw-r--r--source/blender/editors/screen/area.c35
-rw-r--r--source/blender/editors/screen/screen_draw.c2
-rw-r--r--source/blender/editors/screen/screen_edit.c2
-rw-r--r--source/blender/editors/screen/screen_ops.c2
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c2
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c13
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c12
-rw-r--r--source/blender/editors/space_view3d/view3d_draw_legacy.c2
-rw-r--r--source/blender/gpu/GPU_framebuffer.h1
-rw-r--r--source/blender/gpu/GPU_viewport.h2
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.c18
-rw-r--r--source/blender/gpu/intern/gpu_shader.c2
-rw-r--r--source/blender/gpu/intern/gpu_viewport.c21
-rw-r--r--source/blender/makesdna/DNA_screen_types.h13
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h13
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h1
-rw-r--r--source/blender/makesdna/DNA_windowmanager_types.h3
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c20
-rw-r--r--source/blender/windowmanager/WM_api.h9
-rw-r--r--source/blender/windowmanager/intern/wm.c1
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c1026
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c6
-rw-r--r--source/blender/windowmanager/intern/wm_gesture.c4
-rw-r--r--source/blender/windowmanager/intern/wm_stereo.c248
-rw-r--r--source/blender/windowmanager/intern/wm_subwindow.c6
-rw-r--r--source/blender/windowmanager/intern/wm_window.c12
-rw-r--r--source/blender/windowmanager/wm.h7
-rw-r--r--source/blender/windowmanager/wm_draw.h28
38 files changed, 703 insertions, 1052 deletions
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index cc7e8701320..5df49752634 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -535,8 +535,6 @@ class USERPREF_PT_system(Panel):
col.separator()
- col.label(text="Window Draw Method:")
- col.prop(system, "window_draw_method", text="")
col.prop(system, "multi_sample", text="")
if sys.platform == "linux" and system.multi_sample != 'NONE':
col.label(text="Might fail for Mesh editing selection!")
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index 69b5e7ea6fe..17cca92c1fc 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -140,6 +140,8 @@ typedef struct ARegionType {
void (*exit)(struct wmWindowManager *, struct ARegion *);
/* draw entirely, view changes should be handled here */
void (*draw)(const struct bContext *, struct ARegion *);
+ /* optional, refresh popup before drawing */
+ void (*refresh)(const struct bContext *, struct ARegion *);
/* snap the size of the region (can be NULL for no snapping). */
int (*snap_size)(const struct ARegion *ar, int size, int axis);
/* contextual changes should be handled here */
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index 77f7b5f847e..ece68884f5c 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -184,6 +184,7 @@ ARegion *BKE_area_region_copy(SpaceType *st, ARegion *ar)
newar->manipulator_map = NULL;
newar->regiontimer = NULL;
newar->headerstr = NULL;
+ newar->draw_buffer = NULL;
/* use optional regiondata callback */
if (ar->regiondata) {
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index c1539d7edf1..3980c860641 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -6362,7 +6362,6 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
rv3d->sms = NULL;
rv3d->smooth_timer = NULL;
rv3d->compositor = NULL;
- rv3d->viewport = NULL;
}
}
}
@@ -6377,10 +6376,10 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
ar->headerstr = NULL;
ar->visible = 0;
ar->type = NULL;
- ar->swap = 0;
ar->do_draw = 0;
ar->manipulator_map = NULL;
ar->regiontimer = NULL;
+ ar->draw_buffer = NULL;
memset(&ar->drawrct, 0, sizeof(ar->drawrct));
}
@@ -6868,10 +6867,7 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
BLI_listbase_clear(&win->handlers);
BLI_listbase_clear(&win->modalhandlers);
BLI_listbase_clear(&win->gesture);
- BLI_listbase_clear(&win->drawdata);
- win->drawmethod = -1;
- win->drawfail = 0;
win->active = 0;
win->cursor = 0;
@@ -7388,7 +7384,6 @@ static bool direct_link_screen(FileData *fd, bScreen *sc)
sc->regionbase.first = sc->regionbase.last= NULL;
sc->context = NULL;
sc->active_region = NULL;
- sc->swap = 0;
sc->preview = direct_link_preview_image(fd, sc->preview);
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h
index cf76bfdeef5..13bf5426a5d 100644
--- a/source/blender/draw/DRW_engine.h
+++ b/source/blender/draw/DRW_engine.h
@@ -102,10 +102,12 @@ void DRW_draw_render_loop_ex(
struct Depsgraph *depsgraph,
struct RenderEngineType *engine_type,
struct ARegion *ar, struct View3D *v3d,
+ struct GPUViewport *viewport,
const struct bContext *evil_C);
void DRW_draw_render_loop(
struct Depsgraph *depsgraph,
- struct ARegion *ar, struct View3D *v3d);
+ struct ARegion *ar, struct View3D *v3d,
+ struct GPUViewport *viewport);
void DRW_draw_render_loop_offscreen(
struct Depsgraph *depsgraph,
struct RenderEngineType *engine_type,
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 6550fa19105..6e8f9d50aae 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -1041,42 +1041,46 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx)
Scene *scene = update_ctx->scene;
ViewLayer *view_layer = update_ctx->view_layer;
- if (rv3d->viewport == NULL) {
- return;
- }
+ /* Separate update for each stereo view. */
+ for (int view = 0; view < 2; view++) {
+ GPUViewport *viewport = WM_draw_region_get_viewport(ar, view);
+ if (!viewport) {
+ continue;
+ }
- /* XXX Really nasty locking. But else this could
- * be executed by the material previews thread
- * while rendering a viewport. */
- BLI_mutex_lock(&DST.ogl_context_mutex);
+ /* XXX Really nasty locking. But else this could
+ * be executed by the material previews thread
+ * while rendering a viewport. */
+ BLI_mutex_lock(&DST.ogl_context_mutex);
- /* Reset before using it. */
- drw_state_prepare_clean_for_draw(&DST);
+ /* Reset before using it. */
+ drw_state_prepare_clean_for_draw(&DST);
- DST.viewport = rv3d->viewport;
- DST.draw_ctx = (DRWContextState){
- .ar = ar, .rv3d = rv3d, .v3d = v3d,
- .scene = scene, .view_layer = view_layer, .obact = OBACT(view_layer),
- .engine_type = engine_type,
- .depsgraph = depsgraph, .object_mode = OB_MODE_OBJECT,
- };
+ DST.viewport = viewport;
+ DST.draw_ctx = (DRWContextState){
+ .ar = ar, .rv3d = rv3d, .v3d = v3d,
+ .scene = scene, .view_layer = view_layer, .obact = OBACT(view_layer),
+ .engine_type = engine_type,
+ .depsgraph = depsgraph, .object_mode = OB_MODE_OBJECT,
+ };
- drw_engines_enable(view_layer, engine_type);
+ drw_engines_enable(view_layer, engine_type);
- for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
- DrawEngineType *draw_engine = link->data;
- ViewportEngineData *data = drw_viewport_engine_data_ensure(draw_engine);
+ for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
+ DrawEngineType *draw_engine = link->data;
+ ViewportEngineData *data = drw_viewport_engine_data_ensure(draw_engine);
- if (draw_engine->view_update) {
- draw_engine->view_update(data);
+ if (draw_engine->view_update) {
+ draw_engine->view_update(data);
+ }
}
- }
- DST.viewport = NULL;
+ DST.viewport = NULL;
- drw_engines_disable();
+ drw_engines_disable();
- BLI_mutex_unlock(&DST.ogl_context_mutex);
+ BLI_mutex_unlock(&DST.ogl_context_mutex);
+ }
}
/** \} */
@@ -1099,28 +1103,34 @@ void DRW_notify_id_update(const DRWUpdateContext *update_ctx, ID *id)
Depsgraph *depsgraph = update_ctx->depsgraph;
Scene *scene = update_ctx->scene;
ViewLayer *view_layer = update_ctx->view_layer;
- if (rv3d->viewport == NULL) {
- return;
- }
- /* Reset before using it. */
- drw_state_prepare_clean_for_draw(&DST);
- DST.viewport = rv3d->viewport;
- DST.draw_ctx = (DRWContextState){
- .ar = ar, .rv3d = rv3d, .v3d = v3d,
- .scene = scene, .view_layer = view_layer, .obact = OBACT(view_layer),
- .engine_type = engine_type,
- .depsgraph = depsgraph, .object_mode = OB_MODE_OBJECT,
- };
- drw_engines_enable(view_layer, engine_type);
- for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
- DrawEngineType *draw_engine = link->data;
- ViewportEngineData *data = drw_viewport_engine_data_ensure(draw_engine);
- if (draw_engine->id_update) {
- draw_engine->id_update(data, id);
+
+ /* Separate update for each stereo view. */
+ for (int view = 0; view < 2; view++) {
+ GPUViewport *viewport = WM_draw_region_get_viewport(ar, view);
+ if (!viewport) {
+ continue;
+ }
+
+ /* Reset before using it. */
+ drw_state_prepare_clean_for_draw(&DST);
+ DST.viewport = viewport;
+ DST.draw_ctx = (DRWContextState){
+ .ar = ar, .rv3d = rv3d, .v3d = v3d,
+ .scene = scene, .view_layer = view_layer, .obact = OBACT(view_layer),
+ .engine_type = engine_type,
+ .depsgraph = depsgraph, .object_mode = OB_MODE_OBJECT,
+ };
+ drw_engines_enable(view_layer, engine_type);
+ for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
+ DrawEngineType *draw_engine = link->data;
+ ViewportEngineData *data = drw_viewport_engine_data_ensure(draw_engine);
+ if (draw_engine->id_update) {
+ draw_engine->id_update(data, id);
+ }
}
+ DST.viewport = NULL;
+ drw_engines_disable();
}
- DST.viewport = NULL;
- drw_engines_disable();
}
/** \} */
@@ -1140,10 +1150,11 @@ void DRW_draw_view(const bContext *C)
View3D *v3d = CTX_wm_view3d(C);
Scene *scene = DEG_get_evaluated_scene(depsgraph);
RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->drawtype);
+ GPUViewport *viewport = WM_draw_region_get_bound_viewport(ar);
/* Reset before using it. */
drw_state_prepare_clean_for_draw(&DST);
- DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, C);
+ DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, viewport, C);
}
/**
@@ -1154,6 +1165,7 @@ void DRW_draw_render_loop_ex(
struct Depsgraph *depsgraph,
RenderEngineType *engine_type,
ARegion *ar, View3D *v3d,
+ GPUViewport *viewport,
const bContext *evil_C)
{
@@ -1163,7 +1175,7 @@ void DRW_draw_render_loop_ex(
DST.draw_ctx.evil_C = evil_C;
- DST.viewport = rv3d->viewport;
+ DST.viewport = viewport;
v3d->zbuf = true;
/* Setup viewport */
@@ -1298,7 +1310,8 @@ void DRW_draw_render_loop_ex(
void DRW_draw_render_loop(
struct Depsgraph *depsgraph,
- ARegion *ar, View3D *v3d)
+ ARegion *ar, View3D *v3d,
+ GPUViewport *viewport)
{
/* Reset before using it. */
drw_state_prepare_clean_for_draw(&DST);
@@ -1306,7 +1319,7 @@ void DRW_draw_render_loop(
Scene *scene = DEG_get_evaluated_scene(depsgraph);
RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->drawtype);
- DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, NULL);
+ DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, viewport, NULL);
}
/* @viewport CAN be NULL, in this case we create one. */
@@ -1316,18 +1329,10 @@ void DRW_draw_render_loop_offscreen(
const bool draw_background, GPUOffScreen *ofs,
GPUViewport *viewport)
{
- RegionView3D *rv3d = ar->regiondata;
-
- /* backup */
- void *backup_viewport = rv3d->viewport;
- {
- /* backup (_never_ use rv3d->viewport) */
- if (viewport == NULL) {
- rv3d->viewport = GPU_viewport_create_from_offscreen(ofs);
- }
- else {
- rv3d->viewport = viewport;
- }
+ /* Create temporary viewport if needed. */
+ GPUViewport *render_viewport = viewport;
+ if (viewport == NULL) {
+ render_viewport = GPU_viewport_create_from_offscreen(ofs);
}
GPU_framebuffer_restore();
@@ -1336,17 +1341,13 @@ void DRW_draw_render_loop_offscreen(
drw_state_prepare_clean_for_draw(&DST);
DST.options.is_image_render = true;
DST.options.draw_background = draw_background;
- DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, NULL);
-
- /* restore */
- {
- if (viewport == NULL) {
- /* don't free data owned by 'ofs' */
- GPU_viewport_clear_from_offscreen(rv3d->viewport);
- GPU_viewport_free(rv3d->viewport);
- }
+ DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, render_viewport, NULL);
- rv3d->viewport = backup_viewport;
+ /* Free temporary viewport. */
+ if (viewport == NULL) {
+ /* don't free data owned by 'ofs' */
+ GPU_viewport_clear_from_offscreen(render_viewport);
+ GPU_viewport_free(render_viewport);
}
/* we need to re-bind (annoying!) */
@@ -1516,10 +1517,6 @@ void DRW_draw_select_loop(
/* Reset before using it. */
drw_state_prepare_clean_for_draw(&DST);
- /* backup (_never_ use rv3d->viewport) */
- void *backup_viewport = rv3d->viewport;
- rv3d->viewport = NULL;
-
bool use_obedit = false;
int obedit_mode = 0;
if (obedit != NULL) {
@@ -1646,9 +1643,6 @@ void DRW_draw_select_loop(
/* Cleanup for selection state */
GPU_viewport_free(viewport);
-
- /* restore */
- rv3d->viewport = backup_viewport;
#endif /* USE_GPU_SELECT */
}
@@ -1702,10 +1696,6 @@ void DRW_draw_depth_loop(
DRW_opengl_context_enable();
- /* backup (_never_ use rv3d->viewport) */
- void *backup_viewport = rv3d->viewport;
- rv3d->viewport = NULL;
-
/* Reset before using it. */
drw_state_prepare_clean_for_draw(&DST);
@@ -1802,9 +1792,6 @@ void DRW_draw_depth_loop(
gpuPopMatrix();
gpuPopProjectionMatrix();
-
- /* restore */
- rv3d->viewport = backup_viewport;
}
/** \} */
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index b4857051c89..b5f1d947076 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -88,7 +88,7 @@ void ED_region_info_draw(struct ARegion *ar, const char *text, float fill_col
void ED_region_info_draw_multiline(ARegion *ar, const char *text_array[], float fill_color[4], const bool full_redraw);
void ED_region_image_metadata_draw(int x, int y, struct ImBuf *ibuf, const rctf *frame, float zoomx, float zoomy);
void ED_region_grid_draw(struct ARegion *ar, float zoomx, float zoomy);
-float ED_region_blend_factor(struct ARegion *ar);
+float ED_region_blend_alpha(struct ARegion *ar);
void ED_region_visible_rect(struct ARegion *ar, struct rcti *rect);
int ED_region_snap_size_test(const struct ARegion *ar);
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index f84347b97a4..97491d365b7 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -644,7 +644,7 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(w
/* prevent drawing outside widget area */
GLint scissor[4];
glGetIntegerv(GL_SCISSOR_BOX, scissor);
- glScissor(ar->winrct.xmin + rect->xmin, ar->winrct.ymin + rect->ymin, w, h);
+ glScissor(rect->xmin, rect->ymin, w, h);
#endif
glEnable(GL_BLEND);
@@ -773,7 +773,7 @@ static void histogram_draw_one(
#define HISTOGRAM_TOT_GRID_LINES 4
-void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti)
+void ui_draw_but_HISTOGRAM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti)
{
Histogram *hist = (Histogram *)but->poin;
int res = hist->x_resolution;
@@ -800,8 +800,8 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol)
/* need scissor test, histogram can draw outside of boundary */
GLint scissor[4];
glGetIntegerv(GL_SCISSOR_BOX, scissor);
- glScissor(ar->winrct.xmin + (rect.xmin - 1),
- ar->winrct.ymin + (rect.ymin - 1),
+ glScissor((rect.xmin - 1),
+ (rect.ymin - 1),
(rect.xmax + 1) - (rect.xmin - 1),
(rect.ymax + 1) - (rect.ymin - 1));
@@ -873,7 +873,7 @@ static void waveform_draw_one(float *waveform, int nbr, const float col[3])
GWN_batch_discard(batch);
}
-void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti)
+void ui_draw_but_WAVEFORM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti)
{
Scopes *scopes = (Scopes *)but->poin;
GLint scissor[4];
@@ -923,8 +923,8 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol),
/* need scissor test, waveform can draw outside of boundary */
glGetIntegerv(GL_SCISSOR_BOX, scissor);
- glScissor(ar->winrct.xmin + (rect.xmin - 1),
- ar->winrct.ymin + (rect.ymin - 1),
+ glScissor((rect.xmin - 1),
+ (rect.ymin - 1),
(rect.xmax + 1) - (rect.xmin - 1),
(rect.ymax + 1) - (rect.ymin - 1));
@@ -1160,7 +1160,7 @@ static void vectorscope_draw_target(unsigned int pos, float centerx, float cente
immEnd();
}
-void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti)
+void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti)
{
const float skin_rad = DEG2RADF(123.0f); /* angle in radians of the skin tone line */
Scopes *scopes = (Scopes *)but->poin;
@@ -1195,8 +1195,8 @@ void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wco
/* need scissor test, hvectorscope can draw outside of boundary */
GLint scissor[4];
glGetIntegerv(GL_SCISSOR_BOX, scissor);
- glScissor(ar->winrct.xmin + (rect.xmin - 1),
- ar->winrct.ymin + (rect.ymin - 1),
+ glScissor((rect.xmin - 1),
+ (rect.ymin - 1),
(rect.xmax + 1) - (rect.xmin - 1),
(rect.ymax + 1) - (rect.ymin - 1));
@@ -1622,12 +1622,13 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti
GLint scissor[4];
glGetIntegerv(GL_SCISSOR_BOX, scissor);
rcti scissor_new = {
- .xmin = ar->winrct.xmin + rect->xmin,
- .ymin = ar->winrct.ymin + rect->ymin,
- .xmax = ar->winrct.xmin + rect->xmax,
- .ymax = ar->winrct.ymin + rect->ymax
+ .xmin = rect->xmin,
+ .ymin = rect->ymin,
+ .xmax = rect->xmax,
+ .ymax = rect->ymax
};
- BLI_rcti_isect(&scissor_new, &ar->winrct, &scissor_new);
+ rcti scissor_region = {0, ar->winx, 0, ar->winy};
+ BLI_rcti_isect(&scissor_new, &scissor_region, &scissor_new);
glScissor(scissor_new.xmin,
scissor_new.ymin,
BLI_rcti_size_x(&scissor_new),
@@ -1822,7 +1823,7 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti
immUnbindProgram();
}
-void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti)
+void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti)
{
bool ok = false;
MovieClipScopes *scopes = (MovieClipScopes *)but->poin;
@@ -1843,8 +1844,8 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc
/* need scissor test, preview image can draw outside of boundary */
GLint scissor[4];
glGetIntegerv(GL_SCISSOR_BOX, scissor);
- glScissor(ar->winrct.xmin + (rect.xmin - 1),
- ar->winrct.ymin + (rect.ymin - 1),
+ glScissor((rect.xmin - 1),
+ (rect.ymin - 1),
(rect.xmax + 1) - (rect.xmin - 1),
(rect.ymax + 1) - (rect.ymin - 1));
@@ -1881,7 +1882,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc
gpuPushMatrix();
/* draw content of pattern area */
- glScissor(ar->winrct.xmin + rect.xmin, ar->winrct.ymin + rect.ymin, scissor[2], scissor[3]);
+ glScissor(rect.xmin, rect.ymin, scissor[2], scissor[3]);
if (width > 0 && height > 0) {
ImBuf *drawibuf = scopes->track_preview;
@@ -1898,8 +1899,8 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc
/* draw cross for pixel position */
gpuTranslate2f(rect.xmin + scopes->track_pos[0], rect.ymin + scopes->track_pos[1]);
- glScissor(ar->winrct.xmin + rect.xmin,
- ar->winrct.ymin + rect.ymin,
+ glScissor(rect.xmin,
+ rect.ymin,
BLI_rctf_size_x(&rect),
BLI_rctf_size_y(&rect));
@@ -1977,13 +1978,15 @@ void ui_draw_but_NODESOCKET(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol
glGetIntegerv(GL_SCISSOR_BOX, scissor);
rcti scissor_new = {
- .xmin = ar->winrct.xmin + recti->xmin,
- .ymin = ar->winrct.ymin + recti->ymin,
- .xmax = ar->winrct.xmin + recti->xmax,
- .ymax = ar->winrct.ymin + recti->ymax
+ .xmin = recti->xmin,
+ .ymin = recti->ymin,
+ .xmax = recti->xmax,
+ .ymax = recti->ymax
};
- BLI_rcti_isect(&scissor_new, &ar->winrct, &scissor_new);
+ rcti scissor_region = {0, ar->winx, 0, ar->winy};
+
+ BLI_rcti_isect(&scissor_new, &scissor_region, &scissor_new);
glScissor(scissor_new.xmin,
scissor_new.ymin,
BLI_rcti_size_x(&scissor_new),
diff --git a/source/blender/editors/interface/interface_region_popup.c b/source/blender/editors/interface/interface_region_popup.c
index b13d9b0448c..56611627a67 100644
--- a/source/blender/editors/interface/interface_region_popup.c
+++ b/source/blender/editors/interface/interface_region_popup.c
@@ -300,7 +300,7 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
/** \name Menu Block Creation
* \{ */
-static void ui_block_region_draw(const bContext *C, ARegion *ar)
+static void ui_block_region_refresh(const bContext *C, ARegion *ar)
{
ScrArea *ctx_area = CTX_wm_area(C);
ARegion *ctx_region = CTX_wm_region(C);
@@ -331,6 +331,11 @@ static void ui_block_region_draw(const bContext *C, ARegion *ar)
CTX_wm_area_set((bContext *)C, ctx_area);
CTX_wm_region_set((bContext *)C, ctx_region);
+}
+
+static void ui_block_region_draw(const bContext *C, ARegion *ar)
+{
+ uiBlock *block;
for (block = ar->uiblocks.first; block; block = block->next)
UI_block_draw(C, block);
@@ -660,6 +665,7 @@ uiPopupBlockHandle *ui_popup_block_create(
memset(&type, 0, sizeof(ARegionType));
type.draw = ui_block_region_draw;
+ type.refresh = ui_block_region_refresh;
type.regionid = RGN_TYPE_TEMPORARY;
ar->type = &type;
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index ade69050622..d284bde6ce6 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -2171,10 +2171,6 @@ void init_userdef_do_versions(void)
strcpy(km->idname, "Property Editor");
}
}
- if (!USER_VERSION_ATLEAST(250, 16)) {
- if (U.wmdrawmethod == USER_DRAW_TRIPLE)
- U.wmdrawmethod = USER_DRAW_AUTOMATIC;
- }
if (!USER_VERSION_ATLEAST(252, 3)) {
if (U.flag & USER_LMOUSESELECT)
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 0f9378d0a41..a17f7ec6255 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -1075,18 +1075,16 @@ static void region_overlap_fix(ScrArea *sa, ARegion *ar)
}
/* overlapping regions only in the following restricted cases */
-static bool region_is_overlap(wmWindow *win, ScrArea *sa, ARegion *ar)
+static bool region_is_overlap(ScrArea *sa, ARegion *ar)
{
if (U.uiflag2 & USER_REGION_OVERLAP) {
- if (WM_is_draw_triple(win)) {
- if (ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_SEQ)) {
- if (ELEM(ar->regiontype, RGN_TYPE_TOOLS, RGN_TYPE_UI, RGN_TYPE_TOOL_PROPS))
- return 1;
- }
- else if (sa->spacetype == SPACE_IMAGE) {
- if (ELEM(ar->regiontype, RGN_TYPE_TOOLS, RGN_TYPE_UI, RGN_TYPE_TOOL_PROPS, RGN_TYPE_PREVIEW))
- return 1;
- }
+ if (ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_SEQ)) {
+ if (ELEM(ar->regiontype, RGN_TYPE_TOOLS, RGN_TYPE_UI, RGN_TYPE_TOOL_PROPS))
+ return 1;
+ }
+ else if (sa->spacetype == SPACE_IMAGE) {
+ if (ELEM(ar->regiontype, RGN_TYPE_TOOLS, RGN_TYPE_UI, RGN_TYPE_TOOL_PROPS, RGN_TYPE_PREVIEW))
+ return 1;
}
}
@@ -1113,7 +1111,7 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti
alignment = ar->alignment & ~RGN_SPLIT_PREV;
/* set here, assuming userpref switching forces to call this again */
- ar->overlap = region_is_overlap(win, sa, ar);
+ ar->overlap = region_is_overlap(sa, ar);
/* clear state flags first */
ar->flag &= ~RGN_FLAG_TOO_SMALL;
@@ -2062,14 +2060,11 @@ void ED_region_panels(const bContext *C, ARegion *ar, const char *context, int c
if (ar->overlap) {
/* view should be in pixelspace */
UI_view2d_view_restore(C);
- glEnable(GL_BLEND);
- Gwn_VertFormat *format = immVertexFormat();
- unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformThemeColor((ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK);
- immRecti(pos, 0, 0, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct) + 1);
- immUnbindProgram();
- glDisable(GL_BLEND);
+
+ float back[4];
+ UI_GetThemeColor4fv((ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK, back);
+ glClearColor(back[3] * back[0], back[3] * back[1], back[3] * back[2], back[3]);
+ glClear(GL_COLOR_BUFFER_BIT);
}
else {
UI_ThemeClearColor((ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK);
@@ -2278,7 +2273,7 @@ void ED_region_info_draw_multiline(ARegion *ar, const char *text_array[], float
/* setup scissor */
glGetIntegerv(GL_SCISSOR_BOX, scissor);
- glScissor(ar->winrct.xmin + rect.xmin, ar->winrct.ymin + rect.ymin,
+ glScissor(rect.xmin, rect.ymin,
BLI_rcti_size_x(&rect) + 1, BLI_rcti_size_y(&rect) + 1);
glEnable(GL_BLEND);
diff --git a/source/blender/editors/screen/screen_draw.c b/source/blender/editors/screen/screen_draw.c
index 4b388059ca3..fec39ade110 100644
--- a/source/blender/editors/screen/screen_draw.c
+++ b/source/blender/editors/screen/screen_draw.c
@@ -438,8 +438,6 @@ void ED_screen_draw_edges(wmWindow *win)
ScrArea *sa;
- wmWindowViewport(win);
-
unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index ab58d4c8ebf..c7d1605cbbf 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -908,7 +908,7 @@ void ED_region_exit(bContext *C, ARegion *ar)
WM_event_remove_handlers(C, &ar->handlers);
WM_event_modal_handler_region_replace(win, ar, NULL);
- ar->visible = 0;
+ WM_draw_region_free(ar);
if (ar->headerstr) {
MEM_freeN(ar->headerstr);
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 7dab2c7c3db..847afb5f9f1 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -4207,7 +4207,7 @@ typedef struct RegionAlphaInfo {
#define TIMEOUT 0.2f
#define TIMESTEP 0.04f
-float ED_region_blend_factor(ARegion *ar)
+float ED_region_blend_alpha(ARegion *ar)
{
/* check parent too */
if (ar->regiontimer == NULL && (ar->alignment & RGN_SPLIT_PREV) && ar->prev) {
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index fad35060d72..6875971de24 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -1788,7 +1788,7 @@ static void outliner_draw_tree(
CLAMP_MIN(mask_x, 0);
glGetFloatv(GL_SCISSOR_BOX, scissor);
- glScissor(ar->winrct.xmin, ar->winrct.ymin, mask_x, ar->winy);
+ glScissor(0, 0, mask_x, ar->winy);
}
// gray hierarchy lines
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 4fb4193517b..1a23dd0feff 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -545,13 +545,6 @@ static void view3d_main_region_exit(wmWindowManager *wm, ARegion *ar)
GPU_offscreen_free(rv3d->gpuoffscreen);
rv3d->gpuoffscreen = NULL;
}
-
- if (rv3d->viewport) {
- DRW_opengl_context_enable();
- GPU_viewport_free(rv3d->viewport);
- DRW_opengl_context_disable();
- rv3d->viewport = NULL;
- }
}
static int view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
@@ -729,11 +722,6 @@ static void view3d_main_region_free(ARegion *ar)
if (rv3d->gpuoffscreen) {
GPU_offscreen_free(rv3d->gpuoffscreen);
}
- if (rv3d->viewport) {
- DRW_opengl_context_enable();
- GPU_viewport_free(rv3d->viewport);
- DRW_opengl_context_disable();
- }
MEM_freeN(rv3d);
ar->regiondata = NULL;
@@ -758,7 +746,6 @@ static void *view3d_main_region_duplicate(void *poin)
new->sms = NULL;
new->smooth_timer = NULL;
new->compositor = NULL;
- new->viewport = NULL;
return new;
}
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 166684e7230..3bc86a82afd 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -1259,19 +1259,8 @@ RenderEngineType *ED_view3d_engine_type(Scene *scene, int drawtype)
void view3d_main_region_draw(const bContext *C, ARegion *ar)
{
View3D *v3d = CTX_wm_view3d(C);
- RegionView3D *rv3d = ar->regiondata;
-
- if (!rv3d->viewport) {
- rv3d->viewport = GPU_viewport_create();
- }
- GPU_viewport_bind(rv3d->viewport, &ar->winrct);
view3d_draw_view(C, ar);
- GPU_viewport_unbind(rv3d->viewport);
-
- rcti rect = ar->winrct;
- BLI_rcti_translate(&rect, -ar->winrct.xmin, -ar->winrct.ymin);
- GPU_viewport_draw_to_screen(rv3d->viewport, &rect);
GPU_free_images_old();
GPU_pass_cache_garbage_collect();
@@ -1279,7 +1268,6 @@ void view3d_main_region_draw(const bContext *C, ARegion *ar)
v3d->flag |= V3D_INVALID_BACKBUF;
}
-
/* -------------------------------------------------------------------- */
/** \name Offscreen Drawing
diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c
index eecd185aedf..15359dcd6d6 100644
--- a/source/blender/editors/space_view3d/view3d_draw_legacy.c
+++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c
@@ -266,8 +266,6 @@ static void backdrawview3d(
if (rv3d->gpuoffscreen)
GPU_offscreen_unbind(rv3d->gpuoffscreen, true);
- else
- ar->swap = 0; /* mark invalid backbuf for wm draw */
v3d->flag &= ~V3D_INVALID_BACKBUF;
diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h
index c99733ec6da..61dd899f3d9 100644
--- a/source/blender/gpu/GPU_framebuffer.h
+++ b/source/blender/gpu/GPU_framebuffer.h
@@ -185,6 +185,7 @@ void GPU_offscreen_free(GPUOffScreen *ofs);
void GPU_offscreen_bind(GPUOffScreen *ofs, bool save);
void GPU_offscreen_unbind(GPUOffScreen *ofs, bool restore);
void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels);
+void GPU_offscreen_draw_to_screen(GPUOffScreen *ofs, int x, int y);
int GPU_offscreen_width(const GPUOffScreen *ofs);
int GPU_offscreen_height(const GPUOffScreen *ofs);
struct GPUTexture *GPU_offscreen_color_texture(const GPUOffScreen *ofs);
diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h
index ca7d5ae7ceb..d63911374ae 100644
--- a/source/blender/gpu/GPU_viewport.h
+++ b/source/blender/gpu/GPU_viewport.h
@@ -119,6 +119,8 @@ double *GPU_viewport_cache_time_get(GPUViewport *viewport);
void GPU_viewport_tag_update(GPUViewport *viewport);
bool GPU_viewport_do_update(GPUViewport *viewport);
+GPUTexture *GPU_viewport_color_texture(GPUViewport *viewport);
+
/* Texture pool */
GPUTexture *GPU_viewport_texture_pool_query(GPUViewport *viewport, void *engine, int width, int height, int channels, int format);
diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c
index 73a1f14b9f6..3f89adfd8a5 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.c
+++ b/source/blender/gpu/intern/gpu_framebuffer.c
@@ -719,6 +719,24 @@ void GPU_offscreen_unbind(GPUOffScreen *UNUSED(ofs), bool restore)
}
}
+void GPU_offscreen_draw_to_screen(GPUOffScreen *ofs, int x, int y)
+{
+ const int w = GPU_texture_width(ofs->color);
+ const int h = GPU_texture_height(ofs->color);
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, ofs->fb->object);
+ GLenum status = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER);
+
+ if (status == GL_FRAMEBUFFER_COMPLETE) {
+ glBlitFramebuffer(0, 0, w, h, x, y, x + w, y + h, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ }
+ else {
+ gpu_print_framebuffer_error(status, NULL);
+ }
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
+}
+
void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels)
{
const int w = GPU_texture_width(ofs->color);
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index 609aa529872..34dee37001e 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -714,8 +714,6 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
datatoc_gpu_shader_image_desaturate_frag_glsl },
[GPU_SHADER_2D_IMAGE_ALPHA_COLOR] = { datatoc_gpu_shader_2D_image_vert_glsl,
datatoc_gpu_shader_image_alpha_color_frag_glsl },
- [GPU_SHADER_2D_IMAGE_ALPHA] = { datatoc_gpu_shader_2D_image_vert_glsl,
- datatoc_gpu_shader_image_modulate_alpha_frag_glsl },
[GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR] = { datatoc_gpu_shader_2D_image_vert_glsl,
datatoc_gpu_shader_image_shuffle_color_frag_glsl },
[GPU_SHADER_2D_IMAGE_RECT_COLOR] = { datatoc_gpu_shader_2D_image_rect_vert_glsl,
diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c
index 5d89bd59277..383ebec5b72 100644
--- a/source/blender/gpu/intern/gpu_viewport.c
+++ b/source/blender/gpu/intern/gpu_viewport.c
@@ -38,6 +38,8 @@
#include "BLI_string.h"
#include "BLI_mempool.h"
+#include "BIF_gl.h"
+
#include "DNA_vec_types.h"
#include "DNA_userdef_types.h"
@@ -521,6 +523,10 @@ void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect)
BLI_assert(w == BLI_rcti_size_x(rect) + 1);
BLI_assert(h == BLI_rcti_size_y(rect) + 1);
+ /* wmOrtho for the screen has this same offset */
+ const float halfx = GLA_PIXEL_OFS / w;
+ const float halfy = GLA_PIXEL_OFS / h;
+
float x1 = rect->xmin;
float x2 = rect->xmin + w;
float y1 = rect->ymin;
@@ -531,7 +537,7 @@ void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect)
GPU_texture_bind(color, 0);
glUniform1i(GPU_shader_get_uniform(shader, "image"), 0);
- glUniform4f(GPU_shader_get_uniform(shader, "rect_icon"), 0.0f, 0.0f, 1.0f, 1.0f);
+ glUniform4f(GPU_shader_get_uniform(shader, "rect_icon"), halfx, halfy, 1.0f + halfx, 1.0f + halfy);
glUniform4f(GPU_shader_get_uniform(shader, "rect_geom"), x1, y1, x2, y2);
glUniform4f(GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_COLOR), 1.0f, 1.0f, 1.0f, 1.0f);
@@ -545,6 +551,19 @@ void GPU_viewport_unbind(GPUViewport *UNUSED(viewport))
DRW_opengl_context_disable();
}
+
+GPUTexture *GPU_viewport_color_texture(GPUViewport *viewport)
+{
+ DefaultFramebufferList *dfbl = viewport->fbl;
+
+ if (dfbl->default_fb) {
+ DefaultTextureList *dtxl = viewport->txl;
+ return dtxl->color;
+ }
+
+ return NULL;
+}
+
static void gpu_viewport_buffers_free(
FramebufferList *fbl, int fbl_len,
TextureList *txl, int txl_len)
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index a127ad0e2ab..18986206b23 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -44,6 +44,7 @@ struct ARegionType;
struct PanelType;
struct Scene;
struct uiLayout;
+struct wmDrawBuffer;
struct wmTimer;
struct wmTooltipState;
@@ -75,10 +76,9 @@ typedef struct bScreen {
char do_draw_gesture; /* notifier for gesture draw. */
char do_draw_paintcursor; /* notifier for paint cursor draw. */
char do_draw_drag; /* notifier for dragging draw. */
- char swap; /* indicator to survive swap-exchange systems */
char skip_handling; /* set to delay screen handling after switching back from maximized area */
char scrubbing; /* set when scrubbing to avoid some costly updates */
- char pad[2];
+ char pad[3];
struct ARegion *active_region; /* active region that has mouse focus */
@@ -308,10 +308,9 @@ typedef struct ARegion {
short do_draw; /* private, cached notifier events */
short do_draw_overlay; /* private, cached notifier events */
- short swap; /* private, indicator to survive swap-exchange */
short overlap; /* private, set for indicate drawing overlapped */
short flagfullscreen; /* temporary copy of flag settings for clean fullscreen */
- short pad;
+ short pad1, pad2;
struct ARegionType *type; /* callbacks for this region type */
@@ -325,16 +324,12 @@ typedef struct ARegion {
struct wmManipulatorMap *manipulator_map; /* manipulator-map of this region */
struct wmTimer *regiontimer; /* blend in/out */
+ struct wmDrawBuffer *draw_buffer;
char *headerstr; /* use this string to draw info */
void *regiondata; /* XXX 2.50, need spacedata equivalent? */
} ARegion;
-/* swap */
-#define WIN_BACK_OK 1
-#define WIN_FRONT_OK 2
-// #define WIN_EQUAL 3 // UNUSED
-
/* area->flag */
enum {
HEADER_NO_PULLDOWN = (1 << 0),
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 4ef7ce019bb..3973006283d 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -515,9 +515,8 @@ typedef struct UserDef {
short tb_leftmouse, tb_rightmouse;
struct SolidLight light[3];
short manipulator_flag, manipulator_size;
- int pad6;
+ short pad6[3];
short textimeout, texcollectrate;
- short wmdrawmethod; /* eWM_DrawMethod */
short dragthreshold;
int memcachelimit;
int prefetchframes;
@@ -797,16 +796,6 @@ typedef enum eOpenGL_SelectOptions {
USER_SELECT_USE_SELECT_RENDERMODE = 2
} eOpenGL_SelectOptions;
-/* wm draw method.
- * UserDef.wmdrawmethod */
-typedef enum eWM_DrawMethod {
- USER_DRAW_TRIPLE = 0,
- USER_DRAW_OVERLAP = 1,
- USER_DRAW_FULL = 2,
- USER_DRAW_AUTOMATIC = 3,
- USER_DRAW_OVERLAP_FLIP = 4,
-} eWM_DrawMethod;
-
/* text draw options
* UserDef.text_render */
typedef enum eText_Draw_Options {
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index cd45407812a..313997082c7 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -154,7 +154,6 @@ typedef struct RegionView3D {
float rot_axis[3];
struct GPUFX *compositor;
- struct GPUViewport *viewport;
} RegionView3D;
/* 3D ViewPort Struct */
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index 8797f4b1fd6..7d7fa5fcf23 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -222,9 +222,6 @@ typedef struct wmWindow {
* Currently WIN32, runtime-only data */
struct wmIMEData *ime_data;
- int drawmethod, drawfail; /* internal for wm_draw.c only */
- ListBase drawdata; /* internal for wm_draw.c only */
-
ListBase queue; /* all events (ghost level events were handled) */
ListBase handlers; /* window+screen handlers, handled last */
ListBase modalhandlers; /* priority handlers, handled first */
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index dc8db500f24..f99b4b59f1a 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -3908,20 +3908,6 @@ static void rna_def_userdef_system(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
- static const EnumPropertyItem draw_method_items[] = {
- {USER_DRAW_AUTOMATIC, "AUTOMATIC", 0, "Automatic", "Automatically set based on graphics card and driver"},
- {USER_DRAW_TRIPLE, "TRIPLE_BUFFER", 0, "Triple Buffer",
- "Use a third buffer for minimal redraws at the cost of more memory"},
- {USER_DRAW_OVERLAP, "OVERLAP", 0, "Overlap",
- "Redraw all overlapping regions, minimal memory usage but more redraws"},
- {USER_DRAW_OVERLAP_FLIP, "OVERLAP_FLIP", 0, "Overlap Flip",
- "Redraw all overlapping regions, minimal memory usage but more redraws "
- "(for graphics drivers that do flipping)"},
- {USER_DRAW_FULL, "FULL", 0, "Full",
- "Do a full redraw each time, slow, only use for reference or when everything else fails"},
- {0, NULL, 0, NULL, NULL}
- };
-
static const EnumPropertyItem color_picker_types[] = {
{USER_CP_CIRCLE_HSV, "CIRCLE_HSV", 0, "Circle (HSV)", "A circular Hue/Saturation color wheel, with Value slider"},
{USER_CP_CIRCLE_HSL, "CIRCLE_HSL", 0, "Circle (HSL)", "A circular Hue/Saturation color wheel, with Lightness slider"},
@@ -4139,12 +4125,6 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Texture Collection Rate",
"Number of seconds between each run of the GL texture garbage collector");
- prop = RNA_def_property(srna, "window_draw_method", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "wmdrawmethod");
- RNA_def_property_enum_items(prop, draw_method_items);
- RNA_def_property_ui_text(prop, "Window Draw Method", "Drawing method used by the window manager");
- RNA_def_property_update(prop, 0, "rna_userdef_dpi_update");
-
prop = RNA_def_property(srna, "audio_mixing_buffer", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "mixbufsize");
RNA_def_property_enum_items(prop, audio_mixing_samples_items);
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index de5ce6d211d..c65f1064830 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -68,6 +68,7 @@ struct ScrArea;
struct Main;
struct bToolDef;
struct ViewLayer;
+struct GPUViewport;
#ifdef WITH_INPUT_NDOF
struct wmNDOFMotionData;
@@ -139,9 +140,6 @@ struct wmWindow *WM_window_open(struct bContext *C, const struct rcti *rect);
struct wmWindow *WM_window_open_temp(struct bContext *C, int x, int y, int sizex, int sizey, int type);
void WM_window_set_dpi(wmWindow *win);
- /* returns true if draw method is triple buffer */
-bool WM_is_draw_triple(struct wmWindow *win);
-
bool WM_stereo3d_enabled(struct wmWindow *win, bool only_fullscreen_test);
@@ -562,6 +560,11 @@ void *WM_draw_cb_activate(
void WM_draw_cb_exit(struct wmWindow *win, void *handle);
void WM_redraw_windows(struct bContext *C);
+ /* Region drawing */
+void WM_draw_region_free(struct ARegion *ar);
+struct GPUViewport *WM_draw_region_get_viewport(struct ARegion *ar, int view);
+struct GPUViewport *WM_draw_region_get_bound_viewport(struct ARegion *ar);
+
void WM_main_playanim(int argc, const char **argv);
/* debugging only, convenience function to write on crash */
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index 5440fd15bef..a0ad3950e6b 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -487,7 +487,6 @@ void wm_close_and_free(bContext *C, wmWindowManager *wm)
while ((win = BLI_pophead(&wm->windows))) {
WM_window_set_active_workspace(win, NULL); /* prevent draw clear to use screen */
- wm_draw_window_clear(win);
wm_window_free(C, wm, win);
}
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index b3e9eaeec45..8524b629cc5 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -50,6 +50,7 @@
#include "BKE_context.h"
#include "BKE_image.h"
+#include "BKE_screen.h"
#include "BKE_scene.h"
#include "BKE_workspace.h"
@@ -61,7 +62,10 @@
#include "GPU_draw.h"
#include "GPU_extensions.h"
+#include "GPU_framebuffer.h"
#include "GPU_immediate.h"
+#include "GPU_matrix.h"
+#include "GPU_texture.h"
#include "GPU_viewport.h"
#include "RE_engine.h"
@@ -77,72 +81,113 @@
# include "BKE_subsurf.h"
#endif
-/* swap */
-#define WIN_NONE_OK 0
-#define WIN_BACK_OK 1
-#define WIN_FRONT_OK 2
-#define WIN_BOTH_OK 3
-
-/* ******************* drawing, overlays *************** */
+/* ******************* paint cursor *************** */
static void wm_paintcursor_draw(bContext *C, ARegion *ar)
{
wmWindowManager *wm = CTX_wm_manager(C);
-
- if (wm->paintcursors.first) {
- wmWindow *win = CTX_wm_window(C);
- bScreen *screen = WM_window_get_active_screen(win);
- wmPaintCursor *pc;
-
- if (ar->visible && ar == screen->active_region) {
- for (pc = wm->paintcursors.first; pc; pc = pc->next) {
- if (pc->poll == NULL || pc->poll(C)) {
- ARegion *ar_other = CTX_wm_region(C);
- if (ELEM(win->grabcursor, GHOST_kGrabWrap, GHOST_kGrabHide)) {
- int x = 0, y = 0;
- wm_get_cursor_position(win, &x, &y);
- pc->draw(C,
- x - ar_other->winrct.xmin,
- y - ar_other->winrct.ymin,
- pc->customdata);
- }
- else {
- pc->draw(C,
- win->eventstate->x - ar_other->winrct.xmin,
- win->eventstate->y - ar_other->winrct.ymin,
- pc->customdata);
- }
+ wmWindow *win = CTX_wm_window(C);
+ bScreen *screen = WM_window_get_active_screen(win);
+ wmPaintCursor *pc;
+
+ if (ar->visible && ar == screen->active_region) {
+ for (pc = wm->paintcursors.first; pc; pc = pc->next) {
+ if (pc->poll == NULL || pc->poll(C)) {
+ /* Prevent drawing outside region. */
+ GLint scissor[4];
+ glGetIntegerv(GL_SCISSOR_BOX, scissor);
+ glScissor(ar->winrct.xmin,
+ ar->winrct.ymin,
+ BLI_rcti_size_x(&ar->winrct) + 1,
+ BLI_rcti_size_y(&ar->winrct) + 1);
+
+ if (ELEM(win->grabcursor, GHOST_kGrabWrap, GHOST_kGrabHide)) {
+ int x = 0, y = 0;
+ wm_get_cursor_position(win, &x, &y);
+ pc->draw(C,
+ x,
+ y,
+ pc->customdata);
+ }
+ else {
+ pc->draw(C,
+ win->eventstate->x,
+ win->eventstate->y,
+ pc->customdata);
}
+
+ glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
}
}
}
}
-/* ********************* drawing, swap ****************** */
-static void wm_area_mark_invalid_backbuf(ScrArea *sa)
+static bool wm_draw_region_stereo_set(ScrArea *sa, ARegion *ar, eStereoViews sview)
{
- if (sa->spacetype == SPACE_VIEW3D)
- ((View3D *)sa->spacedata.first)->flag |= V3D_INVALID_BACKBUF;
+ /* We could detect better when stereo is actually needed, by inspecting the
+ * image in the image editor and sequencer. */
+ if (ar->regiontype != RGN_TYPE_WINDOW) {
+ return false;
+ }
+
+ switch (sa->spacetype) {
+ case SPACE_IMAGE:
+ {
+ SpaceImage *sima = sa->spacedata.first;
+ sima->iuser.multiview_eye = sview;
+ return true;
+ }
+ case SPACE_VIEW3D:
+ {
+ View3D *v3d = sa->spacedata.first;
+ if (v3d->camera && v3d->camera->type == OB_CAMERA) {
+ Camera *cam = v3d->camera->data;
+ CameraBGImage *bgpic = cam->bg_images.first;
+ v3d->multiview_eye = sview;
+ if (bgpic) bgpic->iuser.multiview_eye = sview;
+ return true;
+ }
+ return false;
+ }
+ case SPACE_NODE:
+ {
+ SpaceNode *snode = sa->spacedata.first;
+ if ((snode->flag & SNODE_BACKDRAW) && ED_node_is_compositor(snode)) {
+ Image *ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
+ ima->eye = sview;
+ return true;
+ }
+ return false;
+ }
+ case SPACE_SEQ:
+ {
+ SpaceSeq *sseq = sa->spacedata.first;
+ sseq->multiview_eye = sview;
+ return true;
+ }
+ }
+
+ return false;
}
-static bool wm_area_test_invalid_backbuf(ScrArea *sa)
+/* ********************* drawing ****************** */
+
+static void wm_area_mark_invalid_backbuf(ScrArea *sa)
{
if (sa->spacetype == SPACE_VIEW3D)
- return (((View3D *)sa->spacedata.first)->flag & V3D_INVALID_BACKBUF) != 0;
- else
- return true;
+ ((View3D *)sa->spacedata.first)->flag |= V3D_INVALID_BACKBUF;
}
static void wm_region_test_render_do_draw(const Scene *scene, struct Depsgraph *depsgraph,
ScrArea *sa, ARegion *ar)
{
/* tag region for redraw from render engine preview running inside of it */
- if (sa->spacetype == SPACE_VIEW3D) {
+ if (sa->spacetype == SPACE_VIEW3D && ar->regiontype == RGN_TYPE_WINDOW) {
RegionView3D *rv3d = ar->regiondata;
- RenderEngine *engine = (rv3d) ? rv3d->render_engine : NULL;
- GPUViewport *viewport = (rv3d) ? rv3d->viewport : NULL;
+ RenderEngine *engine = rv3d->render_engine;
+ GPUViewport *viewport = WM_draw_region_get_viewport(ar, 0);
if (engine && (engine->flag & RE_ENGINE_DO_DRAW)) {
View3D *v3d = sa->spacedata.first;
@@ -162,12 +207,9 @@ static void wm_region_test_render_do_draw(const Scene *scene, struct Depsgraph *
}
}
-static void wm_draw_region(bContext *C, ARegion *ar)
+static bool wm_region_use_viewport(ScrArea *sa, ARegion *ar)
{
- CTX_wm_region_set(C, ar);
- ED_region_do_draw(C, ar);
- ar->do_draw = false;
- CTX_wm_region_set(C, NULL);
+ return (sa->spacetype == SPACE_VIEW3D && ar->regiontype == RGN_TYPE_WINDOW);
}
/********************** draw all **************************/
@@ -213,568 +255,356 @@ static void wm_draw_callbacks(wmWindow *win)
}
}
-static void wm_method_draw_full(bContext *C, wmWindow *win)
-{
- bScreen *screen = WM_window_get_active_screen(win);
- ARegion *ar;
- /* draw area regions */
- ED_screen_areas_iter(win, screen, sa) {
- CTX_wm_area_set(C, sa);
+/************************* Region drawing. ********************************
+ *
+ * Each region draws into its own framebuffer, which is then blit on the
+ * window draw buffer. This helps with fast redrawing if only some regions
+ * change. It also means we can share a single context for multiple windows,
+ * so that for example VAOs can be shared between windows. */
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->visible) {
- CTX_wm_region_set(C, ar);
- ED_region_do_draw(C, ar);
- ar->do_draw = false;
- wm_paintcursor_draw(C, ar);
- CTX_wm_region_set(C, NULL);
+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]);
}
}
-
- wm_area_mark_invalid_backbuf(sa);
- CTX_wm_area_set(C, NULL);
- }
- ED_screen_draw_edges(win);
- screen->do_draw = false;
- wm_draw_callbacks(win);
-
- /* draw overlapping regions */
- for (ar = screen->regionbase.first; ar; ar = ar->next) {
- if (ar->visible) {
- CTX_wm_menu_set(C, ar);
- ED_region_do_draw(C, ar);
- ar->do_draw = false;
- CTX_wm_menu_set(C, NULL);
- }
+ MEM_freeN(ar->draw_buffer);
+ ar->draw_buffer = NULL;
}
-
- if (screen->do_draw_gesture)
- wm_gesture_draw(win);
}
-/****************** draw overlap all **********************/
-/* - redraw marked areas, and anything that overlaps it */
-/* - it also handles swap exchange optionally, assuming */
-/* that on swap no clearing happens and we get back the */
-/* same buffer as we swapped to the front */
-
-/* mark area-regions to redraw if overlapped with rect */
-static void wm_flush_regions_down(wmWindow *win, bScreen *screen, rcti *dirty)
+static void wm_draw_offscreen_texture_parameters(GPUOffScreen *offscreen)
{
- ARegion *ar;
+ /* Setup offscreen color texture for drawing. */
+ GPUTexture *texture = GPU_offscreen_color_texture(offscreen);
- ED_screen_areas_iter(win, screen, sa) {
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (BLI_rcti_isect(dirty, &ar->winrct, NULL)) {
- ar->do_draw = RGN_DRAW;
- memset(&ar->drawrct, 0, sizeof(ar->drawrct));
- ar->swap = WIN_NONE_OK;
- }
- }
- }
-}
+ /* We don't support multisample textures here. */
+ BLI_assert(GPU_texture_target(texture) == GL_TEXTURE_2D);
-/* mark menu-regions to redraw if overlapped with rect */
-static void wm_flush_regions_up(bScreen *screen, rcti *dirty)
-{
- ARegion *ar;
-
- for (ar = screen->regionbase.first; ar; ar = ar->next) {
- if (BLI_rcti_isect(dirty, &ar->winrct, NULL)) {
- ar->do_draw = RGN_DRAW;
- memset(&ar->drawrct, 0, sizeof(ar->drawrct));
- ar->swap = WIN_NONE_OK;
- }
- }
+ glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(texture));
+
+ /* No mipmaps or filtering. */
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
+ /* GL_TEXTURE_BASE_LEVEL = 0 by default */
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
}
-static void wm_method_draw_overlap_all(bContext *C, wmWindow *win, int exchange)
+static void wm_draw_region_buffer_create(ARegion *ar, bool stereo, bool use_viewport)
{
- wmWindowManager *wm = CTX_wm_manager(C);
- bScreen *screen = WM_window_get_active_screen(win);
- ARegion *ar;
- static rcti rect = {0, 0, 0, 0};
-
- /* after backbuffer selection draw, we need to redraw */
- ED_screen_areas_iter(win, screen, sa) {
- for (ar = sa->regionbase.first; ar; ar = ar->next)
- if (ar->visible && !wm_area_test_invalid_backbuf(sa))
- ED_region_tag_redraw(ar);
+ 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);
+ }
+ }
}
- /* flush overlapping regions */
- if (screen->regionbase.first) {
- /* flush redraws of area regions up to overlapping regions */
- ED_screen_areas_iter(win, screen, sa) {
- for (ar = sa->regionbase.first; ar; ar = ar->next)
- if (ar->visible && ar->do_draw)
- wm_flush_regions_up(screen, &ar->winrct);
+ 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;
+ }
- /* flush between overlapping regions */
- for (ar = screen->regionbase.last; ar; ar = ar->prev)
- if (ar->visible && ar->do_draw)
- wm_flush_regions_up(screen, &ar->winrct);
-
- /* flush redraws of overlapping regions down to area regions */
- for (ar = screen->regionbase.last; ar; ar = ar->prev)
- if (ar->visible && ar->do_draw)
- wm_flush_regions_down(win, screen, &ar->winrct);
- }
-
- /* flush drag item */
- if (rect.xmin != rect.xmax) {
- wm_flush_regions_down(win, screen, &rect);
- rect.xmin = rect.xmax = 0;
- }
- if (wm->drags.first) {
- /* doesnt draw, fills rect with boundbox */
- wm_drags_draw(C, win, &rect);
- }
-
- /* draw marked area regions */
- ED_screen_areas_iter(win, screen, sa) {
- CTX_wm_area_set(C, sa);
+ wm_draw_offscreen_texture_parameters(offscreen);
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->visible) {
- if (ar->do_draw) {
- CTX_wm_region_set(C, ar);
- ED_region_do_draw(C, ar);
- ar->do_draw = false;
- wm_paintcursor_draw(C, ar);
- CTX_wm_region_set(C, NULL);
+ GPUOffScreen *offscreen_right = NULL;
+ if (stereo) {
+ offscreen_right = GPU_offscreen_create(ar->winx, ar->winy, 0, false, false, NULL);
- if (exchange)
- ar->swap = WIN_FRONT_OK;
+ if (!offscreen_right) {
+ GPU_offscreen_free(offscreen);
+ return;
}
- else if (exchange) {
- if (ar->swap == WIN_FRONT_OK) {
- CTX_wm_region_set(C, ar);
- ED_region_do_draw(C, ar);
- ar->do_draw = false;
- wm_paintcursor_draw(C, ar);
- CTX_wm_region_set(C, NULL);
- ar->swap = WIN_BOTH_OK;
- }
- else if (ar->swap == WIN_BACK_OK)
- ar->swap = WIN_FRONT_OK;
- else if (ar->swap == WIN_BOTH_OK)
- ar->swap = WIN_BOTH_OK;
- }
+ 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;
}
- wm_area_mark_invalid_backbuf(sa);
- CTX_wm_area_set(C, NULL);
+ ar->draw_buffer->bound_view = -1;
+ ar->draw_buffer->stereo = stereo;
}
+}
- /* after area regions so we can do area 'overlay' drawing */
- if (screen->do_draw) {
- ED_screen_draw_edges(win);
- screen->do_draw = false;
- wm_draw_callbacks(win);
+static void wm_draw_region_bind(ARegion *ar, int view)
+{
+ if (!ar->draw_buffer) {
+ return;
+ }
- if (exchange)
- screen->swap = WIN_FRONT_OK;
+ if (ar->draw_buffer->viewport[view]) {
+ GPU_viewport_bind(ar->draw_buffer->viewport[view], &ar->winrct);
}
- else if (exchange) {
- if (screen->swap == WIN_FRONT_OK) {
- ED_screen_draw_edges(win);
- screen->do_draw = false;
- screen->swap = WIN_BOTH_OK;
- wm_draw_callbacks(win);
- }
- else if (screen->swap == WIN_BACK_OK)
- screen->swap = WIN_FRONT_OK;
- else if (screen->swap == WIN_BOTH_OK)
- screen->swap = WIN_BOTH_OK;
+ else {
+ GPU_offscreen_bind(ar->draw_buffer->offscreen[view], false);
}
- /* draw marked overlapping regions */
- for (ar = screen->regionbase.first; ar; ar = ar->next) {
- if (ar->visible && ar->do_draw) {
- CTX_wm_menu_set(C, ar);
- ED_region_do_draw(C, ar);
- ar->do_draw = false;
- CTX_wm_menu_set(C, NULL);
- }
+ ar->draw_buffer->bound_view = view;
+
+ /* For now scissor is expected by region drawing, we could disable it
+ * and do the enable/disable in the specific cases that setup scissor. */
+ glEnable(GL_SCISSOR_TEST);
+ glScissor(0, 0, ar->winx, ar->winy);
+}
+
+static void wm_draw_region_unbind(ARegion *ar, int view)
+{
+ if (!ar->draw_buffer) {
+ return;
}
- if (screen->do_draw_gesture)
- wm_gesture_draw(win);
-
- /* needs pixel coords in screen */
- if (wm->drags.first) {
- wm_drags_draw(C, win, NULL);
+ glDisable(GL_SCISSOR_TEST);
+
+ ar->draw_buffer->bound_view = -1;
+
+ if (ar->draw_buffer->viewport[view]) {
+ GPU_viewport_unbind(ar->draw_buffer->viewport[view]);
+ }
+ else {
+ GPU_offscreen_unbind(ar->draw_buffer->offscreen[view], false);
}
}
-/****************** draw triple buffer ********************/
-/* - area regions are written into a texture, without any */
-/* of the overlapping menus, brushes, gestures. these */
-/* are redrawn each time. */
-
-static void wm_draw_triple_free(wmDrawTriple *triple)
+static void wm_draw_region_blit(ARegion *ar, int view)
{
- if (triple) {
- glDeleteTextures(1, &triple->bind);
- MEM_freeN(triple);
+ if (!ar->draw_buffer) {
+ return;
+ }
+
+ if (ar->draw_buffer->viewport[view]) {
+ GPU_viewport_draw_to_screen(ar->draw_buffer->viewport[view], &ar->winrct);
+ }
+ else {
+ GPU_offscreen_draw_to_screen(ar->draw_buffer->offscreen[view], ar->winrct.xmin, ar->winrct.ymin);
}
}
-static void wm_draw_triple_fail(bContext *C, wmWindow *win)
+GPUTexture *wm_draw_region_texture(ARegion *ar, int view)
{
- wm_draw_window_clear(win);
+ if (!ar->draw_buffer) {
+ return NULL;
+ }
- win->drawfail = true;
- wm_method_draw_overlap_all(C, win, 0);
+ if (ar->draw_buffer->viewport[view]) {
+ return GPU_viewport_color_texture(ar->draw_buffer->viewport[view]);
+ }
+ else {
+ return GPU_offscreen_color_texture(ar->draw_buffer->offscreen[view]);
+ }
}
-static bool wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple)
+void wm_draw_region_blend(ARegion *ar, int view, bool blend)
{
- /* compute texture sizes */
- const int sizex = WM_window_pixels_x(win);
- const int sizey = WM_window_pixels_y(win);
-
- /* generate texture names */
- glGenTextures(1, &triple->bind);
+ if (!ar->draw_buffer) {
+ return;
+ }
- /* proxy texture is only guaranteed to test for the cases that
- * there is only one texture in use, which may not be the case */
- const GLint maxsize = GPU_max_texture_size();
+ /* Alpha is always 1, except when blend timer is running. */
+ float alpha = ED_region_blend_alpha(ar);
+ if (alpha <= 0.0f) {
+ return;
+ }
- if (sizex > maxsize || sizey > maxsize) {
- printf("WM: failed to allocate texture for triple buffer drawing "
- "(texture too large for graphics card).\n");
- return false;
+ if (!blend) {
+ alpha = 1.0f;
}
/* setup actual texture */
- glBindTexture(GL_TEXTURE_2D, triple->bind);
-
- /* no mipmaps */
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
- /* GL_TEXTURE_BASE_LEVEL = 0 by default */
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, sizex, sizey, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
-
- glBindTexture(GL_TEXTURE_2D, 0);
-
- return true;
-}
-
-void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple, float alpha)
-{
- const int sizex = WM_window_pixels_x(win);
- const int sizey = WM_window_pixels_y(win);
+ GPUTexture *texture = wm_draw_region_texture(ar, view);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(texture));
/* wmOrtho for the screen has this same offset */
- const float ratiox = 1.0f;
- const float ratioy = 1.0f;
- const float halfx = GLA_PIXEL_OFS / sizex;
- const float halfy = GLA_PIXEL_OFS / sizey;
-
- const int activeTex = 7; /* arbitrary */
- glActiveTexture(GL_TEXTURE0 + activeTex);
- glBindTexture(GL_TEXTURE_2D, triple->bind);
+ const float halfx = GLA_PIXEL_OFS / (BLI_rcti_size_x(&ar->winrct) + 1);
+ const float halfy = GLA_PIXEL_OFS / (BLI_rcti_size_y(&ar->winrct) + 1);
- float x1 = halfx;
- float x2 = ratiox + halfx;
- float y1 = halfy;
- float y2 = ratioy + halfy;
+ if (blend) {
+ /* GL_ONE because regions drawn offscreen have premultiplied alpha. */
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ }
GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_RECT_COLOR);
GPU_shader_bind(shader);
- glUniform1i(GPU_shader_get_uniform(shader, "image"), activeTex);
- glUniform4f(GPU_shader_get_uniform(shader, "rect_icon"), x1, y1, x2, y2);
- glUniform4f(GPU_shader_get_uniform(shader, "rect_geom"), 0.0f, 0.0f, sizex, sizey);
+ glUniform1i(GPU_shader_get_uniform(shader, "image"), 0);
+ glUniform4f(GPU_shader_get_uniform(shader, "rect_icon"), halfx, halfy, 1.0f + halfx, 1.0f + halfy);
+ glUniform4f(GPU_shader_get_uniform(shader, "rect_geom"), ar->winrct.xmin, ar->winrct.ymin, ar->winrct.xmax + 1, ar->winrct.ymax + 1);
glUniform4f(GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_COLOR), alpha, alpha, alpha, alpha);
GWN_draw_primitive(GWN_PRIM_TRI_STRIP, 4);
glBindTexture(GL_TEXTURE_2D, 0);
-}
-
-static void wm_triple_copy_textures(wmWindow *win, wmDrawTriple *triple)
-{
- const int sizex = WM_window_pixels_x(win);
- const int sizey = WM_window_pixels_y(win);
- glBindTexture(GL_TEXTURE_2D, triple->bind);
- /* what is GL_READ_BUFFER right now? */
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, sizex, sizey);
- glBindTexture(GL_TEXTURE_2D, 0);
-}
-
-static void wm_draw_region_blend(wmWindow *win, ARegion *ar, wmDrawTriple *triple)
-{
- float fac = ED_region_blend_factor(ar);
-
- /* region blend always is 1, except when blend timer is running */
- if (fac < 1.0f) {
- wmViewport(&ar->winrct);
-
- glEnable(GL_BLEND);
- wm_triple_draw_textures(win, triple, 1.0f - fac);
+ if (blend) {
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_BLEND);
}
}
-static void wm_method_draw_triple(bContext *C, wmWindow *win)
+GPUViewport *WM_draw_region_get_viewport(ARegion *ar, int view)
{
- wmWindowManager *wm = CTX_wm_manager(C);
- wmDrawData *dd, *dd_next, *drawdata = win->drawdata.first;
- bScreen *screen = WM_window_get_active_screen(win);
- ARegion *ar;
- bool copytex = false;
-
- if (drawdata && drawdata->triple) {
-#if 0 /* why do we need to clear before overwriting? */
- glClearColor(1, 1, 0, 0);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-#endif
-
- wmWindowViewport(win);
-
- wm_triple_draw_textures(win, drawdata->triple, 1.0f);
+ if (!ar->draw_buffer) {
+ return NULL;
}
- else {
- /* we run it when we start OR when we turn stereo on */
- if (drawdata == NULL) {
- drawdata = MEM_callocN(sizeof(wmDrawData), "wmDrawData");
- BLI_addhead(&win->drawdata, drawdata);
- }
- drawdata->triple = MEM_callocN(sizeof(wmDrawTriple), "wmDrawTriple");
+ return ar->draw_buffer->viewport[view];
+}
- if (!wm_triple_gen_textures(win, drawdata->triple)) {
- wm_draw_triple_fail(C, win);
- return;
- }
+GPUViewport *WM_draw_region_get_bound_viewport(ARegion *ar)
+{
+ if (!ar->draw_buffer || ar->draw_buffer->bound_view == -1) {
+ return NULL;
}
- /* it means stereo was just turned off */
- /* note: we are removing all drawdatas that are not the first */
- for (dd = drawdata->next; dd; dd = dd_next) {
- dd_next = dd->next;
-
- BLI_remlink(&win->drawdata, dd);
- wm_draw_triple_free(dd->triple);
- MEM_freeN(dd);
- }
+ int view = ar->draw_buffer->bound_view;
+ return ar->draw_buffer->viewport[view];
+}
- wmDrawTriple *triple = drawdata->triple;
+static void wm_draw_window_offscreen(bContext *C, wmWindow *win, bool stereo)
+{
+ bScreen *screen = WM_window_get_active_screen(win);
- /* draw marked area regions (also global ones) */
+ /* Draw screen areas into own frame buffer. */
ED_screen_areas_iter(win, screen, sa) {
CTX_wm_area_set(C, sa);
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
+ for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) {
if (ar->visible && ar->do_draw) {
- if (ar->overlap == false) {
- wm_draw_region(C, ar);
- copytex = true;
+ CTX_wm_region_set(C, ar);
+ bool use_viewport = wm_region_use_viewport(sa, ar);
+
+ if (stereo && wm_draw_region_stereo_set(sa, ar, STEREO_LEFT_ID)) {
+ wm_draw_region_buffer_create(ar, true, use_viewport);
+
+ for (int view = 0; view < 2; view++) {
+ eStereoViews sview;
+ if (view == 0) {
+ sview = STEREO_LEFT_ID;
+ }
+ else {
+ sview = STEREO_RIGHT_ID;
+ wm_draw_region_stereo_set(sa, ar, sview);
+ }
+
+ wm_draw_region_bind(ar, view);
+ ED_region_do_draw(C, ar);
+ wm_draw_region_unbind(ar, view);
+ }
}
- }
- }
-
- wm_area_mark_invalid_backbuf(sa);
- CTX_wm_area_set(C, NULL);
- }
-
- if (copytex) {
- wmWindowViewport(win);
-
- wm_triple_copy_textures(win, triple);
- }
-
- if (wm->paintcursors.first) {
- ED_screen_areas_iter(win, screen, sa) {
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->visible && ar == screen->active_region) {
- CTX_wm_area_set(C, sa);
- CTX_wm_region_set(C, ar);
-
- /* make region ready for draw, scissor, pixelspace */
- wmViewport(&ar->winrct);
- wm_paintcursor_draw(C, ar);
-
- CTX_wm_region_set(C, NULL);
- CTX_wm_area_set(C, NULL);
+ else {
+ wm_draw_region_buffer_create(ar, false, use_viewport);
+ wm_draw_region_bind(ar, 0);
+ ED_region_do_draw(C, ar);
+ wm_draw_region_unbind(ar, 0);
}
- }
- }
-
- wmWindowViewport(win);
- }
- /* draw overlapping area regions (always like popups) */
- ED_screen_areas_iter(win, screen, sa) {
- CTX_wm_area_set(C, sa);
-
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->visible && ar->overlap) {
- wm_draw_region(C, ar);
- wm_draw_region_blend(win, ar, triple);
+ ar->do_draw = false;
+ CTX_wm_region_set(C, NULL);
}
}
+ wm_area_mark_invalid_backbuf(sa);
CTX_wm_area_set(C, NULL);
}
- /* after area regions so we can do area 'overlay' drawing */
- ED_screen_draw_edges(win);
- WM_window_get_active_screen(win)->do_draw = false;
- wm_draw_callbacks(win);
-
- /* draw floating regions (menus) */
- for (ar = screen->regionbase.first; ar; ar = ar->next) {
+ /* Draw menus into their own framebuffer. */
+ for (ARegion *ar = screen->regionbase.first; ar; ar = ar->next) {
if (ar->visible) {
CTX_wm_menu_set(C, ar);
+
+ if (ar->type && ar->type->refresh) {
+ /* UI code reads the OpenGL state, but we have to
+ * refresh beforehand in case the menu size changes. */
+ wmViewport(&ar->winrct);
+ ar->type->refresh(C, ar);
+ }
+
+ wm_draw_region_buffer_create(ar, false, false);
+ wm_draw_region_bind(ar, 0);
+ glClearColor(0, 0, 0, 0);
+ glClear(GL_COLOR_BUFFER_BIT);
ED_region_do_draw(C, ar);
+ wm_draw_region_unbind(ar, 0);
+
ar->do_draw = false;
CTX_wm_menu_set(C, NULL);
}
}
-
- /* always draw, not only when screen tagged */
- if (win->gesture.first)
- wm_gesture_draw(win);
-
- /* needs pixel coords in screen */
- if (wm->drags.first) {
- wm_drags_draw(C, win, NULL);
- }
}
-static void wm_method_draw_triple_multiview(bContext *C, wmWindow *win, eStereoViews sview)
+static void wm_draw_window_onscreen(bContext *C, wmWindow *win, int view)
{
wmWindowManager *wm = CTX_wm_manager(C);
- wmDrawData *drawdata;
- wmDrawTriple *triple_data, *triple_all;
bScreen *screen = WM_window_get_active_screen(win);
- ARegion *ar;
- int copytex = false;
- int id;
-
- /* we store the triple_data in sequence to triple_all */
- for (id = 0; id < 2; id++) {
- drawdata = BLI_findlink(&win->drawdata, (sview * 2) + id);
-
- if (drawdata && drawdata->triple) {
- if (id == 0) {
-#if 0 /* why do we need to clear before overwriting? */
- glClearColor(0, 0, 0, 0);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-#endif
-
- wmWindowViewport(win);
-
- wm_triple_draw_textures(win, drawdata->triple, 1.0f);
- }
- }
- else {
- /* we run it when we start OR when we turn stereo on */
- if (drawdata == NULL) {
- drawdata = MEM_callocN(sizeof(wmDrawData), "wmDrawData");
- BLI_addtail(&win->drawdata, drawdata);
- }
-
- drawdata->triple = MEM_callocN(sizeof(wmDrawTriple), "wmDrawTriple");
- if (!wm_triple_gen_textures(win, drawdata->triple)) {
- wm_draw_triple_fail(C, win);
- return;
- }
- }
- }
-
- triple_data = ((wmDrawData *) BLI_findlink(&win->drawdata, sview * 2))->triple;
- triple_all = ((wmDrawData *) BLI_findlink(&win->drawdata, (sview * 2) + 1))->triple;
+ /* Draw into the window framebuffer, in full window coordinates. */
+ wmWindowViewport(win);
+ glClearColor(0, 0, 0, 0);
+ glClear(GL_COLOR_BUFFER_BIT);
- /* draw marked area regions */
+ /* Blit non-overlapping area regions. */
ED_screen_areas_iter(win, screen, sa) {
- CTX_wm_area_set(C, sa);
-
- switch (sa->spacetype) {
- case SPACE_IMAGE:
- {
- SpaceImage *sima = sa->spacedata.first;
- sima->iuser.multiview_eye = sview;
- break;
- }
- case SPACE_VIEW3D:
- {
- View3D *v3d = sa->spacedata.first;
- if (v3d->camera && v3d->camera->type == OB_CAMERA) {
- Camera *cam = v3d->camera->data;
- CameraBGImage *bgpic = cam->bg_images.first;
- v3d->multiview_eye = sview;
- if (bgpic) bgpic->iuser.multiview_eye = sview;
- }
- break;
- }
- case SPACE_NODE:
- {
- SpaceNode *snode = sa->spacedata.first;
- if ((snode->flag & SNODE_BACKDRAW) && ED_node_is_compositor(snode)) {
- Image *ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
- ima->eye = sview;
+ for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) {
+ if (ar->visible && ar->overlap == false) {
+ if (view == -1 && ar->draw_buffer && ar->draw_buffer->stereo) {
+ /* Stereo drawing from textures. */
+ if(win->stereo3d_format->display_mode == S3D_DISPLAY_ANAGLYPH) {
+ wm_stereo3d_draw_anaglyph(win, ar);
+ }
+ else {
+ wm_stereo3d_draw_interlace(win, ar);
+ }
}
- break;
- }
- case SPACE_SEQ:
- {
- SpaceSeq *sseq = sa->spacedata.first;
- sseq->multiview_eye = sview;
- break;
- }
- }
-
- /* draw marked area regions */
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->visible && ar->do_draw) {
-
- if (ar->overlap == false) {
- CTX_wm_region_set(C, ar);
- ED_region_do_draw(C, ar);
-
- if (sview == STEREO_RIGHT_ID)
- ar->do_draw = false;
-
- CTX_wm_region_set(C, NULL);
- copytex = true;
+ else {
+ /* Blit from offscreen buffer. */
+ wm_draw_region_blit(ar, 0);
}
}
}
-
- wm_area_mark_invalid_backbuf(sa);
- CTX_wm_area_set(C, NULL);
- }
-
- if (copytex) {
- wmWindowViewport(win);
-
- wm_triple_copy_textures(win, triple_data);
}
+ /* Draw paint cursors. */
if (wm->paintcursors.first) {
ED_screen_areas_iter(win, screen, sa) {
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
+ for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) {
if (ar->visible && ar == screen->active_region) {
CTX_wm_area_set(C, sa);
CTX_wm_region_set(C, ar);
/* make region ready for draw, scissor, pixelspace */
- wmViewport(&ar->winrct);
wm_paintcursor_draw(C, ar);
CTX_wm_region_set(C, NULL);
@@ -786,40 +616,23 @@ static void wm_method_draw_triple_multiview(bContext *C, wmWindow *win, eStereoV
wmWindowViewport(win);
}
- /* draw overlapping area regions (always like popups) */
+ /* Blend in overlapping area regions */
ED_screen_areas_iter(win, screen, sa) {
- CTX_wm_area_set(C, sa);
-
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
+ for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) {
if (ar->visible && ar->overlap) {
- CTX_wm_region_set(C, ar);
- ED_region_do_draw(C, ar);
- if (sview == STEREO_RIGHT_ID)
- ar->do_draw = false;
- CTX_wm_region_set(C, NULL);
-
- wm_draw_region_blend(win, ar, triple_data);
+ wm_draw_region_blend(ar, 0, true);
}
}
-
- CTX_wm_area_set(C, NULL);
}
- /* after area regions so we can do area 'overlay' drawing */
+ /* After area regions so we can do area 'overlay' drawing. */
ED_screen_draw_edges(win);
- if (sview == STEREO_RIGHT_ID)
- screen->do_draw = false;
-
wm_draw_callbacks(win);
- /* draw floating regions (menus) */
- for (ar = screen->regionbase.first; ar; ar = ar->next) {
+ /* Blend in floating regions (menus). */
+ for (ARegion *ar = screen->regionbase.first; ar; ar = ar->next) {
if (ar->visible) {
- CTX_wm_menu_set(C, ar);
- ED_region_do_draw(C, ar);
- if (sview == STEREO_RIGHT_ID)
- ar->do_draw = false;
- CTX_wm_menu_set(C, NULL);
+ wm_draw_region_blend(ar, 0, true);
}
}
@@ -831,10 +644,76 @@ static void wm_method_draw_triple_multiview(bContext *C, wmWindow *win, eStereoV
if (wm->drags.first) {
wm_drags_draw(C, win, NULL);
}
+}
- /* copy the ui + overlays */
- wmWindowViewport(win);
- wm_triple_copy_textures(win, triple_all);
+static void wm_draw_window(bContext *C, wmWindow *win)
+{
+ bScreen *screen = WM_window_get_active_screen(win);
+ bool stereo = WM_stereo3d_enabled(win, false);
+
+ /* Draw area regions into their own framebuffer. This way we can redraw
+ * the areas that need it, and blit the rest from existing framebuffers. */
+ wm_draw_window_offscreen(C, win, stereo);
+
+ /* Now we draw into the window framebuffer, in full window coordinates. */
+ if (!stereo) {
+ /* Regular mono drawing. */
+ wm_draw_window_onscreen(C, win, -1);
+ }
+ else if(win->stereo3d_format->display_mode == S3D_DISPLAY_PAGEFLIP) {
+ /* For pageflip we simply draw to both back buffers. */
+ glDrawBuffer(GL_BACK_LEFT);
+ wm_draw_window_onscreen(C, win, 0);
+ glDrawBuffer(GL_BACK_RIGHT);
+ wm_draw_window_onscreen(C, win, 1);
+ glDrawBuffer(GL_BACK);
+ }
+ else if(ELEM(win->stereo3d_format->display_mode, S3D_DISPLAY_ANAGLYPH, S3D_DISPLAY_INTERLACE)) {
+ /* For anaglyph and interlace, we draw individual regions with
+ * stereo framebuffers using different shaders. */
+ wm_draw_window_onscreen(C, win, -1);
+ }
+ else {
+ /* For side-by-side and top-bottom, we need to render each view to an
+ * an offscreen texture and then draw it. This used to happen for all
+ * stereo methods, but it's less efficient than drawing directly. */
+ const int width = WM_window_pixels_x(win);
+ const int height = WM_window_pixels_y(win);
+ GPUOffScreen *offscreen = GPU_offscreen_create(width, height, 0, false, false, NULL);
+
+ if (offscreen) {
+ GPUTexture *texture = GPU_offscreen_color_texture(offscreen);
+ wm_draw_offscreen_texture_parameters(offscreen);
+
+ for (int view = 0; view < 2; view++) {
+ /* Draw view into offscreen buffer. */
+ GPU_offscreen_bind(offscreen, false);
+ wm_draw_window_onscreen(C, win, view);
+ GPU_offscreen_unbind(offscreen, false);
+
+ /* Draw offscreen buffer to screen. */
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(texture));
+
+ if (win->stereo3d_format->display_mode == S3D_DISPLAY_SIDEBYSIDE) {
+ wm_stereo3d_draw_sidebyside(win, view);
+ }
+ else {
+ wm_stereo3d_draw_topbottom(win, view);
+ }
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ }
+
+ GPU_offscreen_free(offscreen);
+ }
+ else {
+ /* Still draw something in case of allocation failure. */
+ wm_draw_window_onscreen(C, win, 0);
+ }
+ }
+
+ screen->do_draw = false;
}
/****************** main update call **********************/
@@ -842,17 +721,17 @@ static void wm_method_draw_triple_multiview(bContext *C, wmWindow *win, eStereoV
/* quick test to prevent changing window drawable */
static bool wm_draw_update_test_window(wmWindow *win)
{
- /*const*/ struct WorkSpace *workspace = WM_window_get_active_workspace(win);
- /*const*/ Scene *scene = WM_window_get_active_scene(win);
- /*const*/ ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene);
+ struct WorkSpace *workspace = WM_window_get_active_workspace(win);
+ Scene *scene = WM_window_get_active_scene(win);
+ ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene);
struct Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true);
- const bScreen *screen = WM_window_get_active_screen(win);
+ bScreen *screen = WM_window_get_active_screen(win);
ARegion *ar;
bool do_draw = false;
for (ar = screen->regionbase.first; ar; ar = ar->next) {
if (ar->do_draw_overlay) {
- wm_tag_redraw_overlay(win, ar);
+ screen->do_draw_paintcursor = true;
ar->do_draw_overlay = false;
}
if (ar->visible && ar->do_draw)
@@ -885,44 +764,14 @@ static bool wm_draw_update_test_window(wmWindow *win)
return false;
}
-static int wm_automatic_draw_method(wmWindow *win)
-{
- /* We assume all supported GPUs now support triple buffer well. */
- if (win->drawmethod == USER_DRAW_AUTOMATIC) {
- return USER_DRAW_TRIPLE;
- }
- else {
- return win->drawmethod;
- }
-}
-
-bool WM_is_draw_triple(wmWindow *win)
-{
- /* function can get called before this variable is set in drawing code below */
- if (win->drawmethod != U.wmdrawmethod)
- win->drawmethod = U.wmdrawmethod;
- return (USER_DRAW_TRIPLE == wm_automatic_draw_method(win));
-}
-
-void wm_tag_redraw_overlay(wmWindow *win, ARegion *ar)
+void WM_paint_cursor_tag_redraw(wmWindow *win, ARegion *UNUSED(ar))
{
- /* for draw triple gestures, paint cursors don't need region redraw */
- if (ar && win) {
+ if (win) {
bScreen *screen = WM_window_get_active_screen(win);
-
- if (wm_automatic_draw_method(win) != USER_DRAW_TRIPLE)
- ED_region_tag_redraw(ar);
screen->do_draw_paintcursor = true;
}
}
-void WM_paint_cursor_tag_redraw(wmWindow *win, ARegion *ar)
-{
- bScreen *screen = WM_window_get_active_screen(win);
- screen->do_draw_paintcursor = true;
- wm_tag_redraw_overlay(win, ar);
-}
-
void wm_draw_update(bContext *C)
{
wmWindowManager *wm = CTX_wm_manager(C);
@@ -946,10 +795,6 @@ void wm_draw_update(bContext *C)
continue;
}
#endif
- if (win->drawmethod != U.wmdrawmethod) {
- wm_draw_window_clear(win);
- win->drawmethod = U.wmdrawmethod;
- }
if (wm_draw_update_test_window(win)) {
bScreen *screen = WM_window_get_active_screen(win);
@@ -963,26 +808,7 @@ void wm_draw_update(bContext *C)
ED_screen_set_active_region(C, &win->eventstate->x);
ED_screen_ensure_updated(wm, win, screen);
- int drawmethod = wm_automatic_draw_method(win);
-
- if (win->drawfail)
- wm_method_draw_overlap_all(C, win, 0);
- else if (drawmethod == USER_DRAW_FULL)
- wm_method_draw_full(C, win);
- else if (drawmethod == USER_DRAW_OVERLAP)
- wm_method_draw_overlap_all(C, win, 0);
- else if (drawmethod == USER_DRAW_OVERLAP_FLIP)
- wm_method_draw_overlap_all(C, win, 1);
- else { /* USER_DRAW_TRIPLE */
- if ((WM_stereo3d_enabled(win, false)) == false) {
- wm_method_draw_triple(C, win);
- }
- else {
- wm_method_draw_triple_multiview(C, win, STEREO_LEFT_ID);
- wm_method_draw_triple_multiview(C, win, STEREO_RIGHT_ID);
- wm_method_draw_stereo3d(C, win);
- }
- }
+ wm_draw_window(C, win);
screen->do_draw_gesture = false;
screen->do_draw_paintcursor = false;
@@ -995,44 +821,16 @@ void wm_draw_update(bContext *C)
}
}
-void wm_draw_data_free(wmWindow *win)
-{
- wmDrawData *dd;
-
- for (dd = win->drawdata.first; dd; dd = dd->next) {
- wm_draw_triple_free(dd->triple);
- }
- BLI_freelistN(&win->drawdata);
-}
-
-void wm_draw_window_clear(wmWindow *win)
+void wm_draw_region_clear(wmWindow *win, ARegion *UNUSED(ar))
{
bScreen *screen = WM_window_get_active_screen(win);
- ARegion *ar;
-
- wm_draw_data_free(win);
-
- /* clear screen swap flags */
- if (screen) {
- ED_screen_areas_iter(win, screen, sa) {
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
- ar->swap = WIN_NONE_OK;
- }
- }
-
- screen->swap = WIN_NONE_OK;
- }
+ screen->do_draw = true;
}
-void wm_draw_region_clear(wmWindow *win, ARegion *ar)
+void WM_draw_region_free(ARegion *ar)
{
- bScreen *screen = WM_window_get_active_screen(win);
- int drawmethod = wm_automatic_draw_method(win);
-
- if (ELEM(drawmethod, USER_DRAW_OVERLAP, USER_DRAW_OVERLAP_FLIP))
- wm_flush_regions_down(win, screen, &ar->winrct);
-
- screen->do_draw = true;
+ wm_draw_region_buffer_free(ar);
+ ar->visible = 0;
}
void WM_redraw_windows(bContext *C)
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 495fac0123e..a64b633b000 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -2614,12 +2614,6 @@ static void wm_event_drag_test(wmWindowManager *wm, wmWindow *win, wmEvent *even
/* restore cursor (disabled, see wm_dragdrop.c) */
// WM_cursor_modal_restore(win);
}
-
- /* overlap fails otherwise */
- if (screen->do_draw_drag)
- if (win->drawmethod == USER_DRAW_OVERLAP)
- screen->do_draw = true;
-
}
/* filter out all events of the pie that spawned the last pie unless it's a release event */
diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c
index c2331f44056..2c3583a9f02 100644
--- a/source/blender/windowmanager/intern/wm_gesture.c
+++ b/source/blender/windowmanager/intern/wm_gesture.c
@@ -447,12 +447,8 @@ void wm_gesture_draw(wmWindow *win)
void wm_gesture_tag_redraw(bContext *C)
{
- wmWindow *win = CTX_wm_window(C);
bScreen *screen = CTX_wm_screen(C);
- ARegion *ar = CTX_wm_region(C);
if (screen)
screen->do_draw_gesture = true;
-
- wm_tag_redraw_overlay(win, ar);
}
diff --git a/source/blender/windowmanager/intern/wm_stereo.c b/source/blender/windowmanager/intern/wm_stereo.c
index b52fc4ae213..14093d01695 100644
--- a/source/blender/windowmanager/intern/wm_stereo.c
+++ b/source/blender/windowmanager/intern/wm_stereo.c
@@ -53,35 +53,18 @@
#include "ED_screen.h"
#include "GPU_immediate.h"
+#include "GPU_framebuffer.h"
+#include "GPU_texture.h"
#include "WM_api.h"
#include "WM_types.h"
#include "wm.h"
-#include "wm_draw.h" /* wmDrawTriple */
+#include "wm_draw.h"
#include "wm_window.h"
#include "UI_interface.h"
#include "UI_resources.h"
-static void wm_method_draw_stereo3d_pageflip(wmWindow *win)
-{
- wmDrawData *drawdata;
- int view;
-
- for (view = 0; view < 2; view ++) {
- drawdata = BLI_findlink(&win->drawdata, (view * 2) + 1);
-
- if (view == STEREO_LEFT_ID)
- glDrawBuffer(GL_BACK_LEFT);
- else //STEREO_RIGHT_ID
- glDrawBuffer(GL_BACK_RIGHT);
-
- wm_triple_draw_textures(win, drawdata->triple, 1.0f);
- }
-
- glDrawBuffer(GL_BACK);
-}
-
static GPUInterlaceShader interlace_gpu_id_from_type(eStereo3dInterlaceType interlace_type)
{
switch (interlace_type) {
@@ -95,75 +78,60 @@ static GPUInterlaceShader interlace_gpu_id_from_type(eStereo3dInterlaceType inte
}
}
-static void wm_method_draw_stereo3d_interlace(wmWindow *win)
+void wm_stereo3d_draw_interlace(wmWindow *win, ARegion *ar)
{
bool swap = (win->stereo3d_format->flag & S3D_INTERLACE_SWAP) != 0;
enum eStereo3dInterlaceType interlace_type = win->stereo3d_format->interlace_type;
- wmDrawData *drawdata[2];
- for (int eye = 0; eye < 2; eye++) {
- int view = swap ? !eye : eye;
- drawdata[eye] = BLI_findlink(&win->drawdata, (view * 2) + 1);
- }
-
- const int sizex = WM_window_pixels_x(win);
- const int sizey = WM_window_pixels_y(win);
-
/* wmOrtho for the screen has this same offset */
- float ratiox = 1.0f;
- float ratioy = 1.0f;
- float halfx = GLA_PIXEL_OFS / sizex;
- float halfy = GLA_PIXEL_OFS / sizex;
+ float halfx = GLA_PIXEL_OFS / ar->winx;
+ float halfy = GLA_PIXEL_OFS / ar->winy;
Gwn_VertFormat *format = immVertexFormat();
unsigned int texcoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_INTERLACE);
-
- /* leave GL_TEXTURE0 as the latest bind texture */
- for (int eye = 1; eye >= 0; eye--) {
- glActiveTexture(GL_TEXTURE0 + eye);
- glBindTexture(GL_TEXTURE_2D, drawdata[eye]->triple->bind);
+ /* leave GL_TEXTURE0 as the latest active texture */
+ for (int view = 1; view >= 0; view--) {
+ GPUTexture *texture = wm_draw_region_texture(ar, view);
+ glActiveTexture(GL_TEXTURE0 + view);
+ glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(texture));
}
- immUniform1i("image_a", 0);
- immUniform1i("image_b", 1);
+ immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_INTERLACE);
+ immUniform1i("image_a", (swap)? 1: 0);
+ immUniform1i("image_b", (swap)? 0: 1);
immUniform1i("interlace_id", interlace_gpu_id_from_type(interlace_type));
immBegin(GWN_PRIM_TRI_FAN, 4);
immAttrib2f(texcoord, halfx, halfy);
- immVertex2f(pos, 0.0f, 0.0f);
+ immVertex2f(pos, ar->winrct.xmin, ar->winrct.ymin);
- immAttrib2f(texcoord, ratiox + halfx, halfy);
- immVertex2f(pos, sizex, 0.0f);
+ immAttrib2f(texcoord, 1.0f + halfx, halfy);
+ immVertex2f(pos, ar->winrct.xmax + 1, ar->winrct.ymin);
- immAttrib2f(texcoord, ratiox + halfx, ratioy + halfy);
- immVertex2f(pos, sizex, sizey);
+ immAttrib2f(texcoord, 1.0f + halfx, 1.0f + halfy);
+ immVertex2f(pos, ar->winrct.xmax + 1, ar->winrct.ymax + 1);
- immAttrib2f(texcoord, halfx, ratioy + halfy);
- immVertex2f(pos, 0.0f, sizey);
+ immAttrib2f(texcoord, halfx, 1.0f + halfy);
+ immVertex2f(pos, ar->winrct.xmin, ar->winrct.ymax + 1);
immEnd();
immUnbindProgram();
- for (int eye = 1; eye >= 0; eye--) {
- glActiveTexture(GL_TEXTURE0 + eye);
+ for (int view = 1; view >= 0; view--) {
+ glActiveTexture(GL_TEXTURE0 + view);
glBindTexture(GL_TEXTURE_2D, 0);
}
}
-static void wm_method_draw_stereo3d_anaglyph(wmWindow *win)
+void wm_stereo3d_draw_anaglyph(wmWindow *win, ARegion *ar)
{
- wmDrawData *drawdata;
- int view, bit;
+ for (int view = 0; view < 2; view ++) {
+ int bit = view + 1;
- for (view = 0; view < 2; view ++) {
- drawdata = BLI_findlink(&win->drawdata, (view * 2) + 1);
-
- bit = view + 1;
switch (win->stereo3d_format->anaglyph_type) {
case S3D_ANAGLYPH_REDCYAN:
glColorMask((1&bit) ? GL_TRUE : GL_FALSE,
@@ -185,158 +153,104 @@ static void wm_method_draw_stereo3d_anaglyph(wmWindow *win)
break;
}
- wm_triple_draw_textures(win, drawdata->triple, 1.0f);
-
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ wm_draw_region_blend(ar, view, false);
}
+
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
-static void wm_method_draw_stereo3d_sidebyside(wmWindow *win)
+void wm_stereo3d_draw_sidebyside(wmWindow *win, int view)
{
- wmDrawData *drawdata;
- wmDrawTriple *triple;
- int view;
- int soffx;
bool cross_eyed = (win->stereo3d_format->flag & S3D_SIDEBYSIDE_CROSSEYED) != 0;
Gwn_VertFormat *format = immVertexFormat();
unsigned int texcoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_ALPHA);
- glActiveTexture(GL_TEXTURE0);
-
- for (view = 0; view < 2; view ++) {
- drawdata = BLI_findlink(&win->drawdata, (view * 2) + 1);
- triple = drawdata->triple;
+ immBindBuiltinProgram(GPU_SHADER_2D_IMAGE);
- soffx = WM_window_pixels_x(win) * 0.5f;
- if (view == STEREO_LEFT_ID) {
- if (!cross_eyed)
- soffx = 0;
- }
- else { //RIGHT_LEFT_ID
- if (cross_eyed)
- soffx = 0;
- }
-
- const int sizex = WM_window_pixels_x(win);
- const int sizey = WM_window_pixels_y(win);
+ int soffx = WM_window_pixels_x(win) * 0.5f;
+ if (view == STEREO_LEFT_ID) {
+ if (!cross_eyed)
+ soffx = 0;
+ }
+ else { //RIGHT_LEFT_ID
+ if (cross_eyed)
+ soffx = 0;
+ }
- /* wmOrtho for the screen has this same offset */
- const float ratiox = 1.0f;
- const float ratioy = 1.0f;
- const float halfx = GLA_PIXEL_OFS / sizex;
- const float halfy = GLA_PIXEL_OFS / sizey;
+ const int sizex = WM_window_pixels_x(win);
+ const int sizey = WM_window_pixels_y(win);
- glBindTexture(GL_TEXTURE_2D, triple->bind);
+ /* wmOrtho for the screen has this same offset */
+ const float halfx = GLA_PIXEL_OFS / sizex;
+ const float halfy = GLA_PIXEL_OFS / sizex;
- immUniform1f("alpha", 1.0f);
- immUniform1i("image", 0); /* default GL_TEXTURE0 unit */
+ immUniform1i("image", 0); /* texture is already bound to GL_TEXTURE0 unit */
- immBegin(GWN_PRIM_TRI_FAN, 4);
+ immBegin(GWN_PRIM_TRI_FAN, 4);
- immAttrib2f(texcoord, halfx, halfy);
- immVertex2f(pos, soffx, 0.0f);
+ immAttrib2f(texcoord, halfx, halfy);
+ immVertex2f(pos, soffx, 0.0f);
- immAttrib2f(texcoord, ratiox + halfx, halfy);
- immVertex2f(pos, soffx + (sizex * 0.5f), 0.0f);
+ immAttrib2f(texcoord, 1.0f + halfx, halfy);
+ immVertex2f(pos, soffx + (sizex * 0.5f), 0.0f);
- immAttrib2f(texcoord, ratiox + halfx, ratioy + halfy);
- immVertex2f(pos, soffx + (sizex * 0.5f), sizey);
+ immAttrib2f(texcoord, 1.0f + halfx, 1.0f + halfy);
+ immVertex2f(pos, soffx + (sizex * 0.5f), sizey);
- immAttrib2f(texcoord, halfx, ratioy + halfy);
- immVertex2f(pos, soffx, sizey);
+ immAttrib2f(texcoord, halfx, 1.0f + halfy);
+ immVertex2f(pos, soffx, sizey);
- immEnd();
- }
+ immEnd();
- glBindTexture(GL_TEXTURE_2D, 0);
immUnbindProgram();
}
-static void wm_method_draw_stereo3d_topbottom(wmWindow *win)
+void wm_stereo3d_draw_topbottom(wmWindow *win, int view)
{
- wmDrawData *drawdata;
- wmDrawTriple *triple;
- int view;
- int soffy;
-
Gwn_VertFormat *format = immVertexFormat();
unsigned int texcoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_ALPHA);
- glActiveTexture(GL_TEXTURE0);
-
- for (view = 0; view < 2; view ++) {
- drawdata = BLI_findlink(&win->drawdata, (view * 2) + 1);
- triple = drawdata->triple;
-
- if (view == STEREO_LEFT_ID) {
- soffy = WM_window_pixels_y(win) * 0.5f;
- }
- else { /* STEREO_RIGHT_ID */
- soffy = 0;
- }
+ immBindBuiltinProgram(GPU_SHADER_2D_IMAGE);
- const int sizex = WM_window_pixels_x(win);
- const int sizey = WM_window_pixels_y(win);
+ int soffy;
+ if (view == STEREO_LEFT_ID) {
+ soffy = WM_window_pixels_y(win) * 0.5f;
+ }
+ else { /* STEREO_RIGHT_ID */
+ soffy = 0;
+ }
- /* wmOrtho for the screen has this same offset */
- const float ratiox = 1.0f;
- const float ratioy = 1.0f;
- const float halfx = GLA_PIXEL_OFS / sizex;
- const float halfy = GLA_PIXEL_OFS / sizey;
+ const int sizex = WM_window_pixels_x(win);
+ const int sizey = WM_window_pixels_y(win);
- glBindTexture(GL_TEXTURE_2D, triple->bind);
+ /* wmOrtho for the screen has this same offset */
+ const float halfx = GLA_PIXEL_OFS / sizex;
+ const float halfy = GLA_PIXEL_OFS / sizex;
- immUniform1f("alpha", 1.0f);
- immUniform1i("image", 0); /* default GL_TEXTURE0 unit */
+ immUniform1i("image", 0); /* texture is already bound to GL_TEXTURE0 unit */
- immBegin(GWN_PRIM_TRI_FAN, 4);
+ immBegin(GWN_PRIM_TRI_FAN, 4);
- immAttrib2f(texcoord, halfx, halfy);
- immVertex2f(pos, 0.0f, soffy);
+ immAttrib2f(texcoord, halfx, halfy);
+ immVertex2f(pos, 0.0f, soffy);
- immAttrib2f(texcoord, ratiox + halfx, halfy);
- immVertex2f(pos, sizex, soffy);
+ immAttrib2f(texcoord, 1.0f + halfx, halfy);
+ immVertex2f(pos, sizex, soffy);
- immAttrib2f(texcoord, ratiox + halfx, ratioy + halfy);
- immVertex2f(pos, sizex, soffy + (sizey * 0.5f));
+ immAttrib2f(texcoord, 1.0f + halfx, 1.0f + halfy);
+ immVertex2f(pos, sizex, soffy + (sizey * 0.5f));
- immAttrib2f(texcoord, halfx, ratioy + halfy);
- immVertex2f(pos, 0.0f, soffy + (sizey * 0.5f));
+ immAttrib2f(texcoord, halfx, 1.0f + halfy);
+ immVertex2f(pos, 0.0f, soffy + (sizey * 0.5f));
- immEnd();
- }
+ immEnd();
immUnbindProgram();
- glBindTexture(GL_TEXTURE_2D, 0);
}
-void wm_method_draw_stereo3d(const bContext *UNUSED(C), wmWindow *win)
-{
- switch (win->stereo3d_format->display_mode) {
- case S3D_DISPLAY_ANAGLYPH:
- wm_method_draw_stereo3d_anaglyph(win);
- break;
- case S3D_DISPLAY_INTERLACE:
- wm_method_draw_stereo3d_interlace(win);
- break;
- case S3D_DISPLAY_PAGEFLIP:
- wm_method_draw_stereo3d_pageflip(win);
- break;
- case S3D_DISPLAY_SIDEBYSIDE:
- wm_method_draw_stereo3d_sidebyside(win);
- break;
- case S3D_DISPLAY_TOPBOTTOM:
- wm_method_draw_stereo3d_topbottom(win);
- break;
- default:
- break;
- }
-}
static bool wm_stereo3d_quadbuffer_supported(void)
{
diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c
index f34b5bf9c95..89a12206a66 100644
--- a/source/blender/windowmanager/intern/wm_subwindow.c
+++ b/source/blender/windowmanager/intern/wm_subwindow.c
@@ -69,6 +69,8 @@ void wmPartialViewport(rcti *drawrct, const rcti *winrct, const rcti *partialrct
scissor_pad = false;
}
+ int x = drawrct->xmin - winrct->xmin;
+ int y = drawrct->ymin - winrct->ymin;
int width = BLI_rcti_size_x(winrct) + 1;
int height = BLI_rcti_size_y(winrct) + 1;
@@ -83,8 +85,8 @@ void wmPartialViewport(rcti *drawrct, const rcti *winrct, const rcti *partialrct
scissor_height += 1;
}
- glViewport(winrct->xmin, winrct->ymin, width, height);
- glScissor(drawrct->xmin, drawrct->ymin, scissor_width, scissor_height);
+ glViewport(0, 0, width, height);
+ glScissor(x, y, scissor_width, scissor_height);
wmOrtho2_pixelspace(width, height);
gpuLoadIdentity();
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 4efca37b921..e0a1f0f14ad 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -228,8 +228,6 @@ void wm_window_free(bContext *C, wmWindowManager *wm, wmWindow *win)
wm_event_free_all(win);
- wm_draw_data_free(win);
-
wm_ghostwindow_destroy(wm, win);
BKE_workspace_instance_hook_free(G.main, win->workspace_hook);
@@ -305,10 +303,6 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *win_src, const bool duplicate_la
layout_new = duplicate_layout ? ED_workspace_layout_duplicate(workspace, layout_old, win_dst) : layout_old;
WM_window_set_active_layout(win_dst, workspace, layout_new);
- win_dst->drawmethod = U.wmdrawmethod;
-
- BLI_listbase_clear(&win_dst->drawdata);
-
*win_dst->stereo3d_format = *win_src->stereo3d_format;
return win_dst;
@@ -508,8 +502,6 @@ void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win)
BLI_remlink(&wm->windows, win);
- wm_draw_window_clear(win);
-
CTX_wm_window_set(C, win); /* needed by handlers */
WM_event_remove_handlers(C, &win->handlers);
WM_event_remove_handlers(C, &win->modalhandlers);
@@ -826,8 +818,6 @@ wmWindow *WM_window_open(bContext *C, const rcti *rect)
win->sizex = BLI_rcti_size_x(rect);
win->sizey = BLI_rcti_size_y(rect);
- win->drawmethod = U.wmdrawmethod;
-
WM_check(C);
if (win->ghostwin) {
@@ -1481,7 +1471,6 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
}
wm_window_make_drawable(wm, win);
- wm_draw_window_clear(win);
BKE_icon_changed(screen->id.icon_id);
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
WM_event_add_notifier(C, NC_WINDOW | NA_EDITED, NULL);
@@ -1604,7 +1593,6 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
CTX_wm_window_set(C, oldWindow);
wm_window_make_drawable(wm, win);
- wm_draw_window_clear(win);
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
WM_event_add_notifier(C, NC_WINDOW | NA_EDITED, NULL);
diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h
index b2e8c914fa8..073adef177c 100644
--- a/source/blender/windowmanager/wm.h
+++ b/source/blender/windowmanager/wm.h
@@ -31,6 +31,7 @@
#ifndef __WM_H__
#define __WM_H__
+struct ARegion;
struct wmWindow;
struct ReportList;
@@ -82,7 +83,11 @@ void wm_autosave_read(bContext *C, struct ReportList *reports);
void wm_autosave_location(char *filepath);
/* wm_stereo.c */
-void wm_method_draw_stereo3d(const bContext *C, wmWindow *win);
+void wm_stereo3d_draw_interlace(wmWindow *win, struct ARegion *ar);
+void wm_stereo3d_draw_anaglyph(wmWindow *win, struct ARegion *ar);
+void wm_stereo3d_draw_sidebyside(wmWindow *win, int view);
+void wm_stereo3d_draw_topbottom(wmWindow *win, int view);
+
void wm_stereo3d_mouse_offset_apply(wmWindow *win, int *r_mouse_xy);
int wm_stereo3d_set_exec(bContext *C, wmOperator *op);
int wm_stereo3d_set_invoke(bContext *C, wmOperator *op, const wmEvent *event);
diff --git a/source/blender/windowmanager/wm_draw.h b/source/blender/windowmanager/wm_draw.h
index fa3d443e6ae..096d241eb64 100644
--- a/source/blender/windowmanager/wm_draw.h
+++ b/source/blender/windowmanager/wm_draw.h
@@ -34,29 +34,27 @@
#include "GPU_glew.h"
-typedef struct wmDrawTriple {
- GLuint bind;
-} wmDrawTriple;
+struct GPUOffScreen;
+struct GPUViewport;
+struct GPUTexture;
-typedef struct wmDrawData {
- struct wmDrawData *next, *prev;
- wmDrawTriple *triple;
-} wmDrawData;
+typedef struct wmDrawBuffer {
+ struct GPUOffScreen *offscreen[2];
+ struct GPUViewport *viewport[2];
+ bool stereo;
+ int bound_view;
+} wmDrawBuffer;
struct bContext;
struct wmWindow;
struct ARegion;
/* wm_draw.c */
-void wm_draw_update (struct bContext *C);
-void wm_draw_window_clear (struct wmWindow *win);
-void wm_draw_region_clear (struct wmWindow *win, struct ARegion *ar);
+void wm_draw_update(struct bContext *C);
+void wm_draw_region_clear(struct wmWindow *win, struct ARegion *ar);
+void wm_draw_region_blend(struct ARegion *ar, int view, bool blend);
-void wm_tag_redraw_overlay (struct wmWindow *win, struct ARegion *ar);
-
-void wm_triple_draw_textures (struct wmWindow *win, struct wmDrawTriple *triple, float alpha);
-
-void wm_draw_data_free (struct wmWindow *win);
+struct GPUTexture *wm_draw_region_texture(struct ARegion *ar, int view);
#endif /* __WM_DRAW_H__ */