Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
Add failsafe to program binary loading
Browse files Browse the repository at this point in the history
  • Loading branch information
Leith Bade committed Jan 4, 2015
1 parent ff6492e commit 8eceb08
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 14 deletions.
4 changes: 4 additions & 0 deletions android/cpp/native_map_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,7 @@ void NativeMapView::loadExtensions() {
}

if (extensions.find("GL_OES_get_program_binary") != std::string::npos) {
mbgl::Log::Info(mbgl::Event::OpenGL, "Using GL_OES_get_program_binary.");
GLint numBinaryFormats;
MBGL_CHECK_ERROR(glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &numBinaryFormats));
if (numBinaryFormats > 0) {
Expand All @@ -638,6 +639,7 @@ void NativeMapView::loadExtensions() {
}

if (extensions.find("GL_KHR_debug") != std::string::npos) {
mbgl::Log::Info(mbgl::Event::OpenGL, "Using GL_KHR_debug.");
gl::DebugMessageControl = reinterpret_cast<gl::PFNGLDEBUGMESSAGECONTROLPROC>(
eglGetProcAddress("glDebugMessageControl"));
gl::DebugMessageInsert = reinterpret_cast<gl::PFNGLDEBUGMESSAGEINSERTPROC>(
Expand Down Expand Up @@ -673,6 +675,7 @@ void NativeMapView::loadExtensions() {
assert(gl::GetObjectPtrLabel != nullptr);
} else {
if (extensions.find("GL_EXT_debug_marker") != std::string::npos) {
mbgl::Log::Info(mbgl::Event::OpenGL, "Using GL_EXT_debug_marker.");
gl::InsertEventMarkerEXT = reinterpret_cast<gl::PFNGLINSERTEVENTMARKEREXTPROC>(
eglGetProcAddress("glInsertEventMarkerEXT"));
gl::PushGroupMarkerEXT = reinterpret_cast<gl::PFNGLPUSHGROUPMARKEREXTPROC>(
Expand All @@ -685,6 +688,7 @@ void NativeMapView::loadExtensions() {
}

if (extensions.find("GL_EXT_debug_label") != std::string::npos) {
mbgl::Log::Info(mbgl::Event::OpenGL, "Using GL_EXT_debug_label.");
gl::LabelObjectEXT = reinterpret_cast<gl::PFNGLLABELOBJECTEXTPROC>(
eglGetProcAddress("glLabelObjectEXT"));
gl::GetObjectLabelEXT = reinterpret_cast<gl::PFNGLGETOBJECTLABELEXTPROC>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ public void onSaveInstanceState(Bundle outState) {
outState.putBoolean(STATE_DEBUG_ACTIVE, isDebugActive());
outState.putString(STATE_STYLE_URL, getStyleUrl());
outState.putString(STATE_ACCESS_TOKEN, getAccessToken());
outState.putStringArrayList(STATE_APPLIED_CLASSES, new ArrayList<String>(getAppliedStyleClasses()));
//outState.putStringArrayList(STATE_APPLIED_CLASSES, new ArrayList<String>(getAppliedStyleClasses()));
outState.putLong(STATE_DEFAULT_TRANSITION_DURATION, mNativeMapView.getDefaultTransitionDuration());
}

Expand Down
5 changes: 2 additions & 3 deletions src/mbgl/map/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -602,8 +602,7 @@ void Map::setAppliedClasses(const std::vector<std::string> &classes) {
if (style->hasTransitions()) {
update();
}
}
else {
} else {
std::lock_guard<std::mutex> lock(appliedClassesMutex);
appliedClasses = mbgl::util::make_unique<std::vector<std::string>>(classes);
}
Expand All @@ -618,7 +617,7 @@ void Map::toggleClass(const std::string &name) {
}

const std::vector<std::string> &Map::getAppliedClasses() const {
return style->getAppliedClasses();
return style->getAppliedClasses();
}

void Map::setDefaultTransitionDuration(uint64_t milliseconds) {
Expand Down
53 changes: 43 additions & 10 deletions src/mbgl/shader/shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <cassert>
#include <iostream>
#include <fstream>
#include <cstdio>

using namespace mbgl;

Expand All @@ -33,17 +34,47 @@ Shader::Shader(const char *name_, const GLchar *vertSource, const GLchar *fragSo
binaryFile.read(reinterpret_cast<char *>(&binaryLength), sizeof(binaryLength));
binaryFile.read(reinterpret_cast<char *>(&binaryFormat), sizeof(binaryFormat));

std::unique_ptr<char[]> binary = mbgl::util::make_unique<char[]>(binaryLength);
binaryFile.read(binary.get(), binaryLength);
binaryFile.close();

MBGL_CHECK_ERROR(gl::ProgramBinary(program, binaryFormat, binary.get(), binaryLength));
GLint numBinaryFormats;
MBGL_CHECK_ERROR(glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &numBinaryFormats));

// Check if the binary was valid
GLint status;
MBGL_CHECK_ERROR(glGetProgramiv(program, GL_LINK_STATUS, &status));
if (status == GL_TRUE) {
skipCompile = true;
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) {
Log::Error(Event::OpenGL, "Trying load program binary with an invalid binaryFormat!");
}

if (binaryLength == 0) {
Log::Error(Event::OpenGL, "Trying load program binary with a zero length binary!");
}

if (validBinaryFormat && (binaryLength != 0)) {

std::unique_ptr<char[]> binary = mbgl::util::make_unique<char[]>(binaryLength);
binaryFile.read(binary.get(), binaryLength);
binaryFile.close();

Log::Error(Event::OpenGL, "glProgramBinary(%u, %u, %u, %u)", program, binaryFormat, 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;
}
} else {
binaryFile.close();

// Delete the bad file
std::remove(binaryFileName.c_str());
}
}

Expand Down Expand Up @@ -180,7 +211,9 @@ Shader::~Shader() {
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, NULL, &binaryFormat, binary.get()));
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());

// Write the binary to a file
std::ofstream binaryFile(binaryFileName, std::ios::out | std::ios::trunc | std::ios::binary);
Expand Down

0 comments on commit 8eceb08

Please sign in to comment.