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