blob: f2b501cdec8d3aca7bc59a40bdacc792de9ee8f0 [file] [log] [blame]
Tobin Ehlis96a184d2018-07-18 16:14:07 -06001//
2// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5
6// Platform.h: The public interface ANGLE exposes to the API layer, for
7// doing platform-specific tasks like gathering data, or for tracing.
8
9#ifndef ANGLE_PLATFORM_H
10#define ANGLE_PLATFORM_H
11
12#include <stdint.h>
13#include <array>
14
15#define EGL_PLATFORM_ANGLE_PLATFORM_METHODS_ANGLEX 0x3482
16
17#if defined(_WIN32)
18# if !defined(LIBANGLE_IMPLEMENTATION)
19# define ANGLE_PLATFORM_EXPORT __declspec(dllimport)
20# else
21# define ANGLE_PLATFORM_EXPORT __declspec(dllexport)
22# endif
23#elif defined(__GNUC__) || defined(__clang__)
24# define ANGLE_PLATFORM_EXPORT __attribute__((visibility ("default")))
25#endif
26#if !defined(ANGLE_PLATFORM_EXPORT)
27# define ANGLE_PLATFORM_EXPORT
28#endif
29
30#if defined(_WIN32)
31# define ANGLE_APIENTRY __stdcall
32#else
33# define ANGLE_APIENTRY
34#endif
35
36namespace angle
37{
38struct WorkaroundsD3D;
Tobin Ehlisf95bf342018-11-13 12:56:01 -070039struct FeaturesVk;
Tobin Ehlis96a184d2018-07-18 16:14:07 -060040using TraceEventHandle = uint64_t;
41using EGLDisplayType = void *;
42struct PlatformMethods;
43
44// Use a C-like API to not trigger undefined calling behaviour.
45// Avoid using decltype here to work around sanitizer limitations.
46// TODO(jmadill): Use decltype here if/when UBSAN is fixed.
47
48// System --------------------------------------------------------------
49
50// Wall clock time in seconds since the epoch.
51// TODO(jmadill): investigate using an ANGLE internal time library
52using CurrentTimeFunc = double (*)(PlatformMethods *platform);
53inline double DefaultCurrentTime(PlatformMethods *platform)
54{
55 return 0.0;
56}
57
58// Monotonically increasing time in seconds from an arbitrary fixed point in the past.
59// This function is expected to return at least millisecond-precision values. For this reason,
60// it is recommended that the fixed point be no further in the past than the epoch.
61using MonotonicallyIncreasingTimeFunc = double (*)(PlatformMethods *platform);
62inline double DefaultMonotonicallyIncreasingTime(PlatformMethods *platform)
63{
64 return 0.0;
65}
66
67// Logging ------------------------------------------------------------
68
69// Log an error message within the platform implementation.
70using LogErrorFunc = void (*)(PlatformMethods *platform, const char *errorMessage);
71inline void DefaultLogError(PlatformMethods *platform, const char *errorMessage)
72{
73}
74
75// Log a warning message within the platform implementation.
76using LogWarningFunc = void (*)(PlatformMethods *platform, const char *warningMessage);
77inline void DefaultLogWarning(PlatformMethods *platform, const char *warningMessage)
78{
79}
80
81// Log an info message within the platform implementation.
82using LogInfoFunc = void (*)(PlatformMethods *platform, const char *infoMessage);
83inline void DefaultLogInfo(PlatformMethods *platform, const char *infoMessage)
84{
85}
86
87// Tracing --------
88
89// Get a pointer to the enabled state of the given trace category. The
90// embedder can dynamically change the enabled state as trace event
91// recording is started and stopped by the application. Only long-lived
92// literal strings should be given as the category name. The implementation
93// expects the returned pointer to be held permanently in a local static. If
94// the unsigned char is non-zero, tracing is enabled. If tracing is enabled,
95// addTraceEvent is expected to be called by the trace event macros.
96using GetTraceCategoryEnabledFlagFunc = const unsigned char *(*)(PlatformMethods *platform,
97 const char *categoryName);
98inline const unsigned char *DefaultGetTraceCategoryEnabledFlag(PlatformMethods *platform,
99 const char *categoryName)
100{
101 return nullptr;
102}
103
104//
105// Add a trace event to the platform tracing system. Depending on the actual
106// enabled state, this event may be recorded or dropped.
107// - phase specifies the type of event:
108// - BEGIN ('B'): Marks the beginning of a scoped event.
109// - END ('E'): Marks the end of a scoped event.
110// - COMPLETE ('X'): Marks the beginning of a scoped event, but doesn't
111// need a matching END event. Instead, at the end of the scope,
112// updateTraceEventDuration() must be called with the TraceEventHandle
113// returned from addTraceEvent().
114// - INSTANT ('I'): Standalone, instantaneous event.
115// - START ('S'): Marks the beginning of an asynchronous event (the end
116// event can occur in a different scope or thread). The id parameter is
117// used to match START/FINISH pairs.
118// - FINISH ('F'): Marks the end of an asynchronous event.
119// - COUNTER ('C'): Used to trace integer quantities that change over
120// time. The argument values are expected to be of type int.
121// - METADATA ('M'): Reserved for internal use.
122// - categoryEnabled is the pointer returned by getTraceCategoryEnabledFlag.
123// - name is the name of the event. Also used to match BEGIN/END and
124// START/FINISH pairs.
125// - id optionally allows events of the same name to be distinguished from
126// each other. For example, to trace the construction and destruction of
127// objects, specify the pointer as the id parameter.
128// - timestamp should be a time value returned from monotonicallyIncreasingTime.
129// - numArgs specifies the number of elements in argNames, argTypes, and
130// argValues.
131// - argNames is the array of argument names. Use long-lived literal strings
132// or specify the COPY flag.
133// - argTypes is the array of argument types:
134// - BOOL (1): bool
135// - UINT (2): unsigned long long
136// - INT (3): long long
137// - DOUBLE (4): double
138// - POINTER (5): void*
139// - STRING (6): char* (long-lived null-terminated char* string)
140// - COPY_STRING (7): char* (temporary null-terminated char* string)
141// - CONVERTABLE (8): WebConvertableToTraceFormat
142// - argValues is the array of argument values. Each value is the unsigned
143// long long member of a union of all supported types.
144// - flags can be 0 or one or more of the following, ORed together:
145// - COPY (0x1): treat all strings (name, argNames and argValues of type
146// string) as temporary so that they will be copied by addTraceEvent.
147// - HAS_ID (0x2): use the id argument to uniquely identify the event for
148// matching with other events of the same name.
149// - MANGLE_ID (0x4): specify this flag if the id parameter is the value
150// of a pointer.
151using AddTraceEventFunc = angle::TraceEventHandle (*)(PlatformMethods *platform,
152 char phase,
153 const unsigned char *categoryEnabledFlag,
154 const char *name,
155 unsigned long long id,
156 double timestamp,
157 int numArgs,
158 const char **argNames,
159 const unsigned char *argTypes,
160 const unsigned long long *argValues,
161 unsigned char flags);
162inline angle::TraceEventHandle DefaultAddTraceEvent(PlatformMethods *platform,
163 char phase,
164 const unsigned char *categoryEnabledFlag,
165 const char *name,
166 unsigned long long id,
167 double timestamp,
168 int numArgs,
169 const char **argNames,
170 const unsigned char *argTypes,
171 const unsigned long long *argValues,
172 unsigned char flags)
173{
174 return 0;
175}
176
177// Set the duration field of a COMPLETE trace event.
178using UpdateTraceEventDurationFunc = void (*)(PlatformMethods *platform,
179 const unsigned char *categoryEnabledFlag,
180 const char *name,
181 angle::TraceEventHandle eventHandle);
182inline void DefaultUpdateTraceEventDuration(PlatformMethods *platform,
183 const unsigned char *categoryEnabledFlag,
184 const char *name,
185 angle::TraceEventHandle eventHandle)
186{
187}
188
189// Callbacks for reporting histogram data.
190// CustomCounts histogram has exponential bucket sizes, so that min=1, max=1000000, bucketCount=50
191// would do.
192using HistogramCustomCountsFunc = void (*)(PlatformMethods *platform,
193 const char *name,
194 int sample,
195 int min,
196 int max,
197 int bucketCount);
198inline void DefaultHistogramCustomCounts(PlatformMethods *platform,
199 const char *name,
200 int sample,
201 int min,
202 int max,
203 int bucketCount)
204{
205}
206// Enumeration histogram buckets are linear, boundaryValue should be larger than any possible sample
207// value.
208using HistogramEnumerationFunc = void (*)(PlatformMethods *platform,
209 const char *name,
210 int sample,
211 int boundaryValue);
212inline void DefaultHistogramEnumeration(PlatformMethods *platform,
213 const char *name,
214 int sample,
215 int boundaryValue)
216{
217}
218// Unlike enumeration histograms, sparse histograms only allocate memory for non-empty buckets.
219using HistogramSparseFunc = void (*)(PlatformMethods *platform, const char *name, int sample);
220inline void DefaultHistogramSparse(PlatformMethods *platform, const char *name, int sample)
221{
222}
223// Boolean histograms track two-state variables.
224using HistogramBooleanFunc = void (*)(PlatformMethods *platform, const char *name, bool sample);
225inline void DefaultHistogramBoolean(PlatformMethods *platform, const char *name, bool sample)
226{
227}
228
229// Allows us to programatically override ANGLE's default workarounds for testing purposes.
230using OverrideWorkaroundsD3DFunc = void (*)(PlatformMethods *platform,
231 angle::WorkaroundsD3D *workaroundsD3D);
232inline void DefaultOverrideWorkaroundsD3D(PlatformMethods *platform,
233 angle::WorkaroundsD3D *workaroundsD3D)
234{
235}
236
Tobin Ehlisf95bf342018-11-13 12:56:01 -0700237using OverrideFeaturesVkFunc = void (*)(PlatformMethods *platform,
238 angle::FeaturesVk *workaroundsVulkan);
239inline void DefaultOverrideFeaturesVk(PlatformMethods *platform,
240 angle::FeaturesVk *workaroundsVulkan)
241{
242}
243
Tobin Ehlis96a184d2018-07-18 16:14:07 -0600244// Callback on a successful program link with the program binary. Can be used to store
245// shaders to disk. Keys are a 160-bit SHA-1 hash.
246using ProgramKeyType = std::array<uint8_t, 20>;
247using CacheProgramFunc = void (*)(PlatformMethods *platform,
248 const ProgramKeyType &key,
249 size_t programSize,
250 const uint8_t *programBytes);
251inline void DefaultCacheProgram(PlatformMethods *platform,
252 const ProgramKeyType &key,
253 size_t programSize,
254 const uint8_t *programBytes)
255{
256}
257
258// Platform methods are enumerated here once.
259#define ANGLE_PLATFORM_OP(OP) \
260 OP(currentTime, CurrentTime) \
261 OP(monotonicallyIncreasingTime, MonotonicallyIncreasingTime) \
262 OP(logError, LogError) \
263 OP(logWarning, LogWarning) \
264 OP(logInfo, LogInfo) \
265 OP(getTraceCategoryEnabledFlag, GetTraceCategoryEnabledFlag) \
266 OP(addTraceEvent, AddTraceEvent) \
267 OP(updateTraceEventDuration, UpdateTraceEventDuration) \
268 OP(histogramCustomCounts, HistogramCustomCounts) \
269 OP(histogramEnumeration, HistogramEnumeration) \
270 OP(histogramSparse, HistogramSparse) \
271 OP(histogramBoolean, HistogramBoolean) \
272 OP(overrideWorkaroundsD3D, OverrideWorkaroundsD3D) \
Tobin Ehlisf95bf342018-11-13 12:56:01 -0700273 OP(overrideFeaturesVk, OverrideFeaturesVk) \
Tobin Ehlis96a184d2018-07-18 16:14:07 -0600274 OP(cacheProgram, CacheProgram)
275
276#define ANGLE_PLATFORM_METHOD_DEF(Name, CapsName) CapsName##Func Name = Default##CapsName;
277
278struct ANGLE_PLATFORM_EXPORT PlatformMethods
279{
280 PlatformMethods() {}
281
282 // User data pointer for any implementation specific members. Put it at the start of the
283 // platform structure so it doesn't become overwritten if one version of the platform
284 // adds or removes new members.
285 void *context = 0;
286
287 ANGLE_PLATFORM_OP(ANGLE_PLATFORM_METHOD_DEF);
288};
289
290#undef ANGLE_PLATFORM_METHOD_DEF
291
292// Subtract one to account for the context pointer.
293constexpr unsigned int g_NumPlatformMethods = (sizeof(PlatformMethods) / sizeof(uintptr_t)) - 1;
294
295#define ANGLE_PLATFORM_METHOD_STRING(Name) #Name
296#define ANGLE_PLATFORM_METHOD_STRING2(Name, CapsName) ANGLE_PLATFORM_METHOD_STRING(Name),
297
298constexpr const char *const g_PlatformMethodNames[g_NumPlatformMethods] = {
299 ANGLE_PLATFORM_OP(ANGLE_PLATFORM_METHOD_STRING2)};
300
301#undef ANGLE_PLATFORM_METHOD_STRING2
302#undef ANGLE_PLATFORM_METHOD_STRING
303
304} // namespace angle
305
306extern "C" {
307
308// Gets the platform methods on the passed-in EGL display. If the method name signature does not
309// match the compiled signature for this ANGLE, false is returned. On success true is returned.
310// The application should set any platform methods it cares about on the returned pointer.
311// If display is not valid, behaviour is undefined.
312
313ANGLE_PLATFORM_EXPORT bool ANGLE_APIENTRY ANGLEGetDisplayPlatform(angle::EGLDisplayType display,
314 const char *const methodNames[],
315 unsigned int methodNameCount,
316 void *context,
317 void *platformMethodsOut);
318
319// Sets the platform methods back to their defaults.
320// If display is not valid, behaviour is undefined.
321ANGLE_PLATFORM_EXPORT void ANGLE_APIENTRY ANGLEResetDisplayPlatform(angle::EGLDisplayType display);
322
323} // extern "C"
324
325namespace angle
326{
327typedef bool(ANGLE_APIENTRY *GetDisplayPlatformFunc)(angle::EGLDisplayType,
328 const char *const *,
329 unsigned int,
330 void *,
331 void *);
332typedef void(ANGLE_APIENTRY *ResetDisplayPlatformFunc)(angle::EGLDisplayType);
333} // namespace angle
334
335// This function is not exported
336angle::PlatformMethods *ANGLEPlatformCurrent();
337
338#endif // ANGLE_PLATFORM_H