0
votes

On some devices (so far samsung galaxy note 2 and 3 + Xperia Z1) I get this error thrown by a call to glUniformMatrix4fv(uMatrixLocation, 10, false, matrix, 0) to set the transformation matrix.

The error is:

java.lang.IllegalArgumentException: length - offset < count*16 < needed
    at android.opengl.GLES20.glUniformMatrix4fv(Native Method)

and it's caused by this line in my textureShaderProgram code:

glUniformMatrix4fv(uMatrixLocation, 10, false, matrix, 0);

uMatrixLocation is the location pointer of the matrix var 10 is the number of transformation matrices (so matrix.length() = 10 * 16 = 160) matrix is the float[] varible containing all the transformation data and 0 is the offset in the matrix

I've tried to increase the count variable in order to solve it but with no success.

The source code from google where this error is generated is at:

https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/jni/android_opengl_GLES20.cpp

and these particular lines do the check and throw the above error:

   _remaining = _env->GetArrayLength(value_ref) - offset;
   if (_remaining < count*16) {
       _exception = 1;
       _exceptionType = "java/lang/IllegalArgumentException";
      _exceptionMessage = "length - offset < count*16 < needed";
      goto exit;
   }

any clue about why these devices throw the error? Could the cpp file on these devices differ from the other devices?

added 20140114 18:47 These are the float values passed to glUniformMatrix4fv(uMatrixLocation, 10, false, matrix, 0) in matrix variable:

my float is: 0.5625
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 1.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: -1.0
my float is: 0.0
my float is: 0.0
my float is: -0.8425926
my float is: 0.0
my float is: 1.0
my float is: 0.5625
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 1.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: -1.0
my float is: 0.0
my float is: 0.098958336
my float is: -1.1574074
my float is: 0.0
my float is: 1.0
my float is: 0.5625
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 1.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: -1.0
my float is: 0.0
my float is: -0.296875
my float is: -1.1574074
my float is: -0.0
my float is: 1.0
my float is: 0.5625
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 1.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: -1.0
my float is: 0.0
my float is: -0.098958336
my float is: -1.1574074
my float is: -0.0
my float is: 1.0
my float is: 0.5625
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 1.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: -1.0
my float is: 0.0
my float is: 0.296875
my float is: -1.1574074
my float is: 0.0
my float is: 1.0
my float is: 0.5625
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 1.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: -1.0
my float is: 0.0
my float is: 0.9010416
my float is: -0.8240741
my float is: 0.0
my float is: 1.0
my float is: 0.5625
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 1.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: -1.0
my float is: 0.0
my float is: 0.9010416
my float is: 0.8240741
my float is: 0.0
my float is: 1.0
my float is: 0.5625
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 1.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: -1.0
my float is: 0.0
my float is: 0.9010416
my float is: 0.0
my float is: 0.0
my float is: 1.0
my float is: 0.5625
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 1.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: 0.0
my float is: -1.0
my float is: 0.0
my float is: 0.0
my float is: -1.1574074
my float is: 0.0
my float is: 1.0

and this is my vertex shader:

uniform mat4 u_Matrix[10]; 

attribute lowp float a_MatrixIndex;

attribute vec4 a_Position;  
attribute vec2 a_TextureCoordinates;
attribute vec3 a_Color;

varying vec3 v_Color;
varying vec2 v_TextureCoordinates;

void main()                    
{                    
v_Color = a_Color;        
int MatrixIndex = int(a_MatrixIndex);

    v_TextureCoordinates = a_TextureCoordinates;          
    gl_Position = u_Matrix[MatrixIndex] * a_Position;    
}
2
Check your types that you send to shader or in your draw method.Sergey Shustikov
hi deathember, look at my addition in the original post. Can you see any strange float values (I couldn't), maybe some devices doesn't handle the precision of the floats I'm sending in?droid4fun
why you think a float contains a 16 bytes? (matrix.length() = 10 * 16 = 160))Sergey Shustikov
Sorry typo from my part... Matrix is a float[] array. It is composed of several matrices containing 16 float components. Actually my matrix float[] array length is 144 and according to the error message it should be compared and inferior to count * 16 = 160 so I don't understand the error message. (and why it only occurs on some phone models)droid4fun
Yes but you define matrix that has 10 elements.Sergey Shustikov

2 Answers

0
votes

If matrix1 is the object containing your float values, you will need to convert that to an array like below.

context.uniformMatrix4fv(loc, false, new Float32Array(matrix1.getAsArray()) );

0
votes

This is now solved. The issue was actually that on Android > 4.2 the implementation of:

glUniformMatrix4fv(uMatrixLocation, count, false, matrix, 0);

must have been changed. The count variable must match exactly the 'number' of transformation matrices inside the matrix variable. (as deathember hinted in one comment above)

So the solution was just to pass a count variable to this function instead of hardcoding it.

You can still use the same texture_vertex code!! In my case it looks like this: (even though I use this program for matrice arrays from 1 to 9 in length, you can set the highest matrix number here)

uniform mat4 u_Matrix[9]; 

attribute lowp float a_MatrixIndex;

attribute vec4 a_Position;  
attribute vec2 a_TextureCoordinates;
attribute vec3 a_Color;

varying vec3 v_Color;
varying vec2 v_TextureCoordinates;

void main()                    
{                    
v_Color = a_Color;        
int MatrixIndex = int(a_MatrixIndex);

    v_TextureCoordinates = a_TextureCoordinates;          
    gl_Position = u_Matrix[MatrixIndex] * a_Position;    
}

If you want to read more how I tested this you can check out my blogg here:

Android device fragmentation, it finally happened