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.
This commit is contained in:
Brecht Van Lommel 2010-01-31 23:45:51 +00:00
parent 873f2c7125
commit 87bbb2d827
12 changed files with 112 additions and 37 deletions

@ -467,7 +467,7 @@ class USERPREF_PT_system(bpy.types.Panel):
#Anti-aliasing is disabled as it breaks broder/lasso select
#col.prop(system, "use_antialiasing")
col.label(text="Window Draw Method:")
col.row().prop(system, "window_draw_method", expand=True)
col.prop(system, "window_draw_method", text="")
col.label(text="Textures:")
col.prop(system, "gl_texture_limit", text="Limit Size")
col.prop(system, "texture_time_out", text="Time Out")

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

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

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

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

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

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

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

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

@ -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."},

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

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