OSDN Git Service

Pre-built shader program support (v4)
authorDongwon Kim <dongwon.kim@intel.com>
Wed, 28 Mar 2018 21:32:11 +0000 (14:32 -0700)
committerKalyan Kondapally <kalyan.kondapally@intel.com>
Sun, 22 Apr 2018 19:02:49 +0000 (12:02 -0700)
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_<number of layers>.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 <dongwon.kim@intel.com>
common/Android.mk
common/Makefile.am
common/compositor/gl/glprogram.cpp
common/compositor/gl/shim.cpp
common/compositor/gl/shim.h

index 4e9fc93..30bef8f 100644 (file)
@@ -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 \
index 53c7f9f..7ba5a2b 100644 (file)
@@ -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
 
index d863633..e72fda0 100644 (file)
@@ -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) {
index eb10d95..25c725a 100644 (file)
@@ -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
index 98f2648..e438ed1 100644 (file)
@@ -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