GPU: automatically draw images with GLSL shader depending on resolution

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.
This commit is contained in:
2019-04-20 12:47:06 +02:00
parent ed0c9654dd
commit 7cbb8f20a4
8 changed files with 38 additions and 15 deletions

View 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

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

View 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. */

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

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

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

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

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