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:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2018-04-27 11:22:37 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2018-04-27 13:14:14 +0300
commite01cadd657c76267266546781703df107c55f83a (patch)
treeaf6685123707af7cce17c74d681dcce378d4bc72 /source/blender
parent868c9ac408f75634c75bf4bc0b17c87b79d7af73 (diff)
WM: new offscreen window draw method to replace all existing methods.
For Blender 2.8 we had to be compatible with very old OpenGL versions, and triple buffer was designed to work without offscreen rendering, by copying the the backbuffer to a texture right before swapping. This way we could avoid redrawing unchanged regions by copying them from this texture on the next redraws. Triple buffer used to suffer from poor performance and driver bugs on specific cards, so alternative draw methods remained available. Now that we require newer OpenGL, we can have just a single draw method that draw each region into an offscreen buffer, and then draws those to the screen. This has some advantages: * Poor 3D view performance when using Region Overlap should be solved now, since we can also cache overlapping regions in offscreen buffers. * Page flip, anaglyph and interlace stereo drawing can be a little faster by avoiding a copy to an intermediate texture. * The new 3D view drawing already writes to an offscreen buffer, which we can draw from directly instead of duplicating it to another buffer. * Eventually we will be able to remove depth and stencil buffers from the window and save memory, though at the moment there are still some tools using it so it's not possible yet. * This also fixes a bug with Eevee sampling not progressing with stereo drawing in the 3D viewport. Differential Revision: https://developer.blender.org/D3061
Diffstat (limited to 'source/blender')
-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
37 files changed, 703 insertions, 1050 deletions
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__ */