summaryrefslogtreecommitdiff
path: root/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
blob: 900fc49b5912b5c107afabc5227ade64c7de9ec3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*
 * Copyright 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_UI_GRAPHICS_ENV_H
#define ANDROID_UI_GRAPHICS_ENV_H 1

#include <graphicsenv/GpuStatsInfo.h>

#include <mutex>
#include <string>
#include <vector>

struct android_namespace_t;

namespace android {

struct NativeLoaderNamespace;

class GraphicsEnv {
public:
    static GraphicsEnv& getInstance();

    // Check if the process is debuggable. It returns false except in any of the
    // following circumstances:
    // 1. ro.debuggable=1 (global debuggable enabled).
    // 2. android:debuggable="true" in the manifest for an individual app.
    // 3. An app which explicitly calls prctl(PR_SET_DUMPABLE, 1).
    // 4. GraphicsEnv calls prctl(PR_SET_DUMPABLE, 1) in the presence of
    //    <meta-data android:name="com.android.graphics.injectLayers.enable"
    //               android:value="true"/>
    //    in the application manifest.
    bool isDebuggable();

    /*
     * Apis for updatable driver
     */
    // Set a search path for loading graphics drivers. The path is a list of
    // directories separated by ':'. A directory can be contained in a zip file
    // (drivers must be stored uncompressed and page aligned); such elements
    // in the search path must have a '!' after the zip filename, e.g.
    //     /data/app/com.example.driver/base.apk!/lib/arm64-v8a
    // Also set additional required sphal libraries to the linker for loading
    // graphics drivers. The string is a list of libraries separated by ':',
    // which is required by android_link_namespaces.
    void setDriverPathAndSphalLibraries(const std::string path, const std::string sphalLibraries);
    // Get the updatable driver namespace.
    android_namespace_t* getDriverNamespace();
    std::string getDriverPath() const;

    /*
     * Apis for GpuStats
     */
    // Hint there's real activity launching on the app process.
    void hintActivityLaunch();
    // Set the initial GpuStats.
    void setGpuStats(const std::string& driverPackageName, const std::string& driverVersionName,
                     uint64_t versionCode, int64_t driverBuildTime,
                     const std::string& appPackageName, const int32_t vulkanVersion);
    // Set stats for target GpuStatsInfo::Stats type.
    void setTargetStats(const GpuStatsInfo::Stats stats, const uint64_t value = 0);
    // Set which driver is intended to load.
    void setDriverToLoad(GpuStatsInfo::Driver driver);
    // Set which driver is actually loaded.
    void setDriverLoaded(GpuStatsInfo::Api api, bool isDriverLoaded, int64_t driverLoadingTime);

    /*
     * Api for Vk/GL layer injection.  Presently, drivers enable certain
     * profiling features when prctl(PR_GET_DUMPABLE) returns true.
     * Calling this when layer injection metadata is present allows the driver
     * to enable profiling even when in a non-debuggable app
     */
    bool setInjectLayersPrSetDumpable();

    /*
     * Apis for ANGLE
     */
    // Check if the requested app should use ANGLE.
    bool shouldUseAngle(std::string appName);
    // Check if this app process should use ANGLE.
    bool shouldUseAngle();
    // Set a search path for loading ANGLE libraries. The path is a list of
    // directories separated by ':'. A directory can be contained in a zip file
    // (libraries must be stored uncompressed and page aligned); such elements
    // in the search path must have a '!' after the zip filename, e.g.
    //     /system/app/ANGLEPrebuilt/ANGLEPrebuilt.apk!/lib/arm64-v8a
    void setAngleInfo(const std::string path, const std::string appName, std::string devOptIn,
                      const std::vector<std::string> eglFeatures, const int rulesFd,
                      const long rulesOffset, const long rulesLength);
    // Get the ANGLE driver namespace.
    android_namespace_t* getAngleNamespace();
    // Get the app name for ANGLE debug message.
    std::string& getAngleAppName();

    const std::vector<std::string>& getAngleEglFeatures();

    /*
     * Apis for debug layer
     */
    // Set additional layer search paths.
    void setLayerPaths(NativeLoaderNamespace* appNamespace, const std::string layerPaths);
    // Get the app namespace for loading layers.
    NativeLoaderNamespace* getAppNamespace();
    // Get additional layer search paths.
    const std::string& getLayerPaths();
    // Set the Vulkan debug layers.
    void setDebugLayers(const std::string layers);
    // Set the GL debug layers.
    void setDebugLayersGLES(const std::string layers);
    // Get the debug layers to load.
    const std::string& getDebugLayers();
    // Get the debug layers to load.
    const std::string& getDebugLayersGLES();

private:
    enum UseAngle { UNKNOWN, YES, NO };

    // Load requested ANGLE library.
    void* loadLibrary(std::string name);
    // Check ANGLE support with the rules.
    bool checkAngleRules(void* so);
    // Update whether ANGLE should be used.
    void updateUseAngle();
    // Link updatable driver namespace with llndk and vndk-sp libs.
    bool linkDriverNamespaceLocked(android_namespace_t* vndkNamespace);
    // Check whether this process is ready to send stats.
    bool readyToSendGpuStatsLocked();
    // Send the initial complete GpuStats to GpuService.
    void sendGpuStatsLocked(GpuStatsInfo::Api api, bool isDriverLoaded, int64_t driverLoadingTime);

    GraphicsEnv() = default;
    // Path to updatable driver libs.
    std::string mDriverPath;
    // Path to additional sphal libs linked to updatable driver namespace.
    std::string mSphalLibraries;
    // This mutex protects mGpuStats and get gpuservice call.
    std::mutex mStatsLock;
    // Cache the activity launch info
    bool mActivityLaunched = false;
    // Information bookkept for GpuStats.
    GpuStatsInfo mGpuStats;
    // Path to ANGLE libs.
    std::string mAnglePath;
    // This App's name.
    std::string mAngleAppName;
    // ANGLE developer opt in status.
    std::string mAngleDeveloperOptIn;
    // ANGLE EGL features;
    std::vector<std::string> mAngleEglFeatures;
    // ANGLE rules.
    std::vector<char> mRulesBuffer;
    // Use ANGLE flag.
    UseAngle mUseAngle = UNKNOWN;
    // Vulkan debug layers libs.
    std::string mDebugLayers;
    // GL debug layers libs.
    std::string mDebugLayersGLES;
    // Additional debug layers search path.
    std::string mLayerPaths;
    // This mutex protects the namespace creation.
    std::mutex mNamespaceMutex;
    // Updatable driver namespace.
    android_namespace_t* mDriverNamespace = nullptr;
    // ANGLE namespace.
    android_namespace_t* mAngleNamespace = nullptr;
    // This App's namespace.
    NativeLoaderNamespace* mAppNamespace = nullptr;
};

} // namespace android

#endif // ANDROID_UI_GRAPHICS_ENV_H