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

Commit

Permalink
[core] Dynamic program compilation for data-driven properties
Browse files Browse the repository at this point in the history
  • Loading branch information
jfirebaugh committed Jun 6, 2017
1 parent 977b55d commit 8a341aa
Show file tree
Hide file tree
Showing 32 changed files with 292 additions and 214 deletions.
2 changes: 1 addition & 1 deletion include/mbgl/map/map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class Map : private util::noncopyable {
GLContextMode contextMode = GLContextMode::Unique,
ConstrainMode constrainMode = ConstrainMode::HeightOnly,
ViewportMode viewportMode = ViewportMode::Default,
const std::string& programCacheDir = "");
const optional<std::string>& programCacheDir = {});
~Map();

// Register a callback that will get called (on the render thread) when all resources have
Expand Down
8 changes: 4 additions & 4 deletions scripts/generate-shaders.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ ${fragmentPrelude}
const source = fs.readFileSync(path.join(inputPath, shaderName + '.vertex.glsl'), 'utf8');
return applyPragmas(source, {
define: `
#ifndef HAS_UNIFORM_{name}
#ifndef HAS_UNIFORM_u_{name}
uniform lowp float a_{name}_t;
attribute {precision} {a_type} a_{name};
varying {precision} {type} {name};
Expand All @@ -85,7 +85,7 @@ uniform {precision} {type} u_{name};
#endif
`,
initialize: `
#ifndef HAS_UNIFORM_{name}
#ifndef HAS_UNIFORM_u_{name}
{name} = unpack_mix_{a_type}(a_{name}, a_{name}_t);
#else
{precision} {type} {name} = u_{name};
Expand All @@ -97,14 +97,14 @@ uniform {precision} {type} u_{name};
const source = fs.readFileSync(path.join(inputPath, shaderName + '.fragment.glsl'), 'utf8');
return applyPragmas(source, {
define: `
#ifndef HAS_UNIFORM_{name}
#ifndef HAS_UNIFORM_u_{name}
varying {precision} {type} {name};
#else
uniform {precision} {type} u_{name};
#endif
`,
initialize: `
#ifdef HAS_UNIFORM_{name}
#ifdef HAS_UNIFORM_u_{name}
{precision} {type} {name} = u_{name};
#endif
`
Expand Down
11 changes: 5 additions & 6 deletions src/mbgl/gl/program.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,17 @@ class Program {
const char* vertexSource_,
const char* fragmentSource_) {
#if MBGL_HAS_BINARY_PROGRAMS
if (!programParameters.cacheDir.empty() && context.supportsProgramBinaries()) {
optional<std::string> cachePath = programParameters.cachePath(name);
if (cachePath && context.supportsProgramBinaries()) {
const std::string vertexSource =
shaders::vertexSource(programParameters, vertexSource_);
const std::string fragmentSource =
shaders::fragmentSource(programParameters, fragmentSource_);
const std::string identifier =
shaders::programIdentifier(vertexSource, fragmentSource_);

const std::string cachePath = programParameters.cachePath(name);

try {
if (auto cachedBinaryProgram = util::readFile(cachePath)) {
if (auto cachedBinaryProgram = util::readFile(*cachePath)) {
const BinaryProgram binaryProgram(std::move(*cachedBinaryProgram));
if (binaryProgram.identifier() == identifier) {
return Program { context, binaryProgram };
Expand All @@ -82,8 +81,8 @@ class Program {
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());
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());
Expand Down
8 changes: 4 additions & 4 deletions src/mbgl/map/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class Map::Impl : public style::Observer,
GLContextMode,
ConstrainMode,
ViewportMode,
std::string programCacheDir);
optional<std::string> programCacheDir);

void onSourceChanged(style::Source&) override;
void onUpdate(Update) override;
Expand All @@ -88,7 +88,7 @@ class Map::Impl : public style::Observer,
const MapMode mode;
const GLContextMode contextMode;
const float pixelRatio;
const std::string programCacheDir;
const optional<std::string> programCacheDir;

MapDebugOptions debugOptions { MapDebugOptions::NoDebug };

Expand Down Expand Up @@ -122,7 +122,7 @@ Map::Map(Backend& backend,
GLContextMode contextMode,
ConstrainMode constrainMode,
ViewportMode viewportMode,
const std::string& programCacheDir)
const optional<std::string>& programCacheDir)
: impl(std::make_unique<Impl>(*this,
backend,
pixelRatio,
Expand All @@ -145,7 +145,7 @@ Map::Impl::Impl(Map& map_,
GLContextMode contextMode_,
ConstrainMode constrainMode_,
ViewportMode viewportMode_,
std::string programCacheDir_)
optional<std::string> programCacheDir_)
: map(map_),
observer(backend_),
backend(backend_),
Expand Down
35 changes: 34 additions & 1 deletion src/mbgl/programs/program.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,21 @@
#include <mbgl/shaders/shaders.hpp>
#include <mbgl/util/io.hpp>

#include <unordered_map>

namespace mbgl {

template <class Shaders,
class Primitive,
class LayoutAttrs,
class Uniforms,
class PaintProperties>
class PaintProps>
class Program {
public:
using LayoutAttributes = LayoutAttrs;
using LayoutVertex = typename LayoutAttributes::Vertex;

using PaintProperties = PaintProps;
using PaintPropertyBinders = typename PaintProperties::Binders;
using PaintAttributes = typename PaintPropertyBinders::Attributes;
using Attributes = gl::ConcatenateAttributes<LayoutAttributes, PaintAttributes>;
Expand Down Expand Up @@ -71,4 +74,34 @@ class Program {
}
};

template <class Program>
class ProgramMap {
public:
using PaintProperties = typename Program::PaintProperties;
using PaintPropertyBinders = typename Program::PaintPropertyBinders;
using Bitset = typename PaintPropertyBinders::Bitset;

ProgramMap(gl::Context& context_, ProgramParameters parameters_)
: context(context_),
parameters(std::move(parameters_)) {
}

Program& get(const typename PaintProperties::PossiblyEvaluated& currentProperties) {
Bitset bits = PaintPropertyBinders::constants(currentProperties);
auto it = programs.find(bits);
if (it != programs.end()) {
return it->second;
}
return programs.emplace(std::piecewise_construct,
std::forward_as_tuple(bits),
std::forward_as_tuple(context,
parameters.withAdditionalDefines(PaintPropertyBinders::defines(currentProperties)))).first->second;
}

private:
gl::Context& context;
ProgramParameters parameters;
std::unordered_map<Bitset, Program> programs;
};

} // namespace mbgl
30 changes: 23 additions & 7 deletions src/mbgl/programs/program_parameters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace mbgl {

ProgramParameters::ProgramParameters(const float pixelRatio,
const bool overdraw,
std::string cacheDir_)
optional<std::string> cacheDir_)
: defines([&] {
std::ostringstream ss;
ss.imbue(std::locale("C"));
Expand All @@ -18,15 +18,31 @@ ProgramParameters::ProgramParameters(const float pixelRatio,
}
return ss.str();
}()),
hash(std::hash<std::string>()(defines)),
cacheDir(std::move(cacheDir_)) {
}

std::string ProgramParameters::cachePath(const char* name) const {
std::ostringstream ss;
ss << cacheDir << "/com.mapbox.gl.shader." << name << "." << std::setfill('0')
<< std::setw(sizeof(size_t) * 2) << std::hex << hash << ".pbf";
return ss.str();
const std::string& ProgramParameters::getDefines() const {
return defines;
}

optional<std::string> ProgramParameters::cachePath(const char* name) const {
if (!cacheDir) {
return {};
} else {
std::ostringstream ss;
ss << *cacheDir << "/com.mapbox.gl.shader." << name << "." << std::setfill('0')
<< std::setw(sizeof(size_t) * 2) << std::hex << std::hash<std::string>()(defines) << ".pbf";
return ss.str();
}
}

ProgramParameters ProgramParameters::withAdditionalDefines(const std::vector<std::string>& additionalDefines) const {
ProgramParameters result(*this);
for (const auto& define : additionalDefines) {
result.defines += define;
result.defines += "\n";
}
return result;
}

} // namespace mbgl
15 changes: 9 additions & 6 deletions src/mbgl/programs/program_parameters.hpp
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
#pragma once

#include <mbgl/util/optional.hpp>

#include <string>
#include <utility>
#include <vector>

namespace mbgl {

class ProgramParameters {
public:
ProgramParameters(float pixelRatio, bool overdraw, std::string cacheDir);
ProgramParameters(float pixelRatio, bool overdraw, optional<std::string> cacheDir);

const std::string defines;
const std::string& getDefines() const;
optional<std::string> cachePath(const char* name) const;

std::string cachePath(const char* name) const;
ProgramParameters withAdditionalDefines(const std::vector<std::string>& defines) const;

private:
const std::size_t hash;
const std::string cacheDir;
std::string defines;
optional<std::string> cacheDir;
};

} // namespace mbgl
26 changes: 13 additions & 13 deletions src/mbgl/programs/programs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,21 @@ class Programs {
collisionBox(context, programParameters) {
}

CircleProgram circle;
ProgramMap<CircleProgram> circle;
ExtrusionTextureProgram extrusionTexture;
FillProgram fill;
FillExtrusionProgram fillExtrusion;
FillExtrusionPatternProgram fillExtrusionPattern;
FillPatternProgram fillPattern;
FillOutlineProgram fillOutline;
FillOutlinePatternProgram fillOutlinePattern;
LineProgram line;
LineSDFProgram lineSDF;
LinePatternProgram linePattern;
ProgramMap<FillProgram> fill;
ProgramMap<FillExtrusionProgram> fillExtrusion;
ProgramMap<FillExtrusionPatternProgram> fillExtrusionPattern;
ProgramMap<FillPatternProgram> fillPattern;
ProgramMap<FillOutlineProgram> fillOutline;
ProgramMap<FillOutlinePatternProgram> fillOutlinePattern;
ProgramMap<LineProgram> line;
ProgramMap<LineSDFProgram> lineSDF;
ProgramMap<LinePatternProgram> linePattern;
RasterProgram raster;
SymbolIconProgram symbolIcon;
SymbolSDFIconProgram symbolIconSDF;
SymbolSDFTextProgram symbolGlyph;
ProgramMap<SymbolIconProgram> symbolIcon;
ProgramMap<SymbolSDFIconProgram> symbolIconSDF;
ProgramMap<SymbolSDFTextProgram> symbolGlyph;

DebugProgram debug;
CollisionBoxProgram collisionBox;
Expand Down
3 changes: 2 additions & 1 deletion src/mbgl/programs/symbol_program.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -323,14 +323,15 @@ template <class Shaders,
class Primitive,
class LayoutAttrs,
class Uniforms,
class PaintProperties>
class PaintProps>
class SymbolProgram {
public:
using LayoutAttributes = LayoutAttrs;
using LayoutVertex = typename LayoutAttributes::Vertex;

using LayoutAndSizeAttributes = gl::ConcatenateAttributes<LayoutAttributes, SymbolSizeAttributes>;

using PaintProperties = PaintProps;
using PaintPropertyBinders = typename PaintProperties::Binders;
using PaintAttributes = typename PaintPropertyBinders::Attributes;
using Attributes = gl::ConcatenateAttributes<LayoutAndSizeAttributes, PaintAttributes>;
Expand Down
Loading

0 comments on commit 8a341aa

Please sign in to comment.