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

Bind only active attributes in order to avoid exceeding attribute limits #9373

Merged
merged 12 commits into from
Jun 29, 2017

Conversation

lbud
Copy link
Contributor

@lbud lbud commented Jun 26, 2017

I think this fixes #9331, although I'm not sure how to go about testing on an older Android device.

This PR

  • flips the order of uniformsState and attributeLocations in the Program constructor, so that the program is initially linked before calling attributeLocations,
  • changes Attributes::bindLocations to query active attributes, temporarily store a set of those attributes, and then manually bind only the active attributes, and
  • re-links the program once more after setting the attribute bindings.

@lbud lbud requested review from ivovandongen and jfirebaugh June 26, 2017 22:29
}

return Locations{ bindAttributeLocation(
id, locationToBindAttribute(activeAttributes, As::name()), As::name())... };
Copy link
Contributor

@jfirebaugh jfirebaugh Jun 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is close, but we want to number them in the order defined by the As argument pack, rather than lexicographical order by name. The latter might put an attribute that's sometimes disabled at location 0, which as we know, causes issues. Try this:

AttributeLocation location = 0;
return Locations {
    (activeAttributes.count(As::name()) ? bindAttributeLocation(id, location++, As::name()) : -1)...
};

@@ -242,7 +247,18 @@ class Attributes {
static constexpr std::size_t Index = TypeIndex<A, As...>::value;

static Locations bindLocations(const ProgramID& id) {
return Locations { bindAttributeLocation(id, Index<As>, As::name())... };
std::set<std::string> activeAttributes;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can minimize the declarations and code here in the header by writing:

std::set<std::string> activeAttributes = getActiveAttributes(id);

Then getActiveAttributes is the only thing that needs to be declared; everything else can go in the .cpp.

namespace mbgl {
namespace gl {

AttributeLocation bindAttributeLocation(ProgramID id, AttributeLocation location, const char* name) {
MBGL_CHECK_ERROR(glBindAttribLocation(id, location, name));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add assert(location <= 8) for good measure.

@ivovandongen
Copy link
Contributor

@lbud Currently crashes on android devices:

********** Crash dump: **********
Build fingerprint: 'google/sailfish/sailfish:7.1.2/NJH47B/4021576:user/release-keys'
pid: 2543, tid: 2543, name: pboxsdk.testapp  >>> com.mapbox.mapboxsdk.testapp <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
Stack frame #00 pc 0010aa6c  /vendor/lib/egl/libGLESv2_adreno.so (_ZN10EsxProgram15GetActiveAttribEP10EsxContextjjPiS2_P22EsxProgramResourceTypePc+107)
Stack frame #01 pc 000ab6a7  /vendor/lib/egl/libGLESv2_adreno.so (_ZN10EsxContext17GlGetActiveAttribEjjiPiS0_PjPc+134)
Stack frame #02 pc 000a005f  /vendor/lib/egl/libGLESv2_adreno.so (glGetActiveAttrib+62)
Stack frame #03 pc 00399123  /data/app/com.mapbox.mapboxsdk.testapp-1/lib/arm/libmapbox-gl.so: Routine operator() at /Users/ivo/git/mapbox-gl-native/src/mbgl/gl/attribute.cpp:39
Stack frame #04 pc 00398fa9  /data/app/com.mapbox.mapboxsdk.testapp-1/lib/arm/libmapbox-gl.so: Routine mbgl::gl::getAttributeName(unsigned int, int, int) at /Users/ivo/git/mapbox-gl-native/src/mbgl/gl/attribute.cpp:39
Stack frame #05 pc 001d716b  /data/app/com.mapbox.mapboxsdk.testapp-1/lib/arm/libmapbox-gl.so: Routine mbgl::gl::Attributes<mbgl::attributes::a_pos>::bindLocations(unsigned int const&) at /Users/ivo/git/mapbox-gl-native/platform/android/MapboxGLAndroidSDK/.externalNativeBuild/cmake/debug/armeabi-v7a/../../../../../../../src/mbgl/gl/attribute.hpp:256
Stack frame #06 pc 001d5e0b  /data/app/com.mapbox.mapboxsdk.testapp-1/lib/arm/libmapbox-gl.so: Routine Program at /Users/ivo/git/mapbox-gl-native/platform/android/MapboxGLAndroidSDK/.externalNativeBuild/cmake/debug/armeabi-v7a/../../../../../../../src/mbgl/gl/program.hpp:37
Stack frame #07 pc 001d5961  /data/app/com.mapbox.mapboxsdk.testapp-1/lib/arm/libmapbox-gl.so: Routine mbgl::gl::Program<mbgl::gl::Triangle, mbgl::gl::Attributes<mbgl::attributes::a_pos>, mbgl::gl::Uniforms<mbgl::uniforms::u_matrix, mbgl::uniforms::u_world, mbgl::uniforms::u_image, mbgl::uniforms::u_opacity> >::createProgram(mbgl::gl::Context&, mbgl::ProgramParameters const&, char const*, char const*, char const*) at /Users/ivo/git/mapbox-gl-native/platform/android/MapboxGLAndroidSDK/.externalNativeBuild/cmake/debug/armeabi-v7a/../../../../../../../src/mbgl/gl/program.hpp:81
Stack frame #08 pc 001d5529  /data/app/com.mapbox.mapboxsdk.testapp-1/lib/arm/libmapbox-gl.so: Routine Program at /Users/ivo/git/mapbox-gl-native/platform/android/MapboxGLAndroidSDK/.externalNativeBuild/cmake/debug/armeabi-v7a/../../../../../../../src/mbgl/programs/program.hpp:40
Stack frame #09 pc 001d5349  /data/app/com.mapbox.mapboxsdk.testapp-1/lib/arm/libmapbox-gl.so: Routine Program at /Users/ivo/git/mapbox-gl-native/platform/android/MapboxGLAndroidSDK/.externalNativeBuild/cmake/debug/armeabi-v7a/../../../../../../../src/mbgl/programs/extrusion_texture_program.hpp:23
Stack frame #10 pc 001d4d8f  /data/app/com.mapbox.mapboxsdk.testapp-1/lib/arm/libmapbox-gl.so: Routine Programs at /Users/ivo/git/mapbox-gl-native/platform/android/MapboxGLAndroidSDK/.externalNativeBuild/cmake/debug/armeabi-v7a/../../../../../../../src/mbgl/programs/programs.hpp:20
Stack frame #11 pc 001cb569  /data/app/com.mapbox.mapboxsdk.testapp-1/lib/arm/libmapbox-gl.so: Routine std::__ndk1::__unique_if<mbgl::Programs>::__unique_single std::__ndk1::make_unique<mbgl::Programs, mbgl::gl::Context&, mbgl::ProgramParameters>(mbgl::gl::Context&, mbgl::ProgramParameters&&) at /Users/ivo/Library/Android/sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/include/memory:3149
Stack frame #12 pc 001bbefb  /data/app/com.mapbox.mapboxsdk.testapp-1/lib/arm/libmapbox-gl.so: Routine std::__ndk1::__unique_if<mbgl::Painter>::__unique_single std::__ndk1::make_unique<mbgl::Painter, mbgl::gl::Context&, mbgl::TransformState const&, float const&, std::experimental::fundamentals_v1::optional<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > > const&>(mbgl::gl::Context&, mbgl::TransformState const&, float const&, std::experimental::fundamentals_v1::optional<std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > > const&) at /Users/ivo/Library/Android/sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/include/memory:3149
Stack frame #13 pc 001bc7e1  /data/app/com.mapbox.mapboxsdk.testapp-1/lib/arm/libmapbox-gl.so: Routine mbgl::Map::render(mbgl::View&) at /Users/ivo/git/mapbox-gl-native/src/mbgl/map/map.cpp:208
Stack frame #14 pc 000b8ab5  /data/app/com.mapbox.mapboxsdk.testapp-1/lib/arm/libmapbox-gl.so: Routine mbgl::android::NativeMapView::render(_JNIEnv&) at /Users/ivo/git/mapbox-gl-native/platform/android/src/native_map_view.cpp:300
Stack frame #15 pc 000ce603  /data/app/com.mapbox.mapboxsdk.testapp-1/lib/arm/libmapbox-gl.so: Routine operator() at /Users/ivo/git/mapbox-gl-native/platform/android/MapboxGLAndroidSDK/.externalNativeBuild/cmake/debug/armeabi-v7a/../../../../../../../mason_packages/headers/jni.hpp/3.0.0/include/jni/native_method.hpp:245
Stack frame #16 pc 000ce599  /data/app/com.mapbox.mapboxsdk.testapp-1/lib/arm/libmapbox-gl.so: Routine operator() at /Users/ivo/git/mapbox-gl-native/platform/android/MapboxGLAndroidSDK/.externalNativeBuild/cmake/debug/armeabi-v7a/../../../../../../../mason_packages/headers/jni.hpp/3.0.0/include/jni/native_method.hpp:112
Stack frame #17 pc 000ce561  /data/app/com.mapbox.mapboxsdk.testapp-1/lib/arm/libmapbox-gl.so: Routine __invoke at /Users/ivo/git/mapbox-gl-native/platform/android/MapboxGLAndroidSDK/.externalNativeBuild/cmake/debug/armeabi-v7a/../../../../../../../mason_packages/headers/jni.hpp/3.0.0/include/jni/native_method.hpp:110
Stack frame #18 pc 000ce68d  /data/app/com.mapbox.mapboxsdk.testapp-1/lib/arm/libmapbox-gl.so: Routine operator()<jni::jobject *> at /Users/ivo/git/mapbox-gl-native/platform/android/MapboxGLAndroidSDK/.externalNativeBuild/cmake/debug/armeabi-v7a/../../../../../../../mason_packages/headers/jni.hpp/3.0.0/include/jni/native_method.hpp:59
Stack frame #19 pc 000ce64d  /data/app/com.mapbox.mapboxsdk.testapp-1/lib/arm/libmapbox-gl.so: Routine __invoke<jni::jobject *> at /Users/ivo/git/mapbox-gl-native/platform/android/MapboxGLAndroidSDK/.externalNativeBuild/cmake/debug/armeabi-v7a/../../../../../../../mason_packages/headers/jni.hpp/3.0.0/include/jni/native_method.hpp:55
Stack frame #20 pc 00558a3f  /data/app/com.mapbox.mapboxsdk.testapp-1/oat/arm/base.odex (offset 0x52e000)

@lbud lbud changed the title Bind only active attributes in order to avoid exceeding attribute limits [not ready] Bind only active attributes in order to avoid exceeding attribute limits Jun 26, 2017
Copy link
Contributor

@ivovandongen ivovandongen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks to be working well on the Nexus 4 now. Thanks!

@lbud lbud changed the title [not ready] Bind only active attributes in order to avoid exceeding attribute limits Bind only active attributes in order to avoid exceeding attribute limits Jun 28, 2017
@lbud
Copy link
Contributor Author

lbud commented Jun 29, 2017

One small thing I wanted to flag is that is that I had to make UniqueProgram program in program.hpp public so that LayoutAttributes::bindings could access the ProgramID, needed to query GL_ACTIVE_ATTRIBUTES and only enable as many attributes as are active rather than the full set of possible attributes.

@@ -255,8 +266,9 @@ class Attributes {
}

template <class DrawMode>
static Bindings bindings(const VertexBuffer<Vertex, DrawMode>& buffer) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does anything actually fail if you don't make this change? In theory, this function is called only for active attributes. If it's called for an attribute that isn't actually present, then there's a bug somewhere I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 @jfirebaugh good question — I added it after this build, which was terminated during the render tests with

terminate called after throwing an instance of 'mbgl::gl::Error'
  what():  glEnableVertexAttribArray(location): Error GL_INVALID_VALUE at ../../../src/mbgl/gl/attribute.cpp:62

(glEnableVertexAttribArray documentation)
But I was able to reproduce that error locally at the time using a fill-color property function, which now works locally if I remove it… I'll remove it and see if any of the CI builds still have issues.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I spoke too soon — locally I get the same error:

libc++abi.dylib: terminating with uncaught exception of type mbgl::gl::Error: glEnableVertexAttribArray(location): Error GL_INVALID_VALUE at /Users/lbud/src/mapbox-gl-native/src/mbgl/gl/attribute.cpp:70

Copy link
Contributor

@jfirebaugh jfirebaugh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, the attempt to bind at location -1 comes from the FillProgram, which includes fill-outline-color in its paint properties, but doesn't use it or have an a_outline_color attribute. Can you add a comment to the if (location == -1) return; explaining this? Looks good otherwise!

@lbud lbud merged commit b5fed11 into master Jun 29, 2017
@lbud lbud deleted the 9331-bind-active-attribs branch June 29, 2017 18:29
@kkaefer kkaefer added the Core The cross-platform C++ core, aka mbgl label Jun 30, 2017
jfirebaugh pushed a commit that referenced this pull request Jul 6, 2017
…ute limits (#9373)

Introducing two new attributes to enable property functions for line-width (#9250) pushed the attribute count over GL_MAX_VERTEX_ATTRIBS on some devices. Now we selectively bind only attributes that are used, making it unlikely to surpass GL_MAX_VERTEX_ATTRIBS.
jfirebaugh pushed a commit that referenced this pull request Jul 17, 2017
…ute limits (#9373)

Introducing two new attributes to enable property functions for line-width (#9250) pushed the attribute count over GL_MAX_VERTEX_ATTRIBS on some devices. Now we selectively bind only attributes that are used, making it unlikely to surpass GL_MAX_VERTEX_ATTRIBS.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Core The cross-platform C++ core, aka mbgl
Projects
None yet
Development

Successfully merging this pull request may close these issues.

glBindAttribLocation(id, location, name): Error GL_INVALID_VALUE
5 participants