From 45e33565111172bde3b00f51806824e1dda2ea7c Mon Sep 17 00:00:00 2001 From: Dongwon Kim Date: Wed, 28 Mar 2018 14:32:11 -0700 Subject: [PATCH] Pre-built shader program support (v4) gl-program now tries to use pre-built shader program if available to save time by skipping run-time build. pre-built shader file name accepted by the program is, 'hwc_shader_prog_.shader_test.bin' And these files are expected to be located at '/vendor/etc/' v2: 1. using get_proc to map glProgramBinaryOES 2. null checking on binary_prog 3. making sure freeing binary_prog only once v3: 1. removed extension check on GL_MESA_program_binary_formats since it's not exposed now in MESA driver 2. define PREBUILT_SHADER_FILE_PATH in the build script v4: 1. file loading is tried only if LOAD_PREBUILT_SHADER_FILE is defined 2. adjusted code formats using clang-format 3. use goto instead of having multi-level nested if-else 4. limit the size of shader program binary file to 10MB Jira: None. Test: Linux tests continue to work as now. Signed-off-by: Dongwon Kim --- common/Android.mk | 3 +- common/Makefile.am | 5 +- common/compositor/gl/glprogram.cpp | 98 ++++++++++++++++++++++++++++++++++---- common/compositor/gl/shim.cpp | 2 + common/compositor/gl/shim.h | 1 + 5 files changed, 98 insertions(+), 11 deletions(-) diff --git a/common/Android.mk b/common/Android.mk index 4e9fc93..30bef8f 100644 --- a/common/Android.mk +++ b/common/Android.mk @@ -142,7 +142,8 @@ LOCAL_SRC_FILES += \ compositor/vk/vkshim.cpp else LOCAL_CPPFLAGS += \ - -DUSE_GL + -DUSE_GL \ + -DPREBUILT_SHADER_FILE_PATH='"/vendor/etc"' LOCAL_SRC_FILES += \ compositor/gl/glprogram.cpp \ diff --git a/common/Makefile.am b/common/Makefile.am index 53c7f9f..7ba5a2b 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -50,7 +50,10 @@ libhwcomposer_common_la_LIBADD += -lvulkan else libhwcomposer_common_la_SOURCES += $(gl_SOURCES) AM_CPP_INCLUDES += -Icompositor/gl -AM_CPPFLAGS += -DUSE_GL +AM_CPPFLAGS += \ + -DUSE_GL \ + -DPREBUILT_SHADER_FILE_PATH='"${prefix}/etc"' + libhwcomposer_common_la_LIBADD += $(GLES2_LIBS) endif diff --git a/common/compositor/gl/glprogram.cpp b/common/compositor/gl/glprogram.cpp index d863633..e72fda0 100644 --- a/common/compositor/gl/glprogram.cpp +++ b/common/compositor/gl/glprogram.cpp @@ -126,8 +126,97 @@ static std::string GenerateFragmentShader(int layer_count) { return fragment_shader_stream.str(); } +static GLint LoadPreBuiltBinary(GLint gl_program, void *binary, long size) { + GLint status; + + /* check if glProgramBinaryOES exists */ + if (!glProgramBinaryOES) + return 0; + + /* currently GL_MESA_program_binary_formats is not exposed by MESA drv + * TODO: will enable this once this is fixed in MESA + */ + + glProgramBinaryOES(gl_program, GL_PROGRAM_BINARY_FORMAT_MESA, binary, size); + + glGetProgramiv(gl_program, GL_LINK_STATUS, &status); + if (status) + return gl_program; + + return 0; +} + static GLint GenerateProgram(unsigned num_textures, std::ostringstream *shader_log) { + GLint status; + GLint program = glCreateProgram(); + void *binary_prog; + long binary_sz; + + if (!program) { + if (shader_log) + *shader_log << "Failed to create program." + << "\n"; + return 0; + } + +#ifdef LOAD_PREBUILT_SHADER_FILE + +/* 10MB limit on shader binary file size */ +#define FILE_SIZE_LIMIT 10485760 + + /* try to load prebuilt shader program from files */ + std::ostringstream shader_program_fname; + shader_program_fname << PREBUILT_SHADER_FILE_PATH "/hwc_shader_prog_" + << num_textures << ".shader_test.bin"; + + FILE *shader_prog_fp; + + shader_prog_fp = fopen(shader_program_fname.str().c_str(), "rb"); + + if (!shader_prog_fp) + goto fail_file_open; + + /* check the size of file */ + fseek(shader_prog_fp, 0, SEEK_END); + binary_sz = ftell(shader_prog_fp); + rewind(shader_prog_fp); + + if (binary_sz > FILE_SIZE_LIMIT) + goto fail_fsize_too_big; + + binary_prog = (void *)malloc(binary_sz); + + if (!binary_prog) + goto fail_buf_creation; + + if (fread(binary_prog, 1, binary_sz, shader_prog_fp) != binary_sz) + goto fail_bin_read; + + status = LoadPreBuiltBinary(program, binary_prog, binary_sz); + if (status) { + if (shader_log) + *shader_log << "Pre-built shader program binary has been loaded " + << "Successfully (from files)\n"; + + free(binary_prog); + fclose(shader_prog_fp); + return program; + } + +fail_bin_read: + free(binary_prog); + +fail_fsize_too_big: +fail_buf_creation: + fclose(shader_prog_fp); + +fail_file_open: + if (shader_log) + *shader_log << "Failed to load pre-built shader program.\n" + << "now trying run-time build\n"; +#endif + std::string vertex_shader_string = GenerateVertexShader(num_textures); const GLchar *vertex_shader_source = vertex_shader_string.c_str(); GLint vertex_shader = CompileAndCheckShader( @@ -144,14 +233,6 @@ static GLint GenerateProgram(unsigned num_textures, return 0; } - GLint program = glCreateProgram(); - if (!program) { - if (shader_log) - *shader_log << "Failed to create program." - << "\n"; - return 0; - } - glAttachShader(program, vertex_shader); glAttachShader(program, fragment_shader); glBindAttribLocation(program, 0, "vPosition"); @@ -162,7 +243,6 @@ static GLint GenerateProgram(unsigned num_textures, glDeleteShader(vertex_shader); glDeleteShader(fragment_shader); - GLint status; glGetProgramiv(program, GL_LINK_STATUS, &status); if (!status) { diff --git a/common/compositor/gl/shim.cpp b/common/compositor/gl/shim.cpp index eb10d95..25c725a 100644 --- a/common/compositor/gl/shim.cpp +++ b/common/compositor/gl/shim.cpp @@ -41,6 +41,7 @@ bool InitializeShims() { get_proc(glDeleteVertexArraysOES, PFNGLDELETEVERTEXARRAYSOESPROC); get_proc(glGenVertexArraysOES, PFNGLGENVERTEXARRAYSOESPROC); get_proc(glBindVertexArrayOES, PFNGLBINDVERTEXARRAYOESPROC); + get_proc(glProgramBinaryOES, PFNGLPROGRAMBINARYOESPROC); #ifndef USE_ANDROID_SHIM get_proc(eglDupNativeFenceFDANDROID, PFNEGLDUPNATIVEFENCEFDANDROIDPROC); #endif @@ -59,6 +60,7 @@ PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES; PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArraysOES; PFNGLGENVERTEXARRAYSOESPROC glGenVertexArraysOES; PFNGLBINDVERTEXARRAYOESPROC glBindVertexArrayOES; +PFNGLPROGRAMBINARYOESPROC glProgramBinaryOES; #ifndef USE_ANDROID_SHIM PFNEGLDUPNATIVEFENCEFDANDROIDPROC eglDupNativeFenceFDANDROID; #endif diff --git a/common/compositor/gl/shim.h b/common/compositor/gl/shim.h index 98f2648..e438ed1 100644 --- a/common/compositor/gl/shim.h +++ b/common/compositor/gl/shim.h @@ -41,6 +41,7 @@ extern PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES; extern PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArraysOES; extern PFNGLGENVERTEXARRAYSOESPROC glGenVertexArraysOES; extern PFNGLBINDVERTEXARRAYOESPROC glBindVertexArrayOES; +extern PFNGLPROGRAMBINARYOESPROC glProgramBinaryOES; #ifndef USE_ANDROID_SHIM extern PFNEGLDUPNATIVEFENCEFDANDROIDPROC eglDupNativeFenceFDANDROID; #endif -- 2.11.0