diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index ea95c925c..f78b8385c 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -250,6 +250,8 @@ void Map::run() { mode = Mode::None; fileSource.clearLoop(); } + + terminate(); } void Map::rerender() { @@ -258,8 +260,9 @@ void Map::rerender() { } else if (mode == Mode::Continuous) { // We only send render events if we want to continuously update the map // (== async rendering). - assert(asyncRender); - asyncRender->send(); + if (asyncRender) { + asyncRender->send(); + } } } @@ -279,7 +282,9 @@ void Map::swapped() { void Map::terminate() { assert(painter); + view.activate(); painter->terminate(); + view.deactivate(); } #pragma mark - Setup diff --git a/src/mbgl/shader/shader.cpp b/src/mbgl/shader/shader.cpp index 62edf1d38..32e10a640 100644 --- a/src/mbgl/shader/shader.cpp +++ b/src/mbgl/shader/shader.cpp @@ -26,26 +26,53 @@ Shader::Shader(const char *name_, const GLchar *vertSource, const GLchar *fragSo // Load binary shader if it exists bool skipCompile = false; if (!binaryFileName.empty() && (gl::ProgramBinary != nullptr)) { - std::ifstream binaryFile(binaryFileName, std::ios::in | std::ios::binary); + 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(&binaryLength), sizeof(binaryLength)); - binaryFile.read(reinterpret_cast(&binaryFormat), sizeof(binaryFormat)); + GLsizei binaryLength; + GLenum binaryFormat; + binaryFile.read(reinterpret_cast(&binaryLength), sizeof(binaryLength)); + binaryFile.read(reinterpret_cast(&binaryFormat), sizeof(binaryFormat)); - std::unique_ptr binary = mbgl::util::make_unique(binaryLength); - binaryFile.read(binary.get(), binaryLength); + GLint numBinaryFormats; + MBGL_CHECK_ERROR(glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &numBinaryFormats)); - MBGL_CHECK_ERROR(gl::ProgramBinary(program, binaryFormat, binary.get(), binaryLength)); + std::unique_ptr validBinaryFormats = mbgl::util::make_unique(numBinaryFormats); + MBGL_CHECK_ERROR(glGetIntegerv(GL_PROGRAM_BINARY_FORMATS, reinterpret_cast(validBinaryFormats.get()))); - // Check if the binary was valid - GLint status; - MBGL_CHECK_ERROR(glGetProgramiv(program, GL_LINK_STATUS, &status)); - if (status == GL_TRUE) { - skipCompile = true; + 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 binary = mbgl::util::make_unique(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(std::exception& e) { + Log::Error(Event::Shader, "Loading binary shader failed!"); + + // Delete the bad file + std::remove(binaryFileName.c_str()); } - - binaryFile.close(); } GLuint vertShader = 0; @@ -183,12 +210,21 @@ Shader::~Shader() { std::unique_ptr binary = mbgl::util::make_unique(binaryLength); MBGL_CHECK_ERROR(gl::GetProgramBinary(program, binaryLength, NULL, &binaryFormat, binary.get())); - // Write the binary to a file - std::ofstream binaryFile(binaryFileName, std::ios::out | std::ios::trunc | std::ios::binary); - binaryFile.write(reinterpret_cast(&binaryLength), sizeof(binaryLength)); - binaryFile.write(reinterpret_cast(&binaryFormat), sizeof(binaryFormat)); - binaryFile.write(binary.get(), binaryLength); - binaryFile.close(); + 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(&binaryLength), sizeof(binaryLength)); + binaryFile.write(reinterpret_cast(&binaryFormat), sizeof(binaryFormat)); + binaryFile.write(binary.get(), binaryLength); + + } catch(std::exception& e) { + Log::Error(Event::Shader, "Saving binary shader failed!"); + + // Delete the bad file + std::remove(binaryFileName.c_str()); + } } }