[core] Remove binary shader support
The implementation is buggy and not worth maintaining anymore because performance benefits are not substantial or sometimes worse. Also, removing it saves about 150 ~ 180 KB in binary size. Below timings are averages of minimum 5 runs. ``` Device Init launch Average relaunch s10 1129.8 ms 700 ms s10 - binary 1346.75 ms 694 ms Pixel 1692 ms 723 ms Pixel - binary 1883 ms 1039 ms Kazam 17948 ms 1339 ms Kazam - binary 19157 ms 1564 ms Wiko 2060 ms 1278 ms Wiko - binary 3876 ms 1136 ms ``` Fixes #14294
This commit is contained in:
@@ -1,19 +0,0 @@
|
||||
// Protocol Version 1
|
||||
|
||||
package mapboxgl.binary_program;
|
||||
|
||||
option optimize_for = LITE_RUNTIME;
|
||||
|
||||
message binding {
|
||||
required string name = 1;
|
||||
required uint32 value = 2;
|
||||
}
|
||||
|
||||
message binary_program {
|
||||
required uint32 format = 1;
|
||||
required bytes code = 2;
|
||||
repeated binding attribute = 3;
|
||||
repeated binding uniform = 4;
|
||||
optional string identifier = 5;
|
||||
repeated binding texture = 6;
|
||||
}
|
||||
@@ -18,7 +18,6 @@
|
||||
"src/mbgl/gfx/attribute.cpp",
|
||||
"src/mbgl/gfx/renderer_backend.cpp",
|
||||
"src/mbgl/gl/attribute.cpp",
|
||||
"src/mbgl/gl/binary_program.cpp",
|
||||
"src/mbgl/gl/command_encoder.cpp",
|
||||
"src/mbgl/gl/context.cpp",
|
||||
"src/mbgl/gl/debugging_extension.cpp",
|
||||
@@ -533,7 +532,6 @@
|
||||
"mbgl/gfx/vertex_buffer.hpp": "src/mbgl/gfx/vertex_buffer.hpp",
|
||||
"mbgl/gfx/vertex_vector.hpp": "src/mbgl/gfx/vertex_vector.hpp",
|
||||
"mbgl/gl/attribute.hpp": "src/mbgl/gl/attribute.hpp",
|
||||
"mbgl/gl/binary_program.hpp": "src/mbgl/gl/binary_program.hpp",
|
||||
"mbgl/gl/command_encoder.hpp": "src/mbgl/gl/command_encoder.hpp",
|
||||
"mbgl/gl/context.hpp": "src/mbgl/gl/context.hpp",
|
||||
"mbgl/gl/debugging_extension.hpp": "src/mbgl/gl/debugging_extension.hpp",
|
||||
@@ -541,13 +539,11 @@
|
||||
"mbgl/gl/draw_scope_resource.hpp": "src/mbgl/gl/draw_scope_resource.hpp",
|
||||
"mbgl/gl/enum.hpp": "src/mbgl/gl/enum.hpp",
|
||||
"mbgl/gl/extension.hpp": "src/mbgl/gl/extension.hpp",
|
||||
"mbgl/gl/features.hpp": "src/mbgl/gl/features.hpp",
|
||||
"mbgl/gl/framebuffer.hpp": "src/mbgl/gl/framebuffer.hpp",
|
||||
"mbgl/gl/index_buffer_resource.hpp": "src/mbgl/gl/index_buffer_resource.hpp",
|
||||
"mbgl/gl/object.hpp": "src/mbgl/gl/object.hpp",
|
||||
"mbgl/gl/offscreen_texture.hpp": "src/mbgl/gl/offscreen_texture.hpp",
|
||||
"mbgl/gl/program.hpp": "src/mbgl/gl/program.hpp",
|
||||
"mbgl/gl/program_binary_extension.hpp": "src/mbgl/gl/program_binary_extension.hpp",
|
||||
"mbgl/gl/render_pass.hpp": "src/mbgl/gl/render_pass.hpp",
|
||||
"mbgl/gl/renderbuffer_resource.hpp": "src/mbgl/gl/renderbuffer_resource.hpp",
|
||||
"mbgl/gl/state.hpp": "src/mbgl/gl/state.hpp",
|
||||
|
||||
@@ -31,12 +31,6 @@ private:
|
||||
public:
|
||||
AttributeLocations() = default;
|
||||
|
||||
template <class BinaryProgram>
|
||||
AttributeLocations(const BinaryProgram& program)
|
||||
: locations{ program.attributeLocation(
|
||||
concat_literals<&string_literal<'a', '_'>::value, &As::name>::value())... } {
|
||||
}
|
||||
|
||||
void queryLocations(const ProgramID& id) {
|
||||
locations = Locations{
|
||||
queryLocation(id, concat_literals<&string_literal<'a', '_'>::value, &As::name>::value())... };
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
#include <mbgl/gl/binary_program.hpp>
|
||||
|
||||
#include <protozero/pbf_reader.hpp>
|
||||
#include <protozero/pbf_writer.hpp>
|
||||
#include <utility>
|
||||
#include <stdexcept>
|
||||
|
||||
template <class Binding>
|
||||
static std::pair<const std::string, Binding> parseBinding(protozero::pbf_reader&& pbf) {
|
||||
bool hasName = false, hasValue = false;
|
||||
std::pair<std::string, Binding> binding;
|
||||
while (pbf.next()) {
|
||||
switch (pbf.tag()) {
|
||||
case 1: // name
|
||||
binding.first = pbf.get_string();
|
||||
hasName = true;
|
||||
break;
|
||||
case 2: // value
|
||||
binding.second = pbf.get_uint32();
|
||||
hasValue = true;
|
||||
break;
|
||||
default:
|
||||
pbf.skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasName || !hasValue) {
|
||||
throw std::runtime_error("BinaryProgram binding is missing required fields");
|
||||
}
|
||||
return binding;
|
||||
}
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
|
||||
BinaryProgram::BinaryProgram(std::string&& data) {
|
||||
bool hasFormat = false, hasCode = false;
|
||||
protozero::pbf_reader pbf(data);
|
||||
while (pbf.next()) {
|
||||
switch (pbf.tag()) {
|
||||
case 1: // format
|
||||
binaryFormat = pbf.get_uint32();
|
||||
hasFormat = true;
|
||||
break;
|
||||
case 2: // code
|
||||
binaryCode = pbf.get_bytes();
|
||||
hasCode = true;
|
||||
break;
|
||||
case 3: // variable
|
||||
attributes.emplace_back(parseBinding<gl::AttributeLocation>(pbf.get_message()));
|
||||
break;
|
||||
case 4: // uniform
|
||||
uniforms.emplace_back(parseBinding<gl::UniformLocation>(pbf.get_message()));
|
||||
break;
|
||||
case 5: // identifier
|
||||
binaryIdentifier = pbf.get_string();
|
||||
break;
|
||||
case 6: // uniform
|
||||
textures.emplace_back(parseBinding<gl::UniformLocation>(pbf.get_message()));
|
||||
break;
|
||||
default:
|
||||
pbf.skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasFormat || !hasCode) {
|
||||
throw std::runtime_error("BinaryProgram is missing required fields");
|
||||
}
|
||||
}
|
||||
|
||||
BinaryProgram::BinaryProgram(
|
||||
gl::BinaryProgramFormat binaryFormat_,
|
||||
std::string&& binaryCode_,
|
||||
std::string binaryIdentifier_,
|
||||
std::vector<std::pair<const std::string, gl::AttributeLocation>>&& attributes_,
|
||||
std::vector<std::pair<const std::string, gl::UniformLocation>>&& uniforms_,
|
||||
std::vector<std::pair<const std::string, gl::UniformLocation>>&& textures_)
|
||||
: binaryFormat(binaryFormat_),
|
||||
binaryCode(std::move(binaryCode_)),
|
||||
binaryIdentifier(std::move(binaryIdentifier_)),
|
||||
attributes(std::move(attributes_)),
|
||||
uniforms(std::move(uniforms_)),
|
||||
textures(std::move(textures_)) {
|
||||
}
|
||||
|
||||
std::string BinaryProgram::serialize() const {
|
||||
std::string data;
|
||||
data.reserve(32 + binaryCode.size() + uniforms.size() * 32 + attributes.size() * 32);
|
||||
protozero::pbf_writer pbf(data);
|
||||
pbf.add_uint32(1 /* format */, binaryFormat);
|
||||
pbf.add_bytes(2 /* code */, binaryCode.data(), binaryCode.size());
|
||||
for (const auto& binding : attributes) {
|
||||
protozero::pbf_writer pbf_binding(pbf, 3 /* attribute */);
|
||||
pbf_binding.add_string(1 /* name */, binding.first);
|
||||
pbf_binding.add_uint32(2 /* value */, binding.second);
|
||||
}
|
||||
for (const auto& binding : uniforms) {
|
||||
protozero::pbf_writer pbf_binding(pbf, 4 /* uniform */);
|
||||
pbf_binding.add_string(1 /* name */, binding.first);
|
||||
pbf_binding.add_uint32(2 /* value */, binding.second);
|
||||
}
|
||||
for (const auto& binding : textures) {
|
||||
protozero::pbf_writer pbf_binding(pbf, 6 /* texture */);
|
||||
pbf_binding.add_string(1 /* name */, binding.first);
|
||||
pbf_binding.add_uint32(2 /* value */, binding.second);
|
||||
}
|
||||
if (!binaryIdentifier.empty()) {
|
||||
pbf.add_string(5 /* identifier */, binaryIdentifier);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
optional<gl::AttributeLocation> BinaryProgram::attributeLocation(const std::string& name) const {
|
||||
for (const auto& pair : attributes) {
|
||||
if (pair.first == name) {
|
||||
return pair.second;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
gl::UniformLocation BinaryProgram::uniformLocation(const std::string& name) const {
|
||||
for (const auto& pair : uniforms) {
|
||||
if (pair.first == name) {
|
||||
return pair.second;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
gl::UniformLocation BinaryProgram::textureLocation(const std::string& name) const {
|
||||
for (const auto& pair : textures) {
|
||||
if (pair.first == name) {
|
||||
return pair.second;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
@@ -1,50 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/gl/types.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
|
||||
class BinaryProgram {
|
||||
public:
|
||||
// Initialize a BinaryProgram object from a serialized represenation.
|
||||
BinaryProgram(std::string&& data);
|
||||
|
||||
BinaryProgram(gl::BinaryProgramFormat,
|
||||
std::string&& binaryCode,
|
||||
std::string binaryIdentifier,
|
||||
std::vector<std::pair<const std::string, gl::AttributeLocation>>&&,
|
||||
std::vector<std::pair<const std::string, gl::UniformLocation>>&&,
|
||||
std::vector<std::pair<const std::string, gl::UniformLocation>>&&);
|
||||
|
||||
std::string serialize() const;
|
||||
|
||||
gl::BinaryProgramFormat format() const {
|
||||
return binaryFormat;
|
||||
}
|
||||
const std::string& code() const {
|
||||
return binaryCode;
|
||||
}
|
||||
const std::string& identifier() const {
|
||||
return binaryIdentifier;
|
||||
}
|
||||
|
||||
optional<gl::AttributeLocation> attributeLocation(const std::string& name) const;
|
||||
gl::UniformLocation uniformLocation(const std::string& name) const;
|
||||
gl::UniformLocation textureLocation(const std::string& name) const;
|
||||
|
||||
private:
|
||||
gl::BinaryProgramFormat binaryFormat = 0;
|
||||
std::string binaryCode;
|
||||
std::string binaryIdentifier;
|
||||
std::vector<std::pair<const std::string, gl::AttributeLocation>> attributes;
|
||||
std::vector<std::pair<const std::string, gl::UniformLocation>> uniforms;
|
||||
std::vector<std::pair<const std::string, gl::UniformLocation>> textures;
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <mbgl/gl/command_encoder.hpp>
|
||||
#include <mbgl/gl/debugging_extension.hpp>
|
||||
#include <mbgl/gl/vertex_array_extension.hpp>
|
||||
#include <mbgl/gl/program_binary_extension.hpp>
|
||||
#include <mbgl/util/traits.hpp>
|
||||
#include <mbgl/util/std.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
@@ -50,8 +49,6 @@ static_assert(underlying_type(UniformDataType::FloatMat4) == GL_FLOAT_MAT4, "Ope
|
||||
static_assert(underlying_type(UniformDataType::Sampler2D) == GL_SAMPLER_2D, "OpenGL type mismatch");
|
||||
static_assert(underlying_type(UniformDataType::SamplerCube) == GL_SAMPLER_CUBE, "OpenGL type mismatch");
|
||||
|
||||
static_assert(std::is_same<BinaryProgramFormat, GLenum>::value, "OpenGL type mismatch");
|
||||
|
||||
Context::Context(RendererBackend& backend_)
|
||||
: gfx::Context(gfx::ContextType::OpenGL, [] {
|
||||
GLint value;
|
||||
@@ -107,10 +104,6 @@ void Context::initializeExtensions(const std::function<gl::ProcAddress(const cha
|
||||
vertexArray = std::make_unique<extension::VertexArray>(fn);
|
||||
}
|
||||
|
||||
#if MBGL_HAS_BINARY_PROGRAMS
|
||||
programBinary = std::make_unique<extension::ProgramBinary>(fn);
|
||||
#endif
|
||||
|
||||
#if MBGL_USE_GLES2
|
||||
constexpr const char* halfFloatExtensionName = "OES_texture_half_float";
|
||||
constexpr const char* halfFloatColorBufferExtensionName = "EXT_color_buffer_half_float";
|
||||
@@ -186,23 +179,6 @@ UniqueProgram Context::createProgram(ShaderID vertexShader, ShaderID fragmentSha
|
||||
return result;
|
||||
}
|
||||
|
||||
#if MBGL_HAS_BINARY_PROGRAMS
|
||||
UniqueProgram Context::createProgram(BinaryProgramFormat binaryFormat,
|
||||
const std::string& binaryProgram) {
|
||||
assert(supportsProgramBinaries());
|
||||
UniqueProgram result{ MBGL_CHECK_ERROR(glCreateProgram()), { this } };
|
||||
MBGL_CHECK_ERROR(programBinary->programBinary(result, static_cast<GLenum>(binaryFormat),
|
||||
binaryProgram.data(),
|
||||
static_cast<GLint>(binaryProgram.size())));
|
||||
verifyProgramLinkage(result);
|
||||
return result;
|
||||
}
|
||||
#else
|
||||
UniqueProgram Context::createProgram(BinaryProgramFormat, const std::string&) {
|
||||
throw std::runtime_error("binary programs are not supported");
|
||||
}
|
||||
#endif
|
||||
|
||||
void Context::linkProgram(ProgramID program_) {
|
||||
MBGL_CHECK_ERROR(glLinkProgram(program_));
|
||||
verifyProgramLinkage(program_);
|
||||
@@ -244,51 +220,6 @@ bool Context::supportsVertexArrays() const {
|
||||
vertexArray->deleteVertexArrays;
|
||||
}
|
||||
|
||||
#if MBGL_HAS_BINARY_PROGRAMS
|
||||
bool Context::supportsProgramBinaries() const {
|
||||
if (!programBinary || !programBinary->programBinary || !programBinary->getProgramBinary) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Blacklist Adreno 3xx, 4xx, and 5xx GPUs due to known bugs:
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=510637
|
||||
// https://chromium.googlesource.com/chromium/src/gpu/+/master/config/gpu_driver_bug_list.json#2316
|
||||
// Blacklist Vivante GC4000 due to bugs when linking loaded programs:
|
||||
// https://github.com/mapbox/mapbox-gl-native/issues/10704
|
||||
const std::string renderer = reinterpret_cast<const char*>(MBGL_CHECK_ERROR(glGetString(GL_RENDERER)));
|
||||
if (renderer.find("Adreno (TM) 3") != std::string::npos
|
||||
|| renderer.find("Adreno (TM) 4") != std::string::npos
|
||||
|| renderer.find("Adreno (TM) 5") != std::string::npos
|
||||
|| renderer.find("Vivante GC4000") != std::string::npos) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
optional<std::pair<BinaryProgramFormat, std::string>>
|
||||
Context::getBinaryProgram(ProgramID program_) const {
|
||||
if (!supportsProgramBinaries()) {
|
||||
return {};
|
||||
}
|
||||
GLint binaryLength;
|
||||
MBGL_CHECK_ERROR(glGetProgramiv(program_, GL_PROGRAM_BINARY_LENGTH, &binaryLength));
|
||||
std::string binary;
|
||||
binary.resize(binaryLength);
|
||||
GLenum binaryFormat;
|
||||
MBGL_CHECK_ERROR(programBinary->getProgramBinary(
|
||||
program_, binaryLength, &binaryLength, &binaryFormat, const_cast<char*>(binary.data())));
|
||||
if (size_t(binaryLength) != binary.size()) {
|
||||
return {};
|
||||
}
|
||||
return { { binaryFormat, std::move(binary) } };
|
||||
}
|
||||
#else
|
||||
optional<std::pair<BinaryProgramFormat, std::string>> Context::getBinaryProgram(ProgramID) const {
|
||||
return {};
|
||||
}
|
||||
#endif
|
||||
|
||||
VertexArray Context::createVertexArray() {
|
||||
if (supportsVertexArrays()) {
|
||||
VertexArrayID id = 0;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/gfx/context.hpp>
|
||||
#include <mbgl/gl/features.hpp>
|
||||
#include <mbgl/gl/object.hpp>
|
||||
#include <mbgl/gl/state.hpp>
|
||||
#include <mbgl/gl/value.hpp>
|
||||
@@ -33,7 +32,6 @@ class RendererBackend;
|
||||
namespace extension {
|
||||
class VertexArray;
|
||||
class Debugging;
|
||||
class ProgramBinary;
|
||||
} // namespace extension
|
||||
|
||||
class Context final : public gfx::Context {
|
||||
@@ -51,18 +49,10 @@ public:
|
||||
|
||||
UniqueShader createShader(ShaderType type, const std::initializer_list<const char*>& sources);
|
||||
UniqueProgram createProgram(ShaderID vertexShader, ShaderID fragmentShader, const char* location0AttribName);
|
||||
UniqueProgram createProgram(BinaryProgramFormat binaryFormat, const std::string& binaryProgram);
|
||||
void verifyProgramLinkage(ProgramID);
|
||||
void linkProgram(ProgramID);
|
||||
UniqueTexture createUniqueTexture();
|
||||
|
||||
#if MBGL_HAS_BINARY_PROGRAMS
|
||||
bool supportsProgramBinaries() const;
|
||||
#else
|
||||
constexpr static bool supportsProgramBinaries() { return false; }
|
||||
#endif
|
||||
optional<std::pair<BinaryProgramFormat, std::string>> getBinaryProgram(ProgramID) const;
|
||||
|
||||
Framebuffer createFramebuffer(const gfx::Renderbuffer<gfx::RenderbufferPixelType::RGBA>&,
|
||||
const gfx::Renderbuffer<gfx::RenderbufferPixelType::DepthStencil>&);
|
||||
Framebuffer createFramebuffer(const gfx::Renderbuffer<gfx::RenderbufferPixelType::RGBA>&);
|
||||
@@ -140,9 +130,6 @@ private:
|
||||
|
||||
std::unique_ptr<extension::Debugging> debugging;
|
||||
std::unique_ptr<extension::VertexArray> vertexArray;
|
||||
#if MBGL_HAS_BINARY_PROGRAMS
|
||||
std::unique_ptr<extension::ProgramBinary> programBinary;
|
||||
#endif
|
||||
|
||||
public:
|
||||
State<value::ActiveTextureUnit> activeTextureUnit;
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#if __APPLE__
|
||||
#define MBGL_HAS_BINARY_PROGRAMS 0
|
||||
#else
|
||||
// https://github.com/mapbox/mapbox-gl-native/issues/14294
|
||||
#define MBGL_HAS_BINARY_PROGRAMS 0
|
||||
#endif
|
||||
@@ -12,8 +12,6 @@
|
||||
#include <mbgl/gl/attribute.hpp>
|
||||
#include <mbgl/gl/uniform.hpp>
|
||||
#include <mbgl/gl/texture.hpp>
|
||||
#include <mbgl/gl/features.hpp>
|
||||
#include <mbgl/gl/binary_program.hpp>
|
||||
#include <mbgl/util/io.hpp>
|
||||
|
||||
#include <mbgl/util/logging.hpp>
|
||||
@@ -57,48 +55,10 @@ public:
|
||||
textureStates.queryLocations(program);
|
||||
}
|
||||
|
||||
template <class BinaryProgram>
|
||||
Instance(Context& context, const BinaryProgram& binaryProgram)
|
||||
: program(context.createProgram(binaryProgram.format(), binaryProgram.code())),
|
||||
attributeLocations(binaryProgram) {
|
||||
uniformStates.loadNamedLocations(binaryProgram);
|
||||
textureStates.loadNamedLocations(binaryProgram);
|
||||
}
|
||||
|
||||
static std::unique_ptr<Instance>
|
||||
createInstance(gl::Context& context,
|
||||
const ProgramParameters& programParameters,
|
||||
const std::string& additionalDefines) {
|
||||
|
||||
|
||||
|
||||
#if MBGL_HAS_BINARY_PROGRAMS
|
||||
optional<std::string> cachePath =
|
||||
programParameters.cachePath(programs::gl::ShaderSource<Name>::name);
|
||||
std::string programIdentifier;
|
||||
if (cachePath && context.supportsProgramBinaries()) {
|
||||
programIdentifier = programs::gl::programIdentifier(
|
||||
programParameters.getDefines(), additionalDefines, programs::gl::preludeHash,
|
||||
programs::gl::ShaderSource<Name>::hash);
|
||||
|
||||
try {
|
||||
if (auto cachedBinaryProgram = util::readFile(*cachePath)) {
|
||||
const BinaryProgram binaryProgram(std::move(*cachedBinaryProgram));
|
||||
if (binaryProgram.identifier() == programIdentifier) {
|
||||
return std::make_unique<Instance>(context, binaryProgram);
|
||||
} else {
|
||||
Log::Warning(Event::OpenGL,
|
||||
"Cached program %s changed. Recompilation required.",
|
||||
programs::gl::ShaderSource<Name>::name);
|
||||
}
|
||||
}
|
||||
} catch (std::runtime_error& error) {
|
||||
Log::Warning(Event::OpenGL, "Could not load cached program: %s",
|
||||
error.what());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Compile the shader
|
||||
const std::initializer_list<const char*> vertexSource = {
|
||||
programParameters.getDefines().c_str(),
|
||||
@@ -114,36 +74,9 @@ public:
|
||||
};
|
||||
auto result = std::make_unique<Instance>(context, vertexSource, fragmentSource);
|
||||
|
||||
#if MBGL_HAS_BINARY_PROGRAMS
|
||||
if (cachePath && context.supportsProgramBinaries()) {
|
||||
try {
|
||||
if (const auto binaryProgram =
|
||||
result->template get<BinaryProgram>(context, programIdentifier)) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
template <class BinaryProgram>
|
||||
optional<BinaryProgram> get(Context& context, const std::string& identifier) const {
|
||||
if (auto binaryProgram = context.getBinaryProgram(program)) {
|
||||
return BinaryProgram{ binaryProgram->first,
|
||||
std::move(binaryProgram->second),
|
||||
identifier,
|
||||
attributeLocations.getNamedLocations(),
|
||||
uniformStates.getNamedLocations(),
|
||||
textureStates.getNamedLocations() };
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
UniqueProgram program;
|
||||
gl::AttributeLocations<AttributeList> attributeLocations;
|
||||
gl::UniformStates<UniformList> uniformStates;
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/gl/features.hpp>
|
||||
#include <mbgl/gl/extension.hpp>
|
||||
#include <mbgl/gl/defines.hpp>
|
||||
|
||||
#if MBGL_HAS_BINARY_PROGRAMS
|
||||
|
||||
#define GL_PROGRAM_BINARY_LENGTH 0x8741
|
||||
#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
|
||||
#define GL_PROGRAM_BINARY_FORMATS 0x87FF
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
namespace extension {
|
||||
|
||||
class ProgramBinary {
|
||||
public:
|
||||
template <typename Fn>
|
||||
ProgramBinary(const Fn& loadExtension)
|
||||
: getProgramBinary(loadExtension({
|
||||
{ "GL_OES_get_program_binary", "glGetProgramBinaryOES" },
|
||||
{ "GL_ARB_get_program_binary", "glGetProgramBinary" },
|
||||
})),
|
||||
programBinary(loadExtension({
|
||||
{ "GL_OES_get_program_binary", "glProgramBinaryOES" },
|
||||
{ "GL_ARB_get_program_binary", "glProgramBinary" },
|
||||
})) {
|
||||
}
|
||||
|
||||
const ExtensionFunction<void(
|
||||
GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary)>
|
||||
getProgramBinary;
|
||||
|
||||
const ExtensionFunction<void(
|
||||
GLuint program, GLenum binaryFormat, const GLvoid* binary, GLint length)>
|
||||
programBinary;
|
||||
};
|
||||
|
||||
} // namespace extension
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
|
||||
#endif
|
||||
@@ -32,12 +32,6 @@ public:
|
||||
concat_literals<&string_literal<'u', '_'>::value, &Ts::name>::value())... };
|
||||
}
|
||||
|
||||
template <class BinaryProgram>
|
||||
void loadNamedLocations(const BinaryProgram& program) {
|
||||
state = State{ program.textureLocation(
|
||||
concat_literals<&string_literal<'u', '_'>::value, &Ts::name>::value())... };
|
||||
}
|
||||
|
||||
NamedUniformLocations getNamedLocations() const {
|
||||
return NamedUniformLocations{ { concat_literals<&string_literal<'u', '_'>::value, &Ts::name>::value(),
|
||||
state.template get<Ts>().location }... };
|
||||
|
||||
@@ -38,8 +38,6 @@ constexpr bool operator!=(const PixelStorageType& a, const PixelStorageType& b)
|
||||
return a.alignment != b.alignment;
|
||||
}
|
||||
|
||||
using BinaryProgramFormat = uint32_t;
|
||||
|
||||
enum class UniformDataType : uint32_t {
|
||||
Float = 0x1406,
|
||||
FloatVec2 = 0x8B50,
|
||||
|
||||
@@ -82,11 +82,6 @@ public:
|
||||
state = State{ gl::uniformLocation(id, concat_literals<&string_literal<'u', '_'>::value, &Us::name>::value())... };
|
||||
}
|
||||
|
||||
template <class BinaryProgram>
|
||||
void loadNamedLocations(const BinaryProgram& program) {
|
||||
state = State{ UniformState<typename Us::Value>(program.uniformLocation(concat_literals<&string_literal<'u', '_'>::value, &Us::name>::value()))... };
|
||||
}
|
||||
|
||||
NamedUniformLocations getNamedLocations() const {
|
||||
return NamedUniformLocations{ { concat_literals<&string_literal<'u', '_'>::value, &Us::name>::value(), state.template get<Us>().location }... };
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
#include <mbgl/test/util.hpp>
|
||||
|
||||
#include <mbgl/gl/binary_program.hpp>
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
TEST(BinaryProgram, ObtainValues) {
|
||||
const gl::BinaryProgram binaryProgram{ 42,
|
||||
"binary code",
|
||||
"identifier",
|
||||
{ { "a_pos", 1 }, { "a_data", 4 } },
|
||||
{ { "u_world", 1 }, { "u_ratio", 3 } },
|
||||
{ { "u_image", 0 } } };
|
||||
|
||||
EXPECT_EQ(42u, binaryProgram.format());
|
||||
EXPECT_EQ("binary code", binaryProgram.code());
|
||||
EXPECT_EQ("identifier", binaryProgram.identifier());
|
||||
EXPECT_EQ(1u, binaryProgram.attributeLocation("a_pos"));
|
||||
EXPECT_FALSE(binaryProgram.attributeLocation("u_world"));
|
||||
EXPECT_EQ(4u, binaryProgram.attributeLocation("a_data"));
|
||||
EXPECT_EQ(1, binaryProgram.uniformLocation("u_world"));
|
||||
EXPECT_EQ(3, binaryProgram.uniformLocation("u_ratio"));
|
||||
EXPECT_EQ(-1, binaryProgram.uniformLocation("a_data"));
|
||||
EXPECT_EQ(0, binaryProgram.textureLocation("u_image"));
|
||||
EXPECT_EQ(-1, binaryProgram.textureLocation("u_image2"));
|
||||
|
||||
auto serialized = binaryProgram.serialize();
|
||||
|
||||
const gl::BinaryProgram binaryProgram2(std::move(serialized));
|
||||
|
||||
EXPECT_EQ(42u, binaryProgram2.format());
|
||||
EXPECT_EQ("binary code", binaryProgram2.code());
|
||||
EXPECT_EQ("identifier", binaryProgram2.identifier());
|
||||
EXPECT_EQ(1u, binaryProgram2.attributeLocation("a_pos"));
|
||||
EXPECT_FALSE(binaryProgram2.attributeLocation("u_world"));
|
||||
EXPECT_EQ(4u, binaryProgram2.attributeLocation("a_data"));
|
||||
EXPECT_EQ(1, binaryProgram2.uniformLocation("u_world"));
|
||||
EXPECT_EQ(3, binaryProgram2.uniformLocation("u_ratio"));
|
||||
EXPECT_EQ(-1, binaryProgram2.uniformLocation("a_data"));
|
||||
EXPECT_EQ(0, binaryProgram.textureLocation("u_image"));
|
||||
EXPECT_EQ(-1, binaryProgram.textureLocation("u_image2"));
|
||||
|
||||
EXPECT_THROW(gl::BinaryProgram(""), std::runtime_error);
|
||||
}
|
||||
@@ -23,7 +23,6 @@
|
||||
"test/math/clamp.test.cpp",
|
||||
"test/math/minmax.test.cpp",
|
||||
"test/math/wrap.test.cpp",
|
||||
"test/programs/binary_program.test.cpp",
|
||||
"test/programs/symbol_program.test.cpp",
|
||||
"test/renderer/backend_scope.test.cpp",
|
||||
"test/renderer/image_manager.test.cpp",
|
||||
|
||||
Reference in New Issue
Block a user