Flutter Impeller
proc_table.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef FLUTTER_IMPELLER_TOOLKIT_ANDROID_PROC_TABLE_H_
6 #define FLUTTER_IMPELLER_TOOLKIT_ANDROID_PROC_TABLE_H_
7 
8 #include <EGL/egl.h>
9 #define EGL_EGLEXT_PROTOTYPES
10 #include <EGL/eglext.h>
11 #include <android/api-level.h>
13 #include <android/hardware_buffer_jni.h>
15 #include <android/trace.h>
16 
17 #include <functional>
18 
19 #include "flutter/fml/logging.h"
20 #include "flutter/fml/native_library.h"
21 
22 namespace impeller::android {
23 
24 ASurfaceTransaction* ASurfaceTransaction_fromJava(JNIEnv* env,
25  jobject transaction);
26 
27 //------------------------------------------------------------------------------
28 /// @brief The Android procs along with the device API level on which these
29 /// will be available. There is no checking of the actual API level
30 /// however (because getting the API level is itself only possible
31 /// on API levels 29 and above).
32 ///
33 /// Take care to explicitly check for the availability of these APIs
34 /// at runtime before invoking them.
35 ///
36 /// Typically, you'll never have to deal with the proc. table
37 /// directly. Instead, rely on the handle wrappers (`Choreographer`,
38 /// `HardwareBuffer`, etc..).
39 ///
40 // clang-format off
41 #define FOR_EACH_ANDROID_PROC(INVOKE) \
42  INVOKE(AChoreographer_getInstance, 24) \
43  _Pragma("GCC diagnostic push") \
44  _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") \
45  INVOKE(AChoreographer_postFrameCallback, 24) \
46  _Pragma("GCC diagnostic pop") \
47  INVOKE(AChoreographer_postFrameCallback64, 29) \
48  INVOKE(AHardwareBuffer_acquire, 26) \
49  INVOKE(AHardwareBuffer_allocate, 26) \
50  INVOKE(AHardwareBuffer_describe, 26) \
51  INVOKE(AHardwareBuffer_fromHardwareBuffer, 26) \
52  INVOKE(AHardwareBuffer_getId, 31) \
53  INVOKE(AHardwareBuffer_isSupported, 29) \
54  INVOKE(AHardwareBuffer_lock, 26) \
55  INVOKE(AHardwareBuffer_release, 26) \
56  INVOKE(AHardwareBuffer_unlock, 26) \
57  INVOKE(ANativeWindow_acquire, 0) \
58  INVOKE(ANativeWindow_getHeight, 0) \
59  INVOKE(ANativeWindow_getWidth, 0) \
60  INVOKE(ANativeWindow_release, 0) \
61  INVOKE(ASurfaceControl_createFromWindow, 29) \
62  INVOKE(ASurfaceControl_release, 29) \
63  INVOKE(ASurfaceTransaction_apply, 29) \
64  INVOKE(ASurfaceTransaction_create, 29) \
65  INVOKE(ASurfaceTransaction_delete, 29) \
66  INVOKE(ASurfaceTransaction_reparent, 29) \
67  INVOKE(ASurfaceTransaction_setBuffer, 29) \
68  INVOKE(ASurfaceTransaction_setColor, 29) \
69  INVOKE(ASurfaceTransaction_setOnComplete, 29) \
70  INVOKE(ASurfaceTransactionStats_getPreviousReleaseFenceFd, 29) \
71  INVOKE(ASurfaceTransaction_fromJava, 34) \
72  INVOKE(ATrace_isEnabled, 23) \
73  INVOKE(eglGetNativeClientBufferANDROID, 0)
74 // clang-format on
75 
76 template <class T>
77 struct AndroidProc {
78  using AndroidProcType = T;
79 
80  const char* proc_name = nullptr;
81 
82  AndroidProcType* proc = nullptr;
83 
84  constexpr bool IsAvailable() const { return proc != nullptr; }
85 
86  explicit constexpr operator bool() const { return IsAvailable(); }
87 
88  template <class... Args>
89  auto operator()(Args&&... args) const {
90  FML_DCHECK(IsAvailable())
91  << "Android method " << proc_name
92  << " is not available on this device. Missing check.";
93  return proc(std::forward<Args>(args)...);
94  }
95 
96  void Reset() { proc = nullptr; }
97 };
98 
99 //------------------------------------------------------------------------------
100 /// @brief The table of Android procs that are resolved dynamically.
101 ///
102 struct ProcTable {
103  ProcTable();
104 
106 
107  ProcTable(const ProcTable&) = delete;
108 
109  ProcTable& operator=(const ProcTable&) = delete;
110 
111  //----------------------------------------------------------------------------
112  /// @brief If a valid proc table could be setup. This may fail in case of
113  /// setup on non-Android platforms.
114  ///
115  /// @return `true` if valid.
116  ///
117  bool IsValid() const;
118 
119  //----------------------------------------------------------------------------
120  /// @brief Check if tracing in enabled in the process. This call can be
121  /// made at any API level.
122  ///
123  /// @return If tracing is enabled.
124  ///
125  bool TraceIsEnabled() const;
126 
127 #define DEFINE_PROC(name, api) \
128  AndroidProc<decltype(name)> name = {.proc_name = #name};
130 #undef DEFINE_PROC
131 
132  private:
133  std::vector<fml::RefPtr<fml::NativeLibrary>> libraries_;
134  bool is_valid_ = false;
135 };
136 
137 const ProcTable& GetProcTable();
138 
139 #ifdef TESTING
141 #endif
142 
143 } // namespace impeller::android
144 
145 #endif // FLUTTER_IMPELLER_TOOLKIT_ANDROID_PROC_TABLE_H_
#define DEFINE_PROC(name, api)
Definition: proc_table.h:127
const ProcTable & GetProcTable()
Definition: proc_table.cc:12
ASurfaceTransaction * ASurfaceTransaction_fromJava(JNIEnv *env, jobject transaction)
ProcTable & GetMutableProcTable()
Definition: proc_table.cc:18
auto operator()(Args &&... args) const
Definition: proc_table.h:89
constexpr bool IsAvailable() const
Definition: proc_table.h:84
AndroidProcType * proc
Definition: proc_table.h:82
The table of Android procs that are resolved dynamically.
Definition: proc_table.h:102
ProcTable(const ProcTable &)=delete
FOR_EACH_ANDROID_PROC(DEFINE_PROC)
bool IsValid() const
If a valid proc table could be setup. This may fail in case of setup on non-Android platforms.
Definition: proc_table.cc:65
bool TraceIsEnabled() const
Check if tracing in enabled in the process. This call can be made at any API level.
Definition: proc_table.cc:69
ProcTable & operator=(const ProcTable &)=delete