summaryrefslogtreecommitdiff
path: root/src/mbgl/gl/program.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/gl/program.hpp')
-rw-r--r--src/mbgl/gl/program.hpp61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/mbgl/gl/program.hpp b/src/mbgl/gl/program.hpp
index 7d7fca5263..1b23abe2b1 100644
--- a/src/mbgl/gl/program.hpp
+++ b/src/mbgl/gl/program.hpp
@@ -8,6 +8,12 @@
#include <mbgl/gl/attribute.hpp>
#include <mbgl/gl/uniform.hpp>
+#include <mbgl/util/io.hpp>
+#include <mbgl/programs/binary_program.hpp>
+#include <mbgl/programs/program_parameters.hpp>
+#include <mbgl/shaders/shaders.hpp>
+
+
#include <string>
namespace mbgl {
@@ -37,6 +43,61 @@ public:
attributeLocations(Attributes::loadNamedLocations(binaryProgram)),
uniformsState(Uniforms::loadNamedLocations(binaryProgram)) {
}
+
+ static Program createProgram(gl::Context& context,
+ const ProgramParameters& programParameters,
+ const char* name,
+ const char* vertexSource_,
+ const char* fragmentSource_) {
+#if MBGL_HAS_BINARY_PROGRAMS
+ if (!programParameters.cacheDir.empty() && context.supportsProgramBinaries()) {
+ const std::string vertexSource =
+ shaders::vertexSource(programParameters, vertexSource_);
+ const std::string fragmentSource =
+ shaders::fragmentSource(programParameters, fragmentSource_);
+ const std::string cachePath =
+ shaders::programCachePath(programParameters, name);
+ const std::string identifier =
+ shaders::programIdentifier(vertexSource, fragmentSource_);
+
+ try {
+ if (auto cachedBinaryProgram = util::readFile(cachePath)) {
+ const BinaryProgram binaryProgram(std::move(*cachedBinaryProgram));
+ if (binaryProgram.identifier() == identifier) {
+ return Program { context, binaryProgram };
+ } else {
+ Log::Warning(Event::OpenGL,
+ "Cached program %s changed. Recompilation required.",
+ name);
+ }
+ }
+ } catch (std::runtime_error& error) {
+ Log::Warning(Event::OpenGL, "Could not load cached program: %s",
+ error.what());
+ }
+
+ // Compile the shader
+ Program result{ context, vertexSource, fragmentSource };
+
+ try {
+ if (const auto binaryProgram =
+ result.template get<BinaryProgram>(context, identifier)) {
+ util::write_file(cachePath, binaryProgram->serialize());
+ Log::Warning(Event::OpenGL, "Caching program in: %s", cachePath.c_str());
+ }
+ } catch (std::runtime_error& error) {
+ Log::Warning(Event::OpenGL, "Failed to cache program: %s", error.what());
+ }
+
+ return std::move(result);
+ }
+#endif
+ (void)name;
+ return Program {
+ context, shaders::vertexSource(programParameters, vertexSource_),
+ shaders::fragmentSource(programParameters, fragmentSource_)
+ };
+ }
template <class BinaryProgram>
optional<BinaryProgram> get(Context& context, const std::string& identifier) const {