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
This commit is contained in:
2018-04-27 10:22:37 +02:00
parent 868c9ac408
commit e01cadd657
38 changed files with 769 additions and 1118 deletions

View File

@@ -535,8 +535,6 @@ class USERPREF_PT_system(Panel):
col.separator()
col.label(text="Window Draw Method:")
col.prop(system, "window_draw_method", text="")
col.prop(system, "multi_sample", text="")
if sys.platform == "linux" and system.multi_sample != 'NONE':
col.label(text="Might fail for Mesh editing selection!")

View File

@@ -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 */

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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,

View File

@@ -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;
}
/* 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);
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->view_update) {
draw_engine->view_update(data);
/* 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);
/* 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->view_update) {
draw_engine->view_update(data);
}
}
DST.viewport = NULL;
drw_engines_disable();
BLI_mutex_unlock(&DST.ogl_context_mutex);
}
DST.viewport = NULL;
drw_engines_disable();
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);
DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, render_viewport, NULL);
/* restore */
{
if (viewport == NULL) {
/* don't free data owned by 'ofs' */
GPU_viewport_clear_from_offscreen(rv3d->viewport);
GPU_viewport_free(rv3d->viewport);
}
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;
}
/** \} */

View File

@@ -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);

View File

@@ -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),

View File

@@ -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;

View File

@@ -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)

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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,

View File

@@ -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)

View File

@@ -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),

View File

@@ -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 {

View File

@@ -154,7 +154,6 @@ typedef struct RegionView3D {
float rot_axis[3];
struct GPUFX *compositor;
struct GPUViewport *viewport;
} RegionView3D;
/* 3D ViewPort Struct */

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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);
}

File diff suppressed because it is too large Load Diff

View File

@@ -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 */

View File

@@ -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);
}

View File

@@ -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);
immBindBuiltinProgram(GPU_SHADER_2D_IMAGE);
for (view = 0; view < 2; view ++) {
drawdata = BLI_findlink(&win->drawdata, (view * 2) + 1);
triple = drawdata->triple;
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);
/* 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;
glBindTexture(GL_TEXTURE_2D, triple->bind);
immUniform1f("alpha", 1.0f);
immUniform1i("image", 0); /* default GL_TEXTURE0 unit */
immBegin(GWN_PRIM_TRI_FAN, 4);
immAttrib2f(texcoord, halfx, halfy);
immVertex2f(pos, soffx, 0.0f);
immAttrib2f(texcoord, ratiox + 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, halfx, ratioy + halfy);
immVertex2f(pos, soffx, sizey);
immEnd();
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;
}
glBindTexture(GL_TEXTURE_2D, 0);
const int sizex = WM_window_pixels_x(win);
const int sizey = WM_window_pixels_y(win);
/* wmOrtho for the screen has this same offset */
const float halfx = GLA_PIXEL_OFS / sizex;
const float halfy = GLA_PIXEL_OFS / sizex;
immUniform1i("image", 0); /* texture is already bound to GL_TEXTURE0 unit */
immBegin(GWN_PRIM_TRI_FAN, 4);
immAttrib2f(texcoord, halfx, halfy);
immVertex2f(pos, soffx, 0.0f);
immAttrib2f(texcoord, 1.0f + halfx, halfy);
immVertex2f(pos, soffx + (sizex * 0.5f), 0.0f);
immAttrib2f(texcoord, 1.0f + halfx, 1.0f + halfy);
immVertex2f(pos, soffx + (sizex * 0.5f), sizey);
immAttrib2f(texcoord, halfx, 1.0f + halfy);
immVertex2f(pos, soffx, sizey);
immEnd();
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);
immBindBuiltinProgram(GPU_SHADER_2D_IMAGE);
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;
}
const int sizex = WM_window_pixels_x(win);
const int sizey = WM_window_pixels_y(win);
/* 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;
glBindTexture(GL_TEXTURE_2D, triple->bind);
immUniform1f("alpha", 1.0f);
immUniform1i("image", 0); /* default GL_TEXTURE0 unit */
immBegin(GWN_PRIM_TRI_FAN, 4);
immAttrib2f(texcoord, halfx, halfy);
immVertex2f(pos, 0.0f, soffy);
immAttrib2f(texcoord, ratiox + halfx, halfy);
immVertex2f(pos, sizex, soffy);
immAttrib2f(texcoord, ratiox + halfx, ratioy + halfy);
immVertex2f(pos, sizex, soffy + (sizey * 0.5f));
immAttrib2f(texcoord, halfx, ratioy + halfy);
immVertex2f(pos, 0.0f, soffy + (sizey * 0.5f));
immEnd();
int soffy;
if (view == STEREO_LEFT_ID) {
soffy = WM_window_pixels_y(win) * 0.5f;
}
else { /* STEREO_RIGHT_ID */
soffy = 0;
}
const int sizex = WM_window_pixels_x(win);
const int sizey = WM_window_pixels_y(win);
/* wmOrtho for the screen has this same offset */
const float halfx = GLA_PIXEL_OFS / sizex;
const float halfy = GLA_PIXEL_OFS / sizex;
immUniform1i("image", 0); /* texture is already bound to GL_TEXTURE0 unit */
immBegin(GWN_PRIM_TRI_FAN, 4);
immAttrib2f(texcoord, halfx, halfy);
immVertex2f(pos, 0.0f, soffy);
immAttrib2f(texcoord, 1.0f + halfx, halfy);
immVertex2f(pos, sizex, soffy);
immAttrib2f(texcoord, 1.0f + halfx, 1.0f + halfy);
immVertex2f(pos, sizex, soffy + (sizey * 0.5f));
immAttrib2f(texcoord, halfx, 1.0f + halfy);
immVertex2f(pos, 0.0f, soffy + (sizey * 0.5f));
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)
{

View File

@@ -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();

View File

@@ -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);

View File

@@ -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);

View File

@@ -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__ */