WM Draw Methods now has a new option Automatic (default). This will
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Sun, 31 Jan 2010 23:45:51 +0000 (23:45 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Sun, 31 Jan 2010 23:45:51 +0000 (23:45 +0000)
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.

12 files changed:
release/scripts/ui/space_userpref.py
source/blender/blenkernel/BKE_blender.h
source/blender/editors/include/BIF_glutil.h
source/blender/editors/interface/resources.c
source/blender/editors/screen/glutil.c
source/blender/editors/space_node/node_draw.c
source/blender/gpu/GPU_extensions.h
source/blender/gpu/intern/gpu_extensions.c
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesrna/intern/rna_userdef.c
source/blender/windowmanager/intern/wm_draw.c
source/blender/windowmanager/intern/wm_subwindow.c

index e596c2b..97dd369 100644 (file)
@@ -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")
index 45df091..666ecf7 100644 (file)
@@ -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
index e394de6..53c725b 100644 (file)
@@ -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);
 
index 9468eb7..313b03f 100644 (file)
@@ -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) {
index 752c6fe..1ea0c2c 100644 (file)
@@ -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
 }
index 03bc834..27719f1 100644 (file)
@@ -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);
index c2af4e8..998c13d 100644 (file)
@@ -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
index a5a8c62..e93dd37 100644 (file)
@@ -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;
 }
index 40de15a..66812ef 100644 (file)
@@ -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) */
 
index d14dfd0..fc677d9 100644 (file)
@@ -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."},
index 0d2f104..0bbd375 100644 (file)
@@ -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)
index decf1f0..68f53a8 100644 (file)
@@ -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...
-