[core] disallow subtyping of gl::Attributes<> and use type aliases instead

This commit is contained in:
Konstantin Käfer
2019-02-27 13:59:49 +01:00
parent 55c7b86053
commit cd06b550dd
10 changed files with 79 additions and 82 deletions

View File

@@ -214,7 +214,7 @@ void bindAttributeLocation(Context&, ProgramID, AttributeLocation, const char *
std::set<std::string> getActiveAttributes(ProgramID);
template <class... As>
class Attributes {
class Attributes final {
public:
using Types = TypeList<As...>;
using Locations = IndexedTuple<

View File

@@ -52,7 +52,7 @@ public:
UniformLocation uniformLocation(ProgramID, const char * name);
template <class... Us>
class Uniforms {
class Uniforms final {
public:
using Types = TypeList<Us...>;
using State = IndexedTuple<TypeList<Us...>, TypeList<UniformState<typename Us::Value>...>>;

View File

@@ -514,20 +514,20 @@ size_t SymbolLayout::addSymbol(Buffer& buffer,
uint16_t index = segment.vertexLength;
// coordinates (2 triangles)
buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(labelAnchor.point, tl, symbol.glyphOffset.y, tex.x, tex.y, sizeData));
buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(labelAnchor.point, tr, symbol.glyphOffset.y, tex.x + tex.w, tex.y, sizeData));
buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(labelAnchor.point, bl, symbol.glyphOffset.y, tex.x, tex.y + tex.h, sizeData));
buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(labelAnchor.point, br, symbol.glyphOffset.y, tex.x + tex.w, tex.y + tex.h, sizeData));
buffer.vertices.emplace_back(SymbolSDFIconProgram::layoutVertex(labelAnchor.point, tl, symbol.glyphOffset.y, tex.x, tex.y, sizeData));
buffer.vertices.emplace_back(SymbolSDFIconProgram::layoutVertex(labelAnchor.point, tr, symbol.glyphOffset.y, tex.x + tex.w, tex.y, sizeData));
buffer.vertices.emplace_back(SymbolSDFIconProgram::layoutVertex(labelAnchor.point, bl, symbol.glyphOffset.y, tex.x, tex.y + tex.h, sizeData));
buffer.vertices.emplace_back(SymbolSDFIconProgram::layoutVertex(labelAnchor.point, br, symbol.glyphOffset.y, tex.x + tex.w, tex.y + tex.h, sizeData));
// Dynamic/Opacity vertices are initialized so that the vertex count always agrees with
// the layout vertex buffer, but they will always be updated before rendering happens
auto dynamicVertex = SymbolDynamicLayoutAttributes::vertex(labelAnchor.point, 0);
auto dynamicVertex = SymbolSDFIconProgram::dynamicLayoutVertex(labelAnchor.point, 0);
buffer.dynamicVertices.emplace_back(dynamicVertex);
buffer.dynamicVertices.emplace_back(dynamicVertex);
buffer.dynamicVertices.emplace_back(dynamicVertex);
buffer.dynamicVertices.emplace_back(dynamicVertex);
auto opacityVertex = SymbolOpacityAttributes::vertex(1.0, 1.0);
auto opacityVertex = SymbolSDFIconProgram::opacityVertex(1.0, 1.0);
buffer.opacityVertices.emplace_back(opacityVertex);
buffer.opacityVertices.emplace_back(opacityVertex);
buffer.opacityVertices.emplace_back(opacityVertex);
@@ -575,14 +575,14 @@ void SymbolLayout::addToDebugBuffers(SymbolBucket& bucket) {
auto& segment = collisionBuffer.segments.back();
uint16_t index = segment.vertexLength;
collisionBuffer.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, symbolInstance.anchor.point, tl));
collisionBuffer.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, symbolInstance.anchor.point, tr));
collisionBuffer.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, symbolInstance.anchor.point, br));
collisionBuffer.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, symbolInstance.anchor.point, bl));
collisionBuffer.vertices.emplace_back(CollisionBoxProgram::layoutVertex(anchor, symbolInstance.anchor.point, tl));
collisionBuffer.vertices.emplace_back(CollisionBoxProgram::layoutVertex(anchor, symbolInstance.anchor.point, tr));
collisionBuffer.vertices.emplace_back(CollisionBoxProgram::layoutVertex(anchor, symbolInstance.anchor.point, br));
collisionBuffer.vertices.emplace_back(CollisionBoxProgram::layoutVertex(anchor, symbolInstance.anchor.point, bl));
// Dynamic vertices are initialized so that the vertex count always agrees with
// the layout vertex buffer, but they will always be updated before rendering happens
auto dynamicVertex = CollisionBoxDynamicAttributes::vertex(false, false);
auto dynamicVertex = CollisionBoxProgram::dynamicVertex(false, false);
collisionBuffer.dynamicVertices.emplace_back(dynamicVertex);
collisionBuffer.dynamicVertices.emplace_back(dynamicVertex);
collisionBuffer.dynamicVertices.emplace_back(dynamicVertex);

View File

@@ -123,7 +123,7 @@ namespace mbgl {
void addDynamicAttributes(const Point<float>& anchorPoint, const float angle,
gl::VertexVector<SymbolDynamicLayoutAttributes::Vertex>& dynamicVertexArray) {
auto dynamicVertex = SymbolDynamicLayoutAttributes::vertex(anchorPoint, angle);
auto dynamicVertex = SymbolSDFIconProgram::dynamicLayoutVertex(anchorPoint, angle);
dynamicVertexArray.emplace_back(dynamicVertex);
dynamicVertexArray.emplace_back(dynamicVertex);
dynamicVertexArray.emplace_back(dynamicVertex);

View File

@@ -159,8 +159,6 @@ struct a_pattern_from {
} // namespace attributes
struct PositionOnlyLayoutAttributes : gl::Attributes<
attributes::a_pos>
{};
using PositionOnlyLayoutAttributes = gl::Attributes<attributes::a_pos>;
} // namespace mbgl

View File

@@ -17,13 +17,7 @@ using CollisionBoxLayoutAttributes = gl::Attributes<
attributes::a_anchor_pos,
attributes::a_extrude>;
struct CollisionBoxDynamicAttributes : gl::Attributes<attributes::a_placed> {
static Vertex vertex(bool placed, bool notUsed) {
return Vertex {
{{ static_cast<uint8_t>(placed), static_cast<uint8_t>(notUsed) }}
};
}
};
using CollisionBoxDynamicAttributes = gl::Attributes<attributes::a_placed>;
class CollisionBoxProgram : public Program<
shaders::collision_box,
@@ -38,8 +32,8 @@ class CollisionBoxProgram : public Program<
public:
using Program::Program;
static CollisionBoxLayoutAttributes::Vertex vertex(Point<float> a, Point<float> anchor, Point<float> o) {
return CollisionBoxLayoutAttributes::Vertex {
static CollisionBoxLayoutAttributes::Vertex layoutVertex(Point<float> a, Point<float> anchor, Point<float> o) {
return {
{{
static_cast<int16_t>(a.x),
static_cast<int16_t>(a.y)
@@ -55,6 +49,12 @@ public:
};
}
static CollisionBoxDynamicAttributes::Vertex dynamicVertex(bool placed, bool notUsed) {
return {
{{ static_cast<uint8_t>(placed), static_cast<uint8_t>(notUsed) }}
};
}
template <class DrawMode>
void draw(gl::Context& context,
DrawMode drawMode,
@@ -120,7 +120,7 @@ public:
using Program::Program;
static CollisionBoxLayoutAttributes::Vertex vertex(Point<float> a, Point<float> anchor, Point<float> o) {
return CollisionBoxLayoutAttributes::Vertex {
return {
{{
static_cast<int16_t>(a.x),
static_cast<int16_t>(a.y)

View File

@@ -29,10 +29,9 @@ MBGL_DEFINE_UNIFORM_SCALAR(float, u_lightintensity);
MBGL_DEFINE_UNIFORM_SCALAR(float, u_height_factor);
} // namespace uniforms
struct FillExtrusionLayoutAttributes : gl::Attributes<
using FillExtrusionLayoutAttributes = gl::Attributes<
attributes::a_pos,
attributes::a_normal_ed>
{};
attributes::a_normal_ed>;
using FillExtrusionUniforms = TypeList<
uniforms::u_matrix,

View File

@@ -29,10 +29,9 @@ MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_patternscale_b);
MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_gl_units_to_pixels);
} // namespace uniforms
struct LineLayoutAttributes : gl::Attributes<
using LineLayoutAttributes = gl::Attributes<
attributes::a_pos_normal,
attributes::a_data<uint8_t, 4>>
{};
attributes::a_data<uint8_t, 4>>;
class LineProgram : public Program<
shaders::line,

View File

@@ -46,53 +46,13 @@ MBGL_DEFINE_UNIFORM_SCALAR(bool, u_rotate_symbol);
MBGL_DEFINE_UNIFORM_SCALAR(float, u_aspect_ratio);
} // namespace uniforms
struct SymbolLayoutAttributes : gl::Attributes<
using SymbolLayoutAttributes = gl::Attributes<
attributes::a_pos_offset,
attributes::a_data<uint16_t, 4>>
{
static Vertex vertex(Point<float> labelAnchor,
Point<float> o,
float glyphOffsetY,
uint16_t tx,
uint16_t ty,
const Range<float>& sizeData) {
return Vertex {
// combining pos and offset to reduce number of vertex attributes passed to shader (8 max for some devices)
{{
static_cast<int16_t>(labelAnchor.x),
static_cast<int16_t>(labelAnchor.y),
static_cast<int16_t>(::round(o.x * 32)), // use 1/32 pixels for placement
static_cast<int16_t>(::round((o.y + glyphOffsetY) * 32))
}},
{{
tx,
ty,
static_cast<uint16_t>(sizeData.min * 256),
static_cast<uint16_t>(sizeData.max * 256)
}}
};
}
};
attributes::a_data<uint16_t, 4>>;
struct SymbolDynamicLayoutAttributes : gl::Attributes<attributes::a_projected_pos> {
static Vertex vertex(Point<float> anchorPoint, float labelAngle) {
return Vertex {
{{
anchorPoint.x,
anchorPoint.y,
labelAngle
}}
};
}
};
using SymbolDynamicLayoutAttributes = gl::Attributes<attributes::a_projected_pos>;
struct SymbolOpacityAttributes : gl::Attributes<attributes::a_fade_opacity> {
static Vertex vertex(bool placed, float opacity) {
return Vertex {
{{ static_cast<uint8_t>((static_cast<uint8_t>(opacity * 127) << 1) | static_cast<uint8_t>(placed)) }}
};
}
};
using SymbolOpacityAttributes = gl::Attributes<attributes::a_fade_opacity>;
struct ZoomEvaluatedSize {
bool isZoomConstant;
@@ -242,13 +202,54 @@ public:
Range<float> coveringZoomStops;
};
class SymbolProgramBase {
public:
static SymbolLayoutAttributes::Vertex layoutVertex(Point<float> labelAnchor,
Point<float> o,
float glyphOffsetY,
uint16_t tx,
uint16_t ty,
const Range<float>& sizeData) {
return {
// combining pos and offset to reduce number of vertex attributes passed to shader (8 max for some devices)
{{
static_cast<int16_t>(labelAnchor.x),
static_cast<int16_t>(labelAnchor.y),
static_cast<int16_t>(::round(o.x * 32)), // use 1/32 pixels for placement
static_cast<int16_t>(::round((o.y + glyphOffsetY) * 32))
}},
{{
tx,
ty,
static_cast<uint16_t>(sizeData.min * 256),
static_cast<uint16_t>(sizeData.max * 256)
}}
};
}
static SymbolDynamicLayoutAttributes::Vertex dynamicLayoutVertex(Point<float> anchorPoint, float labelAngle) {
return {
{{
anchorPoint.x,
anchorPoint.y,
labelAngle
}}
};
}
static SymbolOpacityAttributes::Vertex opacityVertex(bool placed, float opacity) {
return {
{{ static_cast<uint8_t>((static_cast<uint8_t>(opacity * 127) << 1) | static_cast<uint8_t>(placed)) }}
};
}
};
template <class Shaders,
class Primitive,
class LayoutAttrs,
class UniformTypeList,
class PaintProps>
class SymbolProgram {
class SymbolProgram : public SymbolProgramBase {
public:
using LayoutAttributes = LayoutAttrs;
using LayoutVertex = typename LayoutAttributes::Vertex;

View File

@@ -338,7 +338,7 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, std::set<uint32_t>&
seenCrossTileIDs.insert(symbolInstance.crossTileID);
if (symbolInstance.hasText) {
auto opacityVertex = SymbolOpacityAttributes::vertex(opacityState.text.placed, opacityState.text.opacity);
auto opacityVertex = SymbolSDFTextProgram::opacityVertex(opacityState.text.placed, opacityState.text.opacity);
for (size_t i = 0; i < symbolInstance.horizontalGlyphQuads.size() * 4; i++) {
bucket.text.opacityVertices.emplace_back(opacityVertex);
}
@@ -353,7 +353,7 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, std::set<uint32_t>&
}
}
if (symbolInstance.hasIcon) {
auto opacityVertex = SymbolOpacityAttributes::vertex(opacityState.icon.placed, opacityState.icon.opacity);
auto opacityVertex = SymbolIconProgram::opacityVertex(opacityState.icon.placed, opacityState.icon.opacity);
if (symbolInstance.iconQuad) {
bucket.icon.opacityVertices.emplace_back(opacityVertex);
bucket.icon.opacityVertices.emplace_back(opacityVertex);
@@ -369,7 +369,7 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, std::set<uint32_t>&
if (feature.alongLine) {
return;
}
auto dynamicVertex = CollisionBoxDynamicAttributes::vertex(placed, false);
auto dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, false);
for (size_t i = 0; i < feature.boxes.size() * 4; i++) {
bucket.collisionBox.dynamicVertices.emplace_back(dynamicVertex);
}
@@ -380,7 +380,7 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, std::set<uint32_t>&
return;
}
for (const CollisionBox& box : feature.boxes) {
auto dynamicVertex = CollisionBoxDynamicAttributes::vertex(placed, !box.used);
auto dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, !box.used);
bucket.collisionCircle.dynamicVertices.emplace_back(dynamicVertex);
bucket.collisionCircle.dynamicVertices.emplace_back(dynamicVertex);
bucket.collisionCircle.dynamicVertices.emplace_back(dynamicVertex);