GraphicsEnvironment.java revision fd104e7fde7f53700da58cbab57d73b938b837a7
1/* 2 * Copyright 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.os; 18 19import android.content.Context; 20import android.content.pm.ApplicationInfo; 21import android.content.pm.PackageManager; 22import android.opengl.EGL14; 23import android.os.SystemProperties; 24import android.util.Log; 25 26import dalvik.system.VMRuntime; 27 28import java.io.File; 29 30/** @hide */ 31public final class GraphicsEnvironment { 32 33 private static final boolean DEBUG = false; 34 private static final String TAG = "GraphicsEnvironment"; 35 private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0"; 36 37 public static void setupGraphicsEnvironment(Context context) { 38 chooseDriver(context); 39 40 // Now that we've figured out which driver to use for this process, load and initialize it. 41 // This can take multiple frame periods, and it would otherwise happen as part of the first 42 // frame, increasing first-frame latency. Starting it here, as a low-priority background 43 // thread, means that it's usually done long before we start drawing the first frame, 44 // without significantly disrupting other activity launch work. 45 Thread eglInitThread = new Thread( 46 () -> { 47 Thread.currentThread().setPriority(Thread.MIN_PRIORITY); 48 EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY); 49 }, 50 "EGL Init"); 51 eglInitThread.start(); 52 } 53 54 private static void chooseDriver(Context context) { 55 String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER); 56 if (driverPackageName == null || driverPackageName.isEmpty()) { 57 return; 58 } 59 // To minimize risk of driver updates crippling the device beyond user repair, never use an 60 // updated driver for privileged or non-updated system apps. Presumably pre-installed apps 61 // were tested thoroughly with the pre-installed driver. 62 ApplicationInfo ai = context.getApplicationInfo(); 63 if (ai.isPrivilegedApp() || (ai.isSystemApp() && !ai.isUpdatedSystemApp())) { 64 if (DEBUG) Log.v(TAG, "ignoring driver package for privileged/non-updated system app"); 65 return; 66 } 67 ApplicationInfo driverInfo; 68 try { 69 driverInfo = context.getPackageManager().getApplicationInfo(driverPackageName, 70 PackageManager.MATCH_SYSTEM_ONLY); 71 } catch (PackageManager.NameNotFoundException e) { 72 Log.w(TAG, "driver package '" + driverPackageName + "' not installed"); 73 return; 74 } 75 String abi = chooseAbi(driverInfo); 76 if (abi == null) { 77 if (DEBUG) { 78 // This is the normal case for the pre-installed empty driver package, don't spam 79 if (driverInfo.isUpdatedSystemApp()) { 80 Log.w(TAG, "updated driver package has no compatible native libraries"); 81 } 82 } 83 return; 84 } 85 86 StringBuilder sb = new StringBuilder(); 87 sb.append(driverInfo.nativeLibraryDir) 88 .append(File.pathSeparator); 89 sb.append(driverInfo.sourceDir) 90 .append("!/lib/") 91 .append(abi); 92 String paths = sb.toString(); 93 94 if (DEBUG) Log.v(TAG, "gfx driver package libs: " + paths); 95 setDriverPath(paths); 96 } 97 98 private static String chooseAbi(ApplicationInfo ai) { 99 String isa = VMRuntime.getCurrentInstructionSet(); 100 if (ai.primaryCpuAbi != null && 101 isa.equals(VMRuntime.getInstructionSet(ai.primaryCpuAbi))) { 102 return ai.primaryCpuAbi; 103 } 104 if (ai.secondaryCpuAbi != null && 105 isa.equals(VMRuntime.getInstructionSet(ai.secondaryCpuAbi))) { 106 return ai.secondaryCpuAbi; 107 } 108 return null; 109 } 110 111 private static native void setDriverPath(String path); 112 113} 114