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

Commit

Permalink
[core] Avoid increased PaintPropertyBinder template specialization
Browse files Browse the repository at this point in the history
  • Loading branch information
jfirebaugh committed Apr 18, 2017
1 parent 0c8f1fc commit 2b83d39
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 89 deletions.
4 changes: 2 additions & 2 deletions src/mbgl/renderer/circle_bucket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,10 @@ void CircleBucket::addFeature(const GeometryTileFeature& feature,
template <class Property>
static float get(const CircleLayer& layer, const std::map<std::string, CircleProgram::PaintPropertyBinders>& paintPropertyBinders) {
auto it = paintPropertyBinders.find(layer.getID());
if (it == paintPropertyBinders.end() || !it->second.statistics.has<Property>()) {
if (it == paintPropertyBinders.end() || !it->second.statistics<Property>().max()) {
return layer.impl->paint.evaluated.get<Property>().constantOr(Property::defaultValue());
} else {
return it->second.statistics.max<Property>();
return *it->second.statistics<Property>().max();
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/mbgl/renderer/line_bucket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -463,10 +463,10 @@ bool LineBucket::hasData() const {
template <class Property>
static float get(const LineLayer& layer, const std::map<std::string, LineProgram::PaintPropertyBinders>& paintPropertyBinders) {
auto it = paintPropertyBinders.find(layer.getID());
if (it == paintPropertyBinders.end() || !it->second.statistics.has<Property>()) {
if (it == paintPropertyBinders.end() || !it->second.statistics<Property>().max()) {
return layer.impl->paint.evaluated.get<Property>().constantOr(Property::defaultValue());
} else {
return it->second.statistics.max<Property>();
return *it->second.statistics<Property>().max();
}
}

Expand Down
59 changes: 31 additions & 28 deletions src/mbgl/style/paint_property_binder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <mbgl/gl/attribute.hpp>
#include <mbgl/gl/uniform.hpp>
#include <mbgl/util/type_list.hpp>
#include "paint_property_statistics.hpp"
#include <mbgl/style/paint_property_statistics.hpp>

namespace mbgl {
namespace style {
Expand Down Expand Up @@ -77,24 +77,26 @@ std::array<float, N*2> zoomInterpolatedAttributeValue(const std::array<float, N>
`glVertexAttrib*` was unnacceptably slow. Additionally, in GL Native we have
implemented binary shader caching, which works better if the shaders are constant.
*/
template <class P, class T, class A, class Statistics>
template <class T, class A>
class PaintPropertyBinder {
public:
using Attribute = ZoomInterpolatedAttributeType<A>;
using AttributeBinding = typename Attribute::Binding;

virtual ~PaintPropertyBinder() = default;

virtual void populateVertexVector(const GeometryTileFeature& feature, std::size_t length, Statistics& statistics) = 0;
virtual void populateVertexVector(const GeometryTileFeature& feature, std::size_t length) = 0;
virtual void upload(gl::Context& context) = 0;
virtual AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue<T>& currentValue) const = 0;
virtual float interpolationFactor(float currentZoom) const = 0;

static std::unique_ptr<PaintPropertyBinder> create(const PossiblyEvaluatedPropertyValue<T>& value, float zoom, T defaultValue);

PaintPropertyStatistics<T> statistics;
};

template <class P, class T, class A, class Statistics>
class ConstantPaintPropertyBinder : public PaintPropertyBinder<P, T, A, Statistics> {
template <class T, class A>
class ConstantPaintPropertyBinder : public PaintPropertyBinder<T, A> {
public:
using Attribute = ZoomInterpolatedAttributeType<A>;
using AttributeBinding = typename Attribute::Binding;
Expand All @@ -103,8 +105,7 @@ class ConstantPaintPropertyBinder : public PaintPropertyBinder<P, T, A, Statisti
: constant(std::move(constant_)) {
}

void populateVertexVector(const GeometryTileFeature&, std::size_t, Statistics&) override {}

void populateVertexVector(const GeometryTileFeature&, std::size_t) override {}
void upload(gl::Context&) override {}

AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue<T>& currentValue) const override {
Expand All @@ -122,8 +123,8 @@ class ConstantPaintPropertyBinder : public PaintPropertyBinder<P, T, A, Statisti
T constant;
};

template <class P, class T, class A, class Statistics>
class SourceFunctionPaintPropertyBinder : public PaintPropertyBinder<P, T, A, Statistics> {
template <class T, class A>
class SourceFunctionPaintPropertyBinder : public PaintPropertyBinder<T, A> {
public:
using BaseAttribute = A;
using BaseAttributeValue = typename BaseAttribute::Value;
Expand All @@ -137,10 +138,10 @@ class SourceFunctionPaintPropertyBinder : public PaintPropertyBinder<P, T, A, St
defaultValue(std::move(defaultValue_)) {
}

void populateVertexVector(const GeometryTileFeature& feature, std::size_t length, Statistics& statistics) override {
void populateVertexVector(const GeometryTileFeature& feature, std::size_t length) override {
auto evaluated = function.evaluate(feature, defaultValue);
statistics.template add<P>(evaluated);
auto value = attributeValue(evaluated);
this->statistics.add(evaluated);
auto value = attributeValue(function.evaluate(feature, defaultValue));
for (std::size_t i = vertexVector.vertexSize(); i < length; ++i) {
vertexVector.emplace_back(BaseVertex { value });
}
Expand Down Expand Up @@ -172,8 +173,8 @@ class SourceFunctionPaintPropertyBinder : public PaintPropertyBinder<P, T, A, St
optional<gl::VertexBuffer<BaseVertex>> vertexBuffer;
};

template <class P, class T, class A, class Statistics>
class CompositeFunctionPaintPropertyBinder : public PaintPropertyBinder<P, T, A, Statistics> {
template <class T, class A>
class CompositeFunctionPaintPropertyBinder : public PaintPropertyBinder<T, A> {
public:
using BaseAttribute = A;
using BaseAttributeValue = typename BaseAttribute::Value;
Expand All @@ -189,9 +190,10 @@ class CompositeFunctionPaintPropertyBinder : public PaintPropertyBinder<P, T, A,
coveringRanges(function.coveringRanges(zoom)) {
}

void populateVertexVector(const GeometryTileFeature& feature, std::size_t length, Statistics& statistics) override {
void populateVertexVector(const GeometryTileFeature& feature, std::size_t length) override {
Range<T> range = function.evaluate(std::get<1>(coveringRanges), feature, defaultValue);
statistics.template add<P>(range);
this->statistics.add(range.min);
this->statistics.add(range.max);
AttributeValue value = zoomInterpolatedAttributeValue(
attributeValue(range.min),
attributeValue(range.max));
Expand Down Expand Up @@ -228,18 +230,18 @@ class CompositeFunctionPaintPropertyBinder : public PaintPropertyBinder<P, T, A,
optional<gl::VertexBuffer<Vertex>> vertexBuffer;
};

template <class P, class T, class A, class Statistics>
std::unique_ptr<PaintPropertyBinder<P, T, A, Statistics>>
PaintPropertyBinder<P, T, A, Statistics>::create(const PossiblyEvaluatedPropertyValue<T>& value, float zoom, T defaultValue) {
template <class T, class A>
std::unique_ptr<PaintPropertyBinder<T, A>>
PaintPropertyBinder<T, A>::create(const PossiblyEvaluatedPropertyValue<T>& value, float zoom, T defaultValue) {
return value.match(
[&] (const T& constant) -> std::unique_ptr<PaintPropertyBinder<P, T, A, Statistics>> {
return std::make_unique<ConstantPaintPropertyBinder<P, T, A, Statistics>>(constant);
[&] (const T& constant) -> std::unique_ptr<PaintPropertyBinder<T, A>> {
return std::make_unique<ConstantPaintPropertyBinder<T, A>>(constant);
},
[&] (const SourceFunction<T>& function) {
return std::make_unique<SourceFunctionPaintPropertyBinder<P, T, A, Statistics>>(function, defaultValue);
return std::make_unique<SourceFunctionPaintPropertyBinder<T, A>>(function, defaultValue);
},
[&] (const CompositeFunction<T>& function) {
return std::make_unique<CompositeFunctionPaintPropertyBinder<P, T, A, Statistics>>(function, zoom, defaultValue);
return std::make_unique<CompositeFunctionPaintPropertyBinder<T, A>>(function, zoom, defaultValue);
}
);
}
Expand All @@ -264,10 +266,8 @@ class PaintPropertyBinders;
template <class... Ps>
class PaintPropertyBinders<TypeList<Ps...>> {
public:
using Statistics = PaintPropertyStatistics<Ps...>;

template <class P>
using Binder = PaintPropertyBinder<P, typename P::Type, typename P::Attribute::Type, Statistics>;
using Binder = PaintPropertyBinder<typename P::Type, typename P::Attribute::Type>;

using Binders = IndexedTuple<
TypeList<Ps...>,
Expand All @@ -284,7 +284,7 @@ class PaintPropertyBinders<TypeList<Ps...>> {

void populateVertexVectors(const GeometryTileFeature& feature, std::size_t length) {
util::ignore({
(binders.template get<Ps>()->populateVertexVector(feature, length, statistics), 0)...
(binders.template get<Ps>()->populateVertexVector(feature, length), 0)...
});
}

Expand Down Expand Up @@ -319,7 +319,10 @@ class PaintPropertyBinders<TypeList<Ps...>> {
};
}

Statistics statistics;
template <class P>
const auto& statistics() const {
return binders.template get<P>()->statistics;
}

private:
Binders binders;
Expand Down
69 changes: 12 additions & 57 deletions src/mbgl/style/paint_property_statistics.hpp
Original file line number Diff line number Diff line change
@@ -1,75 +1,30 @@
#pragma once

#include <mbgl/util/type_list.hpp>
#include <mbgl/util/indexed_tuple.hpp>
#include <mbgl/util/range.hpp>

#include <mbgl/util/optional.hpp>

namespace mbgl {
namespace style {

/**
* A statistics entry for a property
*/
template <class Type>
class StatsEntry {
template <class T>
class PaintPropertyStatistics {
public:
optional<Type> max;
bool set;
optional<T> max() const { return {}; }
void add(const T&) {}
};

/**
* Holder for paint property statistics,
* calculated just before rendering
*
* <Ps> the DataDrivenPaintProperties in this collection
*/
template <class... Ps>
class PaintPropertyStatistics {
template <>
class PaintPropertyStatistics<float> {
public:

using Properties = TypeList<Ps...>;
using Types = TypeList<StatsEntry<typename Ps::Type>...>;

template <class TypeList>
using Tuple = IndexedTuple<Properties, TypeList>;

class Values : public Tuple<Types> {
public:
using Tuple<Types>::Tuple;
};

template <class P>
bool has() const {
return entries.template get<P>().set;
optional<float> max() const {
return _max;
}

template <class P>
auto max() const {
auto value = entries.template get<P>();
return *value.max;
}

template <class P>
void add(const float& value) {
auto& holder = entries.template get<P>();
holder.max = holder.max ? std::max(*holder.max, value) : value;
holder.set = true;
}

template <class P>
void add(const Range<float>& value) {
add<P>(std::max(value.min, value.max));
}

template <class P, class T>
void add(const T&) {
//NOOP, not interested in these types, yet.
void add(float value) {
_max = _max ? std::max(*_max, value) : value;
}

private:

Values entries;
optional<float> _max;
};

} // namespace style
Expand Down

0 comments on commit 2b83d39

Please sign in to comment.