Path: blob/main_old/include/platform/PlatformMethods.h
1693 views
//1// Copyright 2015 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.45// PlatformMethods.h: The public interface ANGLE exposes to the API layer, for6// doing platform-specific tasks like gathering data, or for tracing.78#ifndef ANGLE_PLATFORMMETHODS_H9#define ANGLE_PLATFORMMETHODS_H1011#include <stdint.h>12#include <stdlib.h>13#include <array>1415#define EGL_PLATFORM_ANGLE_PLATFORM_METHODS_ANGLEX 0x34821617#if !defined(ANGLE_PLATFORM_EXPORT)18# if defined(_WIN32)19# if !defined(LIBANGLE_IMPLEMENTATION)20# define ANGLE_PLATFORM_EXPORT __declspec(dllimport)21# else22# define ANGLE_PLATFORM_EXPORT __declspec(dllexport)23# endif24# elif defined(__GNUC__) || defined(__clang__)25# define ANGLE_PLATFORM_EXPORT __attribute__((visibility("default")))26# endif27#endif28#if !defined(ANGLE_PLATFORM_EXPORT)29# define ANGLE_PLATFORM_EXPORT30#endif3132#if defined(_WIN32)33# define ANGLE_APIENTRY __stdcall34#else35# define ANGLE_APIENTRY36#endif3738namespace angle39{40struct FeaturesD3D;41struct FeaturesVk;42struct FeaturesMtl;43using TraceEventHandle = uint64_t;44using EGLDisplayType = void *;45struct PlatformMethods;4647// Use a C-like API to not trigger undefined calling behaviour.48// Avoid using decltype here to work around sanitizer limitations.49// TODO(jmadill): Use decltype here if/when UBSAN is fixed.5051// System --------------------------------------------------------------5253// Wall clock time in seconds since the epoch.54// TODO(jmadill): investigate using an ANGLE internal time library55using CurrentTimeFunc = double (*)(PlatformMethods *platform);56inline double DefaultCurrentTime(PlatformMethods *platform)57{58return 0.0;59}6061// Monotonically increasing time in seconds from an arbitrary fixed point in the past.62// This function is expected to return at least millisecond-precision values. For this reason,63// it is recommended that the fixed point be no further in the past than the epoch.64using MonotonicallyIncreasingTimeFunc = double (*)(PlatformMethods *platform);65inline double DefaultMonotonicallyIncreasingTime(PlatformMethods *platform)66{67return 0.0;68}6970// Logging ------------------------------------------------------------7172// Log an error message within the platform implementation.73using LogErrorFunc = void (*)(PlatformMethods *platform, const char *errorMessage);74inline void DefaultLogError(PlatformMethods *platform, const char *errorMessage) {}7576// Log a warning message within the platform implementation.77using LogWarningFunc = void (*)(PlatformMethods *platform, const char *warningMessage);78inline void DefaultLogWarning(PlatformMethods *platform, const char *warningMessage) {}7980// Log an info message within the platform implementation.81using LogInfoFunc = void (*)(PlatformMethods *platform, const char *infoMessage);82inline void DefaultLogInfo(PlatformMethods *platform, const char *infoMessage) {}8384// Tracing --------8586// Get a pointer to the enabled state of the given trace category. The87// embedder can dynamically change the enabled state as trace event88// recording is started and stopped by the application. Only long-lived89// literal strings should be given as the category name. The implementation90// expects the returned pointer to be held permanently in a local static. If91// the unsigned char is non-zero, tracing is enabled. If tracing is enabled,92// addTraceEvent is expected to be called by the trace event macros.93using GetTraceCategoryEnabledFlagFunc = const unsigned char *(*)(PlatformMethods *platform,94const char *categoryName);95inline const unsigned char *DefaultGetTraceCategoryEnabledFlag(PlatformMethods *platform,96const char *categoryName)97{98return nullptr;99}100101//102// Add a trace event to the platform tracing system. Depending on the actual103// enabled state, this event may be recorded or dropped.104// - phase specifies the type of event:105// - BEGIN ('B'): Marks the beginning of a scoped event.106// - END ('E'): Marks the end of a scoped event.107// - COMPLETE ('X'): Marks the beginning of a scoped event, but doesn't108// need a matching END event. Instead, at the end of the scope,109// updateTraceEventDuration() must be called with the TraceEventHandle110// returned from addTraceEvent().111// - INSTANT ('I'): Standalone, instantaneous event.112// - START ('S'): Marks the beginning of an asynchronous event (the end113// event can occur in a different scope or thread). The id parameter is114// used to match START/FINISH pairs.115// - FINISH ('F'): Marks the end of an asynchronous event.116// - COUNTER ('C'): Used to trace integer quantities that change over117// time. The argument values are expected to be of type int.118// - METADATA ('M'): Reserved for internal use.119// - categoryEnabled is the pointer returned by getTraceCategoryEnabledFlag.120// - name is the name of the event. Also used to match BEGIN/END and121// START/FINISH pairs.122// - id optionally allows events of the same name to be distinguished from123// each other. For example, to trace the construction and destruction of124// objects, specify the pointer as the id parameter.125// - timestamp should be a time value returned from monotonicallyIncreasingTime.126// - numArgs specifies the number of elements in argNames, argTypes, and127// argValues.128// - argNames is the array of argument names. Use long-lived literal strings129// or specify the COPY flag.130// - argTypes is the array of argument types:131// - BOOL (1): bool132// - UINT (2): unsigned long long133// - INT (3): long long134// - DOUBLE (4): double135// - POINTER (5): void*136// - STRING (6): char* (long-lived null-terminated char* string)137// - COPY_STRING (7): char* (temporary null-terminated char* string)138// - CONVERTABLE (8): WebConvertableToTraceFormat139// - argValues is the array of argument values. Each value is the unsigned140// long long member of a union of all supported types.141// - flags can be 0 or one or more of the following, ORed together:142// - COPY (0x1): treat all strings (name, argNames and argValues of type143// string) as temporary so that they will be copied by addTraceEvent.144// - HAS_ID (0x2): use the id argument to uniquely identify the event for145// matching with other events of the same name.146// - MANGLE_ID (0x4): specify this flag if the id parameter is the value147// of a pointer.148using AddTraceEventFunc = angle::TraceEventHandle (*)(PlatformMethods *platform,149char phase,150const unsigned char *categoryEnabledFlag,151const char *name,152unsigned long long id,153double timestamp,154int numArgs,155const char **argNames,156const unsigned char *argTypes,157const unsigned long long *argValues,158unsigned char flags);159inline angle::TraceEventHandle DefaultAddTraceEvent(PlatformMethods *platform,160char phase,161const unsigned char *categoryEnabledFlag,162const char *name,163unsigned long long id,164double timestamp,165int numArgs,166const char **argNames,167const unsigned char *argTypes,168const unsigned long long *argValues,169unsigned char flags)170{171return 0;172}173174// Set the duration field of a COMPLETE trace event.175using UpdateTraceEventDurationFunc = void (*)(PlatformMethods *platform,176const unsigned char *categoryEnabledFlag,177const char *name,178angle::TraceEventHandle eventHandle);179inline void DefaultUpdateTraceEventDuration(PlatformMethods *platform,180const unsigned char *categoryEnabledFlag,181const char *name,182angle::TraceEventHandle eventHandle)183{}184185// Callbacks for reporting histogram data.186// CustomCounts histogram has exponential bucket sizes, so that min=1, max=1000000, bucketCount=50187// would do.188using HistogramCustomCountsFunc = void (*)(PlatformMethods *platform,189const char *name,190int sample,191int min,192int max,193int bucketCount);194inline void DefaultHistogramCustomCounts(PlatformMethods *platform,195const char *name,196int sample,197int min,198int max,199int bucketCount)200{}201// Enumeration histogram buckets are linear, boundaryValue should be larger than any possible sample202// value.203using HistogramEnumerationFunc = void (*)(PlatformMethods *platform,204const char *name,205int sample,206int boundaryValue);207inline void DefaultHistogramEnumeration(PlatformMethods *platform,208const char *name,209int sample,210int boundaryValue)211{}212// Unlike enumeration histograms, sparse histograms only allocate memory for non-empty buckets.213using HistogramSparseFunc = void (*)(PlatformMethods *platform, const char *name, int sample);214inline void DefaultHistogramSparse(PlatformMethods *platform, const char *name, int sample) {}215// Boolean histograms track two-state variables.216using HistogramBooleanFunc = void (*)(PlatformMethods *platform, const char *name, bool sample);217inline void DefaultHistogramBoolean(PlatformMethods *platform, const char *name, bool sample) {}218219// Allows us to programatically override ANGLE's default workarounds for testing purposes.220using OverrideWorkaroundsD3DFunc = void (*)(PlatformMethods *platform,221angle::FeaturesD3D *featuresD3D);222inline void DefaultOverrideWorkaroundsD3D(PlatformMethods *platform,223angle::FeaturesD3D *featuresD3D)224{}225226using OverrideFeaturesVkFunc = void (*)(PlatformMethods *platform,227angle::FeaturesVk *featuresVulkan);228inline void DefaultOverrideFeaturesVk(PlatformMethods *platform, angle::FeaturesVk *featuresVulkan)229{}230231using OverrideFeaturesMtlFunc = void (*)(PlatformMethods *platform,232angle::FeaturesMtl *featuresMetal);233inline void DefaultOverrideFeaturesMtl(PlatformMethods *platform, angle::FeaturesMtl *featuresMetal)234{}235236// Callback on a successful program link with the program binary. Can be used to store237// shaders to disk. Keys are a 160-bit SHA-1 hash.238using ProgramKeyType = std::array<uint8_t, 20>;239using CacheProgramFunc = void (*)(PlatformMethods *platform,240const ProgramKeyType &key,241size_t programSize,242const uint8_t *programBytes);243inline void DefaultCacheProgram(PlatformMethods *platform,244const ProgramKeyType &key,245size_t programSize,246const uint8_t *programBytes)247{}248249using PostWorkerTaskCallback = void (*)(void *userData);250using PostWorkerTaskFunc = void (*)(PlatformMethods *platform,251PostWorkerTaskCallback callback,252void *userData);253constexpr PostWorkerTaskFunc DefaultPostWorkerTask = nullptr;254255// Platform methods are enumerated here once.256#define ANGLE_PLATFORM_OP(OP) \257OP(currentTime, CurrentTime) \258OP(monotonicallyIncreasingTime, MonotonicallyIncreasingTime) \259OP(logError, LogError) \260OP(logWarning, LogWarning) \261OP(logInfo, LogInfo) \262OP(getTraceCategoryEnabledFlag, GetTraceCategoryEnabledFlag) \263OP(addTraceEvent, AddTraceEvent) \264OP(updateTraceEventDuration, UpdateTraceEventDuration) \265OP(histogramCustomCounts, HistogramCustomCounts) \266OP(histogramEnumeration, HistogramEnumeration) \267OP(histogramSparse, HistogramSparse) \268OP(histogramBoolean, HistogramBoolean) \269OP(overrideWorkaroundsD3D, OverrideWorkaroundsD3D) \270OP(overrideFeaturesVk, OverrideFeaturesVk) \271OP(cacheProgram, CacheProgram) \272OP(overrideFeaturesMtl, OverrideFeaturesMtl) \273OP(postWorkerTask, PostWorkerTask)274275#define ANGLE_PLATFORM_METHOD_DEF(Name, CapsName) CapsName##Func Name = Default##CapsName;276277struct ANGLE_PLATFORM_EXPORT PlatformMethods278{279inline PlatformMethods();280281// User data pointer for any implementation specific members. Put it at the start of the282// platform structure so it doesn't become overwritten if one version of the platform283// adds or removes new members.284void *context = 0;285286ANGLE_PLATFORM_OP(ANGLE_PLATFORM_METHOD_DEF)287};288289inline PlatformMethods::PlatformMethods() = default;290291#undef ANGLE_PLATFORM_METHOD_DEF292293// Subtract one to account for the context pointer.294constexpr unsigned int g_NumPlatformMethods = (sizeof(PlatformMethods) / sizeof(uintptr_t)) - 1;295296#define ANGLE_PLATFORM_METHOD_STRING(Name) #Name297#define ANGLE_PLATFORM_METHOD_STRING2(Name, CapsName) ANGLE_PLATFORM_METHOD_STRING(Name),298299constexpr const char *const g_PlatformMethodNames[g_NumPlatformMethods] = {300ANGLE_PLATFORM_OP(ANGLE_PLATFORM_METHOD_STRING2)};301302#undef ANGLE_PLATFORM_METHOD_STRING2303#undef ANGLE_PLATFORM_METHOD_STRING304305} // namespace angle306307extern "C" {308309// Gets the platform methods on the passed-in EGL display. If the method name signature does not310// match the compiled signature for this ANGLE, false is returned. On success true is returned.311// The application should set any platform methods it cares about on the returned pointer.312// If display is not valid, behaviour is undefined.313314ANGLE_PLATFORM_EXPORT bool ANGLE_APIENTRY ANGLEGetDisplayPlatform(angle::EGLDisplayType display,315const char *const methodNames[],316unsigned int methodNameCount,317void *context,318void *platformMethodsOut);319320// Sets the platform methods back to their defaults.321// If display is not valid, behaviour is undefined.322ANGLE_PLATFORM_EXPORT void ANGLE_APIENTRY ANGLEResetDisplayPlatform(angle::EGLDisplayType display);323} // extern "C"324325namespace angle326{327typedef bool(ANGLE_APIENTRY *GetDisplayPlatformFunc)(angle::EGLDisplayType,328const char *const *,329unsigned int,330void *,331void *);332typedef void(ANGLE_APIENTRY *ResetDisplayPlatformFunc)(angle::EGLDisplayType);333} // namespace angle334335// This function is not exported336angle::PlatformMethods *ANGLEPlatformCurrent();337338#endif // ANGLE_PLATFORMMETHODS_H339340341