4747import java .io .File ;
4848import java .io .IOException ;
4949import java .util .ArrayList ;
50+ import java .util .LinkedHashMap ;
51+ import java .util .Map ;
5052import java .util .logging .Level ;
5153import java .util .logging .Logger ;
5254
7577import androidx .annotation .StringRes ;
7678
7779public class MainActivity extends AppCompatActivity implements AdapterView .OnItemSelectedListener , CompoundButton .OnCheckedChangeListener {
80+ private static final Map <String , Integer > GL_VERSION_MAP = new LinkedHashMap <String , Integer >() {{
81+ put ("Disabled" , 0 );
82+ put ("OpenGL 4.6" , 46 );
83+ put ("OpenGL 4.5" , 45 );
84+ put ("OpenGL 4.4" , 44 );
85+ put ("OpenGL 4.3" , 43 );
86+ put ("OpenGL 4.2" , 42 );
87+ put ("OpenGL 4.1" , 41 );
88+ put ("OpenGL 4.0" , 40 );
89+ put ("OpenGL 3.3" , 33 );
90+ put ("OpenGL 3.2" , 32 );
91+ }};
92+
7893 private static final int REQUEST_CODE_SAF = 2000 ;
7994 public static Uri MGDirectoryUri ;
8095 public static Context MainActivityContext ;
@@ -122,6 +137,8 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
122137 multidrawModeOptions .add (getString (R .string .option_multidraw_mode_compute ));
123138 ArrayAdapter <String > multidrawModeAdapter = new ArrayAdapter <>(this , R .layout .spinner , multidrawModeOptions );
124139 binding .spinnerMultidrawMode .setAdapter (multidrawModeAdapter );
140+
141+ addCustomGLVersionOptions ();
125142
126143 ArrayList <String > angleClearWorkaroundOptions = new ArrayList <>();
127144 angleClearWorkaroundOptions .add (getString (R .string .option_angle_clear_workaround_disable ));
@@ -375,6 +392,7 @@ private void showOptions() {
375392 binding .spinnerAngle .setOnItemSelectedListener (null );
376393 binding .spinnerNoError .setOnItemSelectedListener (null );
377394 binding .spinnerMultidrawMode .setOnItemSelectedListener (null );
395+ binding .spinnerCustomGlVersion .setOnItemSelectedListener (null );
378396 binding .angleClearWorkaround .setOnItemSelectedListener (null );
379397 binding .switchExtGl43 .setOnCheckedChangeListener (null );
380398 binding .switchExtCs .setOnCheckedChangeListener (null );
@@ -383,7 +401,7 @@ private void showOptions() {
383401 config = MGConfig .loadConfig (this );
384402
385403 if (config == null ) {
386- config = new MGConfig (1 , 0 , 0 , 1 , 0 , 1 , 32 , 0 , 0 );
404+ config = new MGConfig (1 , 0 , 0 , 1 , 0 , 1 , 32 , 0 , 0 , 0 );
387405 }
388406 if (config .getEnableANGLE () > 3 || config .getEnableANGLE () < 0 )
389407 config .setEnableANGLE (0 );
@@ -402,10 +420,12 @@ private void showOptions() {
402420 binding .switchExtTimerQuery .setChecked (config .getEnableExtTimerQuery () == 0 );
403421 binding .switchExtDirectStateAccess .setChecked (config .getEnableExtDirectStateAccess () == 0 );
404422 binding .switchExtCs .setChecked (config .getEnableExtComputeShader () == 1 );
423+ setCustomGLVersionSpinnerSelectionByGLVersion (config .getCustomGLVersion ());
405424
406425 binding .spinnerAngle .setOnItemSelectedListener (this );
407426 binding .spinnerNoError .setOnItemSelectedListener (this );
408427 binding .spinnerMultidrawMode .setOnItemSelectedListener (this );
428+ binding .spinnerCustomGlVersion .setOnItemSelectedListener (this );
409429 binding .angleClearWorkaround .setOnItemSelectedListener (this );
410430 binding .switchExtGl43 .setOnCheckedChangeListener (this );
411431 binding .switchExtTimerQuery .setOnCheckedChangeListener (this );
@@ -453,6 +473,7 @@ public void onTextChanged(CharSequence charSequence, int start, int before, int
453473 binding .spinnerAngle .setOnItemSelectedListener (this );
454474 binding .spinnerNoError .setOnItemSelectedListener (this );
455475 binding .spinnerMultidrawMode .setOnItemSelectedListener (this );
476+ binding .spinnerCustomGlVersion .setOnItemSelectedListener (this );
456477 binding .angleClearWorkaround .setOnItemSelectedListener (this );
457478 binding .switchExtGl43 .setOnCheckedChangeListener (this );
458479 binding .switchExtTimerQuery .setOnCheckedChangeListener (this );
@@ -521,7 +542,7 @@ private void checkPermission() {
521542
522543 MGDirectoryUri = treeUri ;
523544 MGConfig config = MGConfig .loadConfig (this );
524- if (config == null ) config = new MGConfig (1 , 0 , 0 , 1 , 0 , 1 , 32 , 0 , 0 );
545+ if (config == null ) config = new MGConfig (1 , 0 , 0 , 1 , 0 , 1 , 32 , 0 , 0 , 0 );
525546 config .saveConfig (this );
526547 showOptions ();
527548 }
@@ -598,6 +619,67 @@ public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l)
598619 }
599620 }
600621
622+ if (adapterView == binding .spinnerCustomGlVersion && config != null ) {
623+ int previous = config .getCustomGLVersion ();
624+ int newValue = getGLVersionBySpinnerIndex (i );
625+
626+ if (newValue == previous ) {
627+ return ;
628+ }
629+
630+ try {
631+ if (previous == 0 ) {
632+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder (this );
633+ builder .setTitle (getString (R .string .dialog_title_warning ))
634+ .setMessage (getText (R .string .warning_enabling_custom_gl_version ))
635+ .setNegativeButton (getString (R .string .dialog_negative ), (dialog , which ) -> {
636+ isSpinnerInitialized = false ;
637+ binding .spinnerCustomGlVersion .setSelection (getSpinnerIndexByGLVersion (previous ));
638+ isSpinnerInitialized = true ;
639+ });
640+
641+ androidx .appcompat .app .AlertDialog dialog = builder .create ();
642+
643+ final int cooldownSeconds = 15 ;
644+ final int [] remainingSeconds = {cooldownSeconds };
645+
646+ dialog .setButton (DialogInterface .BUTTON_POSITIVE , getString (R .string .ok ), (dialogInterface , which ) -> {
647+ try {
648+ config .setCustomGLVersion (newValue );
649+ } catch (IOException e ) {
650+ Logger .getLogger ("MG" ).log (Level .SEVERE , "Failed to save config! Exception: " , e );
651+ Toast .makeText (MainActivity .this , getString (R .string .warning_save_failed ), Toast .LENGTH_SHORT ).show ();
652+ }
653+ });
654+
655+ dialog .setOnShowListener (dialogInterface -> {
656+ Button positiveButton = dialog .getButton (DialogInterface .BUTTON_POSITIVE );
657+ positiveButton .setText (getString (R .string .ok_with_countdown , remainingSeconds [0 ]));
658+ positiveButton .setEnabled (false );
659+
660+ new CountDownTimer (cooldownSeconds * 1000 , 1000 ) {
661+ public void onTick (long millisUntilFinished ) {
662+ remainingSeconds [0 ] = (int ) (millisUntilFinished / 1000 );
663+ positiveButton .setText (getString (R .string .ok_with_countdown , remainingSeconds [0 ]));
664+ }
665+ public void onFinish () {
666+ positiveButton .setText (R .string .ok );
667+ positiveButton .setTextColor (ContextCompat .getColor (MainActivityContext , android .R .color .holo_red_dark ));
668+ positiveButton .setEnabled (true );
669+ }
670+ }.start ();
671+ });
672+ dialog .setCancelable (false );
673+ dialog .show ();
674+ } else {
675+ config .setCustomGLVersion (newValue );
676+ }
677+ } catch (IOException e ) {
678+ Logger .getLogger ("MG" ).log (Level .SEVERE , "Failed to save config! Exception: " , e .getCause ());
679+ Toast .makeText (this , getString (R .string .warning_save_failed ), Toast .LENGTH_SHORT ).show ();
680+ }
681+ }
682+
601683 if (adapterView == binding .angleClearWorkaround && config != null ) {
602684 try {
603685 int previous = config .getAngleDepthClearFixMode ();
@@ -811,4 +893,64 @@ private boolean isAdreno740() {
811893 return renderer != null && renderer .toLowerCase ().contains ("adreno" ) && renderer .contains ("740" );
812894 }
813895
896+ private void addCustomGLVersionOptions () {
897+ ArrayList <String > glVersionOptions = new ArrayList <>(GL_VERSION_MAP .keySet ());
898+
899+ ArrayAdapter <String > glVersionAdapter = new ArrayAdapter <>(
900+ this ,
901+ R .layout .spinner ,
902+ glVersionOptions
903+ );
904+
905+ binding .spinnerCustomGlVersion .setAdapter (glVersionAdapter );
906+ }
907+
908+ private void setCustomGLVersionSpinnerSelectionByGLVersion (int glVersion ) {
909+ String targetDisplay = "Disabled" ;
910+
911+ for (Map .Entry <String , Integer > entry : GL_VERSION_MAP .entrySet ()) {
912+ if (entry .getValue () == glVersion ) {
913+ targetDisplay = entry .getKey ();
914+ break ;
915+ }
916+ }
917+
918+ // noinspection unchecked
919+ ArrayAdapter <String > adapter = (ArrayAdapter <String >)binding .spinnerCustomGlVersion .getAdapter ();
920+ int position = adapter .getPosition (targetDisplay );
921+
922+ binding .spinnerCustomGlVersion .setSelection (Math .max (position , 0 ));
923+ }
924+
925+ private void setCustomGLVersionBySpinnerIndex (int index ) throws IOException {
926+ if (config == null || !isSpinnerInitialized ) return ;
927+
928+ String selected = (String ) binding .spinnerCustomGlVersion .getItemAtPosition (index );
929+
930+ Integer glVersionValue = GL_VERSION_MAP .get (selected );
931+ if (glVersionValue == null ) {
932+ glVersionValue = 0 ;
933+ }
934+
935+ config .setCustomGLVersion (glVersionValue );
936+ }
937+
938+ private int getGLVersionBySpinnerIndex (int index ) {
939+ String selected = (String ) binding .spinnerCustomGlVersion .getItemAtPosition (index );
940+ Integer glVersionValue = GL_VERSION_MAP .get (selected );
941+ return glVersionValue != null ? glVersionValue : 0 ;
942+ }
943+
944+ private int getSpinnerIndexByGLVersion (int glVersion ) {
945+ String targetDisplay = "Disabled" ;
946+ for (Map .Entry <String , Integer > entry : GL_VERSION_MAP .entrySet ()) {
947+ if (entry .getValue () == glVersion ) {
948+ targetDisplay = entry .getKey ();
949+ break ;
950+ }
951+ }
952+ ArrayAdapter <String > adapter = (ArrayAdapter <String >) binding .spinnerCustomGlVersion .getAdapter ();
953+ return adapter .getPosition (targetDisplay );
954+ }
955+
814956}
0 commit comments