commit 42661133ecc0358043bcd1f23788857774745ad1
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Fri Mar 12 22:33:59 2021 +0100

    Another attempt at fixing tthings on early Qualcomm OpenGL ES 3.0 drivers.
    
    The previous version does not work on Adreno 405 driver V@100, present for example in a Asus ZenPad 8.
    Revert the packed 'ivec2' UBO in the vertex shader back to a 'std140' ivec4. This comes at a price if bumping into the bug on Qualcomm driver version 331 on Adreno 308 - i.e. Samsung Galaxy J4+ again.
    
    On this platform, switch off Gigaminx and then set MAX_COMPONENTS to 98.

diff --git a/src/main/java/org/distorted/main/RubikRenderer.java b/src/main/java/org/distorted/main/RubikRenderer.java
index 37ae531e..54ee0bc3 100644
--- a/src/main/java/org/distorted/main/RubikRenderer.java
+++ b/src/main/java/org/distorted/main/RubikRenderer.java
@@ -19,6 +19,9 @@
 
 package org.distorted.main;
 
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.pm.ConfigurationInfo;
 import android.opengl.GLES30;
 import android.opengl.GLSurfaceView;
 
@@ -28,6 +31,7 @@ import org.distorted.library.effect.VertexEffectQuaternion;
 import org.distorted.library.effect.VertexEffectRotate;
 import org.distorted.library.main.DistortedLibrary;
 import org.distorted.library.main.DistortedScreen;
+import org.distorted.library.mesh.MeshBase;
 
 import javax.microedition.khronos.egl.EGLConfig;
 import javax.microedition.khronos.opengles.GL10;
@@ -44,13 +48,14 @@ public class RubikRenderer implements GLSurfaceView.Renderer, DistortedLibrary.E
    private final DistortedScreen mScreen;
    private final Fps mFPS;
    private boolean mErrorShown;
+   private static boolean mSupportsGigaminx;
 
    private static class Fps
      {
      private static final int NUM_FRAMES  = 100;
 
      private long lastTime=0;
-     private long[] durations;
+     private final long[] durations;
      private int currDuration;
      private float currFPS;
 
@@ -127,6 +132,8 @@ public class RubikRenderer implements GLSurfaceView.Renderer, DistortedLibrary.E
       VertexEffectQuaternion.enable();
       BaseEffect.Type.enableEffects();
 
+      assignMaxComponents();
+
       DistortedLibrary.onSurfaceCreated(mView.getContext(),this,1);
       }
 
@@ -171,6 +178,48 @@ public class RubikRenderer implements GLSurfaceView.Renderer, DistortedLibrary.E
        }
      }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+   private void assignMaxComponents()
+     {
+     Context context = mView.getContext();
+
+     final ActivityManager activityManager     = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+     final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
+
+     int glESversion = configurationInfo.reqGlEsVersion;
+     int major = glESversion >> 16;
+     int minor = glESversion & 0xff;
+
+     MeshBase.setMaxEffComponents(242);   // the largest object, Gigaminx, has 242 components
+     mSupportsGigaminx = true;
+
+     if( major==3 && minor==0 )
+       {
+       String vendor  = GLES30.glGetString(GLES30.GL_VENDOR);
+       String version = GLES30.glGetString(GLES30.GL_VERSION);
+       String renderer= GLES30.glGetString(GLES30.GL_RENDERER);
+
+       if( vendor.contains("Qualcomm"))
+         {
+         if( (renderer.contains("Adreno") && renderer.contains("30")) || version.contains("V@331") )
+           {
+           // on Adreno 30x or driver version 331,  do not support Gigaminx.
+           // Then Cube5 is the largest with 98 components.
+           MeshBase.setMaxEffComponents(98);
+           mSupportsGigaminx = false;
+           }
+         }
+       }
+     }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+   public static boolean supportsGigaminx()
+     {
+     return mSupportsGigaminx;
+     }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
    float getFPS()
diff --git a/src/main/java/org/distorted/states/RubikStatePlay.java b/src/main/java/org/distorted/states/RubikStatePlay.java
index 924bcf0a..46ba82bc 100644
--- a/src/main/java/org/distorted/states/RubikStatePlay.java
+++ b/src/main/java/org/distorted/states/RubikStatePlay.java
@@ -38,6 +38,7 @@ import org.distorted.dialogs.RubikDialogScores;
 import org.distorted.dialogs.RubikDialogTutorial;
 import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
+import org.distorted.main.RubikRenderer;
 import org.distorted.objects.ObjectList;
 import org.distorted.scores.RubikScores;
 
@@ -281,11 +282,14 @@ public class RubikStatePlay extends RubikStateBase
             {
             if( act.getPreRender().canPlay() && StateList.getCurrentState()== StateList.PLAY )
               {
-              mObject = obj;
-              mSize   = sizes[index];
-              act.changeObject(list,sizes[index], true);
-              adjustLevels(act);
-              mMoves.clear();
+              if( RubikRenderer.supportsGigaminx() || list!=ObjectList.MEGA || sizes[index]<=3 )
+                {
+                mObject = obj;
+                mSize   = sizes[index];
+                act.changeObject(list,sizes[index], true);
+                adjustLevels(act);
+                mMoves.clear();
+                }
               }
 
             mObjectPopup.dismiss();
