From 87bbb2d827064a4fd59ffc77cc2dcbc31f02ce4f Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 31 Jan 2010 23:45:51 +0000 Subject: WM Draw Methods now has a new option Automatic (default). This will set the draw method to triple buffer or overlap depending on the configuration. Ideally I could get all cases working well with triple buffer but it's hard in practice. At the moment there are two cases that use overlap instead: * opensource ATI drives on linux * windows software renderer Also added a utility function to check GPU device/os/driver. --- source/blender/blenkernel/BKE_blender.h | 2 +- source/blender/editors/include/BIF_glutil.h | 1 - source/blender/editors/interface/resources.c | 5 ++ source/blender/editors/screen/glutil.c | 13 +---- source/blender/editors/space_node/node_draw.c | 4 +- source/blender/gpu/GPU_extensions.h | 31 +++++++++- source/blender/gpu/intern/gpu_extensions.c | 66 +++++++++++++++++++++- source/blender/makesdna/DNA_userdef_types.h | 1 + source/blender/makesrna/intern/rna_userdef.c | 1 + source/blender/windowmanager/intern/wm_draw.c | 9 +++ source/blender/windowmanager/intern/wm_subwindow.c | 14 ----- 11 files changed, 111 insertions(+), 36 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 45df0913079..666ecf7d65d 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -43,7 +43,7 @@ struct bContext; struct ReportList; #define BLENDER_VERSION 250 -#define BLENDER_SUBVERSION 15 +#define BLENDER_SUBVERSION 16 #define BLENDER_MINVERSION 250 #define BLENDER_MINSUBVERSION 0 diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h index e394de613e4..53c725b811c 100644 --- a/source/blender/editors/include/BIF_glutil.h +++ b/source/blender/editors/include/BIF_glutil.h @@ -203,7 +203,6 @@ void bglVertex3f(float x, float y, float z); void bglVertex2fv(float *vec); /* intel gfx cards frontbuffer problem */ void bglFlush(void); -int is_a_really_crappy_intel_card(void); void set_inverted_drawing(int enable); void setlinestyle(int nr); diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 9468eb7a0c6..313b03fdec3 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -1355,6 +1355,11 @@ void init_userdef_do_versions(void) strcpy(km->idname, "Property Editor"); } } + if (G.main->versionfile < 250 || (G.main->versionfile == 250 && G.main->subversionfile < 16)) { + if(U.wmdrawmethod == USER_DRAW_TRIPLE) + U.wmdrawmethod = USER_DRAW_AUTOMATIC; + } + /* GL Texture Garbage Collection (variable abused above!) */ if (U.textimeout == 0) { diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index 752c6feb9af..1ea0c2ccdbd 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -851,22 +851,11 @@ void bglPolygonOffset(float viewdist, float dist) } } -int is_a_really_crappy_intel_card(void) -{ - static int well_is_it= -1; - - /* Do you understand the implication? Do you? */ - if (well_is_it==-1) - well_is_it= (strcmp((char*) glGetString(GL_VENDOR), "Intel Inc.") == 0); - - return well_is_it; -} - void bglFlush(void) { glFlush(); #ifdef __APPLE__ -// if(is_a_really_crappy_intel_card()) +// if(GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_MAC, GPU_DRIVER_OFFICIAL)) // XXX myswapbuffers(); //hack to get mac intel graphics to show frontbuffer #endif } diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 03bc8340810..27719f124a1 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -605,14 +605,12 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv) } } -#ifdef __APPLE__ -// if(is_a_really_crappy_nvidia_card()) { XXX +// if(GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_MAC, GPU_DRIVER_OFFICIAL)) { XXX // float zoomx= curarea->winx/(float)(G.v2d->cur.xmax-G.v2d->cur.xmin); // float zoomy= curarea->winy/(float)(G.v2d->cur.ymax-G.v2d->cur.ymin); // glPixelZoom(zoomx*xscale, zoomy*yscale); // } // else -#endif glPixelZoom(xscale, yscale); glEnable(GL_BLEND); diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h index c2af4e8fcb1..998c13d2a64 100644 --- a/source/blender/gpu/GPU_extensions.h +++ b/source/blender/gpu/GPU_extensions.h @@ -37,8 +37,6 @@ extern "C" { #endif -/* GPU extensions support */ - struct Image; struct ImageUser; @@ -54,6 +52,8 @@ typedef struct GPUOffScreen GPUOffScreen; struct GPUShader; typedef struct GPUShader GPUShader; +/* GPU extensions support */ + void GPU_extensions_disable(void); void GPU_extensions_init(void); /* call this before running any of the functions below */ void GPU_extensions_exit(void); @@ -61,6 +61,33 @@ int GPU_glsl_support(void); int GPU_non_power_of_two_support(void); int GPU_print_error(char *str); +/* GPU Types */ + +typedef enum GPUDeviceType { + GPU_DEVICE_NVIDIA = (1<<0), + GPU_DEVICE_ATI = (1<<1), + GPU_DEVICE_INTEL = (1<<2), + GPU_DEVICE_SOFTWARE = (1<<3), + GPU_DEVICE_UNKNOWN = (1<<4), + GPU_DEVICE_ANY = (0xff) +} GPUDeviceType; + +typedef enum GPUOSType { + GPU_OS_WIN = (1<<16), + GPU_OS_MAC = (1<<17), + GPU_OS_UNIX = (1<<18), + GPU_OS_ANY = (0xff00) +} GPUOSType; + +typedef enum GPUDriverType { + GPU_DRIVER_OFFICIAL = (1<<24), + GPU_DRIVER_OPENSOURCE = (1<<25), + GPU_DRIVER_SOFTWARE = (1<<26), + GPU_DRIVER_UNKNOWN = (0xff0000) +} GPUDriverType; + +int GPU_type_matches(GPUDeviceType device, GPUOSType os, GPUDriverType driver); + /* GPU Texture - always returns unsigned char RGBA textures - if texture with non square dimensions is created, depending on the diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c index a5a8c626cbd..e93dd37db82 100644 --- a/source/blender/gpu/intern/gpu_extensions.c +++ b/source/blender/gpu/intern/gpu_extensions.c @@ -71,8 +71,20 @@ static struct GPUGlobal { GLuint currentfb; int glslsupport; int extdisabled; + GPUDeviceType device; + GPUOSType os; + GPUDriverType driver; } GG = {1, 0, 0, 0}; +/* GPU Types */ + +int GPU_type_matches(GPUDeviceType device, GPUOSType os, GPUDriverType driver) +{ + return (GG.device & device) && (GG.os & os) && (GG.driver & driver); +} + +/* GPU Extensions */ + void GPU_extensions_disable() { GG.extdisabled = 1; @@ -80,6 +92,8 @@ void GPU_extensions_disable() void GPU_extensions_init() { + const char *vendor, *renderer; + glewInit(); /* glewIsSupported("GL_VERSION_2_0") */ @@ -91,6 +105,54 @@ void GPU_extensions_init() if (!GLEW_ARB_multitexture) GG.glslsupport = 0; if (!GLEW_ARB_vertex_shader) GG.glslsupport = 0; if (!GLEW_ARB_fragment_shader) GG.glslsupport = 0; + + vendor = (const char*)glGetString(GL_VENDOR); + renderer = (const char*)glGetString(GL_RENDERER); + + if(strstr(vendor, "ATI")) { + GG.device = GPU_DEVICE_ATI; + GG.driver = GPU_DRIVER_OFFICIAL; + } + else if(strstr(vendor, "NVIDIA")) { + GG.device = GPU_DEVICE_NVIDIA; + GG.driver = GPU_DRIVER_OFFICIAL; + } + else if(strstr(vendor, "Intel") || strstr(renderer, "Mesa DRI Intel")) { + GG.device = GPU_DEVICE_INTEL; + GG.driver = GPU_DRIVER_OFFICIAL; + } + else if(strstr(renderer, "Mesa DRI R")) { + GG.device = GPU_DEVICE_ATI; + GG.driver = GPU_DRIVER_OPENSOURCE; + } + else if(strstr(renderer, "Nouveau")) { + GG.device = GPU_DEVICE_NVIDIA; + GG.driver = GPU_DRIVER_OPENSOURCE; + } + else if(strcmp(vendor, "Mesa") == 0) { + GG.device = GPU_DEVICE_SOFTWARE; + GG.driver = GPU_DRIVER_SOFTWARE; + } + else if(strstr(vendor, "Microsoft")) { + GG.device = GPU_DEVICE_SOFTWARE; + GG.driver = GPU_DRIVER_SOFTWARE; + } + else if(strcmp(renderer, "Apple Software Renderer") == 0) { + GG.device = GPU_DEVICE_SOFTWARE; + GG.driver = GPU_DRIVER_SOFTWARE; + } + else { + GG.device = GPU_DEVICE_UNKNOWN; + GG.driver = GPU_DRIVER_UNKNOWN; + } + + GG.os = GPU_OS_UNIX; +#ifdef _WIN32 + GG.os = GPU_OS_WIN; +#endif +#ifdef __APPLE__ + GG.os = GPU_OS_MAC; +#endif } int GPU_glsl_support() @@ -102,10 +164,8 @@ int GPU_non_power_of_two_support() { /* Exception for buggy ATI/Apple driver in Mac OS X 10.5/10.6, * they claim to support this but can cause system freeze */ -#ifdef __APPLE__ - if(strcmp((char*)glGetString(GL_VENDOR), "ATI Technologies Inc.") == 0) + if(GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_MAC, GPU_DRIVER_OFFICIAL)) return 0; -#endif return GLEW_ARB_texture_non_power_of_two; } diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 40de15ac012..66812efdf3f 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -485,6 +485,7 @@ extern UserDef U; /* from blenkernel blender.c */ #define USER_DRAW_TRIPLE 0 #define USER_DRAW_OVERLAP 1 #define USER_DRAW_FULL 2 +#define USER_DRAW_AUTOMATIC 3 /* tw_flag (transform widget) */ diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index d14dfd08d48..fc677d9d6f7 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -2167,6 +2167,7 @@ static void rna_def_userdef_system(BlenderRNA *brna) {0, NULL, 0, NULL, NULL}}; static 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_FULL, "FULL", 0, "Full", "Do a full redraw each time, slow, only use for reference or when all else fails."}, diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index 0d2f1043d0b..0bbd3757f27 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -689,6 +689,15 @@ void wm_draw_update(bContext *C) if(win->drawfail) wm_method_draw_overlap_all(C, win); + else if(win->drawmethod == USER_DRAW_AUTOMATIC) { + /* ATI opensource driver is known to be very slow at this, + Windows software driver darkens color on each redraw */ + if(GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE) || + GPU_type_matches(GPU_DEVICE_SOFTWARE, GPU_OS_WIN, GPU_DRIVER_SOFTWARE)) + wm_method_draw_overlap_all(C, win); + else + wm_method_draw_triple(C, win); + } else if(win->drawmethod == USER_DRAW_FULL) wm_method_draw_full(C, win); else if(win->drawmethod == USER_DRAW_OVERLAP) diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c index decf1f0d676..68f53a8367f 100644 --- a/source/blender/windowmanager/intern/wm_subwindow.c +++ b/source/blender/windowmanager/intern/wm_subwindow.c @@ -533,17 +533,3 @@ int WM_framebuffer_to_index(unsigned int col) /* ********** END MY WINDOW ************** */ -#if 0 // XXX not used... -#ifdef WIN32 -static int is_a_really_crappy_nvidia_card(void) { - static int well_is_it= -1; - - /* Do you understand the implication? Do you? */ - if (well_is_it==-1) - well_is_it= (strcmp((char*) glGetString(GL_VENDOR), "NVIDIA Corporation") == 0); - - return well_is_it; -} -#endif -#endif // XXX not used... - -- cgit v1.2.3