1 /* 2 * Copyright (C) 2018 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 17 #if defined(__ANDROID__) 18 19 #include <cutils/properties.h> 20 #include "Loader.h" 21 #include "egl_angle_platform.h" 22 23 #pragma GCC diagnostic push 24 #pragma GCC diagnostic ignored "-Wunused-parameter" 25 #include <EGL/Platform.h> 26 #pragma GCC diagnostic pop 27 28 #include <android/dlext.h> 29 #include <dlfcn.h> 30 #include <graphicsenv/GraphicsEnv.h> 31 #include <time.h> 32 #include <log/log.h> 33 34 namespace angle { 35 36 static GetDisplayPlatformFunc angleGetDisplayPlatform = nullptr; 37 static ResetDisplayPlatformFunc angleResetDisplayPlatform = nullptr; 38 39 static time_t startTime = time(nullptr); 40 41 static const unsigned char* getTraceCategoryEnabledFlag(PlatformMethods* /*platform*/, 42 const char* /*categoryName*/) { 43 // Returning ptr to 'g' (non-zero) to ALWAYS enable tracing initially. 44 // This ptr is what will be passed into "category_group_enabled" of addTraceEvent 45 static const unsigned char traceEnabled = 'g'; 46 return &traceEnabled; 47 } 48 49 static double monotonicallyIncreasingTime(PlatformMethods* /*platform*/) { 50 return difftime(time(nullptr), startTime); 51 } 52 53 static void logError(PlatformMethods* /*platform*/, const char* errorMessage) { 54 ALOGE("ANGLE Error:%s", errorMessage); 55 } 56 57 static void logWarning(PlatformMethods* /*platform*/, const char* warningMessage) { 58 ALOGW("ANGLE Warn:%s", warningMessage); 59 } 60 61 static void logInfo(PlatformMethods* /*platform*/, const char* infoMessage) { 62 ALOGD("ANGLE Info:%s", infoMessage); 63 } 64 65 static TraceEventHandle addTraceEvent( 66 PlatformMethods* /**platform*/, char phase, const unsigned char* /*category_group_enabled*/, 67 const char* name, unsigned long long /*id*/, double /*timestamp*/, int /*num_args*/, 68 const char** /*arg_names*/, const unsigned char* /*arg_types*/, 69 const unsigned long long* /*arg_values*/, unsigned char /*flags*/) { 70 switch (phase) { 71 case 'B': { 72 ATRACE_BEGIN(name); 73 break; 74 } 75 case 'E': { 76 ATRACE_END(); 77 break; 78 } 79 case 'I': { 80 ATRACE_NAME(name); 81 break; 82 } 83 default: 84 // Could handle other event types here 85 break; 86 } 87 // Return any non-zero handle to avoid assert in ANGLE 88 TraceEventHandle result = 1.0; 89 return result; 90 } 91 92 static void assignAnglePlatformMethods(PlatformMethods* platformMethods) { 93 platformMethods->addTraceEvent = addTraceEvent; 94 platformMethods->getTraceCategoryEnabledFlag = getTraceCategoryEnabledFlag; 95 platformMethods->monotonicallyIncreasingTime = monotonicallyIncreasingTime; 96 platformMethods->logError = logError; 97 platformMethods->logWarning = logWarning; 98 platformMethods->logInfo = logInfo; 99 } 100 101 // Initialize function ptrs for ANGLE PlatformMethods struct, used for systrace 102 bool initializeAnglePlatform(EGLDisplay dpy) { 103 // Since we're inside libEGL, use dlsym to lookup fptr for ANGLEGetDisplayPlatform 104 android_namespace_t* ns = android::GraphicsEnv::getInstance().getAngleNamespace(); 105 const android_dlextinfo dlextinfo = { 106 .flags = ANDROID_DLEXT_USE_NAMESPACE, 107 .library_namespace = ns, 108 }; 109 void* so = android_dlopen_ext("libGLESv2_angle.so", RTLD_LOCAL | RTLD_NOW, &dlextinfo); 110 angleGetDisplayPlatform = 111 reinterpret_cast<GetDisplayPlatformFunc>(dlsym(so, "ANGLEGetDisplayPlatform")); 112 113 if (!angleGetDisplayPlatform) { 114 ALOGE("dlsym lookup of ANGLEGetDisplayPlatform in libEGL_angle failed!"); 115 return false; 116 } 117 118 angleResetDisplayPlatform = 119 reinterpret_cast<ResetDisplayPlatformFunc>( 120 eglGetProcAddress("ANGLEResetDisplayPlatform")); 121 122 PlatformMethods* platformMethods = nullptr; 123 if (!((angleGetDisplayPlatform)(dpy, g_PlatformMethodNames, 124 g_NumPlatformMethods, nullptr, 125 &platformMethods))) { 126 ALOGE("ANGLEGetDisplayPlatform call failed!"); 127 return false; 128 } 129 if (platformMethods) { 130 assignAnglePlatformMethods(platformMethods); 131 } else { 132 ALOGE("In initializeAnglePlatform() platformMethods struct ptr is NULL. Not assigning " 133 "tracing function ptrs!"); 134 } 135 return true; 136 } 137 138 void resetAnglePlatform(EGLDisplay dpy) { 139 if (angleResetDisplayPlatform) { 140 angleResetDisplayPlatform(dpy); 141 } 142 } 143 144 }; // namespace angle 145 146 #endif // __ANDROID__ 147