GPU: automatically draw images with GLSL shader depending on resolution
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Sat, 20 Apr 2019 10:47:06 +0000 (12:47 +0200)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Sat, 20 Apr 2019 11:32:36 +0000 (13:32 +0200)
This adds a new "Automatic" image display method which uses GLSL shaders for
most images. It only does CPU side color management for higher res images
where sending big float buffers to the GPU is likely to be a bottleneck or
cause memory usage problem.

Automatic is the default now, previously it was 2D Texture.

source/blender/blenkernel/BKE_blender_version.h
source/blender/blenloader/intern/versioning_userdef.c
source/blender/editors/include/BIF_glutil.h
source/blender/editors/render/render_internal.c
source/blender/editors/screen/glutil.c
source/blender/editors/space_sequencer/sequencer_draw.c
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesrna/intern/rna_userdef.c

index 0566ecf344424d19c95c6b294a2993f077e74f21..2433b856697c305eab87db485aa6b0a7562c6a74 100644 (file)
@@ -27,7 +27,7 @@
  * \note Use #STRINGIFY() rather than defining with quotes.
  */
 #define BLENDER_VERSION 280
-#define BLENDER_SUBVERSION 57
+#define BLENDER_SUBVERSION 58
 /** Several breakages with 280, e.g. collections vs layers. */
 #define BLENDER_MINVERSION 280
 #define BLENDER_MINSUBVERSION 0
index 65a19ca80c143f50c617906389b38b5ab5c0e00d..069b1907cceaeb4db06d6193f634ca1c072b5033 100644 (file)
@@ -491,6 +491,12 @@ void BLO_version_defaults_userpref_blend(Main *bmain, UserDef *userdef)
     userdef->move_threshold = 2;
   }
 
+  if (!USER_VERSION_ATLEAST(280, 58)) {
+    if (userdef->image_draw_method != IMAGE_DRAW_METHOD_GLSL) {
+      userdef->image_draw_method = IMAGE_DRAW_METHOD_AUTO;
+    }
+  }
+
   /**
    * Include next version bump.
    */
@@ -505,9 +511,6 @@ void BLO_version_defaults_userpref_blend(Main *bmain, UserDef *userdef)
   if (userdef->pixelsize == 0.0f)
     userdef->pixelsize = 1.0f;
 
-  if (userdef->image_draw_method == 0)
-    userdef->image_draw_method = IMAGE_DRAW_METHOD_2DTEXTURE;
-
   for (bTheme *btheme = userdef->themes.first; btheme; btheme = btheme->next) {
     do_versions_theme(userdef, btheme);
   }
index c30674907da9295c0fa129fdeecdfb2c035fdf00..c88277c2ea52ee896ce30112ec7fc066fe869104 100644 (file)
@@ -167,6 +167,8 @@ void ED_draw_imbuf_ctx_clipping(const struct bContext *C,
                                 float zoom_x,
                                 float zoom_y);
 
+int ED_draw_imbuf_method(struct ImBuf *ibuf);
+
 /* OpenGL drawing utility functions. Do not use these in new code, these
  * are intended to be moved or removed in the future. */
 
index 6df1ba5e0aa07d8068a50bee31a8cb531d9fba27..d9a68a060f831548860ce359b777fe6006421c6f 100644 (file)
@@ -72,6 +72,8 @@
 #include "ED_undo.h"
 #include "ED_view3d.h"
 
+#include "BIF_glutil.h"
+
 #include "RE_pipeline.h"
 #include "RE_engine.h"
 
@@ -607,7 +609,7 @@ static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrec
      * operate with.
      */
     if (rr->do_exr_tile || !rj->supports_glsl_draw || ibuf->channels == 1 ||
-        U.image_draw_method != IMAGE_DRAW_METHOD_GLSL) {
+        ED_draw_imbuf_method(ibuf) != IMAGE_DRAW_METHOD_GLSL) {
       image_buffer_rect_update(rj, rr, ibuf, &rj->iuser, renrect, viewname);
     }
 
index 868bc982c51497de01e4dec50b42b49f6eadcac7..c22d9d6625145fab66625f5a7ad333ffeb75db3d 100644 (file)
@@ -557,7 +557,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
   force_fallback |= ibuf->channels == 1;
 
   /* If user decided not to use GLSL, fallback to glaDrawPixelsAuto */
-  force_fallback |= (U.image_draw_method != IMAGE_DRAW_METHOD_GLSL);
+  force_fallback |= (ED_draw_imbuf_method(ibuf) != IMAGE_DRAW_METHOD_GLSL);
 
   /* Try to draw buffer using GLSL display transform */
   if (force_fallback == false) {
@@ -731,6 +731,22 @@ void ED_draw_imbuf_ctx(
   ED_draw_imbuf_ctx_clipping(C, ibuf, x, y, zoomfilter, 0.0f, 0.0f, 0.0f, 0.0f, zoom_x, zoom_y);
 }
 
+int ED_draw_imbuf_method(ImBuf *ibuf)
+{
+  if (U.image_draw_method == IMAGE_DRAW_METHOD_AUTO) {
+    /* Use faster GLSL when CPU to GPU transfer is unlikely to be a bottleneck,
+     * otherwise do color management on CPU side. */
+    const size_t threshold = 2048 * 2048 * 4 * sizeof(float);
+    const size_t data_size = (ibuf->rect_float) ? sizeof(float) : sizeof(uchar);
+    const size_t size = ibuf->x * ibuf->y * ibuf->channels * data_size;
+
+    return (size > threshold) ? IMAGE_DRAW_METHOD_2DTEXTURE : IMAGE_DRAW_METHOD_GLSL;
+  }
+  else {
+    return U.image_draw_method;
+  }
+}
+
 /* don't move to GPU_immediate_util.h because this uses user-prefs
  * and isn't very low level */
 void immDrawBorderCorners(unsigned int pos, const rcti *border, float zoomx, float zoomy)
index 5842d3b9c0d408e1aaa33686defee7f9e151f751..69fc9ef3e17a7108246bdd4e154f18d008c05907 100644 (file)
@@ -62,6 +62,8 @@
 #include "ED_screen.h"
 #include "ED_space_api.h"
 
+#include "BIF_glutil.h"
+
 #include "UI_interface.h"
 #include "UI_resources.h"
 #include "UI_view2d.h"
@@ -1226,7 +1228,7 @@ static void *sequencer_OCIO_transform_ibuf(
   void *cache_handle = NULL;
   bool force_fallback = false;
   *glsl_used = false;
-  force_fallback |= (U.image_draw_method != IMAGE_DRAW_METHOD_GLSL);
+  force_fallback |= (ED_draw_imbuf_method(ibuf) != IMAGE_DRAW_METHOD_GLSL);
   force_fallback |= (ibuf->dither != 0.0f);
 
   if (force_fallback) {
index c831c14eeaf21e086e0945ac5ae349295ff4de22..60ca9e097a8f67300eca4ba78faee51d588f686b 100644 (file)
@@ -1103,10 +1103,9 @@ typedef enum eMultiSample_Type {
 
 /** #UserDef.image_draw_method */
 typedef enum eImageDrawMethod {
-  /* IMAGE_DRAW_METHOD_AUTO = 0, */ /* Currently unused */
+  IMAGE_DRAW_METHOD_AUTO = 0,
   IMAGE_DRAW_METHOD_GLSL = 1,
   IMAGE_DRAW_METHOD_2DTEXTURE = 2,
-  IMAGE_DRAW_METHOD_DRAWPIXELS = 3,
 } eImageDrawMethod;
 
 /** #UserDef.virtual_pixel */
index d81ae82fbc5434ec7b0ce1917963b0be7aaed05f..488143da3162034693bda5f81c9ecfe7313f74df 100644 (file)
@@ -4580,6 +4580,11 @@ static void rna_def_userdef_system(BlenderRNA *brna)
   };
 
   static const EnumPropertyItem image_draw_methods[] = {
+      {IMAGE_DRAW_METHOD_AUTO,
+       "AUTO",
+       0,
+       "Automatic",
+       "Automatically choose method based on GPU and image"},
       {IMAGE_DRAW_METHOD_2DTEXTURE,
        "2DTEXTURE",
        0,
@@ -4590,12 +4595,6 @@ static void rna_def_userdef_system(BlenderRNA *brna)
        0,
        "GLSL",
        "Use GLSL shaders for display transform and draw image with 2D texture"},
-      {IMAGE_DRAW_METHOD_DRAWPIXELS,
-       "DRAWPIXELS",
-       0,
-       "DrawPixels",
-       "Use CPU for display transform and draw image using DrawPixels"},
-      {0, NULL, 0, NULL, NULL},
   };
 
   srna = RNA_def_struct(brna, "PreferencesSystem", NULL);