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

Dynamically compile shaders with uniforms instead of attributes for DDS #9185

Merged
merged 6 commits into from
Jun 13, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmake/core-files.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ set(MBGL_CORE_FILES
src/mbgl/programs/line_program.cpp
src/mbgl/programs/line_program.hpp
src/mbgl/programs/program.hpp
src/mbgl/programs/program_parameters.cpp
src/mbgl/programs/program_parameters.hpp
src/mbgl/programs/programs.hpp
src/mbgl/programs/raster_program.cpp
Expand Down
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
49 changes: 40 additions & 9 deletions scripts/generate-shaders.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,21 +69,52 @@ ${fragmentPrelude}

fragmentSource = fragmentSource.replace(re, (match, operation, precision, type, name) => {
fragmentPragmas.add(name);
return operation === "define" ?
`varying ${precision} ${type} ${name};` :
``;
return operation === "define" ? `
#ifndef HAS_UNIFORM_u_${name}
varying ${precision} ${type} ${name};
#else
uniform ${precision} ${type} u_${name};
#endif
` : `
#ifdef HAS_UNIFORM_u_${name}
${precision} ${type} ${name} = u_${name};
#endif
`;
});

vertexSource = vertexSource.replace(re, (match, operation, precision, type, name) => {
const a_type = type === "float" ? "vec2" : "vec4";
if (fragmentPragmas.has(name)) {
return operation === "define" ?
`uniform lowp float a_${name}_t;\nattribute ${precision} ${a_type} a_${name};\nvarying ${precision} ${type} ${name};` :
`${name} = unpack_mix_${a_type}(a_${name}, a_${name}_t);`;
return operation === "define" ? `
#ifdef HAS_UNIFORM_u_${name}
uniform lowp float a_${name}_t;
attribute ${precision} ${a_type} a_${name};
varying ${precision} ${type} ${name};
#else
uniform ${precision} ${type} u_${name};
#endif
` : `
#ifndef HAS_UNIFORM_u_${name}
${name} = unpack_mix_${a_type}(a_${name}, a_${name}_t);
#else
${precision} ${type} ${name} = u_${name};
#endif
`;
} else {
return operation === "define" ?
`uniform lowp float a_${name}_t;\nattribute ${precision} ${a_type} a_${name};` :
`${precision} ${type} ${name} = unpack_mix_${a_type}(a_${name}, a_${name}_t);`;
return operation === "define" ? `
#ifdef HAS_UNIFORM_u_${name}
uniform lowp float a_${name}_t;
attribute ${precision} ${a_type} a_${name};
#else
uniform ${precision} ${type} u_${name};
#endif
` : `
#ifndef HAS_UNIFORM_u_${name}
${precision} ${type} ${name} = unpack_mix_${a_type}(a_${name}, a_${name}_t);
#else
${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 cachePath =
shaders::programCachePath(programParameters, name);
const std::string identifier =
shaders::programIdentifier(vertexSource, fragmentSource_);

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
2 changes: 1 addition & 1 deletion src/mbgl/gl/uniform.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class Uniform {
class State {
public:
void operator=(const Value& value) {
if (!current || *current != value.t) {
if (location >= 0 && (!current || *current != value.t)) {
current = value.t;
bindUniform(location, value.t);
}
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
37 changes: 35 additions & 2 deletions 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 @@ -62,7 +65,7 @@ class Program {
std::move(stencilMode),
std::move(colorMode),
uniformValues
.concat(paintPropertyBinders.uniformValues(currentZoom)),
.concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)),
LayoutAttributes::allVariableBindings(layoutVertexBuffer)
.concat(paintPropertyBinders.attributeBindings(currentProperties)),
indexBuffer,
Expand All @@ -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
48 changes: 48 additions & 0 deletions src/mbgl/programs/program_parameters.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include <mbgl/programs/program_parameters.hpp>

#include <iomanip>
#include <sstream>

namespace mbgl {

ProgramParameters::ProgramParameters(const float pixelRatio,
const bool overdraw,
optional<std::string> cacheDir_)
: defines([&] {
std::ostringstream ss;
ss.imbue(std::locale("C"));
ss.setf(std::ios_base::showpoint);
ss << "#define DEVICE_PIXEL_RATIO " << pixelRatio << std::endl;
if (overdraw) {
ss << "#define OVERDRAW_INSPECTOR" << std::endl;
}
return ss.str();
}()),
cacheDir(std::move(cacheDir_)) {
}

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
24 changes: 13 additions & 11 deletions src/mbgl/programs/program_parameters.hpp
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
#pragma once

#include <mbgl/util/optional.hpp>

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

namespace mbgl {

class ProgramParameters {
public:
ProgramParameters(float pixelRatio_ = 1.0,
bool overdraw_ = false,
std::string cacheDir_ = "")
: pixelRatio(pixelRatio_), overdraw(overdraw_), cacheDir(std::move(cacheDir_)) {
}

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

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

ProgramParameters withAdditionalDefines(const std::vector<std::string>& defines) const;

private:
std::string defines;
optional<std::string> cacheDir;
};

} // namespace mbgl

30 changes: 15 additions & 15 deletions src/mbgl/programs/programs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,25 +31,25 @@ class Programs {
symbolIcon(context, programParameters),
symbolIconSDF(context, programParameters),
symbolGlyph(context, programParameters),
debug(context, ProgramParameters(programParameters.pixelRatio, false, programParameters.cacheDir)),
collisionBox(context, ProgramParameters(programParameters.pixelRatio, false, programParameters.cacheDir)) {
debug(context, programParameters),
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
5 changes: 3 additions & 2 deletions src/mbgl/programs/symbol_program.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,14 +324,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 Expand Up @@ -377,7 +378,7 @@ class SymbolProgram {
std::move(colorMode),
uniformValues
.concat(symbolSizeBinder.uniformValues(currentZoom))
.concat(paintPropertyBinders.uniformValues(currentZoom)),
.concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)),
LayoutAttributes::allVariableBindings(layoutVertexBuffer)
.concat(symbolSizeBinder.attributeBindings(currentSizeValue))
.concat(paintPropertyBinders.attributeBindings(currentProperties)),
Expand Down
14 changes: 13 additions & 1 deletion src/mbgl/programs/uniforms.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,19 @@ MBGL_DEFINE_UNIFORM_SCALAR(float, u_blur);
MBGL_DEFINE_UNIFORM_SCALAR(float, u_zoom);
MBGL_DEFINE_UNIFORM_SCALAR(float, u_pitch);
MBGL_DEFINE_UNIFORM_SCALAR(float, u_bearing);

MBGL_DEFINE_UNIFORM_SCALAR(float, u_radius);
MBGL_DEFINE_UNIFORM_SCALAR(float, u_stroke_width);
MBGL_DEFINE_UNIFORM_SCALAR(Color, u_stroke_color);
MBGL_DEFINE_UNIFORM_SCALAR(float, u_stroke_opacity);
MBGL_DEFINE_UNIFORM_SCALAR(Color, u_fill_color);
MBGL_DEFINE_UNIFORM_SCALAR(Color, u_halo_color);
MBGL_DEFINE_UNIFORM_SCALAR(float, u_halo_width);
MBGL_DEFINE_UNIFORM_SCALAR(float, u_halo_blur);
MBGL_DEFINE_UNIFORM_SCALAR(Color, u_outline_color);
MBGL_DEFINE_UNIFORM_SCALAR(float, u_height);
MBGL_DEFINE_UNIFORM_SCALAR(float, u_base);
MBGL_DEFINE_UNIFORM_SCALAR(float, u_gap_width);
MBGL_DEFINE_UNIFORM_SCALAR(float, u_offset);
MBGL_DEFINE_UNIFORM_SCALAR(Size, u_world);
MBGL_DEFINE_UNIFORM_SCALAR(Size, u_texsize);

Expand Down
Loading