| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef FLUTTER_IMPELLER_TOOLKIT_ANDROID_PROC_TABLE_H_ |
| #define FLUTTER_IMPELLER_TOOLKIT_ANDROID_PROC_TABLE_H_ |
| |
| #include <EGL/egl.h> |
| #define EGL_EGLEXT_PROTOTYPES |
| #include <EGL/eglext.h> |
| #include <android/api-level.h> |
| #include <android/hardware_buffer.h> |
| #include <android/hardware_buffer_jni.h> |
| #include <android/surface_control.h> |
| #include <android/trace.h> |
| |
| #include <functional> |
| |
| #include "flutter/fml/logging.h" |
| #include "flutter/fml/native_library.h" |
| |
| namespace impeller::android { |
| |
| //------------------------------------------------------------------------------ |
| /// @brief The Android procs along with the device API level on which these |
| /// will be available. There is no checking of the actual API level |
| /// however (because getting the API level is itself only possible |
| /// on API levels 29 and above). |
| /// |
| /// Take care to explicitly check for the availability of these APIs |
| /// at runtime before invoking them. |
| /// |
| /// Typically, you'll never have to deal with the proc. table |
| /// directly. Instead, rely on the handle wrappers (`Choreographer`, |
| /// `HardwareBuffer`, etc..). |
| /// |
| #define FOR_EACH_ANDROID_PROC(INVOKE) \ |
| INVOKE(AChoreographer_getInstance, 24) \ |
| INVOKE(AChoreographer_postFrameCallback, 24) \ |
| INVOKE(AChoreographer_postFrameCallback64, 29) \ |
| INVOKE(AHardwareBuffer_acquire, 26) \ |
| INVOKE(AHardwareBuffer_allocate, 26) \ |
| INVOKE(AHardwareBuffer_describe, 26) \ |
| INVOKE(AHardwareBuffer_fromHardwareBuffer, 26) \ |
| INVOKE(AHardwareBuffer_getId, 31) \ |
| INVOKE(AHardwareBuffer_isSupported, 29) \ |
| INVOKE(AHardwareBuffer_release, 26) \ |
| INVOKE(ANativeWindow_acquire, 0) \ |
| INVOKE(ANativeWindow_getHeight, 0) \ |
| INVOKE(ANativeWindow_getWidth, 0) \ |
| INVOKE(ANativeWindow_release, 0) \ |
| INVOKE(ASurfaceControl_createFromWindow, 29) \ |
| INVOKE(ASurfaceControl_release, 29) \ |
| INVOKE(ASurfaceTransaction_apply, 29) \ |
| INVOKE(ASurfaceTransaction_create, 29) \ |
| INVOKE(ASurfaceTransaction_delete, 29) \ |
| INVOKE(ASurfaceTransaction_reparent, 29) \ |
| INVOKE(ASurfaceTransaction_setBuffer, 29) \ |
| INVOKE(ASurfaceTransaction_setColor, 29) \ |
| INVOKE(ASurfaceTransaction_setOnComplete, 29) \ |
| INVOKE(ATrace_isEnabled, 23) \ |
| INVOKE(eglGetNativeClientBufferANDROID, 0) |
| |
| template <class T> |
| struct AndroidProc { |
| using AndroidProcType = T; |
| |
| const char* proc_name = nullptr; |
| |
| AndroidProcType* proc = nullptr; |
| |
| constexpr bool IsAvailable() const { return proc != nullptr; } |
| |
| explicit constexpr operator bool() const { return IsAvailable(); } |
| |
| template <class... Args> |
| auto operator()(Args&&... args) const { |
| FML_DCHECK(IsAvailable()) |
| << "Android method " << proc_name |
| << " is not available on this device. Missing check."; |
| return proc(std::forward<Args>(args)...); |
| } |
| |
| void Reset() { proc = nullptr; } |
| }; |
| |
| //------------------------------------------------------------------------------ |
| /// @brief The table of Android procs that are resolved dynamically. |
| /// |
| struct ProcTable { |
| ProcTable(); |
| |
| ~ProcTable(); |
| |
| ProcTable(const ProcTable&) = delete; |
| |
| ProcTable& operator=(const ProcTable&) = delete; |
| |
| //---------------------------------------------------------------------------- |
| /// @brief If a valid proc table could be setup. This may fail in case of |
| /// setup on non-Android platforms. |
| /// |
| /// @return `true` if valid. |
| /// |
| bool IsValid() const; |
| |
| //---------------------------------------------------------------------------- |
| /// @brief Check if tracing in enabled in the process. This call can be |
| /// made at any API level. |
| /// |
| /// @return If tracing is enabled. |
| /// |
| bool TraceIsEnabled() const; |
| |
| #define DEFINE_PROC(name, api) \ |
| AndroidProc<decltype(name)> name = {.proc_name = #name}; |
| FOR_EACH_ANDROID_PROC(DEFINE_PROC); |
| #undef DEFINE_PROC |
| |
| private: |
| std::vector<fml::RefPtr<fml::NativeLibrary>> libraries_; |
| bool is_valid_ = false; |
| }; |
| |
| const ProcTable& GetProcTable(); |
| |
| #ifdef TESTING |
| ProcTable& GetMutableProcTable(); |
| #endif |
| |
| } // namespace impeller::android |
| |
| #endif // FLUTTER_IMPELLER_TOOLKIT_ANDROID_PROC_TABLE_H_ |