@@ -107,20 +107,42 @@ public class GraphicsEnvironment {
private static final int UPDATABLE_DRIVER_GLOBAL_OPT_IN_PRERELEASE_DRIVER = 2 ;
private static final int UPDATABLE_DRIVER_GLOBAL_OPT_IN_OFF = 3 ;
// System properties related to ANGLE and legacy GLES graphics drivers.
private static final String PROPERTY_EGL_SYSTEM_DRIVER = " ro.hardware.egl " ;
// TODO (b/224558229): Properly add this to the list of system properties for a device:
private static final String PROPERTY_EGL_LEGACY_DRIVER = " ro.hardware.egl_legacy " ;
// Values for ANGLE_GL_DRIVER_ALL_ANGLE
private static final int ANGLE_GL_DRIVER_ALL_ANGLE_ON = 1 ;
private static final int ANGLE_GL_DRIVER_ALL_ANGLE_OFF = 0 ;
private static final int ANGLE_GL_DRIVER_ALL_LEGACY = - 1 ;
// Values for ANGLE_GL_DRIVER_SELECTION_VALUES
private static final String ANGLE_GL_DRIVER_CHOICE_DEFAULT = " default " ;
private static final String ANGLE_GL_DRIVER_CHOICE_ANGLE = " angle " ;
private static final String ANGLE_GL_DRIVER_CHOICE_LEGACY = " legacy " ;
// The following value is a deprecated choice for "legacy"
private static final String ANGLE_GL_DRIVER_CHOICE_NATIVE = " native " ;
// Values returned by getDriverForPackage() and getDefaultDriverToUse() (avoid returning
// strings for performance reasons)
private static final int ANGLE_GL_DRIVER_TO_USE_LEGACY = 0 ;
private static final int ANGLE_GL_DRIVER_TO_USE_ANGLE = 1 ;
private ClassLoader mClassLoader ;
private String mLibrarySearchPaths ;
private String mLibraryPermittedPaths ;
private GameManager mGameManager ;
private boolean mAngleIsSystemDriver = false ;
private boolean mNoLegacyDriver = false ;
// When ANGLE is the system driver, this is the name of the legacy driver.
//
// IMPORTANT: When ANGLE is the system driver, and if there is a fallback "legacy" GLES driver
// (e.g. from the GPU provider), the name of that driver must be set here, unles and until
// PROPERTY_EGL_LEGACY_DRIVER has been properly plumbed and this becomes broadly available.
private String mEglLegacyDriver = " " ;
private int mAngleOptInIndex = - 1 ;
/**
@@ -138,6 +160,23 @@ public class GraphicsEnvironment {
setupGpuLayers ( context , coreSettings , pm , packageName , appInfoWithMetaData ) ;
Trace . traceEnd ( Trace . TRACE_TAG_GRAPHICS ) ;
// Determine if ANGLE is the system driver, as this will determine other logic
final String eglSystemDriver = SystemProperties . get ( PROPERTY_EGL_SYSTEM_DRIVER ) ;
Log . v ( TAG , " GLES system driver is ' " + eglSystemDriver + " ' " ) ;
mAngleIsSystemDriver = eglSystemDriver . equals ( ANGLE_DRIVER_NAME ) ;
if ( mAngleIsSystemDriver ) {
// Lookup the legacy driver, to send down to the EGL loader
final String eglLegacyDriver = SystemProperties . get ( PROPERTY_EGL_LEGACY_DRIVER ) ;
if ( eglLegacyDriver . isEmpty ( ) ) {
mNoLegacyDriver = true ;
mEglLegacyDriver = eglSystemDriver ;
}
} else {
mEglLegacyDriver = eglSystemDriver ;
}
Log . v ( TAG , " Legacy GLES driver is ' " + mEglLegacyDriver + " ' " ) ;
// Setup ANGLE and pass down ANGLE details to the C++ code
Trace . traceBegin ( Trace . TRACE_TAG_GRAPHICS , " setupAngle " ) ;
boolean useAngle = false ;
if ( setupAngle ( context , coreSettings , pm , packageName ) ) {
@@ -145,6 +184,9 @@ public class GraphicsEnvironment {
useAngle = true ;
setGpuStats ( ANGLE_DRIVER_NAME , ANGLE_DRIVER_VERSION_NAME , ANGLE_DRIVER_VERSION_CODE ,
0 , packageName , getVulkanVersion ( pm ) ) ;
} else if ( mNoLegacyDriver ) {
Log . e ( TAG , " Unexpected problem with the ANGLE for use with: ' " + packageName + " ' " ) ;
useAngle = true ;
}
}
Trace . traceEnd ( Trace . TRACE_TAG_GRAPHICS ) ;
@@ -188,28 +230,15 @@ public class GraphicsEnvironment {
/**
* Query to determine if ANGLE should be used
*/
private boolean shouldUseAngle ( Context context , Bundle coreSettings ,
String packageName ) {
private boolean shouldUseAngle ( Context context , Bundle coreSettings , String packageName ) {
if ( TextUtils . isEmpty ( packageName ) ) {
Log . v ( TAG , " No package name specified, ANGLE should not be used " ) ;
return false ;
Log . v ( TAG , " No package name specified; use the system driver " ) ;
return mAngleIsSystemDriver ? true : false ;
}
final Str ing devOptIn = getDriverForPackage ( context , coreSettings , packageName ) ;
Log . v ( TAG , " ANGLE Developer option for ' " + packageName + " ' "
+ " set to: ' " + devOptIn + " ' " ) ;
// We only want to use ANGLE if the developer has explicitly chosen something other than
// default driver.
final boolean forceAngle = devOptIn . equals ( ANGLE_GL_DRIVER_CHOICE_ANGLE ) ;
final boolean forceNative = devOptIn . equals ( ANGLE_GL_DRIVER_CHOICE_NATIVE ) ;
if ( forceAngle | | forceNative ) {
Log . v ( TAG , " ANGLE developer option for " + packageName + " : " + devOptIn ) ;
}
final boolean gameModeEnabledAngle = isAngleEnabledByGameMode ( context , packageName ) ;
return ! forceNative & & ( forceAngle | | gameModeEnabledAngle ) ;
final int driverToUse = getDriverForPackage ( context , coreSettings , packageName ) ;
boolean yesOrNo = driverToUse = = ANGLE_GL_DRIVER_TO_USE_ANGLE ;
return yesOrNo ;
}
private int getVulkanVersion ( PackageManager pm ) {
@@ -417,34 +446,69 @@ public class GraphicsEnvironment {
return ai ;
}
private String getDriverForPackage ( Context context , Bundle bundle , String packageName ) {
/**
* Return the appropriate "default" driver, unless overridden by isAngleEnabledByGameMode().
*/
private int getDefaultDriverToUse ( Context context , String packageName ) {
if ( mAngleIsSystemDriver | | isAngleEnabledByGameMode ( context , packageName ) ) {
return ANGLE_GL_DRIVER_TO_USE_ANGLE ;
} else {
return ANGLE_GL_DRIVER_TO_USE_LEGACY ;
}
}
/*
* Determine which GLES "driver" should be used for the package, taking into account the
* following factors (in priority order):
*
* 1) The semi-global switch (i.e. Settings.Global.ANGLE_GL_DRIVER_ALL_ANGLE; which is set by
* the "angle_gl_driver_all_angle" setting; which forces a driver for all processes that
* start after the Java run time is up), if it forces a choice; otherwise ...
* 2) The per-application switch (i.e. Settings.Global.ANGLE_GL_DRIVER_SELECTION_PKGS and
* Settings.Global.ANGLE_GL_DRIVER_SELECTION_VALUES; which corresponds to the
* “angle_gl_driver_selection_pkgs” and “angle_gl_driver_selection_values” settings); if it
* forces a choice; otherwise ...
* 3) Use ANGLE if isAngleEnabledByGameMode() returns true; otherwise ...
* 4) The global switch (i.e. use the system driver, whether ANGLE or legacy;
* a.k.a. mAngleIsSystemDriver, which is set by the device’ s “ro.hardware.egl” property)
*
* Factors 1 and 2 are decided by this method. Factors 3 and 4 are decided by
* getDefaultDriverToUse().
*/
private int getDriverForPackage ( Context context , Bundle bundle , String packageName ) {
// Check the semi-global switch (i.e. once system has booted enough) for whether ANGLE
// should be forced on or off for "all appplications"
final int allUseAngle ;
if ( bundle ! = null ) {
allUseAngle =
bundle . getInt ( Settings . Global . ANGLE_GL_DRIVER_ALL_ANGLE ) ;
allUseAngle = bundle . getInt ( Settings . Global . ANGLE_GL_DRIVER_ALL_ANGLE ) ;
} else {
ContentResolver contentResolver = context . getContentResolver ( ) ;
allUseAngle = Settings . Global . getInt ( contentResolver ,
Settings . Global . ANGLE_GL_DRIVER_ALL_ANGLE ,
ANGLE_GL_DRIVER_ALL_ANGLE_OFF ) ;
Settings . Global . ANGLE_GL_DRIVER_ALL_ANGLE , ANGLE_GL_DRIVER_ALL_ANGLE_OFF ) ;
}
if ( allUseAngle = = ANGLE_GL_DRIVER_ALL_ANGLE_ON ) {
Log . v ( TAG , " Turn on ANGLE for all applications. " ) ;
return ANGLE_GL_DRIVER_CHOIC E_ANGLE ;
return ANGLE_GL_DRIVER_TO_US E_ANGLE ;
}
if ( allUseAngle = = ANGLE_GL_DRIVER_ALL_LEGACY ) {
Log . v ( TAG , " Disable ANGLE for all applications. " ) ;
return ANGLE_GL_DRIVER_TO_USE_LEGACY ;
}
// Make sure we have a good package name
if ( TextUtils . isEmpty ( packageName ) ) {
return ANGLE_GL_DRIVER_CHOICE_DEFAULT ;
return getDefaultDriverToUse ( context , packageName ) ;
}
// Get the per-application settings lists
final ContentResolver contentResolver = context . getContentResolver ( ) ;
final List < String > optInPackages =
getGlobalSettingsString ( contentResolver, bundle ,
Settings . Global . ANGLE_GL_DRIVER_SELECTION_PKGS ) ;
final List < String > optInValues =
getGlobalSettingsString ( contentResolver , bundle ,
Settings . Global . ANGLE_GL_DRIVER_SELECTION_VALUES ) ;
final List < String > optInPackages = getGlobalSettingsString (
contentResolver , bundle , Settings . Global . ANGLE_GL_DRIVER_SELECTION_PKGS ) ;
final List < String > optInValues = getGlobalSettingsString (
contentResolver , bundle , Settings . Global . ANGLE_GL_DRIVER_SELECTION_VALUES ) ;
Log . v ( TAG , " Currently set values for: " ) ;
Log . v ( TAG , " angle_gl_driver_selection_pkgs = " + optInPackages ) ;
Log . v ( TAG , " angle_gl_driver_selection_values = " + optInValues ) ;
// Make sure we have good settings to use
if ( optInPackages . size ( ) ! = optInValues . size ( ) ) {
@@ -454,17 +518,40 @@ public class GraphicsEnvironment {
+ optInPackages . size ( ) + " , "
+ " number of values: "
+ optInValues . size ( ) ) ;
return ANGLE_GL_DRIVER_CHOICE_DEFAULT ;
return getDefaultDriverToUse ( context , packageName ) ;
}
// See if this application is listed in the per-application settings lists
final int pkgIndex = getPackageIndex ( packageName , optInPackages ) ;
if ( pkgIndex < 0 ) {
return ANGLE_GL_DRIVER_CHOICE_DEFAULT ;
// The application is NOT listed in the per-application settings lists; and so use the
// system driver (i.e. either ANGLE or the Legacy driver)
Log . v ( TAG , " getDriverForPackage(): No per-application setting " ) ;
return getDefaultDriverToUse ( context , packageName ) ;
}
mAngleOptInIndex = pkgIndex ;
return optInValues . get ( pkgIndex ) ;
Log . v ( TAG ,
" getDriverForPackage(): using per-application switch: "
+ optInValues . get ( pkgIndex ) ) ;
// The application IS listed in the per-application settings lists; and so use the
// setting--choosing the current system driver if the setting is "default" (i.e. either
// ANGLE or the Legacy driver)
String rtnValue = optInValues . get ( pkgIndex ) ;
Log . v ( TAG ,
" ANGLE Developer option for ' " + packageName + " ' "
+ " set to: ' " + rtnValue + " ' " ) ;
if ( rtnValue . equals ( ANGLE_GL_DRIVER_CHOICE_ANGLE ) ) {
return ANGLE_GL_DRIVER_TO_USE_ANGLE ;
} else if ( rtnValue . equals ( ANGLE_GL_DRIVER_CHOICE_NATIVE )
| | rtnValue . equals ( ANGLE_GL_DRIVER_CHOICE_LEGACY ) ) {
return ANGLE_GL_DRIVER_TO_USE_LEGACY ;
} else {
// The user either chose default or an invalid value; go with the default driver or what
// the game dashboard indicates
return getDefaultDriverToUse ( context , packageName ) ;
}
}
/**
@@ -514,7 +601,13 @@ public class GraphicsEnvironment {
}
/**
* P ass ANGLE details down to trigger enable logic
* Determine whether ANGLE should be used, set it up if so, and p ass ANGLE details down to
* the C++ GraphicsEnv class.
*
* If ANGLE will be used, GraphicsEnv::setAngleInfo() will be called to enable ANGLE to be
* properly used. Otherwise, GraphicsEnv::setLegacyDriverInfo() will be called to
* enable the legacy GLES driver (e.g. when ANGLE is the system driver) to be identified and
* used.
*
* @param context
* @param bundle
@@ -527,6 +620,7 @@ public class GraphicsEnvironment {
String packageName ) {
if ( ! shouldUseAngle ( context , bundle , packageName ) ) {
setLegacyDriverInfo ( packageName , mAngleIsSystemDriver , mEglLegacyDriver ) ;
return false ;
}
@@ -541,6 +635,7 @@ public class GraphicsEnvironment {
angleInfo = pm . getApplicationInfo ( anglePkgName , 0 ) ;
} catch ( PackageManager . NameNotFoundException e ) {
Log . w ( TAG , " ANGLE debug package ' " + anglePkgName + " ' not installed " ) ;
setLegacyDriverInfo ( packageName , mAngleIsSystemDriver , mEglLegacyDriver ) ;
return false ;
}
}
@@ -550,16 +645,18 @@ public class GraphicsEnvironment {
anglePkgName = getAnglePackageName ( pm ) ;
if ( TextUtils . isEmpty ( anglePkgName ) ) {
Log . w ( TAG , " Failed to find ANGLE package. " ) ;
setLegacyDriverInfo ( packageName , mAngleIsSystemDriver , mEglLegacyDriver ) ;
return false ;
}
Log . i ( TAG , " ANGLE package enabled: " + anglePkgName ) ;
Log . v ( TAG , " ANGLE package enabled: " + anglePkgName ) ;
try {
// Production ANGLE libraries must be pre-installed as a system app
angleInfo = pm . getApplicationInfo ( anglePkgName ,
PackageManager . MATCH_SYSTEM_ONLY ) ;
} catch ( PackageManager . NameNotFoundException e ) {
Log . w ( TAG , " ANGLE package ' " + anglePkgName + " ' not installed " ) ;
setLegacyDriverInfo ( packageName , mAngleIsSystemDriver , mEglLegacyDriver ) ;
return false ;
}
}
@@ -573,21 +670,15 @@ public class GraphicsEnvironment {
+ " !/lib/ "
+ abi ;
if ( DEBUG ) Log . v ( TAG , " ANGLE package libs: " + paths ) ;
// We need to call setAngleInfo() with the package name and the developer option value
//(native/angle/other). Then later when we are actually trying to load a driver,
//GraphicsEnv::getShouldUseAngle() has seen the package name before and can confidently
//answer yes/no based on the previously set developer option value.
final String devOptIn ;
final String [ ] features = getAngleEglFeatures ( context , bundle ) ;
final boolean gameModeEnabledAngle = isAngleEnabledByGameMode ( context , packageName ) ;
if ( gameModeEnabledAngle ) {
devOptIn = ANGLE_GL_DRIVER_CHOICE_ANGLE ;
} else {
devOptIn = getDriverForPackage ( context , bundle , packageName ) ;
if ( DEBUG ) {
Log . v ( TAG , " ANGLE package libs: " + paths ) ;
}
setAngleInfo ( paths , packageName , devOptIn , features ) ;
// If we make it to here, ANGLE will be used. Call setAngleInfo() with the package name,
// and features to use.
final String [ ] features = getAngleEglFeatures ( context , bundle ) ;
setAngleInfo (
paths , packageName , mAngleIsSystemDriver , ANGLE_GL_DRIVER_CHOICE_ANGLE , features ) ;
return true ;
}
@@ -876,8 +967,10 @@ public class GraphicsEnvironment {
private static native void setDriverPathAndSphalLibraries ( String path , String sphalLibraries ) ;
private static native void setGpuStats ( String driverPackageName , String driverVersionName ,
long driverVersionCode , long driverBuildTime , String appPackageName , int vulkanVersion ) ;
private static native void setAngleInfo ( String path , String appPackage , String devOptIn ,
String [ ] features ) ;
private static native void setAngleInfo ( String path , String appPackage ,
boolean angleIsSystemDriver , String devOptIn , String [ ] features ) ;
private static native void setLegacyDriverInfo (
String appPackage , boolean angleIsSystemDriver , String legacyDriverName ) ;
private static native boolean getShouldUseAngle ( String packageName ) ;
private static native boolean setInjectLayersPrSetDumpable ( ) ;