summaryrefslogtreecommitdiff
path: root/src/mbgl/programs/attributes.hpp
diff options
context:
space:
mode:
authorMolly Lloyd <molly@mapbox.com>2017-03-01 11:28:31 -0800
committerJohn Firebaugh <john.firebaugh@gmail.com>2017-03-08 15:23:25 -0800
commit692f5e0a9f5321ee2932a976a8eb9e0a83fc3352 (patch)
treecb9ff13dc30455f1700eeb691dc155d0981c4116 /src/mbgl/programs/attributes.hpp
parent3afae825c7b2f95e58cbcb85c59857f2253c945e (diff)
downloadqtlocation-mapboxgl-692f5e0a9f5321ee2932a976a8eb9e0a83fc3352.tar.gz
Pack min + max into one attribute :muscle:
Some devices supported by Mapbox GL provide only 8 vertex attributes; this change packs existing attributes to get us just under that limit. For properties using a composite function, pack the min and max values into a single attribute with two logical components instead of using two separate attributes and buffers. Special logic is included for color attributes, whose integer components must be packed into the available bits of floating-point attributes. (We don't have access to ivec types in GL ES 2.0.) For source functions, continue to bind just a one-component attribute even though the GLSL type is vec2 (or vec4 for colors). The type-checking done by gl::Attribute is relaxed slightly to accommodate this.
Diffstat (limited to 'src/mbgl/programs/attributes.hpp')
-rw-r--r--src/mbgl/programs/attributes.hpp96
1 files changed, 50 insertions, 46 deletions
diff --git a/src/mbgl/programs/attributes.hpp b/src/mbgl/programs/attributes.hpp
index bb90f2c13c..a2e0772762 100644
--- a/src/mbgl/programs/attributes.hpp
+++ b/src/mbgl/programs/attributes.hpp
@@ -13,6 +13,7 @@ namespace attributes {
MBGL_DEFINE_ATTRIBUTE(int16_t, 2, a_pos);
MBGL_DEFINE_ATTRIBUTE(int16_t, 2, a_extrude);
+MBGL_DEFINE_ATTRIBUTE(int16_t, 4, a_pos_offset);
MBGL_DEFINE_ATTRIBUTE(uint16_t, 2, a_texture_pos);
template <std::size_t N>
@@ -27,19 +28,30 @@ struct a_offset : gl::Attribute<int16_t, N> {
// Paint attributes
+/*
+ ZoomInterpolatedAttribute<Attr> is a 'compound' attribute, representing two values of the
+ the base attribute Attr. These two values are provided to the shader to allow interpolation
+ between zoom levels, without the need to repopulate vertex buffers each frame as the map is
+ being zoomed.
+*/
template <class Attr>
-struct Min : Attr {
- static auto name() {
- static const std::string name = Attr::name() + std::string("_min");
- return name.c_str();
- }
-};
+struct ZoomInterpolatedAttribute : gl::Attribute<typename Attr::ValueType, Attr::Dimensions * 2> {
+ using Value = typename gl::Attribute<typename Attr::ValueType, Attr::Dimensions * 2>::Value;
-template <class Attr>
-struct Max : Attr {
static auto name() {
- static const std::string name = Attr::name() + std::string("_max");
- return name.c_str();
+ return Attr::name();
+ }
+
+ template <class InputType>
+ static Value value(const InputType& min, const InputType& max){
+ auto minValue = Attr::value(min);
+ auto maxValue = Attr::value(max);
+ Value result = {{}};
+ for (size_t i = 0; i < Attr::Dimensions; i++) {
+ result[i] = minValue[i];
+ result[Attr::Dimensions+i] = maxValue[i];
+ }
+ return result;
}
};
@@ -51,70 +63,62 @@ struct InterpolationUniform : gl::UniformScalar<InterpolationUniform<Attr>, floa
}
};
-struct a_color : gl::Attribute<gl::Normalized<uint8_t>, 4> {
+/*
+ Encode a four-component color value into a pair of floats. Since csscolorparser
+ uses 8-bit precision for each color component, for each float we use the upper 8
+ bits for one component (e.g. (color.r * 255) * 256), and the lower 8 for another.
+
+ Also note:
+ - Colors come in as floats 0..1, so we scale by 255.
+ - Casting the scaled values to ints is important: without doing this, e.g., the
+ fractional part of the `r` component would corrupt the lower-8 bits of the encoded
+ value, which must be reserved for the `g` component.
+*/
+static std::array<float, 2> encodeColor (const Color& color) {
+ const auto v1 = static_cast<uint16_t>( static_cast<uint16_t>(color.r*255)*256 + color.g*255);
+ const auto v2 = static_cast<uint16_t>( static_cast<uint16_t>(color.b*255)*256 + color.a*255);
+ return {{ static_cast<float>(v1), static_cast<float>(v2) }};
+}
+
+struct a_color : gl::Attribute<float, 2> {
static auto name() { return "a_color"; }
static Value value(const Color& color) {
- return {{
- gl::Normalized<uint8_t>(color.r),
- gl::Normalized<uint8_t>(color.g),
- gl::Normalized<uint8_t>(color.b),
- gl::Normalized<uint8_t>(color.a)
- }};
+ return encodeColor(color);
}
};
// used in the symbol sdf shader
-struct a_fill_color : gl::Attribute<gl::Normalized<uint8_t>, 4> {
+struct a_fill_color : gl::Attribute<float, 2> {
static auto name() { return "a_fill_color"; }
static Value value(const Color& color) {
- return {{
- gl::Normalized<uint8_t>(color.r),
- gl::Normalized<uint8_t>(color.g),
- gl::Normalized<uint8_t>(color.b),
- gl::Normalized<uint8_t>(color.a)
- }};
+ return encodeColor(color);
}
};
// used in the symbol sdf shader
-struct a_halo_color : gl::Attribute<gl::Normalized<uint8_t>, 4> {
+struct a_halo_color : gl::Attribute<float, 2> {
static auto name() { return "a_halo_color"; }
- static Value value(const Color& color) {
- return {{
- gl::Normalized<uint8_t>(color.r),
- gl::Normalized<uint8_t>(color.g),
- gl::Normalized<uint8_t>(color.b),
- gl::Normalized<uint8_t>(color.a)
- }};
+ static Value value(const Color& color) {
+ return encodeColor(color);
}
};
-struct a_stroke_color : gl::Attribute<gl::Normalized<uint8_t>, 4> {
+struct a_stroke_color : gl::Attribute<float, 2> {
static auto name() { return "a_stroke_color"; }
static Value value(const Color& color) {
- return {{
- gl::Normalized<uint8_t>(color.r),
- gl::Normalized<uint8_t>(color.g),
- gl::Normalized<uint8_t>(color.b),
- gl::Normalized<uint8_t>(color.a)
- }};
+ return encodeColor(color);
}
};
-struct a_outline_color : gl::Attribute<gl::Normalized<uint8_t>, 4> {
+struct a_outline_color : gl::Attribute<float, 2> {
static auto name() { return "a_outline_color"; }
static Value value(const Color& color) {
- return {{
- gl::Normalized<uint8_t>(color.r),
- gl::Normalized<uint8_t>(color.g),
- gl::Normalized<uint8_t>(color.b),
- gl::Normalized<uint8_t>(color.a)
- }};
+ return encodeColor(color);
}
};