Remove program binary caching

This commit is contained in:
Leith Bade
2015-01-27 12:34:55 +11:00
parent a8f86d47f6
commit aaedd9c83b
14 changed files with 41 additions and 248 deletions

View File

@@ -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',

View File

@@ -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',

View File

@@ -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',

View File

@@ -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',

View File

@@ -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;

View File

@@ -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.

View File

@@ -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-";
}
}
}

View File

@@ -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;

View File

@@ -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-";
}
}
}

View File

@@ -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];
}
}
}

View File

@@ -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];
}
}
}

View File

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

View File

@@ -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;

View File

@@ -22,8 +22,6 @@ public:
private:
bool compileShader(uint32_t *shader, uint32_t type, const char *source);
std::string binaryFileName;
};
}