Remove program binary caching
This commit is contained in:
@@ -34,7 +34,6 @@
|
||||
},
|
||||
'sources': [
|
||||
'../platform/android/cache_database_data.cpp',
|
||||
'../platform/android/shader_cache_data.cpp',
|
||||
'../platform/android/log_android.cpp',
|
||||
'../platform/android/asset_request_libzip.cpp',
|
||||
'../platform/default/string_stdlib.cpp',
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
],
|
||||
'sources': [
|
||||
'../platform/ios/cache_database_library.mm',
|
||||
'../platform/ios/shader_cache_library.mm',
|
||||
'../platform/darwin/log_nslog.mm',
|
||||
'../platform/darwin/string_nsstring.mm',
|
||||
'../platform/darwin/http_request_baton_cocoa.mm',
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
},
|
||||
'sources': [
|
||||
'../platform/default/cache_database_tmp.cpp',
|
||||
'../platform/default/shader_cache_tmp.cpp',
|
||||
'../platform/default/log_stderr.cpp',
|
||||
'../platform/default/string_stdlib.cpp',
|
||||
'../platform/default/asset_request_libuv.cpp',
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
],
|
||||
'sources': [
|
||||
'../platform/osx/cache_database_application_support.mm',
|
||||
'../platform/osx/shader_cache_application_support.mm',
|
||||
'../platform/darwin/log_nslog.mm',
|
||||
'../platform/darwin/string_nsstring.mm',
|
||||
'../platform/darwin/http_request_baton_cocoa.mm',
|
||||
|
||||
@@ -152,18 +152,6 @@ extern bool isPackedDepthStencilSupported;
|
||||
extern bool isDepth24Supported;
|
||||
#define GL_DEPTH_COMPONENT24 0x81A6
|
||||
|
||||
// GL_ARB_get_program_binary / GL_OES_get_program_binary
|
||||
#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257
|
||||
#define GL_PROGRAM_BINARY_LENGTH 0x8741
|
||||
#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
|
||||
#define GL_PROGRAM_BINARY_FORMATS 0x87FF
|
||||
typedef void (* PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary);
|
||||
typedef void (* PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length);
|
||||
typedef void (* PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value);
|
||||
extern PFNGLGETPROGRAMBINARYPROC GetProgramBinary;
|
||||
extern PFNGLPROGRAMBINARYPROC ProgramBinary;
|
||||
extern PFNGLPROGRAMPARAMETERIPROC ProgramParameteri;
|
||||
|
||||
// Debug group markers, useful for debugging on iOS
|
||||
#if defined(DEBUG)
|
||||
// static int indent = 0;
|
||||
|
||||
@@ -20,9 +20,6 @@ std::string lowercase(const std::string &string);
|
||||
// Returns the path to the default cache database on this system.
|
||||
std::string defaultCacheDatabase();
|
||||
|
||||
// Returns the path to the default shader cache on this system.
|
||||
std::string defaultShaderCache();
|
||||
|
||||
std::string applicationRoot();
|
||||
|
||||
// Shows an alpha image with the specified dimensions in a named window.
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
#include <mbgl/android/jni.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
// Returns the path to the default shader cache on this system.
|
||||
std::string defaultShaderCache() {
|
||||
return mbgl::android::cachePath + "/mbgl-shader-cache-";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -149,19 +149,6 @@ void GLFWView::initialize(mbgl::Map *map_) {
|
||||
assert(gl::IsVertexArray != nullptr);
|
||||
}
|
||||
|
||||
if (extensions.find("GL_ARB_get_program_binary") != std::string::npos) {
|
||||
GLint numBinaryFormats;
|
||||
MBGL_CHECK_ERROR(glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &numBinaryFormats));
|
||||
if (numBinaryFormats > 0) {
|
||||
gl::GetProgramBinary = reinterpret_cast<gl::PFNGLGETPROGRAMBINARYPROC>(glfwGetProcAddress("glGetProgramBinary"));
|
||||
gl::ProgramBinary = reinterpret_cast<gl::PFNGLPROGRAMBINARYPROC>(glfwGetProcAddress("glProgramBinary"));
|
||||
gl::ProgramParameteri = reinterpret_cast<gl::PFNGLPROGRAMPARAMETERIPROC>(glfwGetProcAddress("glProgramParameteri"));
|
||||
assert(gl::GetProgramBinary != nullptr);
|
||||
assert(gl::ProgramBinary != nullptr);
|
||||
assert(gl::ProgramParameteri != nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
// Require packed depth stencil
|
||||
gl::isPackedDepthStencilSupported = true;
|
||||
gl::isDepth24Supported = true;
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
// Returns the path to the default shader cache on this system.
|
||||
std::string defaultShaderCache() {
|
||||
return "/tmp/mbgl-shader-cache-";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
// Returns the path to the default shader cache on this system.
|
||||
std::string defaultShaderCache() {
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
|
||||
if ([paths count] == 0) {
|
||||
// Disable the cache if we don't have a location to write.
|
||||
return "";
|
||||
}
|
||||
|
||||
NSString *libraryDirectory = [paths objectAtIndex:0];
|
||||
return [[libraryDirectory stringByAppendingPathComponent:@"shader-cache-"] UTF8String];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
// Returns the path to the default shader cache on this system.
|
||||
std::string defaultShaderCache() {
|
||||
NSArray *paths =
|
||||
NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
|
||||
if ([paths count] == 0) {
|
||||
// Disable the cache if we don't have a location to write.
|
||||
return "";
|
||||
}
|
||||
|
||||
NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Mapbox GL"];
|
||||
|
||||
if (![[NSFileManager defaultManager] createDirectoryAtPath:path
|
||||
withIntermediateDirectories:YES
|
||||
attributes:nil
|
||||
error:nil]) {
|
||||
// Disable the cache if we couldn't create the directory.
|
||||
return "";
|
||||
}
|
||||
|
||||
return [[path stringByAppendingPathComponent:@"shader-cache-"] UTF8String];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -74,10 +74,6 @@ bool isPackedDepthStencilSupported = false;
|
||||
|
||||
bool isDepth24Supported = false;
|
||||
|
||||
PFNGLGETPROGRAMBINARYPROC GetProgramBinary = nullptr;
|
||||
PFNGLPROGRAMBINARYPROC ProgramBinary = nullptr;
|
||||
PFNGLPROGRAMPARAMETERIPROC ProgramParameteri = nullptr;
|
||||
|
||||
void checkError(const char *cmd, const char *file, int line) {
|
||||
const GLenum err = glGetError();
|
||||
if (err != GL_NO_ERROR) {
|
||||
|
||||
@@ -20,112 +20,51 @@ Shader::Shader(const char *name_, const GLchar *vertSource, const GLchar *fragSo
|
||||
|
||||
program = MBGL_CHECK_ERROR(glCreateProgram());
|
||||
|
||||
if (!mbgl::platform::defaultShaderCache().empty()) {
|
||||
binaryFileName = mbgl::platform::defaultShaderCache() + name + ".bin";
|
||||
}
|
||||
|
||||
// Load binary shader if it exists
|
||||
bool skipCompile = false;
|
||||
if (!binaryFileName.empty() && (gl::ProgramBinary != nullptr)) {
|
||||
try {
|
||||
std::ifstream binaryFile(binaryFileName, std::ios::in | std::ios::binary);
|
||||
binaryFile.exceptions(std::ifstream::failbit | std::ifstream::badbit | std::ifstream::eofbit);
|
||||
|
||||
GLsizei binaryLength;
|
||||
GLenum binaryFormat;
|
||||
binaryFile.read(reinterpret_cast<char *>(&binaryLength), sizeof(binaryLength));
|
||||
binaryFile.read(reinterpret_cast<char *>(&binaryFormat), sizeof(binaryFormat));
|
||||
|
||||
GLint numBinaryFormats;
|
||||
MBGL_CHECK_ERROR(glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &numBinaryFormats));
|
||||
|
||||
std::unique_ptr<GLenum[]> validBinaryFormats = mbgl::util::make_unique<GLenum[]>(numBinaryFormats);
|
||||
MBGL_CHECK_ERROR(glGetIntegerv(GL_PROGRAM_BINARY_FORMATS, reinterpret_cast<GLint *>(validBinaryFormats.get())));
|
||||
|
||||
bool validBinaryFormat = false;
|
||||
for (GLint i = 0; i < numBinaryFormats; i++) {
|
||||
if (validBinaryFormats[i] == binaryFormat) {
|
||||
validBinaryFormat = true;
|
||||
}
|
||||
}
|
||||
if (!validBinaryFormat) {
|
||||
throw std::runtime_error("Trying load program binary with an invalid binaryFormat!");
|
||||
}
|
||||
|
||||
if (binaryLength == 0) {
|
||||
throw std::runtime_error("Trying load program binary with a zero length binary!");
|
||||
}
|
||||
|
||||
std::unique_ptr<char[]> binary = mbgl::util::make_unique<char[]>(binaryLength);
|
||||
binaryFile.read(binary.get(), binaryLength);
|
||||
|
||||
MBGL_CHECK_ERROR(gl::ProgramBinary(program, binaryFormat, binary.get(), binaryLength));
|
||||
|
||||
// Check if the binary was valid
|
||||
GLint status;
|
||||
MBGL_CHECK_ERROR(glGetProgramiv(program, GL_LINK_STATUS, &status));
|
||||
if (status == GL_TRUE) {
|
||||
skipCompile = true;
|
||||
}
|
||||
} catch(const std::exception& e) {
|
||||
Log::Error(Event::Shader, "Loading binary shader failed!");
|
||||
|
||||
// Delete the bad file
|
||||
std::remove(binaryFileName.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
GLuint vertShader = 0;
|
||||
GLuint fragShader = 0;
|
||||
if (!skipCompile) {
|
||||
if (!compileShader(&vertShader, GL_VERTEX_SHADER, vertSource)) {
|
||||
Log::Error(Event::Shader, "Vertex shader %s failed to compile: %s", name, vertSource);
|
||||
MBGL_CHECK_ERROR(glDeleteProgram(program));
|
||||
program = 0;
|
||||
return;
|
||||
}
|
||||
if (!compileShader(&vertShader, GL_VERTEX_SHADER, vertSource)) {
|
||||
Log::Error(Event::Shader, "Vertex shader %s failed to compile: %s", name, vertSource);
|
||||
MBGL_CHECK_ERROR(glDeleteProgram(program));
|
||||
program = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!compileShader(&fragShader, GL_FRAGMENT_SHADER, fragSource)) {
|
||||
Log::Error(Event::Shader, "Fragment shader %s failed to compile: %s", name, fragSource);
|
||||
MBGL_CHECK_ERROR(glDeleteShader(vertShader));
|
||||
vertShader = 0;
|
||||
MBGL_CHECK_ERROR(glDeleteProgram(program));
|
||||
program = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Attach shaders
|
||||
MBGL_CHECK_ERROR(glAttachShader(program, vertShader));
|
||||
MBGL_CHECK_ERROR(glAttachShader(program, fragShader));
|
||||
|
||||
{
|
||||
// Link program
|
||||
GLint status;
|
||||
MBGL_CHECK_ERROR(glLinkProgram(program));
|
||||
|
||||
MBGL_CHECK_ERROR(glGetProgramiv(program, GL_LINK_STATUS, &status));
|
||||
if (status == 0) {
|
||||
GLint logLength;
|
||||
MBGL_CHECK_ERROR(glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength));
|
||||
if (logLength > 0) {
|
||||
std::unique_ptr<GLchar[]> log = mbgl::util::make_unique<GLchar[]>(logLength);
|
||||
MBGL_CHECK_ERROR(glGetProgramInfoLog(program, logLength, &logLength, log.get()));
|
||||
Log::Error(Event::Shader, "Program failed to link: %s", log.get());
|
||||
}
|
||||
|
||||
if (!compileShader(&fragShader, GL_FRAGMENT_SHADER, fragSource)) {
|
||||
Log::Error(Event::Shader, "Fragment shader %s failed to compile: %s", name, fragSource);
|
||||
MBGL_CHECK_ERROR(glDeleteShader(vertShader));
|
||||
vertShader = 0;
|
||||
MBGL_CHECK_ERROR(glDeleteShader(fragShader));
|
||||
fragShader = 0;
|
||||
MBGL_CHECK_ERROR(glDeleteProgram(program));
|
||||
program = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Attach shaders
|
||||
MBGL_CHECK_ERROR(glAttachShader(program, vertShader));
|
||||
MBGL_CHECK_ERROR(glAttachShader(program, fragShader));
|
||||
|
||||
{
|
||||
if (!binaryFileName.empty() && (gl::ProgramParameteri != nullptr)) {
|
||||
MBGL_CHECK_ERROR(gl::ProgramParameteri(program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE));
|
||||
}
|
||||
|
||||
// Link program
|
||||
GLint status;
|
||||
MBGL_CHECK_ERROR(glLinkProgram(program));
|
||||
|
||||
MBGL_CHECK_ERROR(glGetProgramiv(program, GL_LINK_STATUS, &status));
|
||||
if (status == 0) {
|
||||
GLint logLength;
|
||||
MBGL_CHECK_ERROR(glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength));
|
||||
if (logLength > 0) {
|
||||
std::unique_ptr<GLchar[]> log = mbgl::util::make_unique<GLchar[]>(logLength);
|
||||
MBGL_CHECK_ERROR(glGetProgramInfoLog(program, logLength, &logLength, log.get()));
|
||||
Log::Error(Event::Shader, "Program failed to link: %s", log.get());
|
||||
}
|
||||
|
||||
MBGL_CHECK_ERROR(glDeleteShader(vertShader));
|
||||
vertShader = 0;
|
||||
MBGL_CHECK_ERROR(glDeleteShader(fragShader));
|
||||
fragShader = 0;
|
||||
MBGL_CHECK_ERROR(glDeleteProgram(program));
|
||||
program = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
@@ -152,13 +91,11 @@ Shader::Shader(const char *name_, const GLchar *vertSource, const GLchar *fragSo
|
||||
}
|
||||
}
|
||||
|
||||
if (!skipCompile) {
|
||||
// Remove the compiled shaders; they are now part of the program.
|
||||
MBGL_CHECK_ERROR(glDetachShader(program, vertShader));
|
||||
MBGL_CHECK_ERROR(glDeleteShader(vertShader));
|
||||
MBGL_CHECK_ERROR(glDetachShader(program, fragShader));
|
||||
MBGL_CHECK_ERROR(glDeleteShader(fragShader));
|
||||
}
|
||||
// Remove the compiled shaders; they are now part of the program.
|
||||
MBGL_CHECK_ERROR(glDetachShader(program, vertShader));
|
||||
MBGL_CHECK_ERROR(glDeleteShader(vertShader));
|
||||
MBGL_CHECK_ERROR(glDetachShader(program, fragShader));
|
||||
MBGL_CHECK_ERROR(glDeleteShader(fragShader));
|
||||
|
||||
valid = true;
|
||||
}
|
||||
@@ -201,35 +138,6 @@ bool Shader::compileShader(GLuint *shader, GLenum type, const GLchar *source) {
|
||||
}
|
||||
|
||||
Shader::~Shader() {
|
||||
if (!binaryFileName.empty() && (gl::GetProgramBinary != nullptr)) {
|
||||
// Retrieve the program binary
|
||||
GLsizei binaryLength;
|
||||
GLenum binaryFormat;
|
||||
MBGL_CHECK_ERROR(glGetProgramiv(program, GL_PROGRAM_BINARY_LENGTH, &binaryLength));
|
||||
if (binaryLength > 0) {
|
||||
std::unique_ptr<char[]> binary = mbgl::util::make_unique<char[]>(binaryLength);
|
||||
MBGL_CHECK_ERROR(gl::GetProgramBinary(program, binaryLength, nullptr, &binaryFormat, binary.get()));
|
||||
|
||||
Log::Error(Event::OpenGL, "glGetProgramBinary(%u, %u, nullptr, %u, %u)", program, binaryLength, binaryFormat, binary.get());
|
||||
|
||||
try {
|
||||
// Write the binary to a file
|
||||
std::ofstream binaryFile(binaryFileName, std::ios::out | std::ios::trunc | std::ios::binary);
|
||||
binaryFile.exceptions(std::ofstream::failbit | std::ofstream::badbit | std::ofstream::eofbit);
|
||||
|
||||
binaryFile.write(reinterpret_cast<char *>(&binaryLength), sizeof(binaryLength));
|
||||
binaryFile.write(reinterpret_cast<char *>(&binaryFormat), sizeof(binaryFormat));
|
||||
binaryFile.write(binary.get(), binaryLength);
|
||||
|
||||
} catch(const std::exception& e) {
|
||||
Log::Error(Event::Shader, "Saving binary shader failed!");
|
||||
|
||||
// Delete the bad file
|
||||
std::remove(binaryFileName.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (program) {
|
||||
MBGL_CHECK_ERROR(glDeleteProgram(program));
|
||||
program = 0;
|
||||
|
||||
@@ -22,8 +22,6 @@ public:
|
||||
|
||||
private:
|
||||
bool compileShader(uint32_t *shader, uint32_t type, const char *source);
|
||||
|
||||
std::string binaryFileName;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user